- DM support for OMAP PWM backlight
- USB host mode support for AM654
- Minor SPI fixes
- Add support k2g ice board with 1GHz silicon
- Fix GTC programming for K3 devices
This commit is contained in:
Tom Rini 2021-01-12 09:32:48 -05:00
commit ee6726be4f
109 changed files with 6043 additions and 1224 deletions

View File

@ -799,6 +799,7 @@ config ARCH_OMAP2PLUS
select SPL_BOARD_INIT if SPL
select SPL_STACK_R if SPL
select SUPPORT_SPL
imply TI_SYSC if DM && OF_CONTROL
imply FIT
config ARCH_MESON

View File

@ -53,8 +53,6 @@
bkl-pwm = <&pwmbacklight>;
bkl-tps = <&tps_bl>;
u-boot,dm-pre-reloc;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
@ -238,8 +236,19 @@
status = "okay";
};
&lcdc {
status = "disabled";
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
status = "disabled";
};
};
};
};
&elm {

View File

@ -53,8 +53,6 @@
bkl-pwm = <&pwmbacklight>;
bkl-tps = <&tps_bl>;
u-boot,dm-pre-reloc;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
@ -228,8 +226,19 @@
status = "disabled";
};
&lcdc {
status = "disabled";
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
status = "disabled";
};
};
};
};
&elm {

View File

@ -54,8 +54,6 @@
bkl-pwm = <&pwmbacklight>;
bkl-tps = <&tps_bl>;
u-boot,dm-pre-reloc;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
@ -259,8 +257,19 @@
status = "okay";
};
&lcdc {
status = "disabled";
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
status = "disabled";
};
};
};
};
&elm {

View File

@ -59,7 +59,6 @@
/*backlight = <&tps_bl>; */
compatible = "ti,tilcdc,panel";
status = "okay";
u-boot,dm-pre-reloc;
panel-info {
ac-bias = <255>;
@ -298,10 +297,21 @@
status = "okay";
};
&lcdc {
status = "okay";
ti,no-reset-on-init;
ti,no-idle-on-init;
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
status = "okay";
ti,no-reset-on-init;
ti,no-idle-on-init;
};
};
};
};
&elm {

View File

@ -79,8 +79,6 @@
backlight = <&tps_bl>;
u-boot,dm-pre-reloc;
panel-info {
ac-bias = <255>;
ac-bias-intrpt = <0>;
@ -254,10 +252,21 @@
status = "okay";
};
&lcdc {
status = "okay";
ti,no-reset-on-init;
ti,no-idle-on-init;
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
status = "okay";
ti,no-reset-on-init;
ti,no-idle-on-init;
};
};
};
};
&elm {

View File

@ -4,6 +4,8 @@
* Author: Marcin Niestroj <m.niestroj@grinn-global.com>
*/
#include "am33xx-u-boot.dtsi"
/ {
chosen {
stdout-path = &uart0;

View File

@ -20,11 +20,6 @@
};
ocp {
uart0: serial@44e09000 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
status = "okay";
};
i2c0: i2c@44e0b000 {
pinctrl-names = "default";
@ -112,6 +107,12 @@
status = "disabled";
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
status = "okay";
};
&uart4 {
status = "disabled";
};

View File

@ -3,13 +3,22 @@
* Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
*/
/ {
panel {
u-boot,dm-pre-reloc;
#include "am33xx-u-boot.dtsi"
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};
&mmc3 {
status = "disabled";
};

View File

@ -486,7 +486,7 @@
&epwmss0 {
status = "okay";
ecap0: ecap@48300100 {
ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ecap0_pins>;

View File

@ -5,8 +5,18 @@
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
/ {
panel {
u-boot,dm-pre-reloc;
#include "am33xx-u-boot.dtsi"
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};

View File

@ -531,7 +531,7 @@
&epwmss2 {
status = "okay";
ecap2: ecap@48304100 {
ecap2: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ecap2_pins>;

View File

@ -4,20 +4,32 @@
* Copyright (C) 2018 Robert Bosch Power Tools GmbH
*/
#include "am33xx-u-boot.dtsi"
/ {
ocp {
u-boot,dm-pre-reloc;
};
panel {
u-boot,dm-pre-reloc;
};
};
&l4_wkup {
u-boot,dm-pre-reloc;
};
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};
&mmc1 {
u-boot,dm-pre-reloc;
};
@ -26,11 +38,6 @@
u-boot,dm-pre-reloc;
};
&rtc {
clocks = <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clock-names = "int-clk";
};
&scm {
u-boot,dm-pre-reloc;
};

View File

@ -2,6 +2,9 @@
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
#include "am33xx-u-boot.dtsi"
/ {
xtal25mhz: xtal25mhz {
compatible = "fixed-clock";

View File

@ -3,20 +3,32 @@
* Copyright (C) 2018 EETS GmbH - https://www.eets.ch/
*/
#include "am33xx-u-boot.dtsi"
/ {
ocp {
u-boot,dm-pre-reloc;
};
panel {
u-boot,dm-pre-reloc;
};
};
&l4_wkup {
u-boot,dm-pre-reloc;
};
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};
&scm {
u-boot,dm-pre-reloc;
};

View File

@ -148,7 +148,7 @@
&epwmss0 {
status = "okay";
ecap0: ecap@48300100 {
ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ecap0_pins>;

View File

@ -5,8 +5,18 @@
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
/ {
panel {
u-boot,dm-pre-reloc;
#include "am33xx-u-boot.dtsi"
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};

View File

@ -3,6 +3,8 @@
* Copyright (C) 2020 Linumiz
*/
#include "am33xx-u-boot.dtsi"
/ {
chosen {
#address-cells = <1>;

View File

@ -5,8 +5,18 @@
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
/ {
panel {
u-boot,dm-pre-reloc;
#include "am33xx-u-boot.dtsi"
&l4_per {
segment@300000 {
target-module@e000 {
u-boot,dm-pre-reloc;
lcdc: lcdc@0 {
u-boot,dm-pre-reloc;
};
};
};
};

View File

@ -174,7 +174,7 @@
&epwmss0 {
status = "okay";
ecap0: ecap@48300100 {
ecap0: ecap@100 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&ecap0_pins>;

View File

@ -3,6 +3,8 @@
* Copyright (C) 2019 Heiko Schocher <hs@denx.de>
*/
#include "am33xx-u-boot.dtsi"
/ {
ocp {
u-boot,dm-pre-reloc;

View File

@ -136,7 +136,7 @@
&epwmss1 {
status = "okay";
ehrpwm1: pwm@48302200 {
ehrpwm1: pwm@200 {
pinctrl-names = "default";
pinctrl-0 = <&ehrpwm1_pins>;
status = "okay";

View File

@ -3,6 +3,8 @@
* Copyright (C) 2019 DENX Software Engineering GmbH
*/
#include "am33xx-u-boot.dtsi"
/ {
chosen {
#address-cells = <1>;

View File

@ -334,49 +334,49 @@
timer1_fck: timer1_fck@528 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>;
clocks = <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>, <&tclkin_ck>, <&clk_rc32k_ck>, <&clk_32768_ck>;
reg = <0x0528>;
};
timer2_fck: timer2_fck@508 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x0508>;
};
timer3_fck: timer3_fck@50c {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x050c>;
};
timer4_fck: timer4_fck@510 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x0510>;
};
timer5_fck: timer5_fck@518 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x0518>;
};
timer6_fck: timer6_fck@51c {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x051c>;
};
timer7_fck: timer7_fck@504 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&tclkin_ck>, <&sys_clkin_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x0504>;
};
@ -407,7 +407,7 @@
wdt1_fck: wdt1_fck@538 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&clk_rc32k_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&clk_rc32k_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x0538>;
};
@ -477,7 +477,7 @@
gpio0_dbclk_mux_ck: gpio0_dbclk_mux_ck@53c {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clocks = <&clk_rc32k_ck>, <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
reg = <0x053c>;
};
@ -539,77 +539,131 @@
};
&prcm {
l4_per_cm: l4_per_cm@0 {
l4_per_cm: l4_per-cm@0 {
compatible = "ti,omap4-cm";
reg = <0x0 0x200>;
reg = <0x0 0x400>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x0 0x200>;
ranges = <0 0x0 0x400>;
l4_per_clkctrl: clk@14 {
l4ls_clkctrl: l4ls-clkctrl@38 {
compatible = "ti,clkctrl";
reg = <0x14 0x13c>;
reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>;
#clock-cells = <2>;
};
l3s_clkctrl: l3s-clkctrl@1c {
compatible = "ti,clkctrl";
reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4>;
#clock-cells = <2>;
};
l3_clkctrl: l3-clkctrl@24 {
compatible = "ti,clkctrl";
reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>;
#clock-cells = <2>;
};
l4hs_clkctrl: l4hs-clkctrl@120 {
compatible = "ti,clkctrl";
reg = <0x120 0x4>;
#clock-cells = <2>;
};
pruss_ocp_clkctrl: pruss-ocp-clkctrl@e8 {
compatible = "ti,clkctrl";
reg = <0xe8 0x4>;
#clock-cells = <2>;
};
cpsw_125mhz_clkctrl: cpsw-125mhz-clkctrl@0 {
compatible = "ti,clkctrl";
reg = <0x0 0x18>;
#clock-cells = <2>;
};
lcdc_clkctrl: lcdc-clkctrl@18 {
compatible = "ti,clkctrl";
reg = <0x18 0x4>;
#clock-cells = <2>;
};
clk_24mhz_clkctrl: clk-24mhz-clkctrl@14c {
compatible = "ti,clkctrl";
reg = <0x14c 0x4>;
#clock-cells = <2>;
};
};
l4_wkup_cm: l4_wkup_cm@400 {
wkup_cm: wkup-cm@400 {
compatible = "ti,omap4-cm";
reg = <0x400 0x100>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x400 0x100>;
l4_wkup_clkctrl: clk@4 {
l4_wkup_clkctrl: l4-wkup-clkctrl@0 {
compatible = "ti,clkctrl";
reg = <0x4 0xd4>;
reg = <0x4 0x10>, <0xb4 0x24>;
#clock-cells = <2>;
};
l3_aon_clkctrl: l3-aon-clkctrl@14 {
compatible = "ti,clkctrl";
reg = <0x14 0x4>;
#clock-cells = <2>;
};
l4_wkup_aon_clkctrl: l4-wkup-aon-clkctrl@b0 {
compatible = "ti,clkctrl";
reg = <0xb0 0x4>;
#clock-cells = <2>;
};
};
mpu_cm: mpu_cm@600 {
mpu_cm: mpu-cm@600 {
compatible = "ti,omap4-cm";
reg = <0x600 0x100>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x600 0x100>;
mpu_clkctrl: clk@4 {
mpu_clkctrl: mpu-clkctrl@0 {
compatible = "ti,clkctrl";
reg = <0x4 0x4>;
reg = <0x0 0x8>;
#clock-cells = <2>;
};
};
l4_rtc_cm: l4_rtc_cm@800 {
l4_rtc_cm: l4-rtc-cm@800 {
compatible = "ti,omap4-cm";
reg = <0x800 0x100>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x800 0x100>;
l4_rtc_clkctrl: clk@0 {
l4_rtc_clkctrl: l4-rtc-clkctrl@0 {
compatible = "ti,clkctrl";
reg = <0x0 0x4>;
#clock-cells = <2>;
};
};
gfx_l3_cm: gfx_l3_cm@900 {
gfx_l3_cm: gfx-l3-cm@900 {
compatible = "ti,omap4-cm";
reg = <0x900 0x100>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x900 0x100>;
gfx_l3_clkctrl: clk@4 {
gfx_l3_clkctrl: gfx-l3-clkctrl@0 {
compatible = "ti,clkctrl";
reg = <0x4 0x4>;
reg = <0x0 0x8>;
#clock-cells = <2>;
};
};
l4_cefuse_cm: l4_cefuse_cm@a00 {
l4_cefuse_cm: l4-cefuse-cm@a00 {
compatible = "ti,omap4-cm";
reg = <0xa00 0x100>;
#address-cells = <1>;

1962
arch/arm/dts/am33xx-l4.dtsi Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,3 +9,11 @@
u-boot,dm-pre-reloc;
};
};
&prcm_clocks {
compatible = "simple-bus";
};
&scm_clocks {
compatible = "simple-bus";
};

View File

@ -8,6 +8,7 @@
* kind, whether express or implied.
*/
#include <dt-bindings/bus/ti-sysc.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>
#include <dt-bindings/clock/am3.h>
@ -46,6 +47,7 @@
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a8";
enable-method = "ti,am3352";
device_type = "cpu";
reg = <0>;
@ -55,6 +57,17 @@
clock-names = "cpu";
clock-latency = <300000>; /* From omap-cpufreq driver */
cpu-idle-states = <&mpu_gate>;
};
idle-states {
mpu_gate: mpu_gate {
compatible = "arm,idle-state";
entry-latency-us = <40>;
exit-latency-us = <90>;
min-residency-us = <300>;
ti,idle-wkup-m3;
};
};
};
@ -167,11 +180,6 @@
ti,hwmods = "l3_main";
l4_wkup: l4_wkup@44c00000 {
compatible = "ti,am3-l4-wkup", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x44c00000 0x280000>;
wkup_m3: wkup_m3@100000 {
compatible = "ti,am3352-wkup-m3";
reg = <0x100000 0x4000>,
@ -180,73 +188,14 @@
ti,hwmods = "wkup_m3";
ti,pm-firmware = "am335x-pm-firmware.elf";
};
prcm: prcm@200000 {
compatible = "ti,am3-prcm", "simple-bus";
reg = <0x200000 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x200000 0x4000>;
prcm_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
prcm_clockdomains: clockdomains {
};
};
scm: scm@210000 {
compatible = "ti,am3-scm", "simple-bus";
reg = <0x210000 0x2000>;
#address-cells = <1>;
#size-cells = <1>;
#pinctrl-cells = <1>;
ranges = <0 0x210000 0x2000>;
am33xx_pinmux: pinmux@800 {
compatible = "pinctrl-single";
reg = <0x800 0x238>;
#address-cells = <1>;
#size-cells = <0>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x7f>;
};
scm_conf: scm_conf@0 {
compatible = "syscon", "simple-bus";
reg = <0x0 0x800>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0x800>;
scm_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
};
wkup_m3_ipc: wkup_m3_ipc@1324 {
compatible = "ti,am3352-wkup-m3-ipc";
reg = <0x1324 0x24>;
interrupts = <78>;
ti,rproc = <&wkup_m3>;
mboxes = <&mailbox &mbox_wkupm3>;
};
edma_xbar: dma-router@f90 {
compatible = "ti,am335x-edma-crossbar";
reg = <0xf90 0x40>;
#dma-cells = <3>;
dma-requests = <32>;
dma-masters = <&edma>;
};
scm_clockdomains: clockdomains {
};
};
};
l4_per: interconnect@48000000 {
};
l4_fw: interconnect@47c00000 {
};
l4_fast: interconnect@4a000000 {
};
l4_mpuss: interconnect@4b140000 {
};
intc: interrupt-controller@48200000 {
@ -256,45 +205,100 @@
reg = <0x48200000 0x1000>;
};
edma: edma@49000000 {
compatible = "ti,edma3-tpcc";
ti,hwmods = "tpcc";
reg = <0x49000000 0x10000>;
reg-names = "edma3_cc";
interrupts = <12 13 14>;
interrupt-names = "edma3_ccint", "edma3_mperr",
"edma3_ccerrint";
dma-requests = <64>;
#dma-cells = <2>;
target-module@49000000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x49000000 0x4>;
reg-names = "rev";
clocks = <&l3_clkctrl AM3_L3_TPCC_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x49000000 0x10000>;
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
<&edma_tptc2 0>;
edma: dma@0 {
compatible = "ti,edma3-tpcc";
reg = <0 0x10000>;
reg-names = "edma3_cc";
interrupts = <12 13 14>;
interrupt-names = "edma3_ccint", "edma3_mperr",
"edma3_ccerrint";
dma-requests = <64>;
#dma-cells = <2>;
ti,edma-memcpy-channels = <20 21>;
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
<&edma_tptc2 0>;
ti,edma-memcpy-channels = <20 21>;
};
};
edma_tptc0: tptc@49800000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc0";
reg = <0x49800000 0x100000>;
interrupts = <112>;
interrupt-names = "edma3_tcerrint";
target-module@49800000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x49800000 0x4>,
<0x49800010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
ti,sysc-midle = <SYSC_IDLE_FORCE>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_SMART>;
clocks = <&l3_clkctrl AM3_L3_TPTC0_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x49800000 0x100000>;
edma_tptc0: dma@0 {
compatible = "ti,edma3-tptc";
reg = <0 0x100000>;
interrupts = <112>;
interrupt-names = "edma3_tcerrint";
};
};
edma_tptc1: tptc@49900000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc1";
reg = <0x49900000 0x100000>;
interrupts = <113>;
interrupt-names = "edma3_tcerrint";
target-module@49900000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x49900000 0x4>,
<0x49900010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
ti,sysc-midle = <SYSC_IDLE_FORCE>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_SMART>;
clocks = <&l3_clkctrl AM3_L3_TPTC1_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x49900000 0x100000>;
edma_tptc1: dma@0 {
compatible = "ti,edma3-tptc";
reg = <0 0x100000>;
interrupts = <113>;
interrupt-names = "edma3_tcerrint";
};
};
edma_tptc2: tptc@49a00000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc2";
reg = <0x49a00000 0x100000>;
interrupts = <114>;
interrupt-names = "edma3_tcerrint";
target-module@49a00000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x49a00000 0x4>,
<0x49a00010 0x4>;
reg-names = "rev", "sysc";
ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
ti,sysc-midle = <SYSC_IDLE_FORCE>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_SMART>;
clocks = <&l3_clkctrl AM3_L3_TPTC2_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x49a00000 0x100000>;
edma_tptc2: dma@0 {
compatible = "ti,edma3-tptc";
reg = <0 0x100000>;
interrupts = <114>;
interrupt-names = "edma3_tcerrint";
};
};
gpio0: gpio@44e07000 {
@ -341,66 +345,6 @@
interrupts = <62>;
};
uart0: serial@44e09000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart1";
clock-frequency = <48000000>;
reg = <0x44e09000 0x2000>;
interrupts = <72>;
status = "disabled";
dmas = <&edma 26 0>, <&edma 27 0>;
dma-names = "tx", "rx";
};
uart1: serial@48022000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart2";
clock-frequency = <48000000>;
reg = <0x48022000 0x2000>;
interrupts = <73>;
status = "disabled";
dmas = <&edma 28 0>, <&edma 29 0>;
dma-names = "tx", "rx";
};
uart2: serial@48024000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart3";
clock-frequency = <48000000>;
reg = <0x48024000 0x2000>;
interrupts = <74>;
status = "disabled";
dmas = <&edma 30 0>, <&edma 31 0>;
dma-names = "tx", "rx";
};
uart3: serial@481a6000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart4";
clock-frequency = <48000000>;
reg = <0x481a6000 0x2000>;
interrupts = <44>;
status = "disabled";
};
uart4: serial@481a8000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart5";
clock-frequency = <48000000>;
reg = <0x481a8000 0x2000>;
interrupts = <45>;
status = "disabled";
};
uart5: serial@481aa000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart6";
clock-frequency = <48000000>;
reg = <0x481aa000 0x2000>;
interrupts = <46>;
status = "disabled";
};
i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
@ -466,13 +410,6 @@
status = "disabled";
};
hwspinlock: spinlock@480ca000 {
compatible = "ti,omap4-hwspinlock";
reg = <0x480ca000 0x1000>;
ti,hwmods = "spinlock";
#hwlock-cells = <1>;
};
wdt2: wdt@44e35000 {
compatible = "ti,omap3-wdt";
ti,hwmods = "wd_timer2";
@ -480,143 +417,6 @@
interrupts = <91>;
};
dcan0: can@481cc000 {
compatible = "ti,am3352-d_can";
ti,hwmods = "d_can0";
reg = <0x481cc000 0x2000>;
clocks = <&dcan0_fck>;
clock-names = "fck";
syscon-raminit = <&scm_conf 0x644 0>;
interrupts = <52>;
status = "disabled";
};
dcan1: can@481d0000 {
compatible = "ti,am3352-d_can";
ti,hwmods = "d_can1";
reg = <0x481d0000 0x2000>;
clocks = <&dcan1_fck>;
clock-names = "fck";
syscon-raminit = <&scm_conf 0x644 1>;
interrupts = <55>;
status = "disabled";
};
mailbox: mailbox@480c8000 {
compatible = "ti,omap4-mailbox";
reg = <0x480C8000 0x200>;
interrupts = <77>;
ti,hwmods = "mailbox";
#mbox-cells = <1>;
ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <8>;
mbox_wkupm3: wkup_m3 {
ti,mbox-send-noirq;
ti,mbox-tx = <0 0 0>;
ti,mbox-rx = <0 0 3>;
};
};
timer1: timer@44e31000 {
compatible = "ti,am335x-timer-1ms";
reg = <0x44e31000 0x400>;
interrupts = <67>;
ti,hwmods = "timer1";
ti,timer-alwon;
clocks = <&timer1_fck>;
clock-names = "fck";
};
timer2: timer@48040000 {
compatible = "ti,am335x-timer";
reg = <0x48040000 0x400>;
interrupts = <68>;
ti,hwmods = "timer2";
clocks = <&timer2_fck>;
clock-names = "fck";
};
timer3: timer@48042000 {
compatible = "ti,am335x-timer";
reg = <0x48042000 0x400>;
interrupts = <69>;
ti,hwmods = "timer3";
};
timer4: timer@48044000 {
compatible = "ti,am335x-timer";
reg = <0x48044000 0x400>;
interrupts = <92>;
ti,hwmods = "timer4";
ti,timer-pwm;
};
timer5: timer@48046000 {
compatible = "ti,am335x-timer";
reg = <0x48046000 0x400>;
interrupts = <93>;
ti,hwmods = "timer5";
ti,timer-pwm;
};
timer6: timer@48048000 {
compatible = "ti,am335x-timer";
reg = <0x48048000 0x400>;
interrupts = <94>;
ti,hwmods = "timer6";
ti,timer-pwm;
};
timer7: timer@4804a000 {
compatible = "ti,am335x-timer";
reg = <0x4804a000 0x400>;
interrupts = <95>;
ti,hwmods = "timer7";
ti,timer-pwm;
};
rtc: rtc@44e3e000 {
compatible = "ti,am3352-rtc", "ti,da830-rtc";
reg = <0x44e3e000 0x1000>;
interrupts = <75
76>;
ti,hwmods = "rtc";
clocks = <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
clock-names = "int-clk";
};
spi0: spi@48030000 {
compatible = "ti,omap4-mcspi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x48030000 0x400>;
interrupts = <65>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi0";
dmas = <&edma 16 0
&edma 17 0
&edma 18 0
&edma 19 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
spi1: spi@481a0000 {
compatible = "ti,omap4-mcspi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x481a0000 0x400>;
interrupts = <125>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi1";
dmas = <&edma 42 0
&edma 43 0
&edma 44 0
&edma 45 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
usb: usb@47400000 {
compatible = "ti,am33xx-usb";
reg = <0x47400000 0x1000>;
@ -731,121 +531,18 @@
"tx14", "tx15";
};
cppi41dma: dma-controller@47402000 {
cppi41dma: dma-controller@2000 {
compatible = "ti,am3359-cppi41";
reg = <0x47400000 0x1000
0x47402000 0x1000
0x47403000 0x1000
0x47404000 0x4000>;
reg = <0x0000 0x1000>,
<0x2000 0x1000>,
<0x3000 0x1000>,
<0x4000 0x4000>;
reg-names = "glue", "controller", "scheduler", "queuemgr";
interrupts = <17>;
interrupt-names = "glue";
#dma-cells = <2>;
#dma-channels = <30>;
#dma-requests = <256>;
status = "disabled";
};
};
epwmss0: epwmss@48300000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48300000 0x10>;
ti,hwmods = "epwmss0";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48300100 0x48300100 0x80 /* ECAP */
0x48300180 0x48300180 0x80 /* EQEP */
0x48300200 0x48300200 0x80>; /* EHRPWM */
ecap0: ecap@48300100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48300100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <31>;
interrupt-names = "ecap0";
status = "disabled";
};
ehrpwm0: pwm@48300200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48300200 0x80>;
clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
epwmss1: epwmss@48302000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48302000 0x10>;
ti,hwmods = "epwmss1";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48302100 0x48302100 0x80 /* ECAP */
0x48302180 0x48302180 0x80 /* EQEP */
0x48302200 0x48302200 0x80>; /* EHRPWM */
ecap1: ecap@48302100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48302100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <47>;
interrupt-names = "ecap1";
status = "disabled";
};
ehrpwm1: pwm@48302200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48302200 0x80>;
clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
epwmss2: epwmss@48304000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48304000 0x10>;
ti,hwmods = "epwmss2";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48304100 0x48304100 0x80 /* ECAP */
0x48304180 0x48304180 0x80 /* EQEP */
0x48304200 0x48304200 0x80>; /* EHRPWM */
ecap2: ecap@48304100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48304100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <61>;
interrupt-names = "ecap2";
status = "disabled";
};
ehrpwm2: pwm@48304200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48304200 0x80>;
clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
@ -904,60 +601,26 @@
};
};
ocmcram: ocmcram@40300000 {
ocmcram: sram@40300000 {
compatible = "mmio-sram";
reg = <0x40300000 0x10000>; /* 64k */
ranges = <0x0 0x40300000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
pm_sram_code: pm-sram-code@0 {
pm_sram_code: pm-code-sram@0 {
compatible = "ti,sram";
reg = <0x0 0x1000>;
protect-exec;
};
pm_sram_data: pm-sram-data@1000 {
pm_sram_data: pm-data-sram@1000 {
compatible = "ti,sram";
reg = <0x1000 0x1000>;
pool;
};
};
elm: elm@48080000 {
compatible = "ti,am3352-elm";
reg = <0x48080000 0x2000>;
interrupts = <4>;
ti,hwmods = "elm";
status = "disabled";
};
lcdc: lcdc@4830e000 {
compatible = "ti,am33xx-tilcdc";
reg = <0x4830e000 0x1000>;
interrupts = <36>;
ti,hwmods = "lcdc";
status = "disabled";
};
tscadc: tscadc@44e0d000 {
compatible = "ti,am3359-tscadc";
reg = <0x44e0d000 0x1000>;
interrupts = <16>;
ti,hwmods = "adc_tsc";
status = "disabled";
dmas = <&edma 53 0>, <&edma 57 0>;
dma-names = "fifo0", "fifo1";
tsc {
compatible = "ti,am3359-tsc";
};
am335x_adc: adc {
#io-channel-cells = <1>;
compatible = "ti,am3359-adc";
};
};
emif: emif@4c000000 {
compatible = "ti,emif-am3352";
reg = <0x4c000000 0x1000000>;
@ -987,60 +650,116 @@
status = "disabled";
};
sham: sham@53100000 {
compatible = "ti,omap4-sham";
ti,hwmods = "sham";
reg = <0x53100000 0x200>;
interrupts = <109>;
dmas = <&edma 36 0>;
dma-names = "rx";
sham_target: target-module@53100000 {
compatible = "ti,sysc-omap3-sham", "ti,sysc";
reg = <0x53100100 0x4>,
<0x53100110 0x4>,
<0x53100114 0x4>;
reg-names = "rev", "sysc", "syss";
ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
SYSC_OMAP2_AUTOIDLE)>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>;
ti,syss-mask = <1>;
/* Domains (P, C): per_pwrdm, l3_clkdm */
clocks = <&l3_clkctrl AM3_L3_SHAM_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x53100000 0x1000>;
sham: sham@0 {
compatible = "ti,omap4-sham";
reg = <0 0x200>;
interrupts = <109>;
dmas = <&edma 36 0>;
dma-names = "rx";
};
};
aes: aes@53500000 {
compatible = "ti,omap4-aes";
ti,hwmods = "aes";
reg = <0x53500000 0xa0>;
interrupts = <103>;
dmas = <&edma 6 0>,
<&edma 5 0>;
dma-names = "tx", "rx";
aes_target: target-module@53500000 {
compatible = "ti,sysc-omap2", "ti,sysc";
reg = <0x53500080 0x4>,
<0x53500084 0x4>,
<0x53500088 0x4>;
reg-names = "rev", "sysc", "syss";
ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
SYSC_OMAP2_AUTOIDLE)>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>,
<SYSC_IDLE_SMART_WKUP>;
ti,syss-mask = <1>;
/* Domains (P, C): per_pwrdm, l3_clkdm */
clocks = <&l3_clkctrl AM3_L3_AES_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x53500000 0x1000>;
aes: aes@0 {
compatible = "ti,omap4-aes";
reg = <0 0xa0>;
interrupts = <103>;
dmas = <&edma 6 0>,
<&edma 5 0>;
dma-names = "tx", "rx";
};
};
mcasp0: mcasp@48038000 {
compatible = "ti,am33xx-mcasp-audio";
ti,hwmods = "mcasp0";
reg = <0x48038000 0x2000>,
<0x46000000 0x400000>;
reg-names = "mpu", "dat";
interrupts = <80>, <81>;
interrupt-names = "tx", "rx";
status = "disabled";
dmas = <&edma 8 2>,
<&edma 9 2>;
dma-names = "tx", "rx";
};
target-module@56000000 {
compatible = "ti,sysc-omap4", "ti,sysc";
reg = <0x5600fe00 0x4>,
<0x5600fe10 0x4>;
reg-names = "rev", "sysc";
ti,sysc-midle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
<SYSC_IDLE_SMART>;
clocks = <&gfx_l3_clkctrl AM3_GFX_L3_GFX_CLKCTRL 0>;
clock-names = "fck";
resets = <&prm_gfx 0>;
reset-names = "rstctrl";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x56000000 0x1000000>;
mcasp1: mcasp@4803c000 {
compatible = "ti,am33xx-mcasp-audio";
ti,hwmods = "mcasp1";
reg = <0x4803C000 0x2000>,
<0x46400000 0x400000>;
reg-names = "mpu", "dat";
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
status = "disabled";
dmas = <&edma 10 2>,
<&edma 11 2>;
dma-names = "tx", "rx";
};
rng: rng@48310000 {
compatible = "ti,omap4-rng";
ti,hwmods = "rng";
reg = <0x48310000 0x2000>;
interrupts = <111>;
/*
* Closed source PowerVR driver, no child device
* binding or driver in mainline
*/
};
};
};
#include "am33xx-l4.dtsi"
#include "am33xx-clocks.dtsi"
&prcm {
prm_per: prm@c00 {
compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
reg = <0xc00 0x100>;
#reset-cells = <1>;
};
prm_wkup: prm@d00 {
compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
reg = <0xd00 0x100>;
#reset-cells = <1>;
};
prm_device: prm@f00 {
compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
reg = <0xf00 0x100>;
#reset-cells = <1>;
};
prm_gfx: prm@1100 {
compatible = "ti,am3-prm-inst", "ti,omap-prm-inst";
reg = <0x1100 0x100>;
#reset-cells = <1>;
};
};

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* dm8168-evm U-Boot Additions
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
/ {
ocp {
u-boot,dm-pre-reloc;
};
};

View File

@ -14,6 +14,8 @@
aliases {
serial2 = &main_uart0;
ethernet0 = &cpsw_port1;
usb0 = &usb0;
usb1 = &usb1;
};
};
@ -270,7 +272,7 @@
&usb0 {
pinctrl-names = "default";
pinctrl-0 = <&usb0_pins_default>;
dr_mode = "peripheral";
dr_mode = "host";
u-boot,dm-spl;
};

View File

@ -36,6 +36,7 @@
power-domains = <&k3_pds 61 TI_SCI_PD_EXCLUSIVE>,
<&k3_pds 202 TI_SCI_PD_EXCLUSIVE>;
resets = <&k3_reset 202 0>;
clocks = <&k3_clks 61 0>;
assigned-clocks = <&k3_clks 202 0>;
assigned-clock-rates = <800000000>;
ti,sci = <&dmsc>;

View File

@ -32,6 +32,7 @@
power-domains = <&k3_pds 61 TI_SCI_PD_EXCLUSIVE>,
<&k3_pds 202 TI_SCI_PD_EXCLUSIVE>;
resets = <&k3_reset 202 0>;
clocks = <&k3_clks 61 1>;
assigned-clocks = <&k3_clks 202 2>, <&k3_clks 61 1>;
assigned-clock-rates = <2000000000>, <200000000>;
ti,sci = <&dmsc>;

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
* This file was generated by the AM752x_DRA82x_TDA4x_DDRSS_RegConfigTool, Revision: 0.2.0
* This file was generated on 10/09/2019
* This file was generated by the Jacinto7_DDRSS_RegConfigTool, Revision: 0.5.0
* This file was generated on 09/25/2020
*/
#define DDRSS_PLL_FHS_CNT 10
#define DDRSS_PLL_FREQUENCY_1 933000000
#define DDRSS_PLL_FREQUENCY_2 933000000
#define DDRSS_PLL_FREQUENCY_1 1066500000
#define DDRSS_PLL_FREQUENCY_2 1066500000
#define DDRSS_CTL_00_DATA 0x00000B00
#define DDRSS_CTL_01_DATA 0x00000000
@ -20,14 +20,14 @@
#define DDRSS_CTL_08_DATA 0x000186A0
#define DDRSS_CTL_09_DATA 0x00000005
#define DDRSS_CTL_10_DATA 0x00000064
#define DDRSS_CTL_11_DATA 0x0005B18F
#define DDRSS_CTL_12_DATA 0x0038EF90
#define DDRSS_CTL_11_DATA 0x000681C8
#define DDRSS_CTL_12_DATA 0x004111C9
#define DDRSS_CTL_13_DATA 0x00000005
#define DDRSS_CTL_14_DATA 0x00000E94
#define DDRSS_CTL_15_DATA 0x0005B18F
#define DDRSS_CTL_16_DATA 0x0038EF90
#define DDRSS_CTL_14_DATA 0x000010A9
#define DDRSS_CTL_15_DATA 0x000681C8
#define DDRSS_CTL_16_DATA 0x004111C9
#define DDRSS_CTL_17_DATA 0x00000005
#define DDRSS_CTL_18_DATA 0x00000E94
#define DDRSS_CTL_18_DATA 0x000010A9
#define DDRSS_CTL_19_DATA 0x01010000
#define DDRSS_CTL_20_DATA 0x02011001
#define DDRSS_CTL_21_DATA 0x02010000
@ -37,66 +37,66 @@
#define DDRSS_CTL_25_DATA 0x00000000
#define DDRSS_CTL_26_DATA 0x00000000
#define DDRSS_CTL_27_DATA 0x02020200
#define DDRSS_CTL_28_DATA 0x00004B4B
#define DDRSS_CTL_28_DATA 0x00005656
#define DDRSS_CTL_29_DATA 0x00100000
#define DDRSS_CTL_30_DATA 0x00000000
#define DDRSS_CTL_31_DATA 0x00000000
#define DDRSS_CTL_32_DATA 0x00000000
#define DDRSS_CTL_33_DATA 0x00000000
#define DDRSS_CTL_34_DATA 0x040C0000
#define DDRSS_CTL_35_DATA 0x10401040
#define DDRSS_CTL_35_DATA 0x12481248
#define DDRSS_CTL_36_DATA 0x00050804
#define DDRSS_CTL_37_DATA 0x09040008
#define DDRSS_CTL_38_DATA 0x12000204
#define DDRSS_CTL_39_DATA 0x1854007A
#define DDRSS_CTL_40_DATA 0x12003A26
#define DDRSS_CTL_41_DATA 0x1854007A
#define DDRSS_CTL_42_DATA 0x20003A26
#define DDRSS_CTL_38_DATA 0x15000204
#define DDRSS_CTL_39_DATA 0x1B60008B
#define DDRSS_CTL_40_DATA 0x1500422B
#define DDRSS_CTL_41_DATA 0x1B60008B
#define DDRSS_CTL_42_DATA 0x2000422B
#define DDRSS_CTL_43_DATA 0x000A0A09
#define DDRSS_CTL_44_DATA 0x040006DB
#define DDRSS_CTL_45_DATA 0x1B130F04
#define DDRSS_CTL_46_DATA 0x0E00FFCD
#define DDRSS_CTL_47_DATA 0x1B130F0E
#define DDRSS_CTL_48_DATA 0x0E00FFCD
#define DDRSS_CTL_49_DATA 0x0203040E
#define DDRSS_CTL_50_DATA 0x26040500
#define DDRSS_CTL_51_DATA 0x08282628
#define DDRSS_CTL_45_DATA 0x1E161104
#define DDRSS_CTL_46_DATA 0x10012458
#define DDRSS_CTL_47_DATA 0x1E161110
#define DDRSS_CTL_48_DATA 0x10012458
#define DDRSS_CTL_49_DATA 0x02030410
#define DDRSS_CTL_50_DATA 0x2C040500
#define DDRSS_CTL_51_DATA 0x082D2C2D
#define DDRSS_CTL_52_DATA 0x14000D0A
#define DDRSS_CTL_53_DATA 0x03010A0A
#define DDRSS_CTL_54_DATA 0x01010003
#define DDRSS_CTL_55_DATA 0x044E4E08
#define DDRSS_CTL_56_DATA 0x042B2B04
#define DDRSS_CTL_57_DATA 0x00002B2B
#define DDRSS_CTL_53_DATA 0x04010A0A
#define DDRSS_CTL_54_DATA 0x01010004
#define DDRSS_CTL_55_DATA 0x04585808
#define DDRSS_CTL_56_DATA 0x04313104
#define DDRSS_CTL_57_DATA 0x00003131
#define DDRSS_CTL_58_DATA 0x00010100
#define DDRSS_CTL_59_DATA 0x03010000
#define DDRSS_CTL_60_DATA 0x00000E08
#define DDRSS_CTL_61_DATA 0x000000BB
#define DDRSS_CTL_62_DATA 0x0000020B
#define DDRSS_CTL_63_DATA 0x00001C64
#define DDRSS_CTL_64_DATA 0x0000020B
#define DDRSS_CTL_65_DATA 0x00001C64
#define DDRSS_CTL_62_DATA 0x00000256
#define DDRSS_CTL_63_DATA 0x00002073
#define DDRSS_CTL_64_DATA 0x00000256
#define DDRSS_CTL_65_DATA 0x00002073
#define DDRSS_CTL_66_DATA 0x00000005
#define DDRSS_CTL_67_DATA 0x00030000
#define DDRSS_CTL_68_DATA 0x00830010
#define DDRSS_CTL_69_DATA 0x00830386
#define DDRSS_CTL_70_DATA 0x00400386
#define DDRSS_CTL_68_DATA 0x00950010
#define DDRSS_CTL_69_DATA 0x00950408
#define DDRSS_CTL_70_DATA 0x00400408
#define DDRSS_CTL_71_DATA 0x00120103
#define DDRSS_CTL_72_DATA 0x000E0005
#define DDRSS_CTL_73_DATA 0x2908000E
#define DDRSS_CTL_74_DATA 0x05050129
#define DDRSS_CTL_72_DATA 0x00100005
#define DDRSS_CTL_73_DATA 0x2F080010
#define DDRSS_CTL_74_DATA 0x0505012F
#define DDRSS_CTL_75_DATA 0x0401030A
#define DDRSS_CTL_76_DATA 0x041B0E0A
#define DDRSS_CTL_77_DATA 0x0E0A0401
#define DDRSS_CTL_78_DATA 0x0001041B
#define DDRSS_CTL_76_DATA 0x041E100B
#define DDRSS_CTL_77_DATA 0x100B0401
#define DDRSS_CTL_78_DATA 0x0001041E
#define DDRSS_CTL_79_DATA 0x000F000F
#define DDRSS_CTL_80_DATA 0x02190219
#define DDRSS_CTL_81_DATA 0x02190219
#define DDRSS_CTL_80_DATA 0x02660266
#define DDRSS_CTL_81_DATA 0x02660266
#define DDRSS_CTL_82_DATA 0x03050505
#define DDRSS_CTL_83_DATA 0x03010303
#define DDRSS_CTL_84_DATA 0x1C0A0E0A
#define DDRSS_CTL_85_DATA 0x04040E04
#define DDRSS_CTL_86_DATA 0x1C0A0E0A
#define DDRSS_CTL_87_DATA 0x04040E04
#define DDRSS_CTL_84_DATA 0x200B100B
#define DDRSS_CTL_85_DATA 0x04041004
#define DDRSS_CTL_86_DATA 0x200B100B
#define DDRSS_CTL_87_DATA 0x04041004
#define DDRSS_CTL_88_DATA 0x03010000
#define DDRSS_CTL_89_DATA 0x00010000
#define DDRSS_CTL_90_DATA 0x00000000
@ -118,20 +118,20 @@
#define DDRSS_CTL_106_DATA 0x00002EC0
#define DDRSS_CTL_107_DATA 0x00000000
#define DDRSS_CTL_108_DATA 0x0000051D
#define DDRSS_CTL_109_DATA 0x00071900
#define DDRSS_CTL_110_DATA 0x00071900
#define DDRSS_CTL_111_DATA 0x00071900
#define DDRSS_CTL_112_DATA 0x00071900
#define DDRSS_CTL_113_DATA 0x00071900
#define DDRSS_CTL_109_DATA 0x00081CC0
#define DDRSS_CTL_110_DATA 0x00081CC0
#define DDRSS_CTL_111_DATA 0x00081CC0
#define DDRSS_CTL_112_DATA 0x00081CC0
#define DDRSS_CTL_113_DATA 0x00081CC0
#define DDRSS_CTL_114_DATA 0x00000000
#define DDRSS_CTL_115_DATA 0x0000C6BC
#define DDRSS_CTL_116_DATA 0x00071900
#define DDRSS_CTL_117_DATA 0x00071900
#define DDRSS_CTL_118_DATA 0x00071900
#define DDRSS_CTL_119_DATA 0x00071900
#define DDRSS_CTL_120_DATA 0x00071900
#define DDRSS_CTL_115_DATA 0x0000E325
#define DDRSS_CTL_116_DATA 0x00081CC0
#define DDRSS_CTL_117_DATA 0x00081CC0
#define DDRSS_CTL_118_DATA 0x00081CC0
#define DDRSS_CTL_119_DATA 0x00081CC0
#define DDRSS_CTL_120_DATA 0x00081CC0
#define DDRSS_CTL_121_DATA 0x00000000
#define DDRSS_CTL_122_DATA 0x0000C6BC
#define DDRSS_CTL_122_DATA 0x0000E325
#define DDRSS_CTL_123_DATA 0x00000000
#define DDRSS_CTL_124_DATA 0x00000000
#define DDRSS_CTL_125_DATA 0x00000000
@ -140,8 +140,8 @@
#define DDRSS_CTL_128_DATA 0x00000000
#define DDRSS_CTL_129_DATA 0x00000000
#define DDRSS_CTL_130_DATA 0x00000000
#define DDRSS_CTL_131_DATA 0x0A030500
#define DDRSS_CTL_132_DATA 0x00040A04
#define DDRSS_CTL_131_DATA 0x0B030500
#define DDRSS_CTL_132_DATA 0x00040B04
#define DDRSS_CTL_133_DATA 0x0A090000
#define DDRSS_CTL_134_DATA 0x0A090701
#define DDRSS_CTL_135_DATA 0x0900000E
@ -176,23 +176,23 @@
#define DDRSS_CTL_164_DATA 0x000A0000
#define DDRSS_CTL_165_DATA 0x000D0005
#define DDRSS_CTL_166_DATA 0x000D0404
#define DDRSS_CTL_167_DATA 0x00BB0176
#define DDRSS_CTL_168_DATA 0x0E0E01D3
#define DDRSS_CTL_169_DATA 0x017601D3
#define DDRSS_CTL_170_DATA 0x01D300BB
#define DDRSS_CTL_171_DATA 0x01D30E0E
#define DDRSS_CTL_167_DATA 0x00D601AB
#define DDRSS_CTL_168_DATA 0x10100216
#define DDRSS_CTL_169_DATA 0x01AB0216
#define DDRSS_CTL_170_DATA 0x021600D6
#define DDRSS_CTL_171_DATA 0x02161010
#define DDRSS_CTL_172_DATA 0x00000000
#define DDRSS_CTL_173_DATA 0x00000000
#define DDRSS_CTL_174_DATA 0x00000000
#define DDRSS_CTL_175_DATA 0x36E40084
#define DDRSS_CTL_176_DATA 0x330036E4
#define DDRSS_CTL_175_DATA 0x3FF40084
#define DDRSS_CTL_176_DATA 0x33003FF4
#define DDRSS_CTL_177_DATA 0x00003333
#define DDRSS_CTL_178_DATA 0x56000000
#define DDRSS_CTL_179_DATA 0x27270056
#define DDRSS_CTL_180_DATA 0x0F0F0000
#define DDRSS_CTL_181_DATA 0x00000000
#define DDRSS_CTL_182_DATA 0x00840606
#define DDRSS_CTL_183_DATA 0x36E436E4
#define DDRSS_CTL_183_DATA 0x3FF43FF4
#define DDRSS_CTL_184_DATA 0x33333300
#define DDRSS_CTL_185_DATA 0x00000000
#define DDRSS_CTL_186_DATA 0x00565600
@ -270,12 +270,12 @@
#define DDRSS_CTL_258_DATA 0x00320040
#define DDRSS_CTL_259_DATA 0x00020008
#define DDRSS_CTL_260_DATA 0x00400100
#define DDRSS_CTL_261_DATA 0x0038074A
#define DDRSS_CTL_261_DATA 0x00400855
#define DDRSS_CTL_262_DATA 0x01000200
#define DDRSS_CTL_263_DATA 0x074A0040
#define DDRSS_CTL_264_DATA 0x00000038
#define DDRSS_CTL_265_DATA 0x005E0003
#define DDRSS_CTL_266_DATA 0x0100005E
#define DDRSS_CTL_263_DATA 0x08550040
#define DDRSS_CTL_264_DATA 0x00000040
#define DDRSS_CTL_265_DATA 0x006B0003
#define DDRSS_CTL_266_DATA 0x0100006B
#define DDRSS_CTL_267_DATA 0x00000000
#define DDRSS_CTL_268_DATA 0x01010000
#define DDRSS_CTL_269_DATA 0x00000202
@ -327,15 +327,15 @@
#define DDRSS_CTL_315_DATA 0x01000101
#define DDRSS_CTL_316_DATA 0x01010001
#define DDRSS_CTL_317_DATA 0x00010101
#define DDRSS_CTL_318_DATA 0x05090903
#define DDRSS_CTL_319_DATA 0x0E081B1B
#define DDRSS_CTL_320_DATA 0x0009030E
#define DDRSS_CTL_321_DATA 0x0A0D030F
#define DDRSS_CTL_322_DATA 0x0A0D0306
#define DDRSS_CTL_323_DATA 0x0D090006
#define DDRSS_CTL_324_DATA 0x0100000D
#define DDRSS_CTL_325_DATA 0x07030701
#define DDRSS_CTL_326_DATA 0x00000003
#define DDRSS_CTL_318_DATA 0x050A0A03
#define DDRSS_CTL_319_DATA 0x10081F1F
#define DDRSS_CTL_320_DATA 0x00090310
#define DDRSS_CTL_321_DATA 0x0B0C030F
#define DDRSS_CTL_322_DATA 0x0B0C0306
#define DDRSS_CTL_323_DATA 0x0C090006
#define DDRSS_CTL_324_DATA 0x0100000C
#define DDRSS_CTL_325_DATA 0x08040801
#define DDRSS_CTL_326_DATA 0x00000004
#define DDRSS_CTL_327_DATA 0x00000000
#define DDRSS_CTL_328_DATA 0x00010000
#define DDRSS_CTL_329_DATA 0x00280D00
@ -396,7 +396,7 @@
#define DDRSS_CTL_384_DATA 0x00000000
#define DDRSS_CTL_385_DATA 0x00000000
#define DDRSS_CTL_386_DATA 0x00000000
#define DDRSS_CTL_387_DATA 0x37371B00
#define DDRSS_CTL_387_DATA 0x3A3A1B00
#define DDRSS_CTL_388_DATA 0x000A0000
#define DDRSS_CTL_389_DATA 0x00000176
#define DDRSS_CTL_390_DATA 0x00000200
@ -406,22 +406,22 @@
#define DDRSS_CTL_394_DATA 0x00000462
#define DDRSS_CTL_395_DATA 0x00000E9C
#define DDRSS_CTL_396_DATA 0x00000204
#define DDRSS_CTL_397_DATA 0x000038C8
#define DDRSS_CTL_397_DATA 0x000040E6
#define DDRSS_CTL_398_DATA 0x00000200
#define DDRSS_CTL_399_DATA 0x00000200
#define DDRSS_CTL_400_DATA 0x00000200
#define DDRSS_CTL_401_DATA 0x00000200
#define DDRSS_CTL_402_DATA 0x0000AA58
#define DDRSS_CTL_403_DATA 0x000237D0
#define DDRSS_CTL_404_DATA 0x00000C12
#define DDRSS_CTL_405_DATA 0x000038C8
#define DDRSS_CTL_402_DATA 0x0000C2B2
#define DDRSS_CTL_403_DATA 0x000288FC
#define DDRSS_CTL_404_DATA 0x00000E15
#define DDRSS_CTL_405_DATA 0x000040E6
#define DDRSS_CTL_406_DATA 0x00000200
#define DDRSS_CTL_407_DATA 0x00000200
#define DDRSS_CTL_408_DATA 0x00000200
#define DDRSS_CTL_409_DATA 0x00000200
#define DDRSS_CTL_410_DATA 0x0000AA58
#define DDRSS_CTL_411_DATA 0x000237D0
#define DDRSS_CTL_412_DATA 0x02020C12
#define DDRSS_CTL_410_DATA 0x0000C2B2
#define DDRSS_CTL_411_DATA 0x000288FC
#define DDRSS_CTL_412_DATA 0x02020E15
#define DDRSS_CTL_413_DATA 0x03030202
#define DDRSS_CTL_414_DATA 0x00000022
#define DDRSS_CTL_415_DATA 0x00000000
@ -432,13 +432,13 @@
#define DDRSS_CTL_420_DATA 0x00000000
#define DDRSS_CTL_421_DATA 0x00030000
#define DDRSS_CTL_422_DATA 0x0006001E
#define DDRSS_CTL_423_DATA 0x00190031
#define DDRSS_CTL_424_DATA 0x00190031
#define DDRSS_CTL_423_DATA 0x001B0033
#define DDRSS_CTL_424_DATA 0x001B0033
#define DDRSS_CTL_425_DATA 0x00000000
#define DDRSS_CTL_426_DATA 0x00000000
#define DDRSS_CTL_427_DATA 0x02000000
#define DDRSS_CTL_428_DATA 0x01000404
#define DDRSS_CTL_429_DATA 0x091A091A
#define DDRSS_CTL_429_DATA 0x0B1E0B1E
#define DDRSS_CTL_430_DATA 0x00000105
#define DDRSS_CTL_431_DATA 0x00010101
#define DDRSS_CTL_432_DATA 0x00010101
@ -447,8 +447,8 @@
#define DDRSS_CTL_435_DATA 0x02000201
#define DDRSS_CTL_436_DATA 0x02010000
#define DDRSS_CTL_437_DATA 0x00000200
#define DDRSS_CTL_438_DATA 0x22060000
#define DDRSS_CTL_439_DATA 0x00000122
#define DDRSS_CTL_438_DATA 0x28060000
#define DDRSS_CTL_439_DATA 0x00000128
#define DDRSS_CTL_440_DATA 0xFFFFFFFF
#define DDRSS_CTL_441_DATA 0xFFFFFFFF
#define DDRSS_CTL_442_DATA 0x00000000
@ -515,7 +515,7 @@
#define DDRSS_PI_43_DATA 0x00000000
#define DDRSS_PI_44_DATA 0x00000000
#define DDRSS_PI_45_DATA 0x000F0F00
#define DDRSS_PI_46_DATA 0x00000019
#define DDRSS_PI_46_DATA 0x0000001B
#define DDRSS_PI_47_DATA 0x000007D0
#define DDRSS_PI_48_DATA 0x00000300
#define DDRSS_PI_49_DATA 0x00000000
@ -535,13 +535,13 @@
#define DDRSS_PI_63_DATA 0x01000404
#define DDRSS_PI_64_DATA 0x00000000
#define DDRSS_PI_65_DATA 0x00000000
#define DDRSS_PI_66_DATA 0x00000101
#define DDRSS_PI_66_DATA 0x00000100
#define DDRSS_PI_67_DATA 0x0001010F
#define DDRSS_PI_68_DATA 0x00340000
#define DDRSS_PI_69_DATA 0x00000000
#define DDRSS_PI_70_DATA 0x00000000
#define DDRSS_PI_71_DATA 0x00000000
#define DDRSS_PI_72_DATA 0x01000000
#define DDRSS_PI_71_DATA 0x0000FFFF
#define DDRSS_PI_72_DATA 0x00000000
#define DDRSS_PI_73_DATA 0x00080100
#define DDRSS_PI_74_DATA 0x02000200
#define DDRSS_PI_75_DATA 0x01000100
@ -632,18 +632,18 @@
#define DDRSS_PI_160_DATA 0x00000000
#define DDRSS_PI_161_DATA 0x00010000
#define DDRSS_PI_162_DATA 0x00000000
#define DDRSS_PI_163_DATA 0x26260100
#define DDRSS_PI_163_DATA 0x2B2B0100
#define DDRSS_PI_164_DATA 0x00000034
#define DDRSS_PI_165_DATA 0x0000005E
#define DDRSS_PI_166_DATA 0x0002005E
#define DDRSS_PI_165_DATA 0x00000064
#define DDRSS_PI_166_DATA 0x00020064
#define DDRSS_PI_167_DATA 0x02000200
#define DDRSS_PI_168_DATA 0x40100C04
#define DDRSS_PI_169_DATA 0x000E4010
#define DDRSS_PI_168_DATA 0x48120C04
#define DDRSS_PI_169_DATA 0x000E4812
#define DDRSS_PI_170_DATA 0x000000BB
#define DDRSS_PI_171_DATA 0x0000020B
#define DDRSS_PI_172_DATA 0x00001C64
#define DDRSS_PI_173_DATA 0x0000020B
#define DDRSS_PI_174_DATA 0x04001C64
#define DDRSS_PI_171_DATA 0x00000256
#define DDRSS_PI_172_DATA 0x00002073
#define DDRSS_PI_173_DATA 0x00000256
#define DDRSS_PI_174_DATA 0x04002073
#define DDRSS_PI_175_DATA 0x01010404
#define DDRSS_PI_176_DATA 0x00001501
#define DDRSS_PI_177_DATA 0x00150015
@ -654,80 +654,80 @@
#define DDRSS_PI_182_DATA 0x00000101
#define DDRSS_PI_183_DATA 0x00000000
#define DDRSS_PI_184_DATA 0x00000000
#define DDRSS_PI_185_DATA 0x12040000
#define DDRSS_PI_186_DATA 0x0C0C0212
#define DDRSS_PI_185_DATA 0x15040000
#define DDRSS_PI_186_DATA 0x0E0E0215
#define DDRSS_PI_187_DATA 0x00040402
#define DDRSS_PI_188_DATA 0x000C8034
#define DDRSS_PI_189_DATA 0x001F0047
#define DDRSS_PI_190_DATA 0x001F0047
#define DDRSS_PI_189_DATA 0x00218049
#define DDRSS_PI_190_DATA 0x00218049
#define DDRSS_PI_191_DATA 0x01010101
#define DDRSS_PI_192_DATA 0x0003000D
#define DDRSS_PI_193_DATA 0x000301D3
#define DDRSS_PI_194_DATA 0x010001D3
#define DDRSS_PI_192_DATA 0x0004000D
#define DDRSS_PI_193_DATA 0x00040216
#define DDRSS_PI_194_DATA 0x01000216
#define DDRSS_PI_195_DATA 0x000E000E
#define DDRSS_PI_196_DATA 0x01D40100
#define DDRSS_PI_197_DATA 0x010001D4
#define DDRSS_PI_198_DATA 0x01D401D4
#define DDRSS_PI_196_DATA 0x02170100
#define DDRSS_PI_197_DATA 0x01000217
#define DDRSS_PI_198_DATA 0x02170217
#define DDRSS_PI_199_DATA 0x32103200
#define DDRSS_PI_200_DATA 0x01013210
#define DDRSS_PI_201_DATA 0x0A070601
#define DDRSS_PI_202_DATA 0x1C11090D
#define DDRSS_PI_203_DATA 0x1C110913
#define DDRSS_PI_204_DATA 0x0000C013
#define DDRSS_PI_202_DATA 0x1F130A0D
#define DDRSS_PI_203_DATA 0x1F130A14
#define DDRSS_PI_204_DATA 0x0000C014
#define DDRSS_PI_205_DATA 0x00C01000
#define DDRSS_PI_206_DATA 0x00C01000
#define DDRSS_PI_207_DATA 0x00021000
#define DDRSS_PI_208_DATA 0x0021000D
#define DDRSS_PI_209_DATA 0x002101D3
#define DDRSS_PI_210_DATA 0x001101D3
#define DDRSS_PI_208_DATA 0x0024000D
#define DDRSS_PI_209_DATA 0x00240216
#define DDRSS_PI_210_DATA 0x00110216
#define DDRSS_PI_211_DATA 0x32000056
#define DDRSS_PI_212_DATA 0x00000101
#define DDRSS_PI_213_DATA 0x005A0035
#define DDRSS_PI_214_DATA 0x01013212
#define DDRSS_PI_215_DATA 0x00003500
#define DDRSS_PI_216_DATA 0x3212005A
#define DDRSS_PI_217_DATA 0x09000101
#define DDRSS_PI_212_DATA 0x00000301
#define DDRSS_PI_213_DATA 0x005B003A
#define DDRSS_PI_214_DATA 0x03013212
#define DDRSS_PI_215_DATA 0x00003A00
#define DDRSS_PI_216_DATA 0x3212005B
#define DDRSS_PI_217_DATA 0x09000301
#define DDRSS_PI_218_DATA 0x04010504
#define DDRSS_PI_219_DATA 0x0400062B
#define DDRSS_PI_220_DATA 0x0A032001
#define DDRSS_PI_221_DATA 0x262B0F0A
#define DDRSS_PI_222_DATA 0x00002819
#define DDRSS_PI_223_DATA 0x5400E638
#define DDRSS_PI_224_DATA 0x1B1C2007
#define DDRSS_PI_225_DATA 0x262B0F13
#define DDRSS_PI_226_DATA 0x00002819
#define DDRSS_PI_227_DATA 0x5400E638
#define DDRSS_PI_228_DATA 0x1B1C2007
#define DDRSS_PI_229_DATA 0x00017613
#define DDRSS_PI_221_DATA 0x2C31110A
#define DDRSS_PI_222_DATA 0x00002D1C
#define DDRSS_PI_223_DATA 0x6001071C
#define DDRSS_PI_224_DATA 0x1E202008
#define DDRSS_PI_225_DATA 0x2C311116
#define DDRSS_PI_226_DATA 0x00002D1C
#define DDRSS_PI_227_DATA 0x6001071C
#define DDRSS_PI_228_DATA 0x1E202008
#define DDRSS_PI_229_DATA 0x00017616
#define DDRSS_PI_230_DATA 0x00000E9C
#define DDRSS_PI_231_DATA 0x000038C8
#define DDRSS_PI_232_DATA 0x000237D0
#define DDRSS_PI_233_DATA 0x000038C8
#define DDRSS_PI_234_DATA 0x000237D0
#define DDRSS_PI_235_DATA 0x0219000F
#define DDRSS_PI_236_DATA 0x03030219
#define DDRSS_PI_231_DATA 0x000040E6
#define DDRSS_PI_232_DATA 0x000288FC
#define DDRSS_PI_233_DATA 0x000040E6
#define DDRSS_PI_234_DATA 0x000288FC
#define DDRSS_PI_235_DATA 0x0266000F
#define DDRSS_PI_236_DATA 0x03030266
#define DDRSS_PI_237_DATA 0x00271003
#define DDRSS_PI_238_DATA 0x000186A0
#define DDRSS_PI_239_DATA 0x00000005
#define DDRSS_PI_240_DATA 0x00000064
#define DDRSS_PI_241_DATA 0x0000000F
#define DDRSS_PI_242_DATA 0x0005B18F
#define DDRSS_PI_242_DATA 0x000681C8
#define DDRSS_PI_243_DATA 0x000186A0
#define DDRSS_PI_244_DATA 0x00000005
#define DDRSS_PI_245_DATA 0x00000E94
#define DDRSS_PI_246_DATA 0x00000219
#define DDRSS_PI_247_DATA 0x0005B18F
#define DDRSS_PI_245_DATA 0x000010A9
#define DDRSS_PI_246_DATA 0x00000266
#define DDRSS_PI_247_DATA 0x000681C8
#define DDRSS_PI_248_DATA 0x000186A0
#define DDRSS_PI_249_DATA 0x00000005
#define DDRSS_PI_250_DATA 0x00000E94
#define DDRSS_PI_251_DATA 0x01000219
#define DDRSS_PI_250_DATA 0x000010A9
#define DDRSS_PI_251_DATA 0x01000266
#define DDRSS_PI_252_DATA 0x00320040
#define DDRSS_PI_253_DATA 0x00010008
#define DDRSS_PI_254_DATA 0x074A0040
#define DDRSS_PI_255_DATA 0x00010038
#define DDRSS_PI_256_DATA 0x074A0040
#define DDRSS_PI_257_DATA 0x00000338
#define DDRSS_PI_258_DATA 0x005E005E
#define DDRSS_PI_254_DATA 0x08550040
#define DDRSS_PI_255_DATA 0x00010040
#define DDRSS_PI_256_DATA 0x08550040
#define DDRSS_PI_257_DATA 0x00000340
#define DDRSS_PI_258_DATA 0x006B006B
#define DDRSS_PI_259_DATA 0x00040404
#define DDRSS_PI_260_DATA 0x00000055
#define DDRSS_PI_261_DATA 0x55003C5A
@ -746,27 +746,27 @@
#define DDRSS_PI_274_DATA 0x00000000
#define DDRSS_PI_275_DATA 0x00330084
#define DDRSS_PI_276_DATA 0x00160000
#define DDRSS_PI_277_DATA 0x563336E4
#define DDRSS_PI_277_DATA 0x56333FF4
#define DDRSS_PI_278_DATA 0x00160F27
#define DDRSS_PI_279_DATA 0x563336E4
#define DDRSS_PI_279_DATA 0x56333FF4
#define DDRSS_PI_280_DATA 0x00160F27
#define DDRSS_PI_281_DATA 0x00330084
#define DDRSS_PI_282_DATA 0x00160000
#define DDRSS_PI_283_DATA 0x563336E4
#define DDRSS_PI_283_DATA 0x56333FF4
#define DDRSS_PI_284_DATA 0x00160F27
#define DDRSS_PI_285_DATA 0x563336E4
#define DDRSS_PI_285_DATA 0x56333FF4
#define DDRSS_PI_286_DATA 0x00160F27
#define DDRSS_PI_287_DATA 0x00330084
#define DDRSS_PI_288_DATA 0x00160000
#define DDRSS_PI_289_DATA 0x563336E4
#define DDRSS_PI_289_DATA 0x56333FF4
#define DDRSS_PI_290_DATA 0x00160F27
#define DDRSS_PI_291_DATA 0x563336E4
#define DDRSS_PI_291_DATA 0x56333FF4
#define DDRSS_PI_292_DATA 0x00160F27
#define DDRSS_PI_293_DATA 0x00330084
#define DDRSS_PI_294_DATA 0x00160000
#define DDRSS_PI_295_DATA 0x563336E4
#define DDRSS_PI_295_DATA 0x56333FF4
#define DDRSS_PI_296_DATA 0x00160F27
#define DDRSS_PI_297_DATA 0x563336E4
#define DDRSS_PI_297_DATA 0x56333FF4
#define DDRSS_PI_298_DATA 0x00160F27
#define DDRSS_PI_299_DATA 0x00000000
@ -787,7 +787,7 @@
#define DDRSS_PHY_14_DATA 0x060100CC
#define DDRSS_PHY_15_DATA 0x00030066
#define DDRSS_PHY_16_DATA 0x00000000
#define DDRSS_PHY_17_DATA 0x00000001
#define DDRSS_PHY_17_DATA 0x00000301
#define DDRSS_PHY_18_DATA 0x0000AAAA
#define DDRSS_PHY_19_DATA 0x00005555
#define DDRSS_PHY_20_DATA 0x0000B5B5
@ -803,7 +803,7 @@
#define DDRSS_PHY_30_DATA 0x0F000000
#define DDRSS_PHY_31_DATA 0x00000F0F
#define DDRSS_PHY_32_DATA 0x10200000
#define DDRSS_PHY_33_DATA 0x0C002004
#define DDRSS_PHY_33_DATA 0x0C002007
#define DDRSS_PHY_34_DATA 0x00000000
#define DDRSS_PHY_35_DATA 0x00000000
#define DDRSS_PHY_36_DATA 0x55555555
@ -855,35 +855,35 @@
#define DDRSS_PHY_82_DATA 0x00000000
#define DDRSS_PHY_83_DATA 0x00000100
#define DDRSS_PHY_84_DATA 0x01CC0C01
#define DDRSS_PHY_85_DATA 0x0003CC0C
#define DDRSS_PHY_85_DATA 0x1003CC0C
#define DDRSS_PHY_86_DATA 0x20000140
#define DDRSS_PHY_87_DATA 0x07FF0200
#define DDRSS_PHY_88_DATA 0x0000DD01
#define DDRSS_PHY_89_DATA 0x10100303
#define DDRSS_PHY_90_DATA 0x10101010
#define DDRSS_PHY_91_DATA 0x10101010
#define DDRSS_PHY_92_DATA 0x00041010
#define DDRSS_PHY_92_DATA 0x00021010
#define DDRSS_PHY_93_DATA 0x00100010
#define DDRSS_PHY_94_DATA 0x00100010
#define DDRSS_PHY_95_DATA 0x00100010
#define DDRSS_PHY_96_DATA 0x00100010
#define DDRSS_PHY_97_DATA 0x00050010
#define DDRSS_PHY_98_DATA 0x51517041
#define DDRSS_PHY_99_DATA 0x31C06000
#define DDRSS_PHY_99_DATA 0x31C06001
#define DDRSS_PHY_100_DATA 0x07AB0340
#define DDRSS_PHY_101_DATA 0x00C0C001
#define DDRSS_PHY_102_DATA 0x0D0C0001
#define DDRSS_PHY_102_DATA 0x0E0D0001
#define DDRSS_PHY_103_DATA 0x10001000
#define DDRSS_PHY_104_DATA 0x0C063E42
#define DDRSS_PHY_105_DATA 0x0F0C3201
#define DDRSS_PHY_104_DATA 0x0C083E42
#define DDRSS_PHY_105_DATA 0x0F0C3701
#define DDRSS_PHY_106_DATA 0x01000140
#define DDRSS_PHY_107_DATA 0x0C000420
#define DDRSS_PHY_108_DATA 0x000002DD
#define DDRSS_PHY_108_DATA 0x00000322
#define DDRSS_PHY_109_DATA 0x0A0000D0
#define DDRSS_PHY_110_DATA 0x00030200
#define DDRSS_PHY_111_DATA 0x02800000
#define DDRSS_PHY_112_DATA 0x80800000
#define DDRSS_PHY_113_DATA 0x000D2010
#define DDRSS_PHY_113_DATA 0x000E2010
#define DDRSS_PHY_114_DATA 0x76543210
#define DDRSS_PHY_115_DATA 0x00000008
#define DDRSS_PHY_116_DATA 0x02800280
@ -900,13 +900,13 @@
#define DDRSS_PHY_127_DATA 0x00A000A0
#define DDRSS_PHY_128_DATA 0x00A000A0
#define DDRSS_PHY_129_DATA 0x00A000A0
#define DDRSS_PHY_130_DATA 0x006D00A0
#define DDRSS_PHY_130_DATA 0x01C200A0
#define DDRSS_PHY_131_DATA 0x01A00005
#define DDRSS_PHY_132_DATA 0x00000000
#define DDRSS_PHY_133_DATA 0x00000000
#define DDRSS_PHY_134_DATA 0x00080200
#define DDRSS_PHY_135_DATA 0x00000000
#define DDRSS_PHY_136_DATA 0x20202020
#define DDRSS_PHY_136_DATA 0x20202000
#define DDRSS_PHY_137_DATA 0x20202020
#define DDRSS_PHY_138_DATA 0xF0F02020
#define DDRSS_PHY_139_DATA 0x00000000
@ -1043,7 +1043,7 @@
#define DDRSS_PHY_270_DATA 0x060100CC
#define DDRSS_PHY_271_DATA 0x00030066
#define DDRSS_PHY_272_DATA 0x00000000
#define DDRSS_PHY_273_DATA 0x00000001
#define DDRSS_PHY_273_DATA 0x00000301
#define DDRSS_PHY_274_DATA 0x0000AAAA
#define DDRSS_PHY_275_DATA 0x00005555
#define DDRSS_PHY_276_DATA 0x0000B5B5
@ -1059,7 +1059,7 @@
#define DDRSS_PHY_286_DATA 0x0F000000
#define DDRSS_PHY_287_DATA 0x00000F0F
#define DDRSS_PHY_288_DATA 0x10200000
#define DDRSS_PHY_289_DATA 0x0C002004
#define DDRSS_PHY_289_DATA 0x0C002007
#define DDRSS_PHY_290_DATA 0x00000000
#define DDRSS_PHY_291_DATA 0x00000000
#define DDRSS_PHY_292_DATA 0x55555555
@ -1111,35 +1111,35 @@
#define DDRSS_PHY_338_DATA 0x00000000
#define DDRSS_PHY_339_DATA 0x00000100
#define DDRSS_PHY_340_DATA 0x01CC0C01
#define DDRSS_PHY_341_DATA 0x0003CC0C
#define DDRSS_PHY_341_DATA 0x1003CC0C
#define DDRSS_PHY_342_DATA 0x20000140
#define DDRSS_PHY_343_DATA 0x07FF0200
#define DDRSS_PHY_344_DATA 0x0000DD01
#define DDRSS_PHY_345_DATA 0x10100303
#define DDRSS_PHY_346_DATA 0x10101010
#define DDRSS_PHY_347_DATA 0x10101010
#define DDRSS_PHY_348_DATA 0x00041010
#define DDRSS_PHY_348_DATA 0x00021010
#define DDRSS_PHY_349_DATA 0x00100010
#define DDRSS_PHY_350_DATA 0x00100010
#define DDRSS_PHY_351_DATA 0x00100010
#define DDRSS_PHY_352_DATA 0x00100010
#define DDRSS_PHY_353_DATA 0x00050010
#define DDRSS_PHY_354_DATA 0x51517041
#define DDRSS_PHY_355_DATA 0x31C06000
#define DDRSS_PHY_355_DATA 0x31C06001
#define DDRSS_PHY_356_DATA 0x07AB0340
#define DDRSS_PHY_357_DATA 0x00C0C001
#define DDRSS_PHY_358_DATA 0x0D0C0001
#define DDRSS_PHY_358_DATA 0x0E0D0001
#define DDRSS_PHY_359_DATA 0x10001000
#define DDRSS_PHY_360_DATA 0x0C063E42
#define DDRSS_PHY_361_DATA 0x0F0C3201
#define DDRSS_PHY_360_DATA 0x0C083E42
#define DDRSS_PHY_361_DATA 0x0F0C3701
#define DDRSS_PHY_362_DATA 0x01000140
#define DDRSS_PHY_363_DATA 0x0C000420
#define DDRSS_PHY_364_DATA 0x000002DD
#define DDRSS_PHY_364_DATA 0x00000322
#define DDRSS_PHY_365_DATA 0x0A0000D0
#define DDRSS_PHY_366_DATA 0x00030200
#define DDRSS_PHY_367_DATA 0x02800000
#define DDRSS_PHY_368_DATA 0x80800000
#define DDRSS_PHY_369_DATA 0x000D2010
#define DDRSS_PHY_369_DATA 0x000E2010
#define DDRSS_PHY_370_DATA 0x76543210
#define DDRSS_PHY_371_DATA 0x00000008
#define DDRSS_PHY_372_DATA 0x02800280
@ -1156,13 +1156,13 @@
#define DDRSS_PHY_383_DATA 0x00A000A0
#define DDRSS_PHY_384_DATA 0x00A000A0
#define DDRSS_PHY_385_DATA 0x00A000A0
#define DDRSS_PHY_386_DATA 0x006D00A0
#define DDRSS_PHY_386_DATA 0x01C200A0
#define DDRSS_PHY_387_DATA 0x01A00005
#define DDRSS_PHY_388_DATA 0x00000000
#define DDRSS_PHY_389_DATA 0x00000000
#define DDRSS_PHY_390_DATA 0x00080200
#define DDRSS_PHY_391_DATA 0x00000000
#define DDRSS_PHY_392_DATA 0x20202020
#define DDRSS_PHY_392_DATA 0x20202000
#define DDRSS_PHY_393_DATA 0x20202020
#define DDRSS_PHY_394_DATA 0xF0F02020
#define DDRSS_PHY_395_DATA 0x00000000
@ -1299,7 +1299,7 @@
#define DDRSS_PHY_526_DATA 0x060100CC
#define DDRSS_PHY_527_DATA 0x00030066
#define DDRSS_PHY_528_DATA 0x00000000
#define DDRSS_PHY_529_DATA 0x00000001
#define DDRSS_PHY_529_DATA 0x00000301
#define DDRSS_PHY_530_DATA 0x0000AAAA
#define DDRSS_PHY_531_DATA 0x00005555
#define DDRSS_PHY_532_DATA 0x0000B5B5
@ -1315,7 +1315,7 @@
#define DDRSS_PHY_542_DATA 0x0F000000
#define DDRSS_PHY_543_DATA 0x00000F0F
#define DDRSS_PHY_544_DATA 0x10200000
#define DDRSS_PHY_545_DATA 0x0C002004
#define DDRSS_PHY_545_DATA 0x0C002007
#define DDRSS_PHY_546_DATA 0x00000000
#define DDRSS_PHY_547_DATA 0x00000000
#define DDRSS_PHY_548_DATA 0x55555555
@ -1367,35 +1367,35 @@
#define DDRSS_PHY_594_DATA 0x00000000
#define DDRSS_PHY_595_DATA 0x00000100
#define DDRSS_PHY_596_DATA 0x01CC0C01
#define DDRSS_PHY_597_DATA 0x0003CC0C
#define DDRSS_PHY_597_DATA 0x1003CC0C
#define DDRSS_PHY_598_DATA 0x20000140
#define DDRSS_PHY_599_DATA 0x07FF0200
#define DDRSS_PHY_600_DATA 0x0000DD01
#define DDRSS_PHY_601_DATA 0x10100303
#define DDRSS_PHY_602_DATA 0x10101010
#define DDRSS_PHY_603_DATA 0x10101010
#define DDRSS_PHY_604_DATA 0x00041010
#define DDRSS_PHY_604_DATA 0x00021010
#define DDRSS_PHY_605_DATA 0x00100010
#define DDRSS_PHY_606_DATA 0x00100010
#define DDRSS_PHY_607_DATA 0x00100010
#define DDRSS_PHY_608_DATA 0x00100010
#define DDRSS_PHY_609_DATA 0x00050010
#define DDRSS_PHY_610_DATA 0x51517041
#define DDRSS_PHY_611_DATA 0x31C06000
#define DDRSS_PHY_611_DATA 0x31C06001
#define DDRSS_PHY_612_DATA 0x07AB0340
#define DDRSS_PHY_613_DATA 0x00C0C001
#define DDRSS_PHY_614_DATA 0x0D0C0001
#define DDRSS_PHY_614_DATA 0x0E0D0001
#define DDRSS_PHY_615_DATA 0x10001000
#define DDRSS_PHY_616_DATA 0x0C063E42
#define DDRSS_PHY_617_DATA 0x0F0C3201
#define DDRSS_PHY_616_DATA 0x0C083E42
#define DDRSS_PHY_617_DATA 0x0F0C3701
#define DDRSS_PHY_618_DATA 0x01000140
#define DDRSS_PHY_619_DATA 0x0C000420
#define DDRSS_PHY_620_DATA 0x000002DD
#define DDRSS_PHY_620_DATA 0x00000322
#define DDRSS_PHY_621_DATA 0x0A0000D0
#define DDRSS_PHY_622_DATA 0x00030200
#define DDRSS_PHY_623_DATA 0x02800000
#define DDRSS_PHY_624_DATA 0x80800000
#define DDRSS_PHY_625_DATA 0x000D2010
#define DDRSS_PHY_625_DATA 0x000E2010
#define DDRSS_PHY_626_DATA 0x76543210
#define DDRSS_PHY_627_DATA 0x00000008
#define DDRSS_PHY_628_DATA 0x02800280
@ -1412,13 +1412,13 @@
#define DDRSS_PHY_639_DATA 0x00A000A0
#define DDRSS_PHY_640_DATA 0x00A000A0
#define DDRSS_PHY_641_DATA 0x00A000A0
#define DDRSS_PHY_642_DATA 0x006D00A0
#define DDRSS_PHY_642_DATA 0x01C200A0
#define DDRSS_PHY_643_DATA 0x01A00005
#define DDRSS_PHY_644_DATA 0x00000000
#define DDRSS_PHY_645_DATA 0x00000000
#define DDRSS_PHY_646_DATA 0x00080200
#define DDRSS_PHY_647_DATA 0x00000000
#define DDRSS_PHY_648_DATA 0x20202020
#define DDRSS_PHY_648_DATA 0x20202000
#define DDRSS_PHY_649_DATA 0x20202020
#define DDRSS_PHY_650_DATA 0xF0F02020
#define DDRSS_PHY_651_DATA 0x00000000
@ -1555,7 +1555,7 @@
#define DDRSS_PHY_782_DATA 0x060100CC
#define DDRSS_PHY_783_DATA 0x00030066
#define DDRSS_PHY_784_DATA 0x00000000
#define DDRSS_PHY_785_DATA 0x00000001
#define DDRSS_PHY_785_DATA 0x00000301
#define DDRSS_PHY_786_DATA 0x0000AAAA
#define DDRSS_PHY_787_DATA 0x00005555
#define DDRSS_PHY_788_DATA 0x0000B5B5
@ -1571,7 +1571,7 @@
#define DDRSS_PHY_798_DATA 0x0F000000
#define DDRSS_PHY_799_DATA 0x00000F0F
#define DDRSS_PHY_800_DATA 0x10200000
#define DDRSS_PHY_801_DATA 0x0C002004
#define DDRSS_PHY_801_DATA 0x0C002007
#define DDRSS_PHY_802_DATA 0x00000000
#define DDRSS_PHY_803_DATA 0x00000000
#define DDRSS_PHY_804_DATA 0x55555555
@ -1623,35 +1623,35 @@
#define DDRSS_PHY_850_DATA 0x00000000
#define DDRSS_PHY_851_DATA 0x00000100
#define DDRSS_PHY_852_DATA 0x01CC0C01
#define DDRSS_PHY_853_DATA 0x0003CC0C
#define DDRSS_PHY_853_DATA 0x1003CC0C
#define DDRSS_PHY_854_DATA 0x20000140
#define DDRSS_PHY_855_DATA 0x07FF0200
#define DDRSS_PHY_856_DATA 0x0000DD01
#define DDRSS_PHY_857_DATA 0x10100303
#define DDRSS_PHY_858_DATA 0x10101010
#define DDRSS_PHY_859_DATA 0x10101010
#define DDRSS_PHY_860_DATA 0x00041010
#define DDRSS_PHY_860_DATA 0x00021010
#define DDRSS_PHY_861_DATA 0x00100010
#define DDRSS_PHY_862_DATA 0x00100010
#define DDRSS_PHY_863_DATA 0x00100010
#define DDRSS_PHY_864_DATA 0x00100010
#define DDRSS_PHY_865_DATA 0x00050010
#define DDRSS_PHY_866_DATA 0x51517041
#define DDRSS_PHY_867_DATA 0x31C06000
#define DDRSS_PHY_867_DATA 0x31C06001
#define DDRSS_PHY_868_DATA 0x07AB0340
#define DDRSS_PHY_869_DATA 0x00C0C001
#define DDRSS_PHY_870_DATA 0x0D0C0001
#define DDRSS_PHY_870_DATA 0x0E0D0001
#define DDRSS_PHY_871_DATA 0x10001000
#define DDRSS_PHY_872_DATA 0x0C063E42
#define DDRSS_PHY_873_DATA 0x0F0C3201
#define DDRSS_PHY_872_DATA 0x0C083E42
#define DDRSS_PHY_873_DATA 0x0F0C3701
#define DDRSS_PHY_874_DATA 0x01000140
#define DDRSS_PHY_875_DATA 0x0C000420
#define DDRSS_PHY_876_DATA 0x000002DD
#define DDRSS_PHY_876_DATA 0x00000322
#define DDRSS_PHY_877_DATA 0x0A0000D0
#define DDRSS_PHY_878_DATA 0x00030200
#define DDRSS_PHY_879_DATA 0x02800000
#define DDRSS_PHY_880_DATA 0x80800000
#define DDRSS_PHY_881_DATA 0x000D2010
#define DDRSS_PHY_881_DATA 0x000E2010
#define DDRSS_PHY_882_DATA 0x76543210
#define DDRSS_PHY_883_DATA 0x00000008
#define DDRSS_PHY_884_DATA 0x02800280
@ -1668,13 +1668,13 @@
#define DDRSS_PHY_895_DATA 0x00A000A0
#define DDRSS_PHY_896_DATA 0x00A000A0
#define DDRSS_PHY_897_DATA 0x00A000A0
#define DDRSS_PHY_898_DATA 0x006D00A0
#define DDRSS_PHY_898_DATA 0x01C200A0
#define DDRSS_PHY_899_DATA 0x01A00005
#define DDRSS_PHY_900_DATA 0x00000000
#define DDRSS_PHY_901_DATA 0x00000000
#define DDRSS_PHY_902_DATA 0x00080200
#define DDRSS_PHY_903_DATA 0x00000000
#define DDRSS_PHY_904_DATA 0x20202020
#define DDRSS_PHY_904_DATA 0x20202000
#define DDRSS_PHY_905_DATA 0x20202020
#define DDRSS_PHY_906_DATA 0xF0F02020
#define DDRSS_PHY_907_DATA 0x00000000
@ -1834,7 +1834,7 @@
#define DDRSS_PHY_1061_DATA 0x00000000
#define DDRSS_PHY_1062_DATA 0x00000000
#define DDRSS_PHY_1063_DATA 0x00000000
#define DDRSS_PHY_1064_DATA 0x000505FF
#define DDRSS_PHY_1064_DATA 0x000305FF
#define DDRSS_PHY_1065_DATA 0x00030000
#define DDRSS_PHY_1066_DATA 0x00000300
#define DDRSS_PHY_1067_DATA 0x00000300
@ -2163,8 +2163,8 @@
#define DDRSS_PHY_1390_DATA 0x00000000
#define DDRSS_PHY_1391_DATA 0x00000000
#define DDRSS_PHY_1392_DATA 0x00000000
#define DDRSS_PHY_1393_DATA 0x0001F7C5
#define DDRSS_PHY_1394_DATA 0x00000005
#define DDRSS_PHY_1393_DATA 0x0001F7C0
#define DDRSS_PHY_1394_DATA 0x00000003
#define DDRSS_PHY_1395_DATA 0x00000000
#define DDRSS_PHY_1396_DATA 0x00001142
#define DDRSS_PHY_1397_DATA 0x010207AB

View File

@ -6,7 +6,7 @@
/dts-v1/;
#include "k3-j721e-som-p0.dtsi"
#include "k3-j721e-ddr-evm-lp4-3733.dtsi"
#include "k3-j721e-ddr-evm-lp4-4266.dtsi"
#include "k3-j721e-ddr.dtsi"
/ {
@ -28,6 +28,7 @@
power-domains = <&k3_pds 61 TI_SCI_PD_EXCLUSIVE>,
<&k3_pds 202 TI_SCI_PD_EXCLUSIVE>;
resets = <&k3_reset 202 0>;
clocks = <&k3_clks 61 1>;
assigned-clocks = <&k3_clks 202 2>, <&k3_clks 61 1>;
assigned-clock-rates = <2000000000>, <200000000>;
ti,sci = <&dmsc>;

View File

@ -66,6 +66,7 @@
#define DPLL_EN_STOP 1
#define DPLL_EN_MN_BYPASS 4
#define DPLL_EN_LOW_POWER_BYPASS 5
#define DPLL_EN_FAST_RELOCK_BYPASS 6
#define DPLL_EN_LOCK 7
/* CM_IDLEST_DPLL fields */

View File

@ -194,13 +194,14 @@ void do_enable_clocks(u32 *const *clk_domains,
u32 i, max = 100;
/* Put the clock domains in SW_WKUP mode */
for (i = 0; (i < max) && clk_domains[i]; i++) {
for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++) {
enable_clock_domain(clk_domains[i],
CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
}
/* Clock modules that need to be put in SW_EXPLICIT_EN mode */
for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) {
for (i = 0; (i < max) && clk_modules_explicit_en &&
clk_modules_explicit_en[i]; i++) {
enable_clock_module(clk_modules_explicit_en[i],
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
wait_for_enable);
@ -215,12 +216,13 @@ void do_disable_clocks(u32 *const *clk_domains,
/* Clock modules that need to be put in SW_DISABLE */
for (i = 0; (i < max) && clk_modules_disable[i]; i++)
for (i = 0; (i < max) && clk_modules_disable && clk_modules_disable[i];
i++)
disable_clock_module(clk_modules_disable[i],
wait_for_disable);
/* Put the clock domains in SW_SLEEP mode */
for (i = 0; (i < max) && clk_domains[i]; i++)
for (i = 0; (i < max) && clk_domains && clk_domains[i]; i++)
disable_clock_domain(clk_domains[i]);
}

View File

@ -226,7 +226,7 @@ void enable_basic_clocks(void)
&cmper->usb0clkctrl,
&cmper->emiffwclkctrl,
&cmper->emifclkctrl,
#if CONFIG_IS_ENABLED(AM335X_LCD)
#if CONFIG_IS_ENABLED(AM335X_LCD) && !CONFIG_IS_ENABLED(DM_VIDEO)
&cmper->lcdclkctrl,
&cmper->lcdcclkstctrl,
#endif

View File

@ -42,6 +42,7 @@
fdt-dummy1 = "/translation-test@8000/dev@1,100";
fdt-dummy2 = "/translation-test@8000/dev@2,200";
fdt-dummy3 = "/translation-test@8000/noxlatebus@3,300/dev@42";
fdt-dummy4 = "/translation-test@8000/xlatebus@4,400/devs/dev@19";
usb0 = &usb_0;
usb1 = &usb_1;
usb2 = &usb_2;
@ -141,6 +142,52 @@
<&muxcontroller1>;
mux-control-names = "mux0", "mux1", "mux2", "mux3", "mux4";
mux-syscon = <&syscon3>;
display-timings {
timing0: 240x320 {
clock-frequency = <6500000>;
hactive = <240>;
vactive = <320>;
hfront-porch = <6>;
hback-porch = <7>;
hsync-len = <1>;
vback-porch = <5>;
vfront-porch = <8>;
vsync-len = <2>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <1>;
interlaced;
doublescan;
doubleclk;
};
timing1: 480x800 {
clock-frequency = <9000000>;
hactive = <480>;
vactive = <800>;
hfront-porch = <10>;
hback-porch = <59>;
hsync-len = <12>;
vback-porch = <15>;
vfront-porch = <17>;
vsync-len = <16>;
hsync-active = <0>;
vsync-active = <1>;
de-active = <0>;
pixelclk-active = <0>;
};
timing2: 800x480 {
clock-frequency = <33500000>;
hactive = <800>;
vactive = <480>;
hback-porch = <89>;
hfront-porch = <164>;
vback-porch = <23>;
vfront-porch = <10>;
hsync-len = <11>;
vsync-len = <13>;
};
};
};
junk {
@ -1082,6 +1129,7 @@
1 0x100 0x9000 0x1000
2 0x200 0xA000 0x1000
3 0x300 0xB000 0x1000
4 0x400 0xC000 0x1000
>;
dma-ranges = <0 0x000 0x10000000 0x1000
@ -1118,6 +1166,25 @@
reg = <0x42>;
};
};
xlatebus@4,400 {
compatible = "sandbox,zero-size-cells-bus";
reg = <4 0x400 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 4 0x400 0x1000>;
devs {
#address-cells = <1>;
#size-cells = <0>;
dev@19 {
compatible = "denx,u-boot-fdt-dummy";
reg = <0x19>;
};
};
};
};
osd {

View File

@ -105,6 +105,15 @@ int sandbox_clk_test_get_bulk(struct udevice *dev);
* @return: The rate of the clock.
*/
ulong sandbox_clk_test_get_rate(struct udevice *dev, int id);
/**
* sandbox_clk_test_round_rate - Ask the sandbox clock test device to round a
* clock's rate.
*
* @dev: The sandbox clock test (client) device.
* @id: The test device's clock ID to configure.
* @return: The rounded rate of the clock.
*/
ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate);
/**
* sandbox_clk_test_set_rate - Ask the sandbox clock test device to set a
* clock's rate.

View File

@ -12,7 +12,7 @@
#define _BUR_COMMON_H_
#if !CONFIG_IS_ENABLED(DM_VIDEO)
#include <../../../drivers/video/am335x-fb.h>
#include <../../../drivers/video/ti/am335x-fb.h>
int load_lcdtiming(struct am335x_lcdpanel *panel);
#endif

View File

@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
#include <asm/arch/cpu.h>
#include <asm/gpio.h>
#include <power/tps65217.h>
#include "../../../drivers/video/am335x-fb.h"
#include "../../../drivers/video/ti/am335x-fb.h"
void lcdbacklight(int on)
{

View File

@ -879,7 +879,7 @@ int board_late_init(void)
}
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
uclass_get_device_by_name(UCLASS_CLK, "cdce913@65", &dev);
return 0;
}

View File

@ -744,7 +744,7 @@ int board_late_init(void)
#endif
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
uclass_get_device_by_name(UCLASS_CLK, "cdce913@65", &dev);
return 0;
}

View File

@ -38,6 +38,10 @@ enum {
/* Max number of MAC addresses that are parsed/processed per daughter card */
#define DAUGHTER_CARD_NO_OF_MAC_ADDR 8
/* Regiter that controls the SERDES0 lane and clock assignment */
#define CTRLMMR_SERDES0_CTRL 0x00104080
#define PCIE_LANE0 0x1
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
@ -312,6 +316,18 @@ static int probe_daughtercards(void)
(uchar *)mac_addr[j]);
}
/*
* It has been observed that setting SERDES0 lane mux to USB prevents USB
* 2.0 operation on USB0. Setting SERDES0 lane mux to non-USB when USB0 is
* used in USB 2.0 only mode solves this issue. For USB3.0+2.0 operation
* this issue is not present.
*
* Implement this workaround by writing 1 to LANE_FUNC_SEL field in
* CTRLMMR_SERDES0_CTRL register.
*/
if (!strncmp(ep.name, "SER-PCIE2LEVM", sizeof(ep.name)))
writel(PCIE_LANE0, CTRLMMR_SERDES0_CTRL);
/* Skip if no overlays are to be added */
if (!strlen(cards[i].dtbo_name))
continue;

View File

@ -48,11 +48,11 @@ int dram_init(void)
gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
CONFIG_MAX_RAM_BANK_SIZE);
#if defined(CONFIG_TI_AEMIF)
if (!board_is_k2g_ice())
if (!(board_is_k2g_ice() || board_is_k2g_i1()))
aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs);
#endif
if (!board_is_k2g_ice()) {
if (!(board_is_k2g_ice() || board_is_k2g_i1())) {
if (ddr3_size)
ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size);
else

View File

@ -25,6 +25,10 @@ static inline int board_is_k2g_ice(void)
{
return board_ti_is("66AK2GIC");
}
static inline int board_is_k2g_i1(void)
{
return board_ti_is("66AK2GI1");
}
#else
static inline int board_is_k2g_gp(void)
{
@ -34,6 +38,10 @@ static inline int board_is_k2g_ice(void)
{
return false;
}
static inline int board_is_k2g_i1(void)
{
return false;
}
#endif
void spl_init_keystone_plls(void);

View File

@ -248,7 +248,8 @@ int board_fit_config_name_match(const char *name)
else if (!strcmp(name, "keystone-k2g-evm") &&
(board_ti_is("66AK2GGP") || board_ti_is("66AK2GG1")))
return 0;
else if (!strcmp(name, "keystone-k2g-ice") && board_ti_is("66AK2GIC"))
else if (!strcmp(name, "keystone-k2g-ice") &&
(board_ti_is("66AK2GIC") || board_is_k2g_i1()))
return 0;
else
return -1;
@ -322,7 +323,7 @@ int embedded_dtb_select(void)
BIT(9));
setbits_le32(K2G_GPIO1_BANK2_BASE + K2G_GPIO_SETDATA_OFFSET,
BIT(9));
} else if (board_is_k2g_ice()) {
} else if (board_is_k2g_ice() || board_is_k2g_i1()) {
/* GBE Phy workaround. For Phy to latch the input
* configuration, a GPIO reset is asserted at the
* Phy reset pin to latch configuration correctly after SoC
@ -364,6 +365,8 @@ int board_late_init(void)
env_set("board_name", "66AK2GG1\0");
else if (board_is_k2g_ice())
env_set("board_name", "66AK2GIC\0");
else if (board_is_k2g_i1())
env_set("board_name", "66AK2GI1\0");
#endif
return 0;
}

View File

@ -174,7 +174,7 @@ u32 ddr3_init(void)
} else if (board_is_k2g_gp()) {
ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_800_2g);
ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_800_2g);
} else if (board_is_k2g_ice()) {
} else if (board_is_k2g_ice() || board_is_k2g_i1()) {
ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_800_512mb);
ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_800_512mb);
}

View File

@ -377,7 +377,7 @@ void k2g_mux_config(void)
configure_pin_mux(k2g_generic_pin_cfg);
} else if (board_is_k2g_gp() || board_is_k2g_g1()) {
configure_pin_mux(k2g_evm_pin_cfg);
} else if (board_is_k2g_ice()) {
} else if (board_is_k2g_ice() || board_is_k2g_i1()) {
configure_pin_mux(k2g_ice_evm_pin_cfg);
} else {
puts("Unknown board, cannot configure pinmux.");

View File

@ -20,6 +20,8 @@
#include <exports.h>
#include <fdtdec.h>
DECLARE_GLOBAL_DATA_PTR;
/**
* fdt_getprop_u32_default_node - Return a node's property or a default
*
@ -996,8 +998,8 @@ void fdt_del_node_and_alias(void *blob, const char *alias)
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
#define OF_BAD_ADDR FDT_ADDR_T_NONE
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
(ns) > 0)
#define OF_CHECK_COUNTS(na, ns) (((na) > 0 && (na) <= OF_MAX_ADDR_CELLS) && \
((ns) > 0 || gd_size_cells_0()))
/* Debug utility */
#ifdef DEBUG

View File

@ -4,6 +4,7 @@ CONFIG_ARCH_OMAP2PLUS=y
CONFIG_SYS_TEXT_BASE=0x80008000
CONFIG_NR_DRAM_BANKS=2
CONFIG_TARGET_NOKIA_RX51=y
# CONFIG_TI_SYSC is not set
# CONFIG_FIT is not set
CONFIG_BOOTDELAY=30
CONFIG_AUTOBOOT_KEYED=y

View File

@ -5,6 +5,19 @@
menu "Bus devices"
config TI_PWMSS
bool
default y if ARCH_OMAP2PLUS && PWM_TI_EHRPWM
help
PWM Subsystem driver support for AM33xx SOC.
config TI_SYSC
bool "TI sysc interconnect target module driver"
depends on ARCH_OMAP2PLUS
help
Generic driver for Texas Instruments interconnect target module
found on many TI SoCs.
config UNIPHIER_SYSTEM_BUS
bool "UniPhier System Bus driver"
depends on ARCH_UNIPHIER

View File

@ -3,4 +3,6 @@
# Makefile for the bus drivers.
#
obj-$(CONFIG_TI_PWMSS) += ti-pwmss.o
obj-$(CONFIG_TI_SYSC) += ti-sysc.o
obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o

21
drivers/bus/ti-pwmss.c Normal file
View File

@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Pulse-Width Modulation Subsystem (pwmss)
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <dm.h>
static const struct udevice_id ti_pwmss_ids[] = {
{.compatible = "ti,am33xx-pwmss"},
{}
};
U_BOOT_DRIVER(ti_pwmss) = {
.name = "ti_pwmss",
.id = UCLASS_SIMPLE_BUS,
.of_match = ti_pwmss_ids,
.bind = dm_scan_fdt_dev,
};

166
drivers/bus/ti-sysc.c Normal file
View File

@ -0,0 +1,166 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments sysc interconnect target driver
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dm/device_compat.h>
enum ti_sysc_clocks {
TI_SYSC_FCK,
TI_SYSC_ICK,
TI_SYSC_MAX_CLOCKS,
};
static const char *const clock_names[] = {"fck", "ick"};
struct ti_sysc_priv {
int clocks_count;
struct clk clocks[TI_SYSC_MAX_CLOCKS];
};
static const struct udevice_id ti_sysc_ids[] = {
{.compatible = "ti,sysc-omap2"},
{.compatible = "ti,sysc-omap4"},
{.compatible = "ti,sysc-omap4-simple"},
{.compatible = "ti,sysc-omap3430-sr"},
{.compatible = "ti,sysc-omap3630-sr"},
{.compatible = "ti,sysc-omap4-sr"},
{.compatible = "ti,sysc-omap3-sham"},
{.compatible = "ti,sysc-omap-aes"},
{.compatible = "ti,sysc-mcasp"},
{.compatible = "ti,sysc-usb-host-fs"},
{}
};
static int ti_sysc_get_one_clock(struct udevice *dev, enum ti_sysc_clocks index)
{
struct ti_sysc_priv *priv = dev_get_priv(dev);
const char *name;
int err;
switch (index) {
case TI_SYSC_FCK:
break;
case TI_SYSC_ICK:
break;
default:
return -EINVAL;
}
name = clock_names[index];
err = clk_get_by_name(dev, name, &priv->clocks[index]);
if (err) {
if (err == -ENODATA)
return 0;
dev_err(dev, "failed to get %s clock\n", name);
return err;
}
return 0;
}
static int ti_sysc_put_clocks(struct udevice *dev)
{
struct ti_sysc_priv *priv = dev_get_priv(dev);
int err;
err = clk_release_all(priv->clocks, priv->clocks_count);
if (err)
dev_err(dev, "failed to release all clocks\n");
return err;
}
static int ti_sysc_get_clocks(struct udevice *dev)
{
struct ti_sysc_priv *priv = dev_get_priv(dev);
int i, err;
for (i = 0; i < TI_SYSC_MAX_CLOCKS; i++) {
err = ti_sysc_get_one_clock(dev, i);
if (!err)
priv->clocks_count++;
else if (err != -ENOENT)
return err;
}
return 0;
}
static int ti_sysc_child_post_remove(struct udevice *dev)
{
struct ti_sysc_priv *priv = dev_get_priv(dev->parent);
int i, err;
for (i = 0; i < priv->clocks_count; i++) {
err = clk_disable(&priv->clocks[i]);
if (err) {
dev_err(dev->parent, "failed to disable %s clock\n",
clock_names[i]);
return err;
}
}
return 0;
}
static int ti_sysc_child_pre_probe(struct udevice *dev)
{
struct ti_sysc_priv *priv = dev_get_priv(dev->parent);
int i, err;
for (i = 0; i < priv->clocks_count; i++) {
err = clk_enable(&priv->clocks[i]);
if (err) {
dev_err(dev->parent, "failed to enable %s clock\n",
clock_names[i]);
return err;
}
}
return 0;
}
static int ti_sysc_remove(struct udevice *dev)
{
return ti_sysc_put_clocks(dev);
}
static int ti_sysc_probe(struct udevice *dev)
{
int err;
err = ti_sysc_get_clocks(dev);
if (err)
goto clocks_err;
return 0;
clocks_err:
ti_sysc_put_clocks(dev);
return err;
}
UCLASS_DRIVER(ti_sysc) = {
.id = UCLASS_SIMPLE_BUS,
.name = "ti_sysc",
.post_bind = dm_scan_fdt_dev
};
U_BOOT_DRIVER(ti_sysc) = {
.name = "ti_sysc",
.id = UCLASS_SIMPLE_BUS,
.of_match = ti_sysc_ids,
.probe = ti_sysc_probe,
.remove = ti_sysc_remove,
.child_pre_probe = ti_sysc_child_pre_probe,
.child_post_remove = ti_sysc_child_post_remove,
.priv_auto = sizeof(struct ti_sysc_priv)
};

View File

@ -98,14 +98,6 @@ config CLK_STM32F
This clock driver adds support for RCC clock management
for STM32F4 and STM32F7 SoCs.
config CLK_TI_SCI
bool "TI System Control Interface (TI SCI) clock driver"
depends on CLK && TI_SCI_PROTOCOL && OF_CONTROL
help
This enables the clock driver support over TI System Control Interface
available on some new TI's SoCs. If you wish to use clock resources
managed by the TI System Controller, say Y here. Otherwise, say N.
config CLK_HSDK
bool "Enable cgu clock driver for HSDK boards"
depends on CLK && TARGET_HSDK
@ -179,6 +171,7 @@ source "drivers/clk/renesas/Kconfig"
source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sifive/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
config ICS8N3QV01

View File

@ -14,6 +14,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_COMPOSITE_CCF) += clk-composite.o
obj-y += analogbits/
obj-y += imx/
obj-y += tegra/
obj-y += ti/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
@ -47,6 +48,5 @@ obj-$(CONFIG_SANDBOX) += clk_sandbox.o
obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o
obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o

View File

@ -28,8 +28,8 @@
#define UBOOT_DM_CLK_CCF_DIVIDER "ccf_clk_divider"
static unsigned int _get_table_div(const struct clk_div_table *table,
unsigned int val)
unsigned int clk_divider_get_table_div(const struct clk_div_table *table,
unsigned int val)
{
const struct clk_div_table *clkt;
@ -49,7 +49,7 @@ static unsigned int _get_div(const struct clk_div_table *table,
if (flags & CLK_DIVIDER_MAX_AT_ZERO)
return val ? val : clk_div_mask(width) + 1;
if (table)
return _get_table_div(table, val);
return clk_divider_get_table_div(table, val);
return val + 1;
}
@ -89,8 +89,8 @@ static ulong clk_divider_recalc_rate(struct clk *clk)
divider->flags, divider->width);
}
static bool _is_valid_table_div(const struct clk_div_table *table,
unsigned int div)
bool clk_divider_is_valid_table_div(const struct clk_div_table *table,
unsigned int div)
{
const struct clk_div_table *clkt;
@ -100,18 +100,18 @@ static bool _is_valid_table_div(const struct clk_div_table *table,
return false;
}
static bool _is_valid_div(const struct clk_div_table *table, unsigned int div,
unsigned long flags)
bool clk_divider_is_valid_div(const struct clk_div_table *table,
unsigned int div, unsigned long flags)
{
if (flags & CLK_DIVIDER_POWER_OF_TWO)
return is_power_of_2(div);
if (table)
return _is_valid_table_div(table, div);
return clk_divider_is_valid_table_div(table, div);
return true;
}
static unsigned int _get_table_val(const struct clk_div_table *table,
unsigned int div)
unsigned int clk_divider_get_table_val(const struct clk_div_table *table,
unsigned int div)
{
const struct clk_div_table *clkt;
@ -131,7 +131,7 @@ static unsigned int _get_val(const struct clk_div_table *table,
if (flags & CLK_DIVIDER_MAX_AT_ZERO)
return (div == clk_div_mask(width) + 1) ? 0 : div;
if (table)
return _get_table_val(table, div);
return clk_divider_get_table_val(table, div);
return div - 1;
}
int divider_get_val(unsigned long rate, unsigned long parent_rate,
@ -142,7 +142,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
if (!_is_valid_div(table, div, flags))
if (!clk_divider_is_valid_div(table, div, flags))
return -EINVAL;
value = _get_val(table, div, flags, width);

View File

@ -523,6 +523,21 @@ long long clk_get_parent_rate(struct clk *clk)
return pclk->rate;
}
ulong clk_round_rate(struct clk *clk, ulong rate)
{
const struct clk_ops *ops;
debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
if (!clk_valid(clk))
return 0;
ops = clk_dev_ops(clk->dev);
if (!ops->round_rate)
return -ENOSYS;
return ops->round_rate(clk, rate);
}
ulong clk_set_rate(struct clk *clk, ulong rate)
{
const struct clk_ops *ops;

View File

@ -30,6 +30,22 @@ static ulong sandbox_clk_get_rate(struct clk *clk)
return priv->rate[clk->id];
}
static ulong sandbox_clk_round_rate(struct clk *clk, ulong rate)
{
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
if (!priv->probed)
return -ENODEV;
if (clk->id >= SANDBOX_CLK_ID_COUNT)
return -EINVAL;
if (!rate)
return -EINVAL;
return rate;
}
static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
{
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
@ -103,6 +119,7 @@ static int sandbox_clk_free(struct clk *clk)
}
static struct clk_ops sandbox_clk_ops = {
.round_rate = sandbox_clk_round_rate,
.get_rate = sandbox_clk_get_rate,
.set_rate = sandbox_clk_set_rate,
.enable = sandbox_clk_enable,

View File

@ -86,6 +86,16 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
return clk_get_rate(sbct->clkps[id]);
}
ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate)
{
struct sandbox_clk_test *sbct = dev_get_priv(dev);
if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
return -EINVAL;
return clk_round_rate(sbct->clkps[id], rate);
}
ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
{
struct sandbox_clk_test *sbct = dev_get_priv(dev);

43
drivers/clk/ti/Kconfig Normal file
View File

@ -0,0 +1,43 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
#
config CLK_TI_AM3_DPLL
bool "TI AM33XX Digital Phase-Locked Loop (DPLL) clock drivers"
depends on CLK && OF_CONTROL
help
This enables the DPLL clock drivers support on AM33XX SoCs. The DPLL
provides all interface clocks and functional clocks to the processor.
config CLK_TI_CTRL
bool "TI OMAP4 clock controller"
depends on CLK && OF_CONTROL
help
This enables the clock controller driver support on TI's SoCs.
config CLK_TI_DIVIDER
bool "TI divider clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
help
This enables the divider clock driver support on TI's SoCs.
config CLK_TI_GATE
bool "TI gate clock driver"
depends on CLK && OF_CONTROL
help
This enables the gate clock driver support on TI's SoCs.
config CLK_TI_MUX
bool "TI mux clock driver"
depends on CLK && OF_CONTROL && CLK_CCF
help
This enables the mux clock driver support on TI's SoCs.
config CLK_TI_SCI
bool "TI System Control Interface (TI SCI) clock driver"
depends on CLK && TI_SCI_PROTOCOL && OF_CONTROL
help
This enables the clock driver support over TI System Control Interface
available on some new TI's SoCs. If you wish to use clock resources
managed by the TI System Controller, say Y here. Otherwise, say N.

13
drivers/clk/ti/Makefile Normal file
View File

@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
#
obj-$(CONFIG_ARCH_OMAP2PLUS) += clk.o omap4-cm.o
obj-$(CONFIG_CLK_TI_AM3_DPLL) += clk-am3-dpll.o clk-am3-dpll-x2.o
obj-$(CONFIG_CLK_TI_CTRL) += clk-ctrl.o
obj-$(CONFIG_CLK_TI_DIVIDER) += clk-divider.o
obj-$(CONFIG_CLK_TI_GATE) += clk-gate.o
obj-$(CONFIG_CLK_TI_MUX) += clk-mux.o
obj-$(CONFIG_CLK_TI_SCI) += clk-sci.o

View File

@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI DPLL x2 clock support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Loosely based on Linux kernel drivers/clk/ti/dpll.c
*/
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <linux/clk-provider.h>
struct clk_ti_am3_dpll_x2_priv {
struct clk parent;
};
static ulong clk_ti_am3_dpll_x2_get_rate(struct clk *clk)
{
struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(clk->dev);
unsigned long rate;
rate = clk_get_rate(&priv->parent);
if (IS_ERR_VALUE(rate))
return rate;
rate *= 2;
dev_dbg(clk->dev, "rate=%ld\n", rate);
return rate;
}
const struct clk_ops clk_ti_am3_dpll_x2_ops = {
.get_rate = clk_ti_am3_dpll_x2_get_rate,
};
static int clk_ti_am3_dpll_x2_remove(struct udevice *dev)
{
struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(dev);
int err;
err = clk_release_all(&priv->parent, 1);
if (err) {
dev_err(dev, "failed to release parent clock\n");
return err;
}
return 0;
}
static int clk_ti_am3_dpll_x2_probe(struct udevice *dev)
{
struct clk_ti_am3_dpll_x2_priv *priv = dev_get_priv(dev);
int err;
err = clk_get_by_index(dev, 0, &priv->parent);
if (err) {
dev_err(dev, "%s: failed to get parent clock\n", __func__);
return err;
}
return 0;
}
static const struct udevice_id clk_ti_am3_dpll_x2_of_match[] = {
{.compatible = "ti,am3-dpll-x2-clock"},
{}
};
U_BOOT_DRIVER(clk_ti_am3_dpll_x2) = {
.name = "ti_am3_dpll_x2_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_am3_dpll_x2_of_match,
.probe = clk_ti_am3_dpll_x2_probe,
.remove = clk_ti_am3_dpll_x2_remove,
.priv_auto = sizeof(struct clk_ti_am3_dpll_x2_priv),
.ops = &clk_ti_am3_dpll_x2_ops,
};

View File

@ -0,0 +1,268 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI DPLL clock support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Loosely based on Linux kernel drivers/clk/ti/dpll.c
*/
#include <common.h>
#include <clk.h>
#include <clk-uclass.h>
#include <div64.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <hang.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
struct clk_ti_am3_dpll_drv_data {
ulong max_rate;
};
struct clk_ti_am3_dpll_priv {
fdt_addr_t clkmode_reg;
fdt_addr_t idlest_reg;
fdt_addr_t clksel_reg;
struct clk clk_bypass;
struct clk clk_ref;
u16 last_rounded_mult;
u8 last_rounded_div;
ulong max_rate;
};
static ulong clk_ti_am3_dpll_round_rate(struct clk *clk, ulong rate)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(clk->dev);
ulong ret, ref_rate, r;
int m, d, err_min, err;
int mult = INT_MAX, div = INT_MAX;
if (priv->max_rate && rate > priv->max_rate) {
dev_warn(clk->dev, "%ld is to high a rate, lowered to %ld\n",
rate, priv->max_rate);
rate = priv->max_rate;
}
ret = -EFAULT;
err = rate;
err_min = rate;
ref_rate = clk_get_rate(&priv->clk_ref);
for (d = 1; err_min && d <= 128; d++) {
for (m = 2; m <= 2047; m++) {
r = (ref_rate * m) / d;
err = abs(r - rate);
if (err < err_min) {
err_min = err;
ret = r;
mult = m;
div = d;
if (err == 0)
break;
} else if (r > rate) {
break;
}
}
}
priv->last_rounded_mult = mult;
priv->last_rounded_div = div;
dev_dbg(clk->dev, "rate=%ld, best_rate=%ld, mult=%d, div=%d\n", rate,
ret, mult, div);
return ret;
}
static ulong clk_ti_am3_dpll_set_rate(struct clk *clk, ulong rate)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(clk->dev);
u32 v;
ulong round_rate;
round_rate = clk_ti_am3_dpll_round_rate(clk, rate);
if (IS_ERR_VALUE(round_rate))
return round_rate;
v = readl(priv->clksel_reg);
/* enter bypass mode */
clrsetbits_le32(priv->clkmode_reg, CM_CLKMODE_DPLL_DPLL_EN_MASK,
DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT);
/* wait for bypass mode */
if (!wait_on_value(ST_DPLL_CLK_MASK, 0,
(void *)priv->idlest_reg, LDELAY))
dev_err(clk->dev, "failed bypassing dpll\n");
/* set M & N */
v &= ~CM_CLKSEL_DPLL_M_MASK;
v |= (priv->last_rounded_mult << CM_CLKSEL_DPLL_M_SHIFT) &
CM_CLKSEL_DPLL_M_MASK;
v &= ~CM_CLKSEL_DPLL_N_MASK;
v |= ((priv->last_rounded_div - 1) << CM_CLKSEL_DPLL_N_SHIFT) &
CM_CLKSEL_DPLL_N_MASK;
writel(v, priv->clksel_reg);
/* lock dpll */
clrsetbits_le32(priv->clkmode_reg, CM_CLKMODE_DPLL_DPLL_EN_MASK,
DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
/* wait till the dpll locks */
if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
(void *)priv->idlest_reg, LDELAY)) {
dev_err(clk->dev, "failed locking dpll\n");
hang();
}
return round_rate;
}
static ulong clk_ti_am3_dpll_get_rate(struct clk *clk)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(clk->dev);
u64 rate;
u32 m, n, v;
/* Return bypass rate if DPLL is bypassed */
v = readl(priv->clkmode_reg);
v &= CM_CLKMODE_DPLL_EN_MASK;
v >>= CM_CLKMODE_DPLL_EN_SHIFT;
switch (v) {
case DPLL_EN_MN_BYPASS:
case DPLL_EN_LOW_POWER_BYPASS:
case DPLL_EN_FAST_RELOCK_BYPASS:
rate = clk_get_rate(&priv->clk_bypass);
dev_dbg(clk->dev, "rate=%lld\n", rate);
return rate;
}
v = readl(priv->clksel_reg);
m = v & CM_CLKSEL_DPLL_M_MASK;
m >>= CM_CLKSEL_DPLL_M_SHIFT;
n = v & CM_CLKSEL_DPLL_N_MASK;
n >>= CM_CLKSEL_DPLL_N_SHIFT;
rate = clk_get_rate(&priv->clk_ref) * m;
do_div(rate, n + 1);
dev_dbg(clk->dev, "rate=%lld\n", rate);
return rate;
}
const struct clk_ops clk_ti_am3_dpll_ops = {
.round_rate = clk_ti_am3_dpll_round_rate,
.get_rate = clk_ti_am3_dpll_get_rate,
.set_rate = clk_ti_am3_dpll_set_rate,
};
static int clk_ti_am3_dpll_remove(struct udevice *dev)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(dev);
int err;
err = clk_release_all(&priv->clk_bypass, 1);
if (err) {
dev_err(dev, "failed to release bypass clock\n");
return err;
}
err = clk_release_all(&priv->clk_ref, 1);
if (err) {
dev_err(dev, "failed to release reference clock\n");
return err;
}
return 0;
}
static int clk_ti_am3_dpll_probe(struct udevice *dev)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(dev);
int err;
err = clk_get_by_index(dev, 0, &priv->clk_ref);
if (err) {
dev_err(dev, "failed to get reference clock\n");
return err;
}
err = clk_get_by_index(dev, 1, &priv->clk_bypass);
if (err) {
dev_err(dev, "failed to get bypass clock\n");
return err;
}
return 0;
}
static int clk_ti_am3_dpll_of_to_plat(struct udevice *dev)
{
struct clk_ti_am3_dpll_priv *priv = dev_get_priv(dev);
struct clk_ti_am3_dpll_drv_data *data =
(struct clk_ti_am3_dpll_drv_data *)dev_get_driver_data(dev);
priv->max_rate = data->max_rate;
priv->clkmode_reg = dev_read_addr_index(dev, 0);
if (priv->clkmode_reg == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get clkmode register\n");
return -EINVAL;
}
dev_dbg(dev, "clkmode_reg=0x%08lx\n", priv->clkmode_reg);
priv->idlest_reg = dev_read_addr_index(dev, 1);
if (priv->idlest_reg == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get idlest register\n");
return -EINVAL;
}
dev_dbg(dev, "idlest_reg=0x%08lx\n", priv->idlest_reg);
priv->clksel_reg = dev_read_addr_index(dev, 2);
if (priv->clksel_reg == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get clksel register\n");
return -EINVAL;
}
dev_dbg(dev, "clksel_reg=0x%08lx\n", priv->clksel_reg);
return 0;
}
static const struct clk_ti_am3_dpll_drv_data dpll_no_gate_data = {
.max_rate = 1000000000
};
static const struct clk_ti_am3_dpll_drv_data dpll_no_gate_j_type_data = {
.max_rate = 2000000000
};
static const struct clk_ti_am3_dpll_drv_data dpll_core_data = {
.max_rate = 1000000000
};
static const struct udevice_id clk_ti_am3_dpll_of_match[] = {
{.compatible = "ti,am3-dpll-core-clock",
.data = (ulong)&dpll_core_data},
{.compatible = "ti,am3-dpll-no-gate-clock",
.data = (ulong)&dpll_no_gate_data},
{.compatible = "ti,am3-dpll-no-gate-j-type-clock",
.data = (ulong)&dpll_no_gate_j_type_data},
{}
};
U_BOOT_DRIVER(clk_ti_am3_dpll) = {
.name = "ti_am3_dpll_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_am3_dpll_of_match,
.ofdata_to_platdata = clk_ti_am3_dpll_of_to_plat,
.probe = clk_ti_am3_dpll_probe,
.remove = clk_ti_am3_dpll_remove,
.priv_auto = sizeof(struct clk_ti_am3_dpll_priv),
.ops = &clk_ti_am3_dpll_ops,
};

154
drivers/clk/ti/clk-ctrl.c Normal file
View File

@ -0,0 +1,154 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* OMAP clock controller support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
#include <asm/arch-am33xx/clock.h>
struct clk_ti_ctrl_offs {
fdt_addr_t start;
fdt_size_t end;
};
struct clk_ti_ctrl_priv {
int offs_num;
struct clk_ti_ctrl_offs *offs;
};
static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
int i;
for (i = 0; i < priv->offs_num; i++) {
if (offs >= priv->offs[i].start && offs <= priv->offs[i].end)
return 0;
}
return -EFAULT;
}
static int clk_ti_ctrl_disable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
offs = priv->offs[0].start + clk->id;
err = clk_ti_ctrl_check_offs(clk, offs);
if (err) {
dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
return err;
}
clk_modules[0] = (u32 *)(offs);
dev_dbg(clk->dev, "module address=%p\n", clk_modules[0]);
do_disable_clocks(NULL, clk_modules, 1);
return 0;
}
static int clk_ti_ctrl_enable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
offs = priv->offs[0].start + clk->id;
err = clk_ti_ctrl_check_offs(clk, offs);
if (err) {
dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
return err;
}
clk_modules[0] = (u32 *)(offs);
dev_dbg(clk->dev, "module address=%p\n", clk_modules[0]);
do_enable_clocks(NULL, clk_modules, 1);
return 0;
}
static ulong clk_ti_ctrl_get_rate(struct clk *clk)
{
return 0;
}
static int clk_ti_ctrl_of_xlate(struct clk *clk,
struct ofnode_phandle_args *args)
{
if (args->args_count != 2) {
dev_err(clk->dev, "invaild args_count: %d\n", args->args_count);
return -EINVAL;
}
if (args->args_count)
clk->id = args->args[0];
else
clk->id = 0;
dev_dbg(clk->dev, "name=%s, id=%ld\n", clk->dev->name, clk->id);
return 0;
}
static int clk_ti_ctrl_of_to_plat(struct udevice *dev)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(dev);
fdt_size_t fdt_size;
int i, size;
size = dev_read_size(dev, "reg");
if (size < 0) {
dev_err(dev, "failed to get 'reg' size\n");
return size;
}
priv->offs_num = size / 2 / sizeof(u32);
dev_dbg(dev, "size=%d, regs_num=%d\n", size, priv->offs_num);
priv->offs = kmalloc_array(priv->offs_num, sizeof(*priv->offs),
GFP_KERNEL);
if (!priv->offs)
return -ENOMEM;
for (i = 0; i < priv->offs_num; i++) {
priv->offs[i].start =
dev_read_addr_size_index(dev, i, &fdt_size);
if (priv->offs[i].start == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get offset %d\n", i);
return -EINVAL;
}
priv->offs[i].end = priv->offs[i].start + fdt_size;
dev_dbg(dev, "start=0x%08lx, end=0x%08lx\n",
priv->offs[i].start, priv->offs[i].end);
}
return 0;
}
static struct clk_ops clk_ti_ctrl_ops = {
.of_xlate = clk_ti_ctrl_of_xlate,
.enable = clk_ti_ctrl_enable,
.disable = clk_ti_ctrl_disable,
.get_rate = clk_ti_ctrl_get_rate,
};
static const struct udevice_id clk_ti_ctrl_ids[] = {
{.compatible = "ti,clkctrl"},
{},
};
U_BOOT_DRIVER(clk_ti_ctrl) = {
.name = "ti_ctrl_clk",
.id = UCLASS_CLK,
.of_match = clk_ti_ctrl_ids,
.ofdata_to_platdata = clk_ti_ctrl_of_to_plat,
.ops = &clk_ti_ctrl_ops,
.priv_auto = sizeof(struct clk_ti_ctrl_priv),
};

View File

@ -0,0 +1,381 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI divider clock support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Loosely based on Linux kernel drivers/clk/ti/divider.c
*/
#include <common.h>
#include <clk.h>
#include <clk-uclass.h>
#include <div64.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <asm/io.h>
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include "clk.h"
/*
* The reverse of DIV_ROUND_UP: The maximum number which
* divided by m is r
*/
#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
struct clk_ti_divider_priv {
struct clk parent;
fdt_addr_t reg;
const struct clk_div_table *table;
u8 shift;
u8 flags;
u8 div_flags;
s8 latch;
u16 min;
u16 max;
u16 mask;
};
static unsigned int _get_div(const struct clk_div_table *table, ulong flags,
unsigned int val)
{
if (flags & CLK_DIVIDER_ONE_BASED)
return val;
if (flags & CLK_DIVIDER_POWER_OF_TWO)
return 1 << val;
if (table)
return clk_divider_get_table_div(table, val);
return val + 1;
}
static unsigned int _get_val(const struct clk_div_table *table, ulong flags,
unsigned int div)
{
if (flags & CLK_DIVIDER_ONE_BASED)
return div;
if (flags & CLK_DIVIDER_POWER_OF_TWO)
return __ffs(div);
if (table)
return clk_divider_get_table_val(table, div);
return div - 1;
}
static int _div_round_up(const struct clk_div_table *table, ulong parent_rate,
ulong rate)
{
const struct clk_div_table *clkt;
int up = INT_MAX;
int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
for (clkt = table; clkt->div; clkt++) {
if (clkt->div == div)
return clkt->div;
else if (clkt->div < div)
continue;
if ((clkt->div - div) < (up - div))
up = clkt->div;
}
return up;
}
static int _div_round(const struct clk_div_table *table, ulong parent_rate,
ulong rate)
{
if (table)
return _div_round_up(table, parent_rate, rate);
return DIV_ROUND_UP(parent_rate, rate);
}
static int clk_ti_divider_best_div(struct clk *clk, ulong rate,
ulong *best_parent_rate)
{
struct clk_ti_divider_priv *priv = dev_get_priv(clk->dev);
ulong parent_rate, parent_round_rate, max_div;
ulong best_rate, r;
int i, best_div = 0;
parent_rate = clk_get_rate(&priv->parent);
if (IS_ERR_VALUE(parent_rate))
return parent_rate;
if (!rate)
rate = 1;
if (!(clk->flags & CLK_SET_RATE_PARENT)) {
best_div = _div_round(priv->table, parent_rate, rate);
if (best_div == 0)
best_div = 1;
if (best_div > priv->max)
best_div = priv->max;
*best_parent_rate = parent_rate;
return best_div;
}
max_div = min(ULONG_MAX / rate, (ulong)priv->max);
for (best_rate = 0, i = 1; i <= max_div; i++) {
if (!clk_divider_is_valid_div(priv->table, priv->div_flags, i))
continue;
/*
* It's the most ideal case if the requested rate can be
* divided from parent clock without needing to change
* parent rate, so return the divider immediately.
*/
if ((rate * i) == parent_rate) {
*best_parent_rate = parent_rate;
dev_dbg(clk->dev, "rate=%ld, best_rate=%ld, div=%d\n",
rate, rate, i);
return i;
}
parent_round_rate = clk_round_rate(&priv->parent,
MULT_ROUND_UP(rate, i));
if (IS_ERR_VALUE(parent_round_rate))
continue;
r = DIV_ROUND_UP(parent_round_rate, i);
if (r <= rate && r > best_rate) {
best_div = i;
best_rate = r;
*best_parent_rate = parent_round_rate;
if (best_rate == rate)
break;
}
}
if (best_div == 0) {
best_div = priv->max;
parent_round_rate = clk_round_rate(&priv->parent, 1);
if (IS_ERR_VALUE(parent_round_rate))
return parent_round_rate;
}
dev_dbg(clk->dev, "rate=%ld, best_rate=%ld, div=%d\n", rate, best_rate,
best_div);
return best_div;
}
static ulong clk_ti_divider_round_rate(struct clk *clk, ulong rate)
{
ulong parent_rate;
int div;
div = clk_ti_divider_best_div(clk, rate, &parent_rate);
if (div < 0)
return div;
return DIV_ROUND_UP(parent_rate, div);
}
static ulong clk_ti_divider_set_rate(struct clk *clk, ulong rate)
{
struct clk_ti_divider_priv *priv = dev_get_priv(clk->dev);
ulong parent_rate;
int div;
u32 val, v;
div = clk_ti_divider_best_div(clk, rate, &parent_rate);
if (div < 0)
return div;
if (clk->flags & CLK_SET_RATE_PARENT) {
parent_rate = clk_set_rate(&priv->parent, parent_rate);
if (IS_ERR_VALUE(parent_rate))
return parent_rate;
}
val = _get_val(priv->table, priv->div_flags, div);
v = readl(priv->reg);
v &= ~(priv->mask << priv->shift);
v |= val << priv->shift;
writel(v, priv->reg);
clk_ti_latch(priv->reg, priv->latch);
return clk_get_rate(clk);
}
static ulong clk_ti_divider_get_rate(struct clk *clk)
{
struct clk_ti_divider_priv *priv = dev_get_priv(clk->dev);
ulong rate, parent_rate;
unsigned int div;
u32 v;
parent_rate = clk_get_rate(&priv->parent);
if (IS_ERR_VALUE(parent_rate))
return parent_rate;
v = readl(priv->reg) >> priv->shift;
v &= priv->mask;
div = _get_div(priv->table, priv->div_flags, v);
if (!div) {
if (!(priv->div_flags & CLK_DIVIDER_ALLOW_ZERO))
dev_warn(clk->dev,
"zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n");
return parent_rate;
}
rate = DIV_ROUND_UP(parent_rate, div);
dev_dbg(clk->dev, "rate=%ld\n", rate);
return rate;
}
static int clk_ti_divider_request(struct clk *clk)
{
struct clk_ti_divider_priv *priv = dev_get_priv(clk->dev);
clk->flags = priv->flags;
return 0;
}
const struct clk_ops clk_ti_divider_ops = {
.request = clk_ti_divider_request,
.round_rate = clk_ti_divider_round_rate,
.get_rate = clk_ti_divider_get_rate,
.set_rate = clk_ti_divider_set_rate
};
static int clk_ti_divider_remove(struct udevice *dev)
{
struct clk_ti_divider_priv *priv = dev_get_priv(dev);
int err;
err = clk_release_all(&priv->parent, 1);
if (err) {
dev_err(dev, "failed to release parent clock\n");
return err;
}
return 0;
}
static int clk_ti_divider_probe(struct udevice *dev)
{
struct clk_ti_divider_priv *priv = dev_get_priv(dev);
int err;
err = clk_get_by_index(dev, 0, &priv->parent);
if (err) {
dev_err(dev, "failed to get parent clock\n");
return err;
}
return 0;
}
static int clk_ti_divider_of_to_plat(struct udevice *dev)
{
struct clk_ti_divider_priv *priv = dev_get_priv(dev);
struct clk_div_table *table = NULL;
u32 val, valid_div;
u32 min_div = 0;
u32 max_val, max_div = 0;
u16 mask;
int i, div_num;
priv->reg = dev_read_addr(dev);
dev_dbg(dev, "reg=0x%08lx\n", priv->reg);
priv->shift = dev_read_u32_default(dev, "ti,bit-shift", 0);
priv->latch = dev_read_s32_default(dev, "ti,latch-bit", -EINVAL);
if (dev_read_bool(dev, "ti,index-starts-at-one"))
priv->div_flags |= CLK_DIVIDER_ONE_BASED;
if (dev_read_bool(dev, "ti,index-power-of-two"))
priv->div_flags |= CLK_DIVIDER_POWER_OF_TWO;
if (dev_read_bool(dev, "ti,set-rate-parent"))
priv->flags |= CLK_SET_RATE_PARENT;
if (dev_read_prop(dev, "ti,dividers", &div_num)) {
div_num /= sizeof(u32);
/* Determine required size for divider table */
for (i = 0, valid_div = 0; i < div_num; i++) {
dev_read_u32_index(dev, "ti,dividers", i, &val);
if (val)
valid_div++;
}
if (!valid_div) {
dev_err(dev, "no valid dividers\n");
return -EINVAL;
}
table = calloc(valid_div + 1, sizeof(*table));
if (!table)
return -ENOMEM;
for (i = 0, valid_div = 0; i < div_num; i++) {
dev_read_u32_index(dev, "ti,dividers", i, &val);
if (!val)
continue;
table[valid_div].div = val;
table[valid_div].val = i;
valid_div++;
if (val > max_div)
max_div = val;
if (!min_div || val < min_div)
min_div = val;
}
max_val = max_div;
} else {
/* Divider table not provided, determine min/max divs */
min_div = dev_read_u32_default(dev, "ti,min-div", 1);
if (dev_read_u32(dev, "ti,max-div", &max_div)) {
dev_err(dev, "missing 'max-div' property\n");
return -EFAULT;
}
max_val = max_div;
if (!(priv->div_flags & CLK_DIVIDER_ONE_BASED) &&
!(priv->div_flags & CLK_DIVIDER_POWER_OF_TWO))
max_val--;
}
priv->table = table;
priv->min = min_div;
priv->max = max_div;
if (priv->div_flags & CLK_DIVIDER_POWER_OF_TWO)
mask = fls(max_val) - 1;
else
mask = max_val;
priv->mask = (1 << fls(mask)) - 1;
return 0;
}
static const struct udevice_id clk_ti_divider_of_match[] = {
{.compatible = "ti,divider-clock"},
{}
};
U_BOOT_DRIVER(clk_ti_divider) = {
.name = "ti_divider_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_divider_of_match,
.ofdata_to_platdata = clk_ti_divider_of_to_plat,
.probe = clk_ti_divider_probe,
.remove = clk_ti_divider_remove,
.priv_auto = sizeof(struct clk_ti_divider_priv),
.ops = &clk_ti_divider_ops,
};

93
drivers/clk/ti/clk-gate.c Normal file
View File

@ -0,0 +1,93 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI gate clock support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Loosely based on Linux kernel drivers/clk/ti/gate.c
*/
#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
#include <asm/io.h>
#include <linux/clk-provider.h>
struct clk_ti_gate_priv {
fdt_addr_t reg;
u8 enable_bit;
u32 flags;
bool invert_enable;
};
static int clk_ti_gate_disable(struct clk *clk)
{
struct clk_ti_gate_priv *priv = dev_get_priv(clk->dev);
u32 v;
v = readl(priv->reg);
if (priv->invert_enable)
v |= (1 << priv->enable_bit);
else
v &= ~(1 << priv->enable_bit);
writel(v, priv->reg);
/* No OCP barrier needed here since it is a disable operation */
return 0;
}
static int clk_ti_gate_enable(struct clk *clk)
{
struct clk_ti_gate_priv *priv = dev_get_priv(clk->dev);
u32 v;
v = readl(priv->reg);
if (priv->invert_enable)
v &= ~(1 << priv->enable_bit);
else
v |= (1 << priv->enable_bit);
writel(v, priv->reg);
/* OCP barrier */
v = readl(priv->reg);
return 0;
}
static int clk_ti_gate_of_to_plat(struct udevice *dev)
{
struct clk_ti_gate_priv *priv = dev_get_priv(dev);
priv->reg = dev_read_addr(dev);
if (priv->reg == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get control register\n");
return -EINVAL;
}
dev_dbg(dev, "reg=0x%08lx\n", priv->reg);
priv->enable_bit = dev_read_u32_default(dev, "ti,bit-shift", 0);
if (dev_read_bool(dev, "ti,set-rate-parent"))
priv->flags |= CLK_SET_RATE_PARENT;
priv->invert_enable = dev_read_bool(dev, "ti,set-bit-to-disable");
return 0;
}
static struct clk_ops clk_ti_gate_ops = {
.enable = clk_ti_gate_enable,
.disable = clk_ti_gate_disable,
};
static const struct udevice_id clk_ti_gate_of_match[] = {
{ .compatible = "ti,gate-clock" },
{ },
};
U_BOOT_DRIVER(clk_ti_gate) = {
.name = "ti_gate_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_gate_of_match,
.ofdata_to_platdata = clk_ti_gate_of_to_plat,
.priv_auto = sizeof(struct clk_ti_gate_priv),
.ops = &clk_ti_gate_ops,
};

253
drivers/clk/ti/clk-mux.c Normal file
View File

@ -0,0 +1,253 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI multiplexer clock support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Based on Linux kernel drivers/clk/ti/mux.c
*/
#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
#include <asm/io.h>
#include <linux/clk-provider.h>
#include "clk.h"
struct clk_ti_mux_priv {
struct clk_bulk parents;
fdt_addr_t reg;
u32 flags;
u32 mux_flags;
u32 mask;
u32 shift;
s32 latch;
};
static struct clk *clk_ti_mux_get_parent_by_index(struct clk_bulk *parents,
int index)
{
if (index < 0 || !parents)
return ERR_PTR(-EINVAL);
if (index >= parents->count)
return ERR_PTR(-ENODEV);
return &parents->clks[index];
}
static int clk_ti_mux_get_parent_index(struct clk_bulk *parents,
struct clk *parent)
{
int i;
if (!parents || !parent)
return -EINVAL;
for (i = 0; i < parents->count; i++) {
if (parents->clks[i].dev == parent->dev)
return i;
}
return -ENODEV;
}
static int clk_ti_mux_get_index(struct clk *clk)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
u32 val;
val = readl(priv->reg);
val >>= priv->shift;
val &= priv->mask;
if (val && (priv->flags & CLK_MUX_INDEX_BIT))
val = ffs(val) - 1;
if (val && (priv->flags & CLK_MUX_INDEX_ONE))
val--;
if (val >= priv->parents.count)
return -EINVAL;
return val;
}
static int clk_ti_mux_set_parent(struct clk *clk, struct clk *parent)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
int index;
u32 val;
index = clk_ti_mux_get_parent_index(&priv->parents, parent);
if (index < 0) {
dev_err(clk->dev, "failed to get parent clock\n");
return index;
}
index = clk_mux_index_to_val(NULL, priv->flags, index);
if (priv->flags & CLK_MUX_HIWORD_MASK) {
val = priv->mask << (priv->shift + 16);
} else {
val = readl(priv->reg);
val &= ~(priv->mask << priv->shift);
}
val |= index << priv->shift;
writel(val, priv->reg);
clk_ti_latch(priv->reg, priv->latch);
return 0;
}
static ulong clk_ti_mux_set_rate(struct clk *clk, ulong rate)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
struct clk *parent;
int index;
if ((clk->flags & CLK_SET_RATE_PARENT) == 0)
return -ENOSYS;
index = clk_ti_mux_get_index(clk);
parent = clk_ti_mux_get_parent_by_index(&priv->parents, index);
if (IS_ERR(parent))
return PTR_ERR(parent);
rate = clk_set_rate(parent, rate);
dev_dbg(clk->dev, "rate=%ld\n", rate);
return rate;
}
static ulong clk_ti_mux_get_rate(struct clk *clk)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
int index;
struct clk *parent;
ulong rate;
index = clk_ti_mux_get_index(clk);
parent = clk_ti_mux_get_parent_by_index(&priv->parents, index);
if (IS_ERR(parent))
return PTR_ERR(parent);
rate = clk_get_rate(parent);
dev_dbg(clk->dev, "rate=%ld\n", rate);
return rate;
}
static ulong clk_ti_mux_round_rate(struct clk *clk, ulong rate)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
struct clk *parent;
int index;
if ((clk->flags & CLK_SET_RATE_PARENT) == 0)
return -ENOSYS;
index = clk_ti_mux_get_index(clk);
parent = clk_ti_mux_get_parent_by_index(&priv->parents, index);
if (IS_ERR(parent))
return PTR_ERR(parent);
rate = clk_round_rate(parent, rate);
dev_dbg(clk->dev, "rate=%ld\n", rate);
return rate;
}
static int clk_ti_mux_request(struct clk *clk)
{
struct clk_ti_mux_priv *priv = dev_get_priv(clk->dev);
struct clk *parent;
int index;
clk->flags = priv->flags;
index = clk_ti_mux_get_index(clk);
parent = clk_ti_mux_get_parent_by_index(&priv->parents, index);
if (IS_ERR(parent))
return PTR_ERR(parent);
return clk_ti_mux_set_parent(clk, parent);
}
static struct clk_ops clk_ti_mux_ops = {
.request = clk_ti_mux_request,
.round_rate = clk_ti_mux_round_rate,
.get_rate = clk_ti_mux_get_rate,
.set_rate = clk_ti_mux_set_rate,
.set_parent = clk_ti_mux_set_parent,
};
static int clk_ti_mux_remove(struct udevice *dev)
{
struct clk_ti_mux_priv *priv = dev_get_priv(dev);
int err;
err = clk_release_all(priv->parents.clks, priv->parents.count);
if (err)
dev_dbg(dev, "could not release all parents' clocks\n");
return err;
}
static int clk_ti_mux_probe(struct udevice *dev)
{
struct clk_ti_mux_priv *priv = dev_get_priv(dev);
int err;
err = clk_get_bulk(dev, &priv->parents);
if (err || priv->parents.count < 2) {
dev_err(dev, "mux-clock must have parents\n");
return err ? err : -EFAULT;
}
/* Generate bit-mask based on parents info */
priv->mask = priv->parents.count;
if (!(priv->mux_flags & CLK_MUX_INDEX_ONE))
priv->mask--;
priv->mask = (1 << fls(priv->mask)) - 1;
return 0;
}
static int clk_ti_mux_of_to_plat(struct udevice *dev)
{
struct clk_ti_mux_priv *priv = dev_get_priv(dev);
priv->reg = dev_read_addr(dev);
if (priv->reg == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get register\n");
return -EINVAL;
}
dev_dbg(dev, "reg=0x%08lx\n", priv->reg);
priv->shift = dev_read_u32_default(dev, "ti,bit-shift", 0);
priv->latch = dev_read_s32_default(dev, "ti,latch-bit", -EINVAL);
priv->flags = CLK_SET_RATE_NO_REPARENT;
if (dev_read_bool(dev, "ti,set-rate-parent"))
priv->flags |= CLK_SET_RATE_PARENT;
if (dev_read_bool(dev, "ti,index-starts-at-one"))
priv->mux_flags |= CLK_MUX_INDEX_ONE;
return 0;
}
static const struct udevice_id clk_ti_mux_of_match[] = {
{.compatible = "ti,mux-clock"},
{},
};
U_BOOT_DRIVER(clk_ti_mux) = {
.name = "ti_mux_clock",
.id = UCLASS_CLK,
.of_match = clk_ti_mux_of_match,
.ofdata_to_platdata = clk_ti_mux_of_to_plat,
.probe = clk_ti_mux_probe,
.remove = clk_ti_mux_remove,
.priv_auto = sizeof(struct clk_ti_mux_priv),
.ops = &clk_ti_mux_ops,
};

34
drivers/clk/ti/clk.c Normal file
View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI clock utilities
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <asm/io.h>
#include "clk.h"
static void clk_ti_rmw(u32 val, u32 mask, fdt_addr_t reg)
{
u32 v;
v = readl(reg);
v &= ~mask;
v |= val;
writel(v, reg);
}
void clk_ti_latch(fdt_addr_t reg, s8 shift)
{
u32 latch;
if (shift < 0)
return;
latch = 1 << shift;
clk_ti_rmw(latch, latch, reg);
clk_ti_rmw(0, latch, reg);
readl(reg); /* OCP barrier */
}

13
drivers/clk/ti/clk.h Normal file
View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* TI clock utilities header
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#ifndef _CLK_TI_H
#define _CLK_TI_H
void clk_ti_latch(fdt_addr_t reg, s8 shift);
#endif /* #ifndef _CLK_TI_H */

22
drivers/clk/ti/omap4-cm.c Normal file
View File

@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* OMAP4 clock manager (cm)
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <dm.h>
#include <dm/lists.h>
static const struct udevice_id ti_omap4_cm_ids[] = {
{.compatible = "ti,omap4-cm"},
{}
};
U_BOOT_DRIVER(ti_omap4_cm) = {
.name = "ti_omap4_cm",
.id = UCLASS_SIMPLE_BUS,
.of_match = ti_omap4_cm_ids,
.bind = dm_scan_fdt_dev,
};

View File

@ -247,6 +247,18 @@ config OF_TRANSLATE
used for the address translation. This function is faster and
smaller in size than fdt_translate_address().
config OF_TRANSLATE_ZERO_SIZE_CELLS
bool "Enable translation for zero size cells"
depends on OF_TRANSLATE
default n
help
The routine used to translate an FDT address into a physical CPU
address was developed by IBM. It considers that crossing any level
with #size-cells = <0> makes translation impossible, even if it is
not the way it was specified.
Enabling this option makes translation possible even in the case
of crossing levels with #size-cells = <0>.
config SPL_OF_TRANSLATE
bool "Translate addresses using fdt_translate_address in SPL"
depends on SPL_DM && SPL_OF_CONTROL

View File

@ -49,7 +49,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index)
reg += index * (na + ns);
if (ns) {
if (ns || gd_size_cells_0()) {
/*
* Use the full-fledged translate function for complex
* bus setups.

View File

@ -18,7 +18,8 @@
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && \
((ns) > 0 || gd_size_cells_0()))
static struct of_bus *of_match_bus(struct device_node *np);
@ -162,11 +163,6 @@ const __be32 *of_get_address(const struct device_node *dev, int index,
}
EXPORT_SYMBOL(of_get_address);
static int of_empty_ranges_quirk(const struct device_node *np)
{
return false;
}
static int of_translate_one(const struct device_node *parent,
struct of_bus *bus, struct of_bus *pbus,
__be32 *addr, int na, int ns, int pna,
@ -193,11 +189,8 @@ static int of_translate_one(const struct device_node *parent,
* As far as we know, this damage only exists on Apple machines, so
* This code is only enabled on powerpc. --gcl
*/
ranges = of_get_property(parent, rprop, &rlen);
if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
debug("no ranges; cannot translate\n");
return 1;
}
if (ranges == NULL || rlen == 0) {
offset = of_read_number(addr, na);
memset(addr, 0, pna * 4);

View File

@ -316,7 +316,8 @@ fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
ns = of_n_size_cells(ofnode_to_np(node));
if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
if (IS_ENABLED(CONFIG_OF_TRANSLATE) &&
(ns > 0 || gd_size_cells_0())) {
return of_translate_address(ofnode_to_np(node), prop_val);
} else {
na = of_n_addr_cells(ofnode_to_np(node));
@ -690,8 +691,10 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
ns = of_n_size_cells(np);
*sizep = of_read_number(prop + na, ns);
if (CONFIG_IS_ENABLED(OF_TRANSLATE) && ns > 0)
if (CONFIG_IS_ENABLED(OF_TRANSLATE) &&
(ns > 0 || gd_size_cells_0())) {
return of_translate_address(np, prop);
}
else
return of_read_number(prop, na);
} else {

View File

@ -379,3 +379,9 @@ int dev_read_pci_bus_range(const struct udevice *dev,
return 0;
}
int dev_decode_display_timing(const struct udevice *dev, int index,
struct display_timing *config)
{
return ofnode_decode_display_timing(dev_ofnode(dev), index, config);
}

View File

@ -132,6 +132,9 @@ int dm_init(bool of_live)
{
int ret;
if (IS_ENABLED(CONFIG_OF_TRANSLATE_ZERO_SIZE_CELLS))
gd->dm_flags |= GD_DM_FLG_SIZE_CELLS_0;
if (gd->dm_root) {
dm_warn("Virtual root driver already exists!\n");
return -EINVAL;

View File

@ -213,6 +213,24 @@ static int tca642x_info(uchar chip)
return 0;
}
static int tca642x_get_bank(int pin)
{
int gpio_bank;
if (pin <= 7) {
gpio_bank = 0;
} else if ((pin >= 10) && (pin <= 17)) {
gpio_bank = 1;
} else if ((pin >= 20) && (pin <= 27)) {
gpio_bank = 2;
} else {
printf("Requested pin is not available\n");
gpio_bank = -1;
}
return gpio_bank;
}
static struct cmd_tbl cmd_tca642x[] = {
U_BOOT_CMD_MKENT(device, 3, 0, (void *)TCA642X_CMD_DEVICE, "", ""),
U_BOOT_CMD_MKENT(output, 4, 0, (void *)TCA642X_CMD_OUTPUT, "", ""),
@ -226,7 +244,7 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc,
{
static uchar chip = CONFIG_SYS_I2C_TCA642X_ADDR;
int ret = CMD_RET_USAGE, val;
uint8_t gpio_bank = 0;
int gpio_bank = 0;
uint8_t bank_shift;
ulong ul_arg2 = 0;
ulong ul_arg3 = 0;
@ -247,20 +265,8 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc,
ul_arg2 = simple_strtoul(argv[2], NULL, 10);
/* arg3 used as pin or invert value */
if (argc > 3) {
if (argc > 3)
ul_arg3 = simple_strtoul(argv[3], NULL, 10) & 0x1;
if (ul_arg2 <= 7) {
gpio_bank = 0;
} else if ((ul_arg2 >= 10) && (ul_arg2 <= 17)) {
gpio_bank = 1;
} else if ((ul_arg2 >= 20) && (ul_arg2 <= 27)) {
gpio_bank = 2;
} else {
printf("Requested pin is not available\n");
ret = CMD_RET_FAILURE;
goto error;
}
}
switch ((int)c->cmd) {
case TCA642X_CMD_INFO:
@ -277,6 +283,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc,
break;
case TCA642X_CMD_INPUT:
gpio_bank = tca642x_get_bank(ul_arg2);
if (gpio_bank < 0) {
ret = CMD_RET_FAILURE;
goto error;
}
bank_shift = ul_arg2 - (gpio_bank * 10);
ret = tca642x_set_dir(chip, gpio_bank, (1 << bank_shift),
TCA642X_DIR_IN << bank_shift);
@ -291,6 +302,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc,
break;
case TCA642X_CMD_OUTPUT:
gpio_bank = tca642x_get_bank(ul_arg2);
if (gpio_bank < 0) {
ret = CMD_RET_FAILURE;
goto error;
}
bank_shift = ul_arg2 - (gpio_bank * 10);
ret = tca642x_set_dir(chip, gpio_bank, (1 << bank_shift),
(TCA642X_DIR_OUT << bank_shift));
@ -303,6 +319,11 @@ static int do_tca642x(struct cmd_tbl *cmdtp, int flag, int argc,
break;
case TCA642X_CMD_INVERT:
gpio_bank = tca642x_get_bank(ul_arg2);
if (gpio_bank < 0) {
ret = CMD_RET_FAILURE;
goto error;
}
bank_shift = ul_arg2 - (gpio_bank * 10);
ret = tca642x_set_pol(chip, gpio_bank, (1 << bank_shift),
(ul_arg3 << bank_shift));

View File

@ -75,3 +75,10 @@ config PWM_SUNXI
help
This PWM is found on H3, A64 and other Allwinner SoCs. It supports a
programmable period and duty cycle. A 16-bit counter is used.
config PWM_TI_EHRPWM
bool "Enable support for EHRPWM PWM"
depends on DM_PWM && ARCH_OMAP2PLUS
default y
help
PWM driver support for the EHRPWM controller found on TI SOCs.

View File

@ -19,3 +19,4 @@ obj-$(CONFIG_PWM_SANDBOX) += sandbox_pwm.o
obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
obj-$(CONFIG_PWM_TEGRA) += tegra_pwm.o
obj-$(CONFIG_PWM_SUNXI) += sunxi_pwm.o
obj-$(CONFIG_PWM_TI_EHRPWM) += pwm-ti-ehrpwm.o

468
drivers/pwm/pwm-ti-ehrpwm.c Normal file
View File

@ -0,0 +1,468 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* EHRPWM PWM driver
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*
* Based on Linux kernel drivers/pwm/pwm-tiehrpwm.c
*/
#include <common.h>
#include <clk.h>
#include <div64.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <pwm.h>
#include <asm/io.h>
#define NSEC_PER_SEC 1000000000L
/* Time base module registers */
#define TI_EHRPWM_TBCTL 0x00
#define TI_EHRPWM_TBPRD 0x0A
#define TI_EHRPWM_TBCTL_PRDLD_MASK BIT(3)
#define TI_EHRPWM_TBCTL_PRDLD_SHDW 0
#define TI_EHRPWM_TBCTL_PRDLD_IMDT BIT(3)
#define TI_EHRPWM_TBCTL_CLKDIV_MASK GENMASK(12, 7)
#define TI_EHRPWM_TBCTL_CTRMODE_MASK GENMASK(1, 0)
#define TI_EHRPWM_TBCTL_CTRMODE_UP 0
#define TI_EHRPWM_TBCTL_CTRMODE_DOWN BIT(0)
#define TI_EHRPWM_TBCTL_CTRMODE_UPDOWN BIT(1)
#define TI_EHRPWM_TBCTL_CTRMODE_FREEZE GENMASK(1, 0)
#define TI_EHRPWM_TBCTL_HSPCLKDIV_SHIFT 7
#define TI_EHRPWM_TBCTL_CLKDIV_SHIFT 10
#define TI_EHRPWM_CLKDIV_MAX 7
#define TI_EHRPWM_HSPCLKDIV_MAX 7
#define TI_EHRPWM_PERIOD_MAX 0xFFFF
/* Counter compare module registers */
#define TI_EHRPWM_CMPA 0x12
#define TI_EHRPWM_CMPB 0x14
/* Action qualifier module registers */
#define TI_EHRPWM_AQCTLA 0x16
#define TI_EHRPWM_AQCTLB 0x18
#define TI_EHRPWM_AQSFRC 0x1A
#define TI_EHRPWM_AQCSFRC 0x1C
#define TI_EHRPWM_AQCTL_CBU_MASK GENMASK(9, 8)
#define TI_EHRPWM_AQCTL_CBU_FRCLOW BIT(8)
#define TI_EHRPWM_AQCTL_CBU_FRCHIGH BIT(9)
#define TI_EHRPWM_AQCTL_CBU_FRCTOGGLE GENMASK(9, 8)
#define TI_EHRPWM_AQCTL_CAU_MASK GENMASK(5, 4)
#define TI_EHRPWM_AQCTL_CAU_FRCLOW BIT(4)
#define TI_EHRPWM_AQCTL_CAU_FRCHIGH BIT(5)
#define TI_EHRPWM_AQCTL_CAU_FRCTOGGLE GENMASK(5, 4)
#define TI_EHRPWM_AQCTL_PRD_MASK GENMASK(3, 2)
#define TI_EHRPWM_AQCTL_PRD_FRCLOW BIT(2)
#define TI_EHRPWM_AQCTL_PRD_FRCHIGH BIT(3)
#define TI_EHRPWM_AQCTL_PRD_FRCTOGGLE GENMASK(3, 2)
#define TI_EHRPWM_AQCTL_ZRO_MASK GENMASK(1, 0)
#define TI_EHRPWM_AQCTL_ZRO_FRCLOW BIT(0)
#define TI_EHRPWM_AQCTL_ZRO_FRCHIGH BIT(1)
#define TI_EHRPWM_AQCTL_ZRO_FRCTOGGLE GENMASK(1, 0)
#define TI_EHRPWM_AQCTL_CHANA_POLNORMAL (TI_EHRPWM_AQCTL_CAU_FRCLOW | \
TI_EHRPWM_AQCTL_PRD_FRCHIGH | \
TI_EHRPWM_AQCTL_ZRO_FRCHIGH)
#define TI_EHRPWM_AQCTL_CHANA_POLINVERSED (TI_EHRPWM_AQCTL_CAU_FRCHIGH | \
TI_EHRPWM_AQCTL_PRD_FRCLOW | \
TI_EHRPWM_AQCTL_ZRO_FRCLOW)
#define TI_EHRPWM_AQCTL_CHANB_POLNORMAL (TI_EHRPWM_AQCTL_CBU_FRCLOW | \
TI_EHRPWM_AQCTL_PRD_FRCHIGH | \
TI_EHRPWM_AQCTL_ZRO_FRCHIGH)
#define TI_EHRPWM_AQCTL_CHANB_POLINVERSED (TI_EHRPWM_AQCTL_CBU_FRCHIGH | \
TI_EHRPWM_AQCTL_PRD_FRCLOW | \
TI_EHRPWM_AQCTL_ZRO_FRCLOW)
#define TI_EHRPWM_AQSFRC_RLDCSF_MASK GENMASK(7, 6)
#define TI_EHRPWM_AQSFRC_RLDCSF_ZRO 0
#define TI_EHRPWM_AQSFRC_RLDCSF_PRD BIT(6)
#define TI_EHRPWM_AQSFRC_RLDCSF_ZROPRD BIT(7)
#define TI_EHRPWM_AQSFRC_RLDCSF_IMDT GENMASK(7, 6)
#define TI_EHRPWM_AQCSFRC_CSFB_MASK GENMASK(3, 2)
#define TI_EHRPWM_AQCSFRC_CSFB_FRCDIS 0
#define TI_EHRPWM_AQCSFRC_CSFB_FRCLOW BIT(2)
#define TI_EHRPWM_AQCSFRC_CSFB_FRCHIGH BIT(3)
#define TI_EHRPWM_AQCSFRC_CSFB_DISSWFRC GENMASK(3, 2)
#define TI_EHRPWM_AQCSFRC_CSFA_MASK GENMASK(1, 0)
#define TI_EHRPWM_AQCSFRC_CSFA_FRCDIS 0
#define TI_EHRPWM_AQCSFRC_CSFA_FRCLOW BIT(0)
#define TI_EHRPWM_AQCSFRC_CSFA_FRCHIGH BIT(1)
#define TI_EHRPWM_AQCSFRC_CSFA_DISSWFRC GENMASK(1, 0)
#define TI_EHRPWM_NUM_CHANNELS 2
struct ti_ehrpwm_priv {
fdt_addr_t regs;
u32 clk_rate;
struct clk tbclk;
unsigned long period_cycles[TI_EHRPWM_NUM_CHANNELS];
bool polarity_reversed[TI_EHRPWM_NUM_CHANNELS];
};
static void ti_ehrpwm_modify(u16 val, u16 mask, fdt_addr_t reg)
{
unsigned short v;
v = readw(reg);
v &= ~mask;
v |= val & mask;
writew(v, reg);
}
static int ti_ehrpwm_set_invert(struct udevice *dev, uint channel,
bool polarity)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
if (channel >= TI_EHRPWM_NUM_CHANNELS)
return -ENOSPC;
/* Configuration of polarity in hardware delayed, do at enable */
priv->polarity_reversed[channel] = polarity;
return 0;
}
/**
* set_prescale_div - Set up the prescaler divider function
* @rqst_prescaler: prescaler value min
* @prescale_div: prescaler value set
* @tb_clk_div: Time Base Control prescaler bits
*/
static int set_prescale_div(unsigned long rqst_prescaler, u16 *prescale_div,
u16 *tb_clk_div)
{
unsigned int clkdiv, hspclkdiv;
for (clkdiv = 0; clkdiv <= TI_EHRPWM_CLKDIV_MAX; clkdiv++) {
for (hspclkdiv = 0; hspclkdiv <= TI_EHRPWM_HSPCLKDIV_MAX;
hspclkdiv++) {
/*
* calculations for prescaler value :
* prescale_div = HSPCLKDIVIDER * CLKDIVIDER.
* HSPCLKDIVIDER = 2 ** hspclkdiv
* CLKDIVIDER = (1), if clkdiv == 0 *OR*
* (2 * clkdiv), if clkdiv != 0
*
* Configure prescale_div value such that period
* register value is less than 65535.
*/
*prescale_div = (1 << clkdiv) *
(hspclkdiv ? (hspclkdiv * 2) : 1);
if (*prescale_div > rqst_prescaler) {
*tb_clk_div =
(clkdiv << TI_EHRPWM_TBCTL_CLKDIV_SHIFT) |
(hspclkdiv <<
TI_EHRPWM_TBCTL_HSPCLKDIV_SHIFT);
return 0;
}
}
}
return 1;
}
static void ti_ehrpwm_configure_polarity(struct udevice *dev, uint channel)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
u16 aqctl_val, aqctl_mask;
unsigned int aqctl_reg;
/*
* Configure PWM output to HIGH/LOW level on counter
* reaches compare register value and LOW/HIGH level
* on counter value reaches period register value and
* zero value on counter
*/
if (channel == 1) {
aqctl_reg = TI_EHRPWM_AQCTLB;
aqctl_mask = TI_EHRPWM_AQCTL_CBU_MASK;
if (priv->polarity_reversed[channel])
aqctl_val = TI_EHRPWM_AQCTL_CHANB_POLINVERSED;
else
aqctl_val = TI_EHRPWM_AQCTL_CHANB_POLNORMAL;
} else {
aqctl_reg = TI_EHRPWM_AQCTLA;
aqctl_mask = TI_EHRPWM_AQCTL_CAU_MASK;
if (priv->polarity_reversed[channel])
aqctl_val = TI_EHRPWM_AQCTL_CHANA_POLINVERSED;
else
aqctl_val = TI_EHRPWM_AQCTL_CHANA_POLNORMAL;
}
aqctl_mask |= TI_EHRPWM_AQCTL_PRD_MASK | TI_EHRPWM_AQCTL_ZRO_MASK;
ti_ehrpwm_modify(aqctl_val, aqctl_mask, priv->regs + aqctl_reg);
}
/*
* period_ns = 10^9 * (ps_divval * period_cycles) / PWM_CLK_RATE
* duty_ns = 10^9 * (ps_divval * duty_cycles) / PWM_CLK_RATE
*/
static int ti_ehrpwm_set_config(struct udevice *dev, uint channel,
uint period_ns, uint duty_ns)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
u32 period_cycles, duty_cycles;
u16 ps_divval, tb_divval;
unsigned int i, cmp_reg;
unsigned long long c;
if (channel >= TI_EHRPWM_NUM_CHANNELS)
return -ENOSPC;
if (period_ns > NSEC_PER_SEC)
return -ERANGE;
c = priv->clk_rate;
c = c * period_ns;
do_div(c, NSEC_PER_SEC);
period_cycles = (unsigned long)c;
if (period_cycles < 1) {
period_cycles = 1;
duty_cycles = 1;
} else {
c = priv->clk_rate;
c = c * duty_ns;
do_div(c, NSEC_PER_SEC);
duty_cycles = (unsigned long)c;
}
dev_dbg(dev, "channel=%d, period_ns=%d, duty_ns=%d\n",
channel, period_ns, duty_ns);
/*
* Period values should be same for multiple PWM channels as IP uses
* same period register for multiple channels.
*/
for (i = 0; i < TI_EHRPWM_NUM_CHANNELS; i++) {
if (priv->period_cycles[i] &&
priv->period_cycles[i] != period_cycles) {
/*
* Allow channel to reconfigure period if no other
* channels being configured.
*/
if (i == channel)
continue;
dev_err(dev, "period value conflicts with channel %u\n",
i);
return -EINVAL;
}
}
priv->period_cycles[channel] = period_cycles;
/* Configure clock prescaler to support Low frequency PWM wave */
if (set_prescale_div(period_cycles / TI_EHRPWM_PERIOD_MAX, &ps_divval,
&tb_divval)) {
dev_err(dev, "unsupported values\n");
return -EINVAL;
}
/* Update clock prescaler values */
ti_ehrpwm_modify(tb_divval, TI_EHRPWM_TBCTL_CLKDIV_MASK,
priv->regs + TI_EHRPWM_TBCTL);
/* Update period & duty cycle with presacler division */
period_cycles = period_cycles / ps_divval;
duty_cycles = duty_cycles / ps_divval;
/* Configure shadow loading on Period register */
ti_ehrpwm_modify(TI_EHRPWM_TBCTL_PRDLD_SHDW, TI_EHRPWM_TBCTL_PRDLD_MASK,
priv->regs + TI_EHRPWM_TBCTL);
writew(period_cycles, priv->regs + TI_EHRPWM_TBPRD);
/* Configure ehrpwm counter for up-count mode */
ti_ehrpwm_modify(TI_EHRPWM_TBCTL_CTRMODE_UP,
TI_EHRPWM_TBCTL_CTRMODE_MASK,
priv->regs + TI_EHRPWM_TBCTL);
if (channel == 1)
/* Channel 1 configured with compare B register */
cmp_reg = TI_EHRPWM_CMPB;
else
/* Channel 0 configured with compare A register */
cmp_reg = TI_EHRPWM_CMPA;
writew(duty_cycles, priv->regs + cmp_reg);
return 0;
}
static int ti_ehrpwm_disable(struct udevice *dev, uint channel)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
u16 aqcsfrc_val, aqcsfrc_mask;
int err;
if (channel >= TI_EHRPWM_NUM_CHANNELS)
return -ENOSPC;
/* Action Qualifier puts PWM output low forcefully */
if (channel) {
aqcsfrc_val = TI_EHRPWM_AQCSFRC_CSFB_FRCLOW;
aqcsfrc_mask = TI_EHRPWM_AQCSFRC_CSFB_MASK;
} else {
aqcsfrc_val = TI_EHRPWM_AQCSFRC_CSFA_FRCLOW;
aqcsfrc_mask = TI_EHRPWM_AQCSFRC_CSFA_MASK;
}
/* Update shadow register first before modifying active register */
ti_ehrpwm_modify(TI_EHRPWM_AQSFRC_RLDCSF_ZRO,
TI_EHRPWM_AQSFRC_RLDCSF_MASK,
priv->regs + TI_EHRPWM_AQSFRC);
ti_ehrpwm_modify(aqcsfrc_val, aqcsfrc_mask,
priv->regs + TI_EHRPWM_AQCSFRC);
/*
* Changes to immediate action on Action Qualifier. This puts
* Action Qualifier control on PWM output from next TBCLK
*/
ti_ehrpwm_modify(TI_EHRPWM_AQSFRC_RLDCSF_IMDT,
TI_EHRPWM_AQSFRC_RLDCSF_MASK,
priv->regs + TI_EHRPWM_AQSFRC);
ti_ehrpwm_modify(aqcsfrc_val, aqcsfrc_mask,
priv->regs + TI_EHRPWM_AQCSFRC);
/* Disabling TBCLK on PWM disable */
err = clk_disable(&priv->tbclk);
if (err) {
dev_err(dev, "failed to disable tbclk\n");
return err;
}
return 0;
}
static int ti_ehrpwm_enable(struct udevice *dev, uint channel)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
u16 aqcsfrc_val, aqcsfrc_mask;
int err;
if (channel >= TI_EHRPWM_NUM_CHANNELS)
return -ENOSPC;
/* Disabling Action Qualifier on PWM output */
if (channel) {
aqcsfrc_val = TI_EHRPWM_AQCSFRC_CSFB_FRCDIS;
aqcsfrc_mask = TI_EHRPWM_AQCSFRC_CSFB_MASK;
} else {
aqcsfrc_val = TI_EHRPWM_AQCSFRC_CSFA_FRCDIS;
aqcsfrc_mask = TI_EHRPWM_AQCSFRC_CSFA_MASK;
}
/* Changes to shadow mode */
ti_ehrpwm_modify(TI_EHRPWM_AQSFRC_RLDCSF_ZRO,
TI_EHRPWM_AQSFRC_RLDCSF_MASK,
priv->regs + TI_EHRPWM_AQSFRC);
ti_ehrpwm_modify(aqcsfrc_val, aqcsfrc_mask,
priv->regs + TI_EHRPWM_AQCSFRC);
/* Channels polarity can be configured from action qualifier module */
ti_ehrpwm_configure_polarity(dev, channel);
err = clk_enable(&priv->tbclk);
if (err) {
dev_err(dev, "failed to enable tbclk\n");
return err;
}
return 0;
}
static int ti_ehrpwm_set_enable(struct udevice *dev, uint channel, bool enable)
{
if (enable)
return ti_ehrpwm_enable(dev, channel);
return ti_ehrpwm_disable(dev, channel);
}
static int ti_ehrpwm_of_to_plat(struct udevice *dev)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
priv->regs = dev_read_addr(dev);
if (priv->regs == FDT_ADDR_T_NONE) {
dev_err(dev, "invalid address\n");
return -EINVAL;
}
dev_dbg(dev, "regs=0x%08lx\n", priv->regs);
return 0;
}
static int ti_ehrpwm_remove(struct udevice *dev)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
clk_release_all(&priv->tbclk, 1);
return 0;
}
static int ti_ehrpwm_probe(struct udevice *dev)
{
struct ti_ehrpwm_priv *priv = dev_get_priv(dev);
struct clk clk;
int err;
err = clk_get_by_name(dev, "fck", &clk);
if (err) {
dev_err(dev, "failed to get clock\n");
return err;
}
priv->clk_rate = clk_get_rate(&clk);
if (IS_ERR_VALUE(priv->clk_rate) || !priv->clk_rate) {
dev_err(dev, "failed to get clock rate\n");
if (IS_ERR_VALUE(priv->clk_rate))
return priv->clk_rate;
return -EINVAL;
}
/* Acquire tbclk for Time Base EHRPWM submodule */
err = clk_get_by_name(dev, "tbclk", &priv->tbclk);
if (err) {
dev_err(dev, "failed to get tbclk clock\n");
return err;
}
return 0;
}
static const struct pwm_ops ti_ehrpwm_ops = {
.set_config = ti_ehrpwm_set_config,
.set_enable = ti_ehrpwm_set_enable,
.set_invert = ti_ehrpwm_set_invert,
};
static const struct udevice_id ti_ehrpwm_ids[] = {
{.compatible = "ti,am3352-ehrpwm"},
{.compatible = "ti,am33xx-ehrpwm"},
{}
};
U_BOOT_DRIVER(ti_ehrpwm) = {
.name = "ti_ehrpwm",
.id = UCLASS_PWM,
.of_match = ti_ehrpwm_ids,
.ops = &ti_ehrpwm_ops,
.ofdata_to_platdata = ti_ehrpwm_of_to_plat,
.probe = ti_ehrpwm_probe,
.remove = ti_ehrpwm_remove,
.priv_auto = sizeof(struct ti_ehrpwm_priv),
};

View File

@ -23,6 +23,7 @@
#define INVALID_ID 0xffff
#define GTC_CNTCR_REG 0x0
#define GTC_CNTFID0_REG 0x20
#define GTC_CNTR_EN 0x3
/**
@ -31,6 +32,7 @@
* @rproc_rst: rproc reset control data
* @sci: Pointer to TISCI handle
* @tsp: TISCI processor control helper structure
* @gtc_clk: GTC clock description
* @gtc_base: Timer base address.
*/
struct k3_arm64_privdata {
@ -38,6 +40,7 @@ struct k3_arm64_privdata {
struct power_domain gtc_pwrdmn;
struct reset_ctl rproc_rst;
struct ti_sci_proc tsp;
struct clk gtc_clk;
void *gtc_base;
};
@ -73,6 +76,7 @@ static int k3_arm64_load(struct udevice *dev, ulong addr, ulong size)
static int k3_arm64_start(struct udevice *dev)
{
struct k3_arm64_privdata *rproc = dev_get_priv(dev);
ulong gtc_rate;
int ret;
dev_dbg(dev, "%s\n", __func__);
@ -83,6 +87,11 @@ static int k3_arm64_start(struct udevice *dev)
return ret;
}
gtc_rate = clk_get_rate(&rproc->gtc_clk);
dev_dbg(dev, "GTC RATE= %d\n", (u32) gtc_rate);
/* Store the clock frequency down for GTC users to pick up */
writel((u32)gtc_rate, rproc->gtc_base + GTC_CNTFID0_REG);
/* Enable the timer before starting remote core */
writel(GTC_CNTR_EN, rproc->gtc_base + GTC_CNTCR_REG);
@ -169,6 +178,12 @@ static int k3_arm64_of_to_priv(struct udevice *dev,
return ret;
}
ret = clk_get_by_index(dev, 0, &rproc->gtc_clk);
if (ret) {
dev_err(dev, "clk_get failed: %d\n", ret);
return ret;
}
ret = reset_get_by_index(dev, 0, &rproc->rproc_rst);
if (ret) {
dev_err(dev, "reset_get() failed: %d\n", ret);

View File

@ -37,6 +37,8 @@ struct omap3_spi_priv {
unsigned int mode;
unsigned int wordlen;
unsigned int pin_dir:1;
bool bus_claimed;
};
static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val)
@ -372,6 +374,8 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
writel(conf, &priv->regs->modulctrl);
priv->bus_claimed = true;
}
static int omap3_spi_claim_bus(struct udevice *dev)
@ -381,9 +385,12 @@ static int omap3_spi_claim_bus(struct udevice *dev)
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
priv->cs = slave_plat->cs;
priv->freq = slave_plat->max_hz;
if (!priv->freq)
priv->freq = slave_plat->max_hz;
_omap3_spi_claim_bus(priv);
_omap3_spi_set_speed(priv);
_omap3_spi_set_mode(priv);
return 0;
}
@ -395,6 +402,8 @@ static int omap3_spi_release_bus(struct udevice *dev)
writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
priv->bus_claimed = false;
return 0;
}
@ -440,7 +449,8 @@ static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
struct omap3_spi_priv *priv = dev_get_priv(dev);
priv->freq = speed;
_omap3_spi_set_speed(priv);
if (priv->bus_claimed)
_omap3_spi_set_speed(priv);
return 0;
}
@ -451,7 +461,8 @@ static int omap3_spi_set_mode(struct udevice *dev, uint mode)
priv->mode = mode;
_omap3_spi_set_mode(priv);
if (priv->bus_claimed)
_omap3_spi_set_mode(priv);
return 0;
}

View File

@ -467,8 +467,8 @@ static int ti_qspi_of_to_plat(struct udevice *bus)
priv->memory_map = map_physmem(mmap_addr, mmap_size, MAP_NOCACHE);
priv->mmap_size = mmap_size;
priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
if (priv->max_hz < 0) {
priv->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
if (!priv->max_hz) {
debug("Error: Max frequency missing\n");
return -ENODEV;
}

View File

@ -19,8 +19,6 @@
#define TCLR_PRE_EN BIT(5) /* Pre-scaler enable */
#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV))
struct omap_gptimer_regs {
unsigned int tidr; /* offset 0x00 */
unsigned char res1[12];
@ -61,7 +59,9 @@ static int omap_timer_probe(struct udevice *dev)
struct omap_timer_priv *priv = dev_get_priv(dev);
if (!uc_priv->clock_rate)
uc_priv->clock_rate = TIMER_CLOCK;
uc_priv->clock_rate = V_SCLK;
uc_priv->clock_rate /= (2 << CONFIG_SYS_PTV);
/* start the counter ticking up, reload value on overflow */
writel(0, &priv->regs->tldr);

View File

@ -546,10 +546,7 @@ config ATMEL_HLCD
help
HLCDC supports video output to an attached LCD panel.
config AM335X_LCD
bool "Enable AM335x video support"
help
Supports video output to an attached LCD panel.
source "drivers/video/ti/Kconfig"
config LOGICORE_DP_TX
bool "Enable Logicore DP TX driver"

View File

@ -22,8 +22,8 @@ obj-${CONFIG_EXYNOS_FB} += exynos/
obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
obj-${CONFIG_VIDEO_STM32} += stm32/
obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
obj-y += ti/
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o

8
drivers/video/ti/Kconfig Normal file
View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
#
config AM335X_LCD
bool "Enable AM335x video support"
help
Supports video output to an attached LCD panel.

10
drivers/video/ti/Makefile Normal file
View File

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
#
ifdef CONFIG_DM_VIDEO
obj-$(CONFIG_AM335X_LCD) += tilcdc.o tilcdc-panel.o
else
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
endif

View File

@ -12,16 +12,13 @@
* - starts output DMA from gd->fb_base buffer
*/
#include <common.h>
#include <dm.h>
#include <lcd.h>
#include <log.h>
#include <video.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/omap.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <asm/utils.h>
#include <linux/delay.h>
#include <linux/err.h>
#include "am335x-fb.h"
@ -110,6 +107,25 @@ struct am335x_lcdhw {
unsigned int clkc_reset; /* 0x70 */
};
DECLARE_GLOBAL_DATA_PTR;
#if !defined(LCD_CNTL_BASE)
#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
#endif
/* Macro definitions */
#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & GENMASK(25, 20))
static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
int lcd_get_size(int *line_length)
{
*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
return *line_length * panel_info.vl_row + 0x20;
}
struct dpll_data {
unsigned long rounded_rate;
u16 rounded_m;
@ -117,8 +133,6 @@ struct dpll_data {
u8 rounded_div;
};
DECLARE_GLOBAL_DATA_PTR;
/**
* am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
*
@ -197,25 +211,6 @@ static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate)
return round_rate;
}
#if !CONFIG_IS_ENABLED(DM_VIDEO)
#if !defined(LCD_CNTL_BASE)
#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
#endif
/* Macro definitions */
#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & GENMASK(25, 20))
static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
int lcd_get_size(int *line_length)
{
*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
return *line_length * panel_info.vl_row + 0x20;
}
int am335xfb_init(struct am335x_lcdpanel *panel)
{
u32 raster_ctrl = 0;
@ -320,301 +315,3 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
return 0;
}
#else /* CONFIG_DM_VIDEO */
#define FBSIZE(t, p) (((t)->hactive.typ * (t)->vactive.typ * (p)->bpp) >> 3)
enum {
LCD_MAX_WIDTH = 2048,
LCD_MAX_HEIGHT = 2048,
LCD_MAX_LOG2_BPP = VIDEO_BPP32,
};
/**
* tilcdc_panel_info: Panel parameters
*
* @ac_bias: AC Bias Pin Frequency
* @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt
* @dma_burst_sz: DMA burst size
* @bpp: Bits per pixel
* @fdd: FIFO DMA Request Delay
* @tft_alt_mode: TFT Alternative Signal Mapping (Only for active)
* @invert_pxl_clk: Invert pixel clock
* @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
* @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore
* @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
* @fifo_th: DMA FIFO threshold
*/
struct tilcdc_panel_info {
u32 ac_bias;
u32 ac_bias_intrpt;
u32 dma_burst_sz;
u32 bpp;
u32 fdd;
bool tft_alt_mode;
bool invert_pxl_clk;
u32 sync_edge;
u32 sync_ctrl;
u32 raster_order;
u32 fifo_th;
};
struct am335x_fb_priv {
struct am335x_lcdhw *regs;
struct tilcdc_panel_info panel;
struct display_timing timing;
};
static int am335x_fb_remove(struct udevice *dev)
{
struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
uc_plat->base -= 0x20;
uc_plat->size += 0x20;
return 0;
}
static int am335x_fb_probe(struct udevice *dev)
{
struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct am335x_fb_priv *priv = dev_get_priv(dev);
struct am335x_lcdhw *regs = priv->regs;
struct tilcdc_panel_info *panel = &priv->panel;
struct display_timing *timing = &priv->timing;
struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
u32 reg;
/* Before relocation we don't need to do anything */
if (!(gd->flags & GD_FLG_RELOC))
return 0;
am335x_fb_set_pixel_clk_rate(regs, timing->pixelclock.typ);
/* clock source for LCDC from dispPLL M2 */
writel(0, &cmdpll->clklcdcpixelclk);
/* palette default entry */
memset((void *)uc_plat->base, 0, 0x20);
*(unsigned int *)uc_plat->base = 0x4000;
/* point fb behind palette */
uc_plat->base += 0x20;
uc_plat->size -= 0x20;
writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN |
LCDC_CLKC_ENABLE_DMACLKEN, &regs->clkc_enable);
writel(0, &regs->raster_ctrl);
reg = readl(&regs->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK;
reg |= LCDC_CTRL_RASTER_MODE;
writel(reg, &regs->ctrl);
writel(uc_plat->base, &regs->lcddma_fb0_base);
writel(uc_plat->base + FBSIZE(timing, panel),
&regs->lcddma_fb0_ceiling);
writel(uc_plat->base, &regs->lcddma_fb1_base);
writel(uc_plat->base + FBSIZE(timing, panel),
&regs->lcddma_fb1_ceiling);
reg = LCDC_DMA_CTRL_FIFO_TH(panel->fifo_th);
switch (panel->dma_burst_sz) {
case 1:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1);
break;
case 2:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2);
break;
case 4:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4);
break;
case 8:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8);
break;
case 16:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
break;
}
writel(reg, &regs->lcddma_ctrl);
writel(LCDC_RASTER_TIMING_0_HORLSB(timing->hactive.typ) |
LCDC_RASTER_TIMING_0_HORMSB(timing->hactive.typ) |
LCDC_RASTER_TIMING_0_HFPLSB(timing->hfront_porch.typ) |
LCDC_RASTER_TIMING_0_HBPLSB(timing->hback_porch.typ) |
LCDC_RASTER_TIMING_0_HSWLSB(timing->hsync_len.typ),
&regs->raster_timing0);
writel(LCDC_RASTER_TIMING_1_VBP(timing->vback_porch.typ) |
LCDC_RASTER_TIMING_1_VFP(timing->vfront_porch.typ) |
LCDC_RASTER_TIMING_1_VSW(timing->vsync_len.typ) |
LCDC_RASTER_TIMING_1_VERLSB(timing->vactive.typ),
&regs->raster_timing1);
reg = LCDC_RASTER_TIMING_2_ACB(panel->ac_bias) |
LCDC_RASTER_TIMING_2_ACBI(panel->ac_bias_intrpt) |
LCDC_RASTER_TIMING_2_HSWMSB(timing->hsync_len.typ) |
LCDC_RASTER_TIMING_2_VERMSB(timing->vactive.typ) |
LCDC_RASTER_TIMING_2_HBPMSB(timing->hback_porch.typ) |
LCDC_RASTER_TIMING_2_HFPMSB(timing->hfront_porch.typ);
if (timing->flags & DISPLAY_FLAGS_VSYNC_LOW)
reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT;
if (timing->flags & DISPLAY_FLAGS_HSYNC_LOW)
reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT;
if (panel->invert_pxl_clk)
reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT;
if (panel->sync_edge)
reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL;
if (panel->sync_ctrl)
reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL;
writel(reg, &regs->raster_timing2);
reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE |
LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(panel->fdd);
if (panel->tft_alt_mode)
reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE;
if (panel->bpp == 24)
reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
else if (panel->bpp == 32)
reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE |
LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
if (panel->raster_order)
reg |= LCDC_RASTER_CTRL_DATA_ORDER;
writel(reg, &regs->raster_ctrl);
uc_priv->xsize = timing->hactive.typ;
uc_priv->ysize = timing->vactive.typ;
uc_priv->bpix = log_2_n_round_up(panel->bpp);
return 0;
}
static int am335x_fb_of_to_plat(struct udevice *dev)
{
struct am335x_fb_priv *priv = dev_get_priv(dev);
struct tilcdc_panel_info *panel = &priv->panel;
struct display_timing *timing = &priv->timing;
ofnode node;
int err;
node = ofnode_by_compatible(ofnode_null(), "ti,am33xx-tilcdc");
if (!ofnode_valid(node)) {
dev_err(dev, "missing 'ti,am33xx-tilcdc' node\n");
return -ENXIO;
}
priv->regs = (struct am335x_lcdhw *)ofnode_get_addr(node);
dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs);
err = ofnode_decode_display_timing(dev_ofnode(dev), 0, timing);
if (err) {
dev_err(dev, "failed to get display timing\n");
return err;
}
if (timing->pixelclock.typ > (LCDC_FMAX / 2)) {
dev_err(dev, "invalid display clock-frequency: %d Hz\n",
timing->pixelclock.typ);
return -EINVAL;
}
if (timing->hactive.typ > LCD_MAX_WIDTH)
timing->hactive.typ = LCD_MAX_WIDTH;
if (timing->vactive.typ > LCD_MAX_HEIGHT)
timing->vactive.typ = LCD_MAX_HEIGHT;
node = ofnode_find_subnode(dev_ofnode(dev), "panel-info");
if (!ofnode_valid(node)) {
dev_err(dev, "missing 'panel-info' node\n");
return -ENXIO;
}
err |= ofnode_read_u32(node, "ac-bias", &panel->ac_bias);
err |= ofnode_read_u32(node, "ac-bias-intrpt", &panel->ac_bias_intrpt);
err |= ofnode_read_u32(node, "dma-burst-sz", &panel->dma_burst_sz);
err |= ofnode_read_u32(node, "bpp", &panel->bpp);
err |= ofnode_read_u32(node, "fdd", &panel->fdd);
err |= ofnode_read_u32(node, "sync-edge", &panel->sync_edge);
err |= ofnode_read_u32(node, "sync-ctrl", &panel->sync_ctrl);
err |= ofnode_read_u32(node, "raster-order", &panel->raster_order);
err |= ofnode_read_u32(node, "fifo-th", &panel->fifo_th);
if (err) {
dev_err(dev, "failed to get panel info\n");
return err;
}
switch (panel->bpp) {
case 16:
case 24:
case 32:
break;
default:
dev_err(dev, "invalid seting, bpp: %d\n", panel->bpp);
return -EINVAL;
}
switch (panel->dma_burst_sz) {
case 1:
case 2:
case 4:
case 8:
case 16:
break;
default:
dev_err(dev, "invalid setting, dma-burst-sz: %d\n",
panel->dma_burst_sz);
return -EINVAL;
}
/* optional */
panel->tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode");
panel->invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk");
dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n", timing->hactive.typ,
timing->vactive.typ, panel->bpp, timing->pixelclock.typ);
dev_dbg(dev, " hbp=%d, hfp=%d, hsw=%d\n", timing->hback_porch.typ,
timing->hfront_porch.typ, timing->hsync_len.typ);
dev_dbg(dev, " vbp=%d, vfp=%d, vsw=%d\n", timing->vback_porch.typ,
timing->vfront_porch.typ, timing->vsync_len.typ);
return 0;
}
static int am335x_fb_bind(struct udevice *dev)
{
struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
uc_plat->size = ((LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
(1 << LCD_MAX_LOG2_BPP)) >> 3) + 0x20;
dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size);
return 0;
}
static const struct udevice_id am335x_fb_ids[] = {
{ .compatible = "ti,tilcdc,panel" },
{ }
};
U_BOOT_DRIVER(am335x_fb) = {
.name = "am335x_fb",
.id = UCLASS_VIDEO,
.of_match = am335x_fb_ids,
.bind = am335x_fb_bind,
.of_to_plat = am335x_fb_of_to_plat,
.probe = am335x_fb_probe,
.remove = am335x_fb_remove,
.priv_auto = sizeof(struct am335x_fb_priv),
};
#endif /* CONFIG_DM_VIDEO */

View File

@ -7,8 +7,6 @@
#ifndef AM335X_FB_H
#define AM335X_FB_H
#if !CONFIG_IS_ENABLED(DM_VIDEO)
#define HSVS_CONTROL BIT(25) /*
* 0 = lcd_lp and lcd_fp are driven on
* opposite edges of pixel clock than
@ -70,6 +68,4 @@ struct am335x_lcdpanel {
int am335xfb_init(struct am335x_lcdpanel *panel);
#endif /* CONFIG_DM_VIDEO */
#endif /* AM335X_FB_H */

View File

@ -0,0 +1,172 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* OMAP panel support
*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <backlight.h>
#include <clk.h>
#include <display.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <log.h>
#include <panel.h>
#include <asm/gpio.h>
#include <linux/err.h>
#include "tilcdc.h"
struct tilcdc_panel_priv {
struct tilcdc_panel_info info;
struct display_timing timing;
struct udevice *backlight;
struct gpio_desc enable;
};
static int tilcdc_panel_enable_backlight(struct udevice *dev)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->enable))
dm_gpio_set_value(&priv->enable, 1);
if (priv->backlight)
return backlight_enable(priv->backlight);
return 0;
}
static int tilcdc_panel_set_backlight(struct udevice *dev, int percent)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->enable))
dm_gpio_set_value(&priv->enable, 1);
if (priv->backlight)
return backlight_set_brightness(priv->backlight, percent);
return 0;
}
int tilcdc_panel_get_display_info(struct udevice *dev,
struct tilcdc_panel_info *info)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
memcpy(info, &priv->info, sizeof(*info));
return 0;
}
static int tilcdc_panel_get_display_timing(struct udevice *dev,
struct display_timing *timing)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
memcpy(timing, &priv->timing, sizeof(*timing));
return 0;
}
static int tilcdc_panel_remove(struct udevice *dev)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->enable))
dm_gpio_free(dev, &priv->enable);
return 0;
}
static int tilcdc_panel_probe(struct udevice *dev)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
int err;
err = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
"backlight", &priv->backlight);
if (err)
dev_warn(dev, "failed to get backlight\n");
err = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
GPIOD_IS_OUT);
if (err) {
dev_warn(dev, "failed to get enable GPIO\n");
if (err != -ENOENT)
return err;
}
return 0;
}
static int tilcdc_panel_of_to_plat(struct udevice *dev)
{
struct tilcdc_panel_priv *priv = dev_get_priv(dev);
ofnode node;
int err;
err = ofnode_decode_display_timing(dev_ofnode(dev), 0, &priv->timing);
if (err) {
dev_err(dev, "failed to get display timing\n");
return err;
}
node = dev_read_subnode(dev, "panel-info");
if (!ofnode_valid(node)) {
dev_err(dev, "missing 'panel-info' node\n");
return -ENXIO;
}
err |= ofnode_read_u32(node, "ac-bias", &priv->info.ac_bias);
err |= ofnode_read_u32(node, "ac-bias-intrpt",
&priv->info.ac_bias_intrpt);
err |= ofnode_read_u32(node, "dma-burst-sz", &priv->info.dma_burst_sz);
err |= ofnode_read_u32(node, "bpp", &priv->info.bpp);
err |= ofnode_read_u32(node, "fdd", &priv->info.fdd);
err |= ofnode_read_u32(node, "sync-edge", &priv->info.sync_edge);
err |= ofnode_read_u32(node, "sync-ctrl", &priv->info.sync_ctrl);
err |= ofnode_read_u32(node, "raster-order", &priv->info.raster_order);
err |= ofnode_read_u32(node, "fifo-th", &priv->info.fifo_th);
if (err) {
dev_err(dev, "failed to get panel info\n");
return err;
}
/* optional */
priv->info.tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode");
priv->info.invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk");
dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n",
priv->timing.hactive.typ, priv->timing.vactive.typ,
priv->info.bpp, priv->timing.pixelclock.typ);
dev_dbg(dev, " hbp=%d, hfp=%d, hsw=%d\n",
priv->timing.hback_porch.typ, priv->timing.hfront_porch.typ,
priv->timing.hsync_len.typ);
dev_dbg(dev, " vbp=%d, vfp=%d, vsw=%d\n",
priv->timing.vback_porch.typ, priv->timing.vfront_porch.typ,
priv->timing.vsync_len.typ);
return 0;
}
static const struct panel_ops tilcdc_panel_ops = {
.enable_backlight = tilcdc_panel_enable_backlight,
.set_backlight = tilcdc_panel_set_backlight,
.get_display_timing = tilcdc_panel_get_display_timing,
};
static const struct udevice_id tilcdc_panel_ids[] = {
{.compatible = "ti,tilcdc,panel"},
{}
};
U_BOOT_DRIVER(tilcdc_panel) = {
.name = "tilcdc_panel",
.id = UCLASS_PANEL,
.of_match = tilcdc_panel_ids,
.ops = &tilcdc_panel_ops,
.ofdata_to_platdata = tilcdc_panel_of_to_plat,
.probe = tilcdc_panel_probe,
.remove = tilcdc_panel_remove,
.priv_auto = sizeof(struct tilcdc_panel_priv),
};

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#ifndef _TILCDC_PANEL_H
#define _TILCDC_PANEL_H
#include "tilcdc.h"
int tilcdc_panel_get_display_info(struct udevice *dev,
struct tilcdc_panel_info *info);
#endif /* _TILCDC_PANEL_H */

425
drivers/video/ti/tilcdc.c Normal file
View File

@ -0,0 +1,425 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <lcd.h>
#include <log.h>
#include <panel.h>
#include <video.h>
#include <asm/io.h>
#include <asm/utils.h>
#include "tilcdc.h"
#include "tilcdc-panel.h"
#define LCDC_FMAX 200000000
/* LCD Control Register */
#define LCDC_CTRL_CLK_DIVISOR_MASK GENMASK(15, 8)
#define LCDC_CTRL_RASTER_MODE BIT(0)
#define LCDC_CTRL_CLK_DIVISOR(x) (((x) & GENMASK(7, 0)) << 8)
/* LCD Clock Enable Register */
#define LCDC_CLKC_ENABLE_CORECLKEN BIT(0)
#define LCDC_CLKC_ENABLE_LIDDCLKEN BIT(1)
#define LCDC_CLKC_ENABLE_DMACLKEN BIT(2)
/* LCD DMA Control Register */
#define LCDC_DMA_CTRL_BURST_SIZE(x) (((x) & GENMASK(2, 0)) << 4)
#define LCDC_DMA_CTRL_BURST_1 0x0
#define LCDC_DMA_CTRL_BURST_2 0x1
#define LCDC_DMA_CTRL_BURST_4 0x2
#define LCDC_DMA_CTRL_BURST_8 0x3
#define LCDC_DMA_CTRL_BURST_16 0x4
#define LCDC_DMA_CTRL_FIFO_TH(x) (((x) & GENMASK(2, 0)) << 8)
/* LCD Timing_0 Register */
#define LCDC_RASTER_TIMING_0_HORMSB(x) ((((x) - 1) & BIT(10)) >> 7)
#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4)
#define LCDC_RASTER_TIMING_0_HSWLSB(x) ((((x) - 1) & GENMASK(5, 0)) << 10)
#define LCDC_RASTER_TIMING_0_HFPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 16)
#define LCDC_RASTER_TIMING_0_HBPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 24)
/* LCD Timing_1 Register */
#define LCDC_RASTER_TIMING_1_VERLSB(x) (((x) - 1) & GENMASK(9, 0))
#define LCDC_RASTER_TIMING_1_VSW(x) ((((x) - 1) & GENMASK(5, 0)) << 10)
#define LCDC_RASTER_TIMING_1_VFP(x) (((x) & GENMASK(7, 0)) << 16)
#define LCDC_RASTER_TIMING_1_VBP(x) (((x) & GENMASK(7, 0)) << 24)
/* LCD Timing_2 Register */
#define LCDC_RASTER_TIMING_2_HFPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 8)
#define LCDC_RASTER_TIMING_2_HBPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 4)
#define LCDC_RASTER_TIMING_2_ACB(x) (((x) & GENMASK(7, 0)) << 8)
#define LCDC_RASTER_TIMING_2_ACBI(x) (((x) & GENMASK(3, 0)) << 16)
#define LCDC_RASTER_TIMING_2_VSYNC_INVERT BIT(20)
#define LCDC_RASTER_TIMING_2_HSYNC_INVERT BIT(21)
#define LCDC_RASTER_TIMING_2_PXCLK_INVERT BIT(22)
#define LCDC_RASTER_TIMING_2_DE_INVERT BIT(23)
#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL BIT(24)
#define LCDC_RASTER_TIMING_2_HSVS_CONTROL BIT(25)
#define LCDC_RASTER_TIMING_2_VERMSB(x) ((((x) - 1) & BIT(10)) << 16)
#define LCDC_RASTER_TIMING_2_HSWMSB(x) ((((x) - 1) & GENMASK(9, 6)) << 21)
/* LCD Raster Ctrl Register */
#define LCDC_RASTER_CTRL_ENABLE BIT(0)
#define LCDC_RASTER_CTRL_TFT_MODE BIT(7)
#define LCDC_RASTER_CTRL_DATA_ORDER BIT(8)
#define LCDC_RASTER_CTRL_REQDLY(x) (((x) & GENMASK(7, 0)) << 12)
#define LCDC_RASTER_CTRL_PALMODE_RAWDATA (0x02 << 20)
#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE BIT(23)
#define LCDC_RASTER_CTRL_TFT_24BPP_MODE BIT(25)
#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK BIT(26)
enum {
LCDC_MAX_WIDTH = 2048,
LCDC_MAX_HEIGHT = 2048,
LCDC_MAX_LOG2_BPP = VIDEO_BPP32,
};
struct tilcdc_regs {
u32 pid;
u32 ctrl;
u32 gap0;
u32 lidd_ctrl;
u32 lidd_cs0_conf;
u32 lidd_cs0_addr;
u32 lidd_cs0_data;
u32 lidd_cs1_conf;
u32 lidd_cs1_addr;
u32 lidd_cs1_data;
u32 raster_ctrl;
u32 raster_timing0;
u32 raster_timing1;
u32 raster_timing2;
u32 raster_subpanel;
u32 raster_subpanel2;
u32 lcddma_ctrl;
u32 lcddma_fb0_base;
u32 lcddma_fb0_ceiling;
u32 lcddma_fb1_base;
u32 lcddma_fb1_ceiling;
u32 sysconfig;
u32 irqstatus_raw;
u32 irqstatus;
u32 irqenable_set;
u32 irqenable_clear;
u32 gap1;
u32 clkc_enable;
u32 clkc_reset;
};
struct tilcdc_priv {
struct tilcdc_regs *regs;
struct clk gclk;
struct clk dpll_m2_clk;
};
DECLARE_GLOBAL_DATA_PTR;
static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate)
{
struct tilcdc_priv *priv = dev_get_priv(dev);
struct tilcdc_regs *regs = priv->regs;
ulong mult_rate, mult_round_rate, best_err, err;
u32 v;
int div, i;
best_err = rate;
div = 0;
for (i = 2; i <= 255; i++) {
mult_rate = rate * i;
mult_round_rate = clk_round_rate(&priv->gclk, mult_rate);
if (IS_ERR_VALUE(mult_round_rate))
return mult_round_rate;
err = mult_rate - mult_round_rate;
if (err < best_err) {
best_err = err;
div = i;
if (err == 0)
break;
}
}
if (div == 0) {
dev_err(dev, "failed to find a divisor\n");
return -EFAULT;
}
mult_rate = clk_set_rate(&priv->gclk, rate * div);
v = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
v |= LCDC_CTRL_CLK_DIVISOR(div);
writel(v, &regs->ctrl);
rate = mult_rate / div;
dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err);
return rate;
}
static int tilcdc_remove(struct udevice *dev)
{
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
struct tilcdc_priv *priv = dev_get_priv(dev);
uc_plat->base -= 0x20;
uc_plat->size += 0x20;
clk_release_all(&priv->gclk, 1);
clk_release_all(&priv->dpll_m2_clk, 1);
return 0;
}
static int tilcdc_probe(struct udevice *dev)
{
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct tilcdc_priv *priv = dev_get_priv(dev);
struct tilcdc_regs *regs = priv->regs;
struct udevice *panel, *clk_dev;
struct tilcdc_panel_info info;
struct display_timing timing;
ulong rate;
u32 reg;
int err;
/* Before relocation we don't need to do anything */
if (!(gd->flags & GD_FLG_RELOC))
return 0;
err = uclass_get_device(UCLASS_PANEL, 0, &panel);
if (err) {
dev_err(dev, "failed to get panel\n");
return err;
}
err = panel_get_display_timing(panel, &timing);
if (err) {
dev_err(dev, "failed to get display timing\n");
return err;
}
if (timing.pixelclock.typ > (LCDC_FMAX / 2)) {
dev_err(dev, "invalid display clock-frequency: %d Hz\n",
timing.pixelclock.typ);
return -EINVAL;
}
if (timing.hactive.typ > LCDC_MAX_WIDTH)
timing.hactive.typ = LCDC_MAX_WIDTH;
if (timing.vactive.typ > LCDC_MAX_HEIGHT)
timing.vactive.typ = LCDC_MAX_HEIGHT;
err = tilcdc_panel_get_display_info(panel, &info);
if (err) {
dev_err(dev, "failed to get panel info\n");
return err;
}
switch (info.bpp) {
case 16:
case 24:
case 32:
break;
default:
dev_err(dev, "invalid seting, bpp: %d\n", info.bpp);
return -EINVAL;
}
switch (info.dma_burst_sz) {
case 1:
case 2:
case 4:
case 8:
case 16:
break;
default:
dev_err(dev, "invalid setting, dma-burst-sz: %d\n",
info.dma_burst_sz);
return -EINVAL;
}
err = uclass_get_device_by_name(UCLASS_CLK, "lcd_gclk@534", &clk_dev);
if (err) {
dev_err(dev, "failed to get lcd_gclk device\n");
return err;
}
err = clk_request(clk_dev, &priv->gclk);
if (err) {
dev_err(dev, "failed to get %s clock\n", clk_dev->name);
return err;
}
rate = tilcdc_set_pixel_clk_rate(dev, timing.pixelclock.typ);
if (IS_ERR_VALUE(rate)) {
dev_err(dev, "failed to set pixel clock rate\n");
return rate;
}
err = uclass_get_device_by_name(UCLASS_CLK, "dpll_disp_m2_ck@4a4",
&clk_dev);
if (err) {
dev_err(dev, "failed to get dpll_disp_m2 clock device\n");
return err;
}
err = clk_request(clk_dev, &priv->dpll_m2_clk);
if (err) {
dev_err(dev, "failed to get %s clock\n", clk_dev->name);
return err;
}
err = clk_set_parent(&priv->gclk, &priv->dpll_m2_clk);
if (err) {
dev_err(dev, "failed to set %s clock as %s's parent\n",
priv->dpll_m2_clk.dev->name, priv->gclk.dev->name);
return err;
}
/* palette default entry */
memset((void *)uc_plat->base, 0, 0x20);
*(unsigned int *)uc_plat->base = 0x4000;
/* point fb behind palette */
uc_plat->base += 0x20;
uc_plat->size -= 0x20;
writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN |
LCDC_CLKC_ENABLE_DMACLKEN, &regs->clkc_enable);
writel(0, &regs->raster_ctrl);
reg = readl(&regs->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK;
reg |= LCDC_CTRL_RASTER_MODE;
writel(reg, &regs->ctrl);
reg = (timing.hactive.typ * timing.vactive.typ * info.bpp) >> 3;
reg += uc_plat->base;
writel(uc_plat->base, &regs->lcddma_fb0_base);
writel(reg, &regs->lcddma_fb0_ceiling);
writel(uc_plat->base, &regs->lcddma_fb1_base);
writel(reg, &regs->lcddma_fb1_ceiling);
reg = LCDC_DMA_CTRL_FIFO_TH(info.fifo_th);
switch (info.dma_burst_sz) {
case 1:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1);
break;
case 2:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2);
break;
case 4:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4);
break;
case 8:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8);
break;
case 16:
reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
break;
}
writel(reg, &regs->lcddma_ctrl);
writel(LCDC_RASTER_TIMING_0_HORLSB(timing.hactive.typ) |
LCDC_RASTER_TIMING_0_HORMSB(timing.hactive.typ) |
LCDC_RASTER_TIMING_0_HFPLSB(timing.hfront_porch.typ) |
LCDC_RASTER_TIMING_0_HBPLSB(timing.hback_porch.typ) |
LCDC_RASTER_TIMING_0_HSWLSB(timing.hsync_len.typ),
&regs->raster_timing0);
writel(LCDC_RASTER_TIMING_1_VBP(timing.vback_porch.typ) |
LCDC_RASTER_TIMING_1_VFP(timing.vfront_porch.typ) |
LCDC_RASTER_TIMING_1_VSW(timing.vsync_len.typ) |
LCDC_RASTER_TIMING_1_VERLSB(timing.vactive.typ),
&regs->raster_timing1);
reg = LCDC_RASTER_TIMING_2_ACB(info.ac_bias) |
LCDC_RASTER_TIMING_2_ACBI(info.ac_bias_intrpt) |
LCDC_RASTER_TIMING_2_HSWMSB(timing.hsync_len.typ) |
LCDC_RASTER_TIMING_2_VERMSB(timing.vactive.typ) |
LCDC_RASTER_TIMING_2_HBPMSB(timing.hback_porch.typ) |
LCDC_RASTER_TIMING_2_HFPMSB(timing.hfront_porch.typ);
if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT;
if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT;
if (info.invert_pxl_clk)
reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT;
if (info.sync_edge)
reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL;
if (info.sync_ctrl)
reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL;
writel(reg, &regs->raster_timing2);
reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE |
LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(info.fdd);
if (info.tft_alt_mode)
reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE;
if (info.bpp == 24)
reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
else if (info.bpp == 32)
reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE |
LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
if (info.raster_order)
reg |= LCDC_RASTER_CTRL_DATA_ORDER;
writel(reg, &regs->raster_ctrl);
uc_priv->xsize = timing.hactive.typ;
uc_priv->ysize = timing.vactive.typ;
uc_priv->bpix = log_2_n_round_up(info.bpp);
err = panel_enable_backlight(panel);
if (err) {
dev_err(dev, "failed to enable panel backlight\n");
return err;
}
return 0;
}
static int tilcdc_of_to_plat(struct udevice *dev)
{
struct tilcdc_priv *priv = dev_get_priv(dev);
priv->regs = (struct tilcdc_regs *)dev_read_addr(dev);
if ((fdt_addr_t)priv->regs == FDT_ADDR_T_NONE) {
dev_err(dev, "failed to get base address\n");
return -EINVAL;
}
dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs);
return 0;
}
static int tilcdc_bind(struct udevice *dev)
{
struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
uc_plat->size = ((LCDC_MAX_WIDTH * LCDC_MAX_HEIGHT *
(1 << LCDC_MAX_LOG2_BPP)) >> 3) + 0x20;
dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size);
return 0;
}
static const struct udevice_id tilcdc_ids[] = {
{.compatible = "ti,am33xx-tilcdc"},
{}
};
U_BOOT_DRIVER(tilcdc) = {
.name = "tilcdc",
.id = UCLASS_VIDEO,
.of_match = tilcdc_ids,
.bind = tilcdc_bind,
.ofdata_to_platdata = tilcdc_of_to_plat,
.probe = tilcdc_probe,
.remove = tilcdc_remove,
.priv_auto = sizeof(struct tilcdc_priv)
};

38
drivers/video/ti/tilcdc.h Normal file
View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
*/
#ifndef _TILCDC_H
#define _TILCDC_H
/**
* tilcdc_panel_info: Panel parameters
*
* @ac_bias: AC Bias Pin Frequency
* @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt
* @dma_burst_sz: DMA burst size
* @bpp: Bits per pixel
* @fdd: FIFO DMA Request Delay
* @tft_alt_mode: TFT Alternative Signal Mapping (Only for active)
* @invert_pxl_clk: Invert pixel clock
* @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
* @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore
* @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
* @fifo_th: DMA FIFO threshold
*/
struct tilcdc_panel_info {
u32 ac_bias;
u32 ac_bias_intrpt;
u32 dma_burst_sz;
u32 bpp;
u32 fdd;
bool tft_alt_mode;
bool invert_pxl_clk;
u32 sync_edge;
u32 sync_ctrl;
u32 raster_order;
u32 fifo_th;
};
#endif /* _TILCDC_H */

View File

@ -183,6 +183,12 @@ struct global_data {
struct global_data *new_gd;
#ifdef CONFIG_DM
/**
* @dm_flags: additional flags for Driver Model
*
* See &enum gd_dm_flags
*/
unsigned long dm_flags;
/**
* @dm_root: root instance for Driver Model
*/
@ -471,6 +477,12 @@ struct global_data {
#define gd_acpi_ctx() NULL
#endif
#if CONFIG_IS_ENABLED(DM)
#define gd_size_cells_0() (gd->dm_flags & GD_DM_FLG_SIZE_CELLS_0)
#else
#define gd_size_cells_0() (0)
#endif
/**
* enum gd_flags - global data flags
*
@ -555,6 +567,18 @@ enum gd_flags {
GD_FLG_SMP_READY = 0x40000,
};
/**
* enum gd_dm_flags - global data flags for Driver Model
*
* See field dm_flags of &struct global_data.
*/
enum gd_dm_flags {
/**
* @GD_DM_FLG_SIZE_CELLS_0: Enable #size-cells=<0> translation
*/
GD_DM_FLG_SIZE_CELLS_0 = 0x00001,
};
#endif /* __ASSEMBLY__ */
#endif /* __ASM_GENERIC_GBL_DATA_H */

View File

@ -61,6 +61,14 @@ struct clk_ops {
* @return 0 if OK, or a negative error code.
*/
int (*rfree)(struct clk *clock);
/**
* round_rate() - Adjust a rate to the exact rate a clock can provide.
*
* @clk: The clock to manipulate.
* @rate: Desidered clock rate in Hz.
* @return rounded rate in Hz, or -ve error code.
*/
ulong (*round_rate)(struct clk *clk, ulong rate);
/**
* get_rate() - Get current clock rate.
*

View File

@ -366,6 +366,29 @@ struct clk *clk_get_parent(struct clk *clk);
*/
long long clk_get_parent_rate(struct clk *clk);
/**
* clk_round_rate() - Adjust a rate to the exact rate a clock can provide
*
* This answers the question "if I were to pass @rate to clk_set_rate(),
* what clock rate would I end up with?" without changing the hardware
* in any way. In other words:
*
* rate = clk_round_rate(clk, r);
*
* and:
*
* rate = clk_set_rate(clk, r);
*
* are equivalent except the former does not modify the clock hardware
* in any way.
*
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
* @rate: desired clock rate in Hz.
* @return rounded rate in Hz, or -ve error code.
*/
ulong clk_round_rate(struct clk *clk, ulong rate);
/**
* clk_set_rate() - Set current clock rate.
*
@ -482,6 +505,11 @@ static inline long long clk_get_parent_rate(struct clk *clk)
return -ENOSYS;
}
static inline ulong clk_round_rate(struct clk *clk, ulong rate)
{
return -ENOSYS;
}
static inline ulong clk_set_rate(struct clk *clk, ulong rate)
{
return -ENOSYS;

View File

@ -56,6 +56,12 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
/*
* If the maximum size is not declared then it is defined as
* CONFIG_SYS_DFU_DATA_BUF_SIZE.
*/
#define CONFIG_SYS_DFU_MAX_FILE_SIZE (1024 * 1024 * 8) /* 8 MiB */
#define CONFIG_SPL_MAX_SIZE CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
#define CONFIG_SYS_BOOTM_LEN SZ_64M

Some files were not shown because too many files have changed in this diff Show More