mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-20 22:21:41 +00:00
Merge git://git.denx.de/u-boot-dm
- MPC83xx device tree additions (CPU and RAM) - Fix sandbox build error - Sync bitrev with Linux - Various ofnode/DT improvements
This commit is contained in:
commit
4e710ebb44
70 changed files with 4695 additions and 91 deletions
23
Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
Normal file
23
Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
MPC83xx system clock devices
|
||||||
|
|
||||||
|
MPC83xx SoCs supply a variety of clocks to drive various components of a
|
||||||
|
system.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: must be one of "fsl,mpc8308-clk",
|
||||||
|
"fsl,mpc8309-clk",
|
||||||
|
"fsl,mpc8313-clk",
|
||||||
|
"fsl,mpc8315-clk",
|
||||||
|
"fsl,mpc832x-clk",
|
||||||
|
"fsl,mpc8349-clk",
|
||||||
|
"fsl,mpc8360-clk",
|
||||||
|
"fsl,mpc8379-clk"
|
||||||
|
depending on which SoC is employed
|
||||||
|
- #clock-cells: Must be 1
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
socclocks: clocks {
|
||||||
|
compatible = "fsl,mpc832x-clk";
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
34
Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
Normal file
34
Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
MPC83xx CPU devices
|
||||||
|
|
||||||
|
MPC83xx SoCs contain a e300 core as their main processor.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: must be one of "fsl,mpc83xx",
|
||||||
|
"fsl,mpc8308",
|
||||||
|
"fsl,mpc8309",
|
||||||
|
"fsl,mpc8313",
|
||||||
|
"fsl,mpc8315",
|
||||||
|
"fsl,mpc832x",
|
||||||
|
"fsl,mpc8349",
|
||||||
|
"fsl,mpc8360",
|
||||||
|
"fsl,mpc8379"
|
||||||
|
- clocks: has to have two entries, which must be the core clock at index 0 and
|
||||||
|
the CSB (Coherent System Bus) clock at index 1. Both are given by a suitable
|
||||||
|
"fsl,mpc83xx-clk" device
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
socclocks: clocks {
|
||||||
|
compatible = "fsl,mpc8315-clk";
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
compatible = "cpu_bus";
|
||||||
|
|
||||||
|
PowerPC,8315@0 {
|
||||||
|
compatible = "fsl,mpc8315";
|
||||||
|
clocks = <&socclocks MPC83XX_CLK_CORE
|
||||||
|
&socclocks MPC83XX_CLK_CSB>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
MPC83xx SerDes controller devices
|
||||||
|
|
||||||
|
MPC83xx SoCs contain a built-in SerDes controller that determines which
|
||||||
|
protocols (SATA, PCI Express, SGMII, ...) are used on the system's serdes lines
|
||||||
|
and how the lines are configured.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: must be "fsl,mpc83xx-serdes"
|
||||||
|
- reg: must point to the serdes controller's register map
|
||||||
|
- proto: selects for which protocol the serdes lines are configured. One of
|
||||||
|
"sata", "pex", "pex-x2", "sgmii"
|
||||||
|
- serdes-clk: determines the frequency the serdes lines are configured for. One
|
||||||
|
of 100, 125, 150.
|
||||||
|
- vdd: determines whether 1.0V core VDD is used or not
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
SERDES: serdes@e3000 {
|
||||||
|
reg = <0xe3000 0x200>;
|
||||||
|
compatible = "fsl,mpc83xx-serdes";
|
||||||
|
proto = "pex";
|
||||||
|
serdes-clk = <100>;
|
||||||
|
vdd;
|
||||||
|
};
|
|
@ -0,0 +1,314 @@
|
||||||
|
MPC83xx RAM controller
|
||||||
|
|
||||||
|
This driver supplies support for the embedded RAM controller on MCP83xx-series
|
||||||
|
SoCs.
|
||||||
|
|
||||||
|
For static configuration mode, each controller node should have child nodes
|
||||||
|
describing the actual RAM modules installed.
|
||||||
|
|
||||||
|
Controller node
|
||||||
|
===============
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Must be "fsl,mpc83xx-mem-controller"
|
||||||
|
- reg: The address of the RAM controller's register space
|
||||||
|
- #address-cells: Must be 2
|
||||||
|
- #size-cells: Must be 1
|
||||||
|
- driver_software_override: DDR driver software override is enabled (1) or
|
||||||
|
disabled (0)
|
||||||
|
- p_impedance_override: DDR driver software p-impedance override; possible
|
||||||
|
values:
|
||||||
|
* DSO_P_IMPEDANCE_HIGHEST_Z
|
||||||
|
* DSO_P_IMPEDANCE_MUCH_HIGHER_Z
|
||||||
|
* DSO_P_IMPEDANCE_HIGHER_Z
|
||||||
|
* DSO_P_IMPEDANCE_NOMINAL
|
||||||
|
* DSO_P_IMPEDANCE_LOWER_Z
|
||||||
|
- n_impedance_override: DDR driver software n-impedance override; possible
|
||||||
|
values:
|
||||||
|
* DSO_N_IMPEDANCE_HIGHEST_Z
|
||||||
|
* DSO_N_IMPEDANCE_MUCH_HIGHER_Z
|
||||||
|
* DSO_N_IMPEDANCE_HIGHER_Z
|
||||||
|
* DSO_N_IMPEDANCE_NOMINAL
|
||||||
|
* DSO_N_IMPEDANCE_LOWER_Z
|
||||||
|
- odt_termination_value: ODT termination value for I/Os; possible values:
|
||||||
|
* ODT_TERMINATION_75_OHM
|
||||||
|
* ODT_TERMINATION_150_OHM
|
||||||
|
- ddr_type: Selects voltage level for DDR pads; possible
|
||||||
|
values:
|
||||||
|
* DDR_TYPE_DDR2_1_8_VOLT
|
||||||
|
* DDR_TYPE_DDR1_2_5_VOLT
|
||||||
|
- mvref_sel: Determine where MVREF_SEL signal is generated;
|
||||||
|
possible values:
|
||||||
|
* MVREF_SEL_EXTERNAL
|
||||||
|
* MVREF_SEL_INTERNAL_GVDD
|
||||||
|
- m_odr: Disable memory transaction reordering; possible
|
||||||
|
values:
|
||||||
|
* M_ODR_ENABLE
|
||||||
|
* M_ODR_DISABLE
|
||||||
|
- clock_adjust: Clock adjust; possible values:
|
||||||
|
* CLOCK_ADJUST_025
|
||||||
|
* CLOCK_ADJUST_05
|
||||||
|
* CLOCK_ADJUST_075
|
||||||
|
* CLOCK_ADJUST_1
|
||||||
|
- ext_refresh_rec: Extended refresh recovery time; possible values:
|
||||||
|
0, 16, 32, 48, 64, 80, 96, 112
|
||||||
|
- read_to_write: Read-to-write turnaround; possible values:
|
||||||
|
0, 1, 2, 3
|
||||||
|
- write_to_read: Write-to-read turnaround; possible values:
|
||||||
|
0, 1, 2, 3
|
||||||
|
- read_to_read: Read-to-read turnaround; possible values:
|
||||||
|
0, 1, 2, 3
|
||||||
|
- write_to_write: Write-to-write turnaround; possible values:
|
||||||
|
0, 1, 2, 3
|
||||||
|
- active_powerdown_exit: Active powerdown exit timing; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- precharge_powerdown_exit: Precharge powerdown exit timing; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- odt_powerdown_exit: ODT powerdown exit timing; possible values:
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12, 13, 14, 15
|
||||||
|
- mode_reg_set_cycle: Mode register set cycle time; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||||
|
- precharge_to_activate: Precharge-to-acitvate interval; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- activate_to_precharge: Activate to precharge interval; possible values:
|
||||||
|
4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||||
|
13, 14, 15, 16, 17, 18, 19
|
||||||
|
- activate_to_readwrite: Activate to read/write interval for SDRAM;
|
||||||
|
possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- mcas_latency: MCAS latency from READ command; possible values:
|
||||||
|
* CASLAT_20
|
||||||
|
* CASLAT_25
|
||||||
|
* CASLAT_30
|
||||||
|
* CASLAT_35
|
||||||
|
* CASLAT_40
|
||||||
|
* CASLAT_45
|
||||||
|
* CASLAT_50
|
||||||
|
* CASLAT_55
|
||||||
|
* CASLAT_60
|
||||||
|
* CASLAT_65
|
||||||
|
* CASLAT_70
|
||||||
|
* CASLAT_75
|
||||||
|
* CASLAT_80
|
||||||
|
- refresh_recovery: Refresh recovery time; possible values:
|
||||||
|
8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23
|
||||||
|
- last_data_to_precharge: Last data to precharge minimum interval; possible
|
||||||
|
values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- activate_to_activate: Activate-to-activate interval; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- last_write_data_to_read: Last write data pair to read command issue
|
||||||
|
interval; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- additive_latency: Additive latency; possible values:
|
||||||
|
0, 1, 2, 3, 4, 5
|
||||||
|
- mcas_to_preamble_override: MCAS-to-preamble-override; possible values:
|
||||||
|
* READ_LAT
|
||||||
|
* READ_LAT_PLUS_1_4
|
||||||
|
* READ_LAT_PLUS_1_2
|
||||||
|
* READ_LAT_PLUS_3_4
|
||||||
|
* READ_LAT_PLUS_1
|
||||||
|
* READ_LAT_PLUS_5_4
|
||||||
|
* READ_LAT_PLUS_3_2
|
||||||
|
* READ_LAT_PLUS_7_4
|
||||||
|
* READ_LAT_PLUS_2
|
||||||
|
* READ_LAT_PLUS_9_4
|
||||||
|
* READ_LAT_PLUS_5_2
|
||||||
|
* READ_LAT_PLUS_11_4
|
||||||
|
* READ_LAT_PLUS_3
|
||||||
|
* READ_LAT_PLUS_13_4
|
||||||
|
* READ_LAT_PLUS_7_2
|
||||||
|
* READ_LAT_PLUS_15_4
|
||||||
|
* READ_LAT_PLUS_4
|
||||||
|
* READ_LAT_PLUS_17_4
|
||||||
|
* READ_LAT_PLUS_9_2
|
||||||
|
* READ_LAT_PLUS_19_4
|
||||||
|
- write_latency: Write latency; possible values:
|
||||||
|
1, 2, 3, 4, 5, 6, 7
|
||||||
|
- read_to_precharge: Read to precharge; possible values:
|
||||||
|
1, 2, 3, 4
|
||||||
|
- write_cmd_to_write_data: Write command to write data strobe timing
|
||||||
|
adjustment; possible values:
|
||||||
|
* CLOCK_DELAY_0
|
||||||
|
* CLOCK_DELAY_1_4
|
||||||
|
* CLOCK_DELAY_1_2
|
||||||
|
* CLOCK_DELAY_3_4
|
||||||
|
* CLOCK_DELAY_1
|
||||||
|
* CLOCK_DELAY_5_4
|
||||||
|
* CLOCK_DELAY_3_2
|
||||||
|
- minimum_cke_pulse_width: Minimum CKE pulse width; possible values:
|
||||||
|
1, 2, 3, 4
|
||||||
|
- four_activates_window: Window for four activates; possible values:
|
||||||
|
1, 2, 3, 4 8, 9, 10, 11, 12,
|
||||||
|
13, 14, 15, 16, 17, 18, 19
|
||||||
|
- self_refresh: Self refresh (during sleep); possible values:
|
||||||
|
* SREN_DISABLE
|
||||||
|
* SREN_ENABLE
|
||||||
|
- ecc: Support for ECC; possible values:
|
||||||
|
* ECC_DISABLE
|
||||||
|
* ECC_ENABLE
|
||||||
|
- registered_dram: Support for registered DRAM; possible values:
|
||||||
|
* RD_DISABLE
|
||||||
|
* RD_ENABLE
|
||||||
|
- sdram_type: Type of SDRAM device to be used; possible values:
|
||||||
|
* TYPE_DDR1
|
||||||
|
* TYPE_DDR2
|
||||||
|
- dynamic_power_management: Dynamic power management mode; possible values:
|
||||||
|
* DYN_PWR_DISABLE
|
||||||
|
* DYN_PWR_ENABLE
|
||||||
|
- databus_width: DRAM data bus width; possible values
|
||||||
|
* DATA_BUS_WIDTH_16
|
||||||
|
* DATA_BUS_WIDTH_32
|
||||||
|
- nc_auto_precharge: Non-concurrent auto-precharge; possible values:
|
||||||
|
* NCAP_DISABLE
|
||||||
|
* NCAP_ENABLE
|
||||||
|
- timing_2t: 2T timing; possible values:
|
||||||
|
* TIMING_1T
|
||||||
|
* TIMING_2T
|
||||||
|
- bank_interleaving_ctrl: Bank (chip select) interleaving control; possible
|
||||||
|
values:
|
||||||
|
* INTERLEAVE_NONE
|
||||||
|
* INTERLEAVE_1_AND_2
|
||||||
|
- precharge_bit_8: Precharge bin 8; possible values
|
||||||
|
* PRECHARGE_MA_10
|
||||||
|
* PRECHARGE_MA_8
|
||||||
|
- half_strength: Global half-strength override; possible values:
|
||||||
|
* STRENGTH_FULL
|
||||||
|
* STRENGTH_HALF
|
||||||
|
- bypass_initialization: Bypass initialization; possible values:
|
||||||
|
* INITIALIZATION_DONT_BYPASS
|
||||||
|
* INITIALIZATION_BYPASS
|
||||||
|
- force_self_refresh: Force self refresh; possible values:
|
||||||
|
* MODE_NORMAL
|
||||||
|
* MODE_REFRESH
|
||||||
|
- dll_reset: DLL reset; possible values:
|
||||||
|
* DLL_RESET_ENABLE
|
||||||
|
* DLL_RESET_DISABLE
|
||||||
|
- dqs_config: DQS configuration; possible values:
|
||||||
|
* DQS_TRUE
|
||||||
|
- odt_config: ODT configuration; possible values:
|
||||||
|
* ODT_ASSERT_NEVER
|
||||||
|
* ODT_ASSERT_WRITES
|
||||||
|
* ODT_ASSERT_READS
|
||||||
|
* ODT_ASSERT_ALWAYS
|
||||||
|
- posted_refreshes: Number of posted refreshes
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8
|
||||||
|
- sdmode: Initial value loaded into the DDR SDRAM mode
|
||||||
|
register
|
||||||
|
- esdmode: Initial value loaded into the DDR SDRAM extended
|
||||||
|
mode register
|
||||||
|
- esdmode2: Initial value loaded into the DDR SDRAM extended
|
||||||
|
mode 2 register
|
||||||
|
- esdmode3: Initial value loaded into the DDR SDRAM extended
|
||||||
|
mode 3 register
|
||||||
|
- refresh_interval: Refresh interval; possible values:
|
||||||
|
0 - 65535
|
||||||
|
- precharge_interval: Precharge interval; possible values:
|
||||||
|
0 - 16383
|
||||||
|
|
||||||
|
RAM module node:
|
||||||
|
================
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- reg: A triple <cs addr size>, which consists of:
|
||||||
|
* cs - the chipselect used to drive this RAM module
|
||||||
|
* addr - the address where this RAM module's memory is map
|
||||||
|
to in the global memory space
|
||||||
|
* size - the size of the RAM module's memory in bytes
|
||||||
|
- auto_precharge: Chip select auto-precharge; possible values:
|
||||||
|
* AUTO_PRECHARGE_ENABLE
|
||||||
|
* AUTO_PRECHARGE_DISABLE
|
||||||
|
- odt_rd_cfg: ODT for reads configuration; possible values:
|
||||||
|
* ODT_RD_NEVER
|
||||||
|
* ODT_RD_ONLY_CURRENT
|
||||||
|
* ODT_RD_ONLY_OTHER_CS
|
||||||
|
* ODT_RD_ONLY_OTHER_DIMM
|
||||||
|
* ODT_RD_ALL
|
||||||
|
- odt_wr_cfg: ODT for writes configuration; possible values:
|
||||||
|
* ODT_WR_NEVER
|
||||||
|
* ODT_WR_ONLY_CURRENT
|
||||||
|
* ODT_WR_ONLY_OTHER_CS
|
||||||
|
* ODT_WR_ONLY_OTHER_DIMM
|
||||||
|
* ODT_WR_ALL
|
||||||
|
- bank_bits: Number of bank bits for SDRAM on chip select; possible
|
||||||
|
values:
|
||||||
|
2, 3
|
||||||
|
- row_bits: Number of row bits for SDRAM on chip select; possible values:
|
||||||
|
12, 13, 14
|
||||||
|
- col_bits: Number of column bits for SDRAM on chip select; possible
|
||||||
|
values:
|
||||||
|
8, 9, 10, 11
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
memory@2000 {
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "fsl,mpc83xx-mem-controller";
|
||||||
|
reg = <0x2000 0x1000>;
|
||||||
|
device_type = "memory";
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
|
||||||
|
driver_software_override = <DSO_ENABLE>;
|
||||||
|
p_impedance_override = <DSO_P_IMPEDANCE_NOMINAL>;
|
||||||
|
n_impedance_override = <DSO_N_IMPEDANCE_NOMINAL>;
|
||||||
|
odt_termination_value = <ODT_TERMINATION_150_OHM>;
|
||||||
|
ddr_type = <DDR_TYPE_DDR2_1_8_VOLT>;
|
||||||
|
|
||||||
|
clock_adjust = <CLOCK_ADJUST_05>;
|
||||||
|
|
||||||
|
read_to_write = <0>;
|
||||||
|
write_to_read = <0>;
|
||||||
|
read_to_read = <0>;
|
||||||
|
write_to_write = <0>;
|
||||||
|
active_powerdown_exit = <2>;
|
||||||
|
precharge_powerdown_exit = <6>;
|
||||||
|
odt_powerdown_exit = <8>;
|
||||||
|
mode_reg_set_cycle = <2>;
|
||||||
|
|
||||||
|
precharge_to_activate = <2>;
|
||||||
|
activate_to_precharge = <6>;
|
||||||
|
activate_to_readwrite = <2>;
|
||||||
|
mcas_latency = <CASLAT_40>;
|
||||||
|
refresh_recovery = <17>;
|
||||||
|
last_data_to_precharge = <2>;
|
||||||
|
activate_to_activate = <2>;
|
||||||
|
last_write_data_to_read = <2>;
|
||||||
|
|
||||||
|
additive_latency = <0>;
|
||||||
|
mcas_to_preamble_override = <READ_LAT_PLUS_1_2>;
|
||||||
|
write_latency = <3>;
|
||||||
|
read_to_precharge = <2>;
|
||||||
|
write_cmd_to_write_data = <CLOCK_DELAY_1_2>;
|
||||||
|
minimum_cke_pulse_width = <3>;
|
||||||
|
four_activates_window = <5>;
|
||||||
|
|
||||||
|
self_refresh = <SREN_ENABLE>;
|
||||||
|
sdram_type = <TYPE_DDR2>;
|
||||||
|
databus_width = <DATA_BUS_WIDTH_32>;
|
||||||
|
|
||||||
|
force_self_refresh = <MODE_NORMAL>;
|
||||||
|
dll_reset = <DLL_RESET_ENABLE>;
|
||||||
|
dqs_config = <DQS_TRUE>;
|
||||||
|
odt_config = <ODT_ASSERT_READS>;
|
||||||
|
posted_refreshes = <1>;
|
||||||
|
|
||||||
|
refresh_interval = <2084>;
|
||||||
|
precharge_interval = <256>;
|
||||||
|
|
||||||
|
sdmode = <0x0242>;
|
||||||
|
esdmode = <0x0440>;
|
||||||
|
|
||||||
|
ram@0 {
|
||||||
|
reg = <0x0 0x0 0x8000000>;
|
||||||
|
compatible = "nanya,nt5tu64m16hg";
|
||||||
|
|
||||||
|
odt_rd_cfg = <ODT_RD_NEVER>;
|
||||||
|
odt_wr_cfg = <ODT_WR_ONLY_CURRENT>;
|
||||||
|
bank_bits = <3>;
|
||||||
|
row_bits = <13>;
|
||||||
|
col_bits = <10>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
MPC83xx timer devices
|
||||||
|
|
||||||
|
MPC83xx SoCs offer a decrementer interrupt that can be used to implement delay
|
||||||
|
functionality, and periodically triggered actions.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: must be "fsl,mpc83xx-timer"
|
||||||
|
- clocks: must be a reference to the system's CSB (coherent system bus) clock,
|
||||||
|
provided by one of the "fsl,mpc83xx-clk" devices
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
socclocks: clocks {
|
||||||
|
compatible = "fsl,mpc832x-clk";
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
timer {
|
||||||
|
compatible = "fsl,mpc83xx-timer";
|
||||||
|
clocks = <&socclocks MPC83XX_CLK_CSB>;
|
||||||
|
};
|
11
MAINTAINERS
11
MAINTAINERS
|
@ -519,6 +519,17 @@ POWERPC MPC83XX
|
||||||
M: Mario Six <mario.six@gdsys.cc>
|
M: Mario Six <mario.six@gdsys.cc>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.denx.de/u-boot-mpc83xx.git
|
T: git git://git.denx.de/u-boot-mpc83xx.git
|
||||||
|
F: drivers/ram/mpc83xx_sdram.c
|
||||||
|
F: include/dt-bindings/memory/mpc83xx-sdram.h
|
||||||
|
F: drivers/sysreset/sysreset_mpc83xx.c
|
||||||
|
F: drivers/sysreset/sysreset_mpc83xx.h
|
||||||
|
F: drivers/clk/mpc83xx_clk.c
|
||||||
|
F: drivers/clk/mpc83xx_clk.h
|
||||||
|
F: include/dt-bindings/clk/mpc83xx-clk.h
|
||||||
|
F: drivers/timer/mpc83xx_timer.c
|
||||||
|
F: drivers/cpu/mpc83xx_cpu.c
|
||||||
|
F: drivers/cpu/mpc83xx_cpu.h
|
||||||
|
F: drivers/misc/mpc83xx_serdes.c
|
||||||
F: arch/powerpc/cpu/mpc83xx/
|
F: arch/powerpc/cpu/mpc83xx/
|
||||||
F: arch/powerpc/include/asm/arch-mpc83xx/
|
F: arch/powerpc/include/asm/arch-mpc83xx/
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ config SANDBOX
|
||||||
select LZO
|
select LZO
|
||||||
select SPI
|
select SPI
|
||||||
select SUPPORT_OF_CONTROL
|
select SUPPORT_OF_CONTROL
|
||||||
|
imply BITREVERSE
|
||||||
imply CMD_DM
|
imply CMD_DM
|
||||||
imply CMD_GETTIME
|
imply CMD_GETTIME
|
||||||
imply CMD_HASH
|
imply CMD_HASH
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
#ifndef CONFIG_CPU_MPC83XX
|
||||||
int checkcpu(void)
|
int checkcpu(void)
|
||||||
{
|
{
|
||||||
volatile immap_t *immr;
|
volatile immap_t *immr;
|
||||||
|
@ -114,7 +115,9 @@ int checkcpu(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_SYSRESET
|
||||||
int
|
int
|
||||||
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
|
@ -169,17 +172,17 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get timebase clock frequency (like cpu_clk in Hz)
|
* Get timebase clock frequency (like cpu_clk in Hz)
|
||||||
*/
|
*/
|
||||||
|
#ifndef CONFIG_TIMER
|
||||||
unsigned long get_tbclk(void)
|
unsigned long get_tbclk(void)
|
||||||
{
|
{
|
||||||
return (gd->bus_clk + 3L) / 4L;
|
return (gd->bus_clk + 3L) / 4L;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_WATCHDOG)
|
#if defined(CONFIG_WATCHDOG)
|
||||||
void watchdog_reset (void)
|
void watchdog_reset (void)
|
||||||
|
|
|
@ -464,6 +464,7 @@ static int print_83xx_arb_event(int force)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DISPLAY_AER_xxxx */
|
#endif /* CONFIG_DISPLAY_AER_xxxx */
|
||||||
|
|
||||||
|
#ifndef CONFIG_CPU_MPC83XX
|
||||||
/*
|
/*
|
||||||
* Figure out the cause of the reset
|
* Figure out the cause of the reset
|
||||||
*/
|
*/
|
||||||
|
@ -505,3 +506,4 @@ int prt_83xx_rsr(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
* Author: Li Yang <leoli@freescale.com>
|
* Author: Li Yang <leoli@freescale.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_SERDES
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -148,3 +150,5 @@ void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd)
|
||||||
tmp |= FSL_SRDSRSTCTL_RST;
|
tmp |= FSL_SRDSRSTCTL_RST;
|
||||||
out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
|
out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !CONFIG_MPC83XX_SERDES */
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* Xianghua Xiao (X.Xiao@motorola.com)
|
* Xianghua Xiao (X.Xiao@motorola.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_SDRAM
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -924,3 +926,5 @@ void ddr_enable_ecc(unsigned int dram_size)
|
||||||
__asm__ __volatile__ ("isync");
|
__asm__ __volatile__ ("isync");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DDR_ECC */
|
#endif /* CONFIG_DDR_ECC */
|
||||||
|
|
||||||
|
#endif /* !CONFIG_MPC83XX_SDRAM */
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
|
* Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_CLK_MPC83XX
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <mpc83xx.h>
|
#include <mpc83xx.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
@ -590,3 +592,5 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
|
||||||
"print clock configuration",
|
"print clock configuration",
|
||||||
" clocks"
|
" clocks"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
74
arch/powerpc/include/asm/arch-mpc83xx/soc.h
Normal file
74
arch/powerpc/include/asm/arch-mpc83xx/soc.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MPC83XX_SOC_H_
|
||||||
|
#define _MPC83XX_SOC_H_
|
||||||
|
|
||||||
|
enum soc_type {
|
||||||
|
SOC_MPC8308,
|
||||||
|
SOC_MPC8309,
|
||||||
|
SOC_MPC8313,
|
||||||
|
SOC_MPC8315,
|
||||||
|
SOC_MPC832X,
|
||||||
|
SOC_MPC8349,
|
||||||
|
SOC_MPC8360,
|
||||||
|
SOC_MPC8379,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool mpc83xx_has_sdhc(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8308) ||
|
||||||
|
(type == SOC_MPC8309) ||
|
||||||
|
(type == SOC_MPC8379);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_tsec(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8308) ||
|
||||||
|
(type == SOC_MPC8313) ||
|
||||||
|
(type == SOC_MPC8315) ||
|
||||||
|
(type == SOC_MPC8349) ||
|
||||||
|
(type == SOC_MPC8379);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_pcie1(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8308) ||
|
||||||
|
(type == SOC_MPC8315) ||
|
||||||
|
(type == SOC_MPC8379);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_pcie2(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8315) ||
|
||||||
|
(type == SOC_MPC8379);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_sata(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8315) ||
|
||||||
|
(type == SOC_MPC8379);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_pci(int type)
|
||||||
|
{
|
||||||
|
return type != SOC_MPC8308;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_second_i2c(int type)
|
||||||
|
{
|
||||||
|
return (type != SOC_MPC8315) &&
|
||||||
|
(type != SOC_MPC832X);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mpc83xx_has_quicc_engine(int type)
|
||||||
|
{
|
||||||
|
return (type == SOC_MPC8309) ||
|
||||||
|
(type == SOC_MPC832X) ||
|
||||||
|
(type == SOC_MPC8360);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _MPC83XX_SOC_H_ */
|
|
@ -75,7 +75,7 @@
|
||||||
/* All PPC boards must swap IDE bytes */
|
/* All PPC boards must swap IDE bytes */
|
||||||
#define CONFIG_IDE_SWAP_IO
|
#define CONFIG_IDE_SWAP_IO
|
||||||
|
|
||||||
#if defined(CONFIG_DM_SERIAL)
|
#if defined(CONFIG_DM_SERIAL) && !defined(CONFIG_CLK_MPC83XX)
|
||||||
/*
|
/*
|
||||||
* TODO: Convert this to a clock driver exists that can give us the UART
|
* TODO: Convert this to a clock driver exists that can give us the UART
|
||||||
* clock here.
|
* clock here.
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#ifndef __FSL_MPC83XX_SERDES_H
|
#ifndef __FSL_MPC83XX_SERDES_H
|
||||||
#define __FSL_MPC83XX_SERDES_H
|
#define __FSL_MPC83XX_SERDES_H
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_SERDES
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#define FSL_SERDES_CLK_100 (0 << 28)
|
#define FSL_SERDES_CLK_100 (0 << 28)
|
||||||
|
@ -19,4 +21,6 @@
|
||||||
|
|
||||||
extern void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd);
|
extern void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd);
|
||||||
|
|
||||||
|
#endif /* !CONFIG_MPC83XX_SERDES */
|
||||||
|
|
||||||
#endif /* __FSL_MPC83XX_SERDES_H */
|
#endif /* __FSL_MPC83XX_SERDES_H */
|
||||||
|
|
|
@ -30,6 +30,9 @@ struct arch_global_data {
|
||||||
#endif
|
#endif
|
||||||
/* TODO: sjg@chromium.org: Should these be unslgned long? */
|
/* TODO: sjg@chromium.org: Should these be unslgned long? */
|
||||||
#if defined(CONFIG_MPC83xx)
|
#if defined(CONFIG_MPC83xx)
|
||||||
|
#ifdef CONFIG_CLK_MPC83XX
|
||||||
|
u32 core_clk;
|
||||||
|
#else
|
||||||
/* There are other clocks in the MPC83XX */
|
/* There are other clocks in the MPC83XX */
|
||||||
u32 csb_clk;
|
u32 csb_clk;
|
||||||
# if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
|
# if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
|
||||||
|
@ -62,6 +65,7 @@ struct arch_global_data {
|
||||||
u32 mem_sec_clk;
|
u32 mem_sec_clk;
|
||||||
# endif /* CONFIG_MPC8360 */
|
# endif /* CONFIG_MPC8360 */
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
|
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
|
||||||
u32 lbc_clk;
|
u32 lbc_clk;
|
||||||
void *cpu;
|
void *cpu;
|
||||||
|
|
|
@ -282,6 +282,24 @@ static inline void out_be32(volatile unsigned __iomem *addr, u32 val)
|
||||||
#define setbits_8(addr, set) setbits(8, addr, set)
|
#define setbits_8(addr, set) setbits(8, addr, set)
|
||||||
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
|
#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
|
||||||
|
|
||||||
|
#define readb_be(addr) \
|
||||||
|
__raw_readb((__force unsigned *)(addr))
|
||||||
|
#define readw_be(addr) \
|
||||||
|
be16_to_cpu(__raw_readw((__force unsigned *)(addr)))
|
||||||
|
#define readl_be(addr) \
|
||||||
|
be32_to_cpu(__raw_readl((__force unsigned *)(addr)))
|
||||||
|
#define readq_be(addr) \
|
||||||
|
be64_to_cpu(__raw_readq((__force unsigned *)(addr)))
|
||||||
|
|
||||||
|
#define writeb_be(val, addr) \
|
||||||
|
__raw_writeb((val), (__force unsigned *)(addr))
|
||||||
|
#define writew_be(val, addr) \
|
||||||
|
__raw_writew(cpu_to_be16((val)), (__force unsigned *)(addr))
|
||||||
|
#define writel_be(val, addr) \
|
||||||
|
__raw_writel(cpu_to_be32((val)), (__force unsigned *)(addr))
|
||||||
|
#define writeq_be(val, addr) \
|
||||||
|
__raw_writeq(cpu_to_be64((val)), (__force unsigned *)(addr))
|
||||||
|
|
||||||
static inline void *phys_to_virt(phys_addr_t paddr)
|
static inline void *phys_to_virt(phys_addr_t paddr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ADDR_MAP
|
#ifdef CONFIG_ADDR_MAP
|
||||||
|
|
|
@ -1325,7 +1325,9 @@ void ll_puts(const char *);
|
||||||
/* In misc.c */
|
/* In misc.c */
|
||||||
void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
|
void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
|
||||||
|
|
||||||
|
#ifndef CONFIG_CPU_MPC83XX
|
||||||
int prt_83xx_rsr(void);
|
int prt_83xx_rsr(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* ndef ASSEMBLY*/
|
#endif /* ndef ASSEMBLY*/
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,17 @@ endif
|
||||||
|
|
||||||
ifdef MINIMAL
|
ifdef MINIMAL
|
||||||
obj-y += cache.o time.o
|
obj-y += cache.o time.o
|
||||||
|
ifndef CONFIG_TIMER
|
||||||
obj-y += ticks.o
|
obj-y += ticks.o
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
|
|
||||||
obj-y += ppcstring.o
|
obj-y += ppcstring.o
|
||||||
|
|
||||||
obj-y += ppccache.o
|
obj-y += ppccache.o
|
||||||
|
ifndef CONFIG_TIMER
|
||||||
obj-y += ticks.o
|
obj-y += ticks.o
|
||||||
|
endif
|
||||||
obj-y += reloc.o
|
obj-y += reloc.o
|
||||||
|
|
||||||
obj-$(CONFIG_BAT_RW) += bat_rw.o
|
obj-$(CONFIG_BAT_RW) += bat_rw.o
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <status_led.h>
|
#include <status_led.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_TIMER
|
||||||
#ifdef CONFIG_SHOW_ACTIVITY
|
#ifdef CONFIG_SHOW_ACTIVITY
|
||||||
void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
|
void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ static __inline__ void set_dec (unsigned long val)
|
||||||
if (val)
|
if (val)
|
||||||
asm volatile ("mtdec %0"::"r" (val));
|
asm volatile ("mtdec %0"::"r" (val));
|
||||||
}
|
}
|
||||||
|
#endif /* !CONFIG_MPC83XX_TIMER */
|
||||||
|
|
||||||
void enable_interrupts (void)
|
void enable_interrupts (void)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +61,7 @@ int disable_interrupts (void)
|
||||||
return ((msr & MSR_EE) != 0);
|
return ((msr & MSR_EE) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_TIMER
|
||||||
int interrupt_init (void)
|
int interrupt_init (void)
|
||||||
{
|
{
|
||||||
/* call cpu specific function from $(CPU)/interrupts.c */
|
/* call cpu specific function from $(CPU)/interrupts.c */
|
||||||
|
@ -102,3 +104,4 @@ ulong get_timer (ulong base)
|
||||||
{
|
{
|
||||||
return (timestamp - base);
|
return (timestamp - base);
|
||||||
}
|
}
|
||||||
|
#endif /* !CONFIG_MPC83XX_TIMER */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
|
PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
|
||||||
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
|
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
|
||||||
|
PLATFORM_CPPFLAGS += -fPIC
|
||||||
PLATFORM_LIBS += -lrt
|
PLATFORM_LIBS += -lrt
|
||||||
|
|
||||||
# Define this to avoid linking with SDL, which requires SDL libraries
|
# Define this to avoid linking with SDL, which requires SDL libraries
|
||||||
|
|
|
@ -297,6 +297,18 @@
|
||||||
mbox-names = "other", "test";
|
mbox-names = "other", "test";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cpu-test1 {
|
||||||
|
compatible = "sandbox,cpu_sandbox";
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu-test2 {
|
||||||
|
compatible = "sandbox,cpu_sandbox";
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu-test3 {
|
||||||
|
compatible = "sandbox,cpu_sandbox";
|
||||||
|
};
|
||||||
|
|
||||||
misc-test {
|
misc-test {
|
||||||
compatible = "sandbox,misc_sandbox";
|
compatible = "sandbox,misc_sandbox";
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,8 +11,9 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
#include <environment.h>
|
#include <cpu.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <environment.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
#include <relocate.h>
|
#include <relocate.h>
|
||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
#include <status_led.h>
|
#include <status_led.h>
|
||||||
|
#include <sysreset.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <trace.h>
|
#include <trace.h>
|
||||||
#include <video.h>
|
#include <video.h>
|
||||||
|
@ -140,6 +142,57 @@ static int display_text_info(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSRESET
|
||||||
|
static int print_resetinfo(void)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
char status[256];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uclass_first_device_err(UCLASS_SYSRESET, &dev);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: No sysreset device found (error: %d)\n",
|
||||||
|
__func__, ret);
|
||||||
|
/* Not all boards have sysreset drivers available during early
|
||||||
|
* boot, so don't fail if one can't be found.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sysreset_get_status(dev, status, sizeof(status)))
|
||||||
|
printf("%s", status);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_DISPLAY_CPUINFO) && CONFIG_IS_ENABLED(CPU)
|
||||||
|
static int print_cpuinfo(void)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
char desc[512];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uclass_first_device_err(UCLASS_CPU, &dev);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not get CPU device (err = %d)\n",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cpu_get_desc(dev, desc, sizeof(desc));
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not get CPU description (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s", desc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int announce_dram_init(void)
|
static int announce_dram_init(void)
|
||||||
{
|
{
|
||||||
puts("DRAM: ");
|
puts("DRAM: ");
|
||||||
|
@ -790,6 +843,9 @@ static const init_fnc_t init_sequence_f[] = {
|
||||||
#if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
|
#if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
|
||||||
checkcpu,
|
checkcpu,
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_SYSRESET)
|
||||||
|
print_resetinfo,
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||||
print_cpuinfo, /* display cpu info (and speed) */
|
print_cpuinfo, /* display cpu info (and speed) */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,4 +107,10 @@ config ICS8N3QV01
|
||||||
Crystal Oscillator). The output frequency can be programmed via an
|
Crystal Oscillator). The output frequency can be programmed via an
|
||||||
I2C interface.
|
I2C interface.
|
||||||
|
|
||||||
|
config CLK_MPC83XX
|
||||||
|
bool "Enable MPC83xx clock driver"
|
||||||
|
depends on CLK
|
||||||
|
help
|
||||||
|
Support for the clock driver of the MPC83xx series of SoCs.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -18,6 +18,7 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
|
||||||
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
|
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
|
||||||
obj-$(CONFIG_CLK_EXYNOS) += exynos/
|
obj-$(CONFIG_CLK_EXYNOS) += exynos/
|
||||||
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
|
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
|
||||||
|
obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
|
||||||
obj-$(CONFIG_CLK_OWL) += owl/
|
obj-$(CONFIG_CLK_OWL) += owl/
|
||||||
obj-$(CONFIG_CLK_RENESAS) += renesas/
|
obj-$(CONFIG_CLK_RENESAS) += renesas/
|
||||||
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
|
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
|
||||||
|
|
410
drivers/clk/mpc83xx_clk.c
Normal file
410
drivers/clk/mpc83xx_clk.c
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2017
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <clk-uclass.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <dm/lists.h>
|
||||||
|
#include <dt-bindings/clk/mpc83xx-clk.h>
|
||||||
|
#include <asm/arch/soc.h>
|
||||||
|
|
||||||
|
#include "mpc83xx_clk.h"
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mpc83xx_clk_priv - Private data structure for the MPC83xx clock
|
||||||
|
* driver
|
||||||
|
* @speed: Array containing the speed values of all system clocks (initialized
|
||||||
|
* once, then only read back)
|
||||||
|
*/
|
||||||
|
struct mpc83xx_clk_priv {
|
||||||
|
u32 speed[MPC83XX_CLK_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_clk_valid() - Check if clock ID is valid for given clock device
|
||||||
|
* @clk: The clock device for which to check a clock ID
|
||||||
|
* @id: The clock ID to check
|
||||||
|
*
|
||||||
|
* Return: true if clock ID is valid for clock device, false if not
|
||||||
|
*/
|
||||||
|
static inline bool is_clk_valid(struct udevice *clk, int id)
|
||||||
|
{
|
||||||
|
ulong type = dev_get_driver_data(clk);
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case MPC83XX_CLK_MEM:
|
||||||
|
return true;
|
||||||
|
case MPC83XX_CLK_MEM_SEC:
|
||||||
|
return type == SOC_MPC8360;
|
||||||
|
case MPC83XX_CLK_ENC:
|
||||||
|
return (type == SOC_MPC8308) || (type == SOC_MPC8309);
|
||||||
|
case MPC83XX_CLK_I2C1:
|
||||||
|
return true;
|
||||||
|
case MPC83XX_CLK_TDM:
|
||||||
|
return type == SOC_MPC8315;
|
||||||
|
case MPC83XX_CLK_SDHC:
|
||||||
|
return mpc83xx_has_sdhc(type);
|
||||||
|
case MPC83XX_CLK_TSEC1:
|
||||||
|
case MPC83XX_CLK_TSEC2:
|
||||||
|
return mpc83xx_has_tsec(type);
|
||||||
|
case MPC83XX_CLK_USBDR:
|
||||||
|
return type == SOC_MPC8360;
|
||||||
|
case MPC83XX_CLK_USBMPH:
|
||||||
|
return type == SOC_MPC8349;
|
||||||
|
case MPC83XX_CLK_PCIEXP1:
|
||||||
|
return mpc83xx_has_pcie1(type);
|
||||||
|
case MPC83XX_CLK_PCIEXP2:
|
||||||
|
return mpc83xx_has_pcie2(type);
|
||||||
|
case MPC83XX_CLK_SATA:
|
||||||
|
return mpc83xx_has_sata(type);
|
||||||
|
case MPC83XX_CLK_DMAC:
|
||||||
|
return (type == SOC_MPC8308) || (type == SOC_MPC8309);
|
||||||
|
case MPC83XX_CLK_PCI:
|
||||||
|
return mpc83xx_has_pci(type);
|
||||||
|
case MPC83XX_CLK_CSB:
|
||||||
|
return true;
|
||||||
|
case MPC83XX_CLK_I2C2:
|
||||||
|
return mpc83xx_has_second_i2c(type);
|
||||||
|
case MPC83XX_CLK_QE:
|
||||||
|
case MPC83XX_CLK_BRG:
|
||||||
|
return mpc83xx_has_quicc_engine(type) && (type != SOC_MPC8309);
|
||||||
|
case MPC83XX_CLK_LCLK:
|
||||||
|
case MPC83XX_CLK_LBIU:
|
||||||
|
case MPC83XX_CLK_CORE:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init_single_clk() - Initialize a clock with a given ID
|
||||||
|
* @dev: The clock device for which to initialize the clock
|
||||||
|
* @clk: The clock ID
|
||||||
|
*
|
||||||
|
* The clock speed is read from the hardware's registers, and stored in the
|
||||||
|
* private data structure of the driver. From there it is only retrieved, and
|
||||||
|
* not set.
|
||||||
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
static int init_single_clk(struct udevice *dev, int clk)
|
||||||
|
{
|
||||||
|
struct mpc83xx_clk_priv *priv = dev_get_priv(dev);
|
||||||
|
immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
|
||||||
|
ulong type = dev_get_driver_data(dev);
|
||||||
|
struct clk_mode mode;
|
||||||
|
ulong mask;
|
||||||
|
u32 csb_clk = get_csb_clk(im);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = retrieve_mode(clk, type, &mode);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not retrieve mode for clk %d (ret = %d)\n",
|
||||||
|
dev->name, clk, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.type == TYPE_INVALID) {
|
||||||
|
debug("%s: clock %d invalid\n", dev->name, clk);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.type == TYPE_SCCR_STANDARD) {
|
||||||
|
mask = GENMASK(31 - mode.low, 31 - mode.high);
|
||||||
|
|
||||||
|
switch (sccr_field(im, mask)) {
|
||||||
|
case 0:
|
||||||
|
priv->speed[clk] = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
priv->speed[clk] = csb_clk;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
priv->speed[clk] = csb_clk / 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
priv->speed[clk] = csb_clk / 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priv->speed[clk] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.type == TYPE_SPMR_DIRECT_MULTIPLY) {
|
||||||
|
mask = GENMASK(31 - mode.low, 31 - mode.high);
|
||||||
|
|
||||||
|
priv->speed[clk] = csb_clk * (1 + sccr_field(im, mask));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_CSB || clk == MPC83XX_CLK_I2C2) {
|
||||||
|
priv->speed[clk] = csb_clk; /* i2c-2 clk is equal to csb clk */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_QE || clk == MPC83XX_CLK_BRG) {
|
||||||
|
u32 pci_sync_in = get_pci_sync_in(im);
|
||||||
|
u32 qepmf = spmr_field(im, SPMR_CEPMF);
|
||||||
|
u32 qepdf = spmr_field(im, SPMR_CEPDF);
|
||||||
|
u32 qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_QE)
|
||||||
|
priv->speed[clk] = qe_clk;
|
||||||
|
else
|
||||||
|
priv->speed[clk] = qe_clk / 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_LCLK || clk == MPC83XX_CLK_LBIU) {
|
||||||
|
u32 lbiu_clk = csb_clk *
|
||||||
|
(1 + spmr_field(im, SPMR_LBIUCM));
|
||||||
|
u32 clkdiv = lcrr_field(im, LCRR_CLKDIV);
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_LBIU)
|
||||||
|
priv->speed[clk] = lbiu_clk;
|
||||||
|
|
||||||
|
switch (clkdiv) {
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
priv->speed[clk] = lbiu_clk / clkdiv;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unknown lcrr */
|
||||||
|
priv->speed[clk] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clk == MPC83XX_CLK_CORE) {
|
||||||
|
u8 corepll = spmr_field(im, SPMR_COREPLL);
|
||||||
|
u32 corecnf_tab_index = ((corepll & 0x1F) << 2) |
|
||||||
|
((corepll & 0x60) >> 5);
|
||||||
|
|
||||||
|
if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
|
||||||
|
debug("%s: Core configuration index %02x too high; possible wrong value",
|
||||||
|
dev->name, corecnf_tab_index);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
|
||||||
|
case RAT_BYP:
|
||||||
|
case RAT_1_TO_1:
|
||||||
|
priv->speed[clk] = csb_clk;
|
||||||
|
break;
|
||||||
|
case RAT_1_5_TO_1:
|
||||||
|
priv->speed[clk] = (3 * csb_clk) / 2;
|
||||||
|
break;
|
||||||
|
case RAT_2_TO_1:
|
||||||
|
priv->speed[clk] = 2 * csb_clk;
|
||||||
|
break;
|
||||||
|
case RAT_2_5_TO_1:
|
||||||
|
priv->speed[clk] = (5 * csb_clk) / 2;
|
||||||
|
break;
|
||||||
|
case RAT_3_TO_1:
|
||||||
|
priv->speed[clk] = 3 * csb_clk;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unknown core to csb ratio */
|
||||||
|
priv->speed[clk] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown clk value -> error */
|
||||||
|
debug("%s: clock %d invalid\n", dev->name, clk);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init_all_clks() - Initialize all clocks of a clock device
|
||||||
|
* @dev: The clock device whose clocks should be initialized
|
||||||
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
static inline int init_all_clks(struct udevice *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!is_clk_valid(dev, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = init_single_clk(dev, i);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Failed to initialize %s clock\n",
|
||||||
|
dev->name, names[i]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_clk_request(struct clk *clock)
|
||||||
|
{
|
||||||
|
/* Reject requests of clocks that are not available */
|
||||||
|
if (is_clk_valid(clock->dev, clock->id))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong mpc83xx_clk_get_rate(struct clk *clk)
|
||||||
|
{
|
||||||
|
struct mpc83xx_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
|
|
||||||
|
if (clk->id >= MPC83XX_CLK_COUNT) {
|
||||||
|
debug("%s: clock index %lu invalid\n", __func__, clk->id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv->speed[clk->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_clocks(void)
|
||||||
|
{
|
||||||
|
/* Empty implementation to keep the prototype in common.h happy */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_serial_clock(void)
|
||||||
|
{
|
||||||
|
struct mpc83xx_clk_priv *priv;
|
||||||
|
struct udevice *clk;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uclass_first_device_err(UCLASS_CLK, &clk);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not get clock device\n", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = dev_get_priv(clk);
|
||||||
|
|
||||||
|
return priv->speed[MPC83XX_CLK_CSB];
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct clk_ops mpc83xx_clk_ops = {
|
||||||
|
.request = mpc83xx_clk_request,
|
||||||
|
.get_rate = mpc83xx_clk_get_rate,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id mpc83xx_clk_match[] = {
|
||||||
|
{ .compatible = "fsl,mpc8308-clk", .data = SOC_MPC8308 },
|
||||||
|
{ .compatible = "fsl,mpc8309-clk", .data = SOC_MPC8309 },
|
||||||
|
{ .compatible = "fsl,mpc8313-clk", .data = SOC_MPC8313 },
|
||||||
|
{ .compatible = "fsl,mpc8315-clk", .data = SOC_MPC8315 },
|
||||||
|
{ .compatible = "fsl,mpc832x-clk", .data = SOC_MPC832X },
|
||||||
|
{ .compatible = "fsl,mpc8349-clk", .data = SOC_MPC8349 },
|
||||||
|
{ .compatible = "fsl,mpc8360-clk", .data = SOC_MPC8360 },
|
||||||
|
{ .compatible = "fsl,mpc8379-clk", .data = SOC_MPC8379 },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mpc83xx_clk_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_clk_priv *priv = dev_get_priv(dev);
|
||||||
|
ulong type;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = init_all_clks(dev);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not initialize all clocks (ret = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = dev_get_driver_data(dev);
|
||||||
|
|
||||||
|
if (mpc83xx_has_sdhc(type))
|
||||||
|
gd->arch.sdhc_clk = priv->speed[MPC83XX_CLK_SDHC];
|
||||||
|
|
||||||
|
gd->arch.core_clk = priv->speed[MPC83XX_CLK_CORE];
|
||||||
|
gd->arch.i2c1_clk = priv->speed[MPC83XX_CLK_I2C1];
|
||||||
|
if (mpc83xx_has_second_i2c(type))
|
||||||
|
gd->arch.i2c2_clk = priv->speed[MPC83XX_CLK_I2C2];
|
||||||
|
|
||||||
|
gd->mem_clk = priv->speed[MPC83XX_CLK_MEM];
|
||||||
|
|
||||||
|
if (mpc83xx_has_pci(type))
|
||||||
|
gd->pci_clk = priv->speed[MPC83XX_CLK_PCI];
|
||||||
|
|
||||||
|
gd->cpu_clk = priv->speed[MPC83XX_CLK_CORE];
|
||||||
|
gd->bus_clk = priv->speed[MPC83XX_CLK_CSB];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_clk_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct udevice *sys_child;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since there is no corresponding device tree entry, and since the
|
||||||
|
* clock driver has to be present in either case, bind the sysreset
|
||||||
|
* driver here.
|
||||||
|
*/
|
||||||
|
ret = device_bind_driver(dev, "mpc83xx_sysreset", "sysreset",
|
||||||
|
&sys_child);
|
||||||
|
if (ret)
|
||||||
|
debug("%s: No sysreset driver: ret=%d\n",
|
||||||
|
dev->name, ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(mpc83xx_clk) = {
|
||||||
|
.name = "mpc83xx_clk",
|
||||||
|
.id = UCLASS_CLK,
|
||||||
|
.of_match = mpc83xx_clk_match,
|
||||||
|
.ops = &mpc83xx_clk_ops,
|
||||||
|
.probe = mpc83xx_clk_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mpc83xx_clk_priv),
|
||||||
|
.bind = mpc83xx_clk_bind,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char buf[32];
|
||||||
|
struct udevice *clk;
|
||||||
|
int ret;
|
||||||
|
struct mpc83xx_clk_priv *priv;
|
||||||
|
|
||||||
|
ret = uclass_first_device_err(UCLASS_CLK, &clk);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not get clock device\n", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
|
||||||
|
if (!is_clk_valid(clk, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
priv = dev_get_priv(clk);
|
||||||
|
|
||||||
|
printf("%s = %s MHz\n", names[i], strmhz(buf, priv->speed[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_BOOT_CMD(clocks, 1, 1, do_clocks,
|
||||||
|
"display values of SoC's clocks",
|
||||||
|
""
|
||||||
|
);
|
379
drivers/clk/mpc83xx_clk.h
Normal file
379
drivers/clk/mpc83xx_clk.h
Normal file
|
@ -0,0 +1,379 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum ratio - Description of a core clock ratio
|
||||||
|
* @RAT_UNK: Unknown ratio
|
||||||
|
* @RAT_BYP: Bypass
|
||||||
|
* @RAT_1_TO_8: Ratio 1:8
|
||||||
|
* @RAT_1_TO_4: Ratio 1:4
|
||||||
|
* @RAT_1_TO_2: Ratio 1:2
|
||||||
|
* @RAT_1_TO_1: Ratio 1:1
|
||||||
|
* @RAT_1_5_TO_1: Ratio 1.5:1
|
||||||
|
* @RAT_2_TO_1: Ratio 2:1
|
||||||
|
* @RAT_2_5_TO_1: Ratio 2.5:1
|
||||||
|
* @RAT_3_TO_1: Ratio 3:1
|
||||||
|
*/
|
||||||
|
enum ratio {
|
||||||
|
RAT_UNK,
|
||||||
|
RAT_BYP,
|
||||||
|
RAT_1_TO_8,
|
||||||
|
RAT_1_TO_4,
|
||||||
|
RAT_1_TO_2,
|
||||||
|
RAT_1_TO_1,
|
||||||
|
RAT_1_5_TO_1,
|
||||||
|
RAT_2_TO_1,
|
||||||
|
RAT_2_5_TO_1,
|
||||||
|
RAT_3_TO_1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct corecnf - Description for a core clock configuration
|
||||||
|
* @core_csb_ratio: Core clock frequency to CSB clock frequency ratio
|
||||||
|
* @vco_divider: VCO divider (Core VCO frequency = Core frequency * VCO divider)
|
||||||
|
*/
|
||||||
|
struct corecnf {
|
||||||
|
int core_csb_ratio;
|
||||||
|
int vco_divider;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table with all valid Core CSB frequency ratio / VCO divider combinations as
|
||||||
|
* indexed by the COREPLL field of the SPMR
|
||||||
|
*/
|
||||||
|
static const struct corecnf corecnf_tab[] = {
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x00 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x01 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x02 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x03 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x04 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x05 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x06 */
|
||||||
|
{RAT_BYP, RAT_BYP}, /* 0x07 */
|
||||||
|
{RAT_1_TO_1, RAT_1_TO_2}, /* 0x08 */
|
||||||
|
{RAT_1_TO_1, RAT_1_TO_4}, /* 0x09 */
|
||||||
|
{RAT_1_TO_1, RAT_1_TO_8}, /* 0x0A */
|
||||||
|
{RAT_1_TO_1, RAT_1_TO_8}, /* 0x0B */
|
||||||
|
{RAT_1_5_TO_1, RAT_1_TO_2}, /* 0x0C */
|
||||||
|
{RAT_1_5_TO_1, RAT_1_TO_4}, /* 0x0D */
|
||||||
|
{RAT_1_5_TO_1, RAT_1_TO_8}, /* 0x0E */
|
||||||
|
{RAT_1_5_TO_1, RAT_1_TO_8}, /* 0x0F */
|
||||||
|
{RAT_2_TO_1, RAT_1_TO_2}, /* 0x10 */
|
||||||
|
{RAT_2_TO_1, RAT_1_TO_4}, /* 0x11 */
|
||||||
|
{RAT_2_TO_1, RAT_1_TO_8}, /* 0x12 */
|
||||||
|
{RAT_2_TO_1, RAT_1_TO_8}, /* 0x13 */
|
||||||
|
{RAT_2_5_TO_1, RAT_1_TO_2}, /* 0x14 */
|
||||||
|
{RAT_2_5_TO_1, RAT_1_TO_4}, /* 0x15 */
|
||||||
|
{RAT_2_5_TO_1, RAT_1_TO_8}, /* 0x16 */
|
||||||
|
{RAT_2_5_TO_1, RAT_1_TO_8}, /* 0x17 */
|
||||||
|
{RAT_3_TO_1, RAT_1_TO_2}, /* 0x18 */
|
||||||
|
{RAT_3_TO_1, RAT_1_TO_4}, /* 0x19 */
|
||||||
|
{RAT_3_TO_1, RAT_1_TO_8}, /* 0x1A */
|
||||||
|
{RAT_3_TO_1, RAT_1_TO_8}, /* 0x1B */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum reg_type - Register to read a field from
|
||||||
|
* @REG_SCCR: Use the SCCR register
|
||||||
|
* @REG_SPMR: Use the SPMR register
|
||||||
|
*/
|
||||||
|
enum reg_type {
|
||||||
|
REG_SCCR,
|
||||||
|
REG_SPMR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum mode_type - Description of how to read a specific frequency value
|
||||||
|
* @TYPE_INVALID: Unknown type, will provoke error
|
||||||
|
* @TYPE_SCCR_STANDARD: Read a field from the SCCR register, and use it
|
||||||
|
* as a divider for the CSB clock to compute the
|
||||||
|
* frequency
|
||||||
|
* @TYPE_SCCR_ONOFF: The field describes a bit flag that can turn the
|
||||||
|
* clock on or off
|
||||||
|
* @TYPE_SPMR_DIRECT_MULTIPLY: Read a field from the SPMR register, and use it
|
||||||
|
* as a multiplier for the CSB clock to compute the
|
||||||
|
* frequency
|
||||||
|
* @TYPE_SPECIAL: The frequency is calculated in a non-standard way
|
||||||
|
*/
|
||||||
|
enum mode_type {
|
||||||
|
TYPE_INVALID = 0,
|
||||||
|
TYPE_SCCR_STANDARD,
|
||||||
|
TYPE_SCCR_ONOFF,
|
||||||
|
TYPE_SPMR_DIRECT_MULTIPLY,
|
||||||
|
TYPE_SPECIAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Map of each clock index to its human-readable name */
|
||||||
|
static const char * const names[] = {
|
||||||
|
[MPC83XX_CLK_CORE] = "Core",
|
||||||
|
[MPC83XX_CLK_CSB] = "Coherent System Bus",
|
||||||
|
[MPC83XX_CLK_QE] = "QE",
|
||||||
|
[MPC83XX_CLK_BRG] = "BRG",
|
||||||
|
[MPC83XX_CLK_LBIU] = "Local Bus Controller",
|
||||||
|
[MPC83XX_CLK_LCLK] = "Local Bus",
|
||||||
|
[MPC83XX_CLK_MEM] = "DDR",
|
||||||
|
[MPC83XX_CLK_MEM_SEC] = "DDR Secondary",
|
||||||
|
[MPC83XX_CLK_ENC] = "SEC",
|
||||||
|
[MPC83XX_CLK_I2C1] = "I2C1",
|
||||||
|
[MPC83XX_CLK_I2C2] = "I2C2",
|
||||||
|
[MPC83XX_CLK_TDM] = "TDM",
|
||||||
|
[MPC83XX_CLK_SDHC] = "SDHC",
|
||||||
|
[MPC83XX_CLK_TSEC1] = "TSEC1",
|
||||||
|
[MPC83XX_CLK_TSEC2] = "TSEC2",
|
||||||
|
[MPC83XX_CLK_USBDR] = "USB DR",
|
||||||
|
[MPC83XX_CLK_USBMPH] = "USB MPH",
|
||||||
|
[MPC83XX_CLK_PCIEXP1] = "PCIEXP1",
|
||||||
|
[MPC83XX_CLK_PCIEXP2] = "PCIEXP2",
|
||||||
|
[MPC83XX_CLK_SATA] = "SATA",
|
||||||
|
[MPC83XX_CLK_DMAC] = "DMAC",
|
||||||
|
[MPC83XX_CLK_PCI] = "PCI",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct clk_mode - Structure for clock mode descriiptions
|
||||||
|
* @low: The low bit of the data field to read for this mode (may not apply to
|
||||||
|
* some modes)
|
||||||
|
* @high: The high bit of the data field to read for this mode (may not apply to
|
||||||
|
* some modes)
|
||||||
|
* @type: The type of the mode description (one of enum mode_type)
|
||||||
|
*/
|
||||||
|
struct clk_mode {
|
||||||
|
u8 low;
|
||||||
|
u8 high;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_mode() - Build a clock mode description from data
|
||||||
|
* @mode: The clock mode description to be filled out
|
||||||
|
* @low: The low bit of the data field to read for this mode (may not apply to
|
||||||
|
* some modes)
|
||||||
|
* @high: The high bit of the data field to read for this mode (may not apply to
|
||||||
|
* some modes)
|
||||||
|
* @type: The type of the mode description (one of enum mode_type)
|
||||||
|
*
|
||||||
|
* Clock mode descriptions are a succinct description of how to read a specific
|
||||||
|
* clock's rate from the hardware; usually by reading a specific field of a
|
||||||
|
* register, such a s the SCCR register, but some types use different methods
|
||||||
|
* for obtaining the clock rate.
|
||||||
|
*/
|
||||||
|
static void set_mode(struct clk_mode *mode, u8 low, u8 high, int type)
|
||||||
|
{
|
||||||
|
mode->low = low;
|
||||||
|
mode->high = high;
|
||||||
|
mode->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve_mode() - Get the clock mode description for a specific clock
|
||||||
|
* @clk: The identifier of the clock for which the clock description should
|
||||||
|
* be retrieved
|
||||||
|
* @soc_type: The type of MPC83xx SoC for which the clock description should be
|
||||||
|
* retrieved
|
||||||
|
* @mode: Pointer to a clk_mode structure to be filled with data for the
|
||||||
|
* clock
|
||||||
|
*
|
||||||
|
* Since some clock rate are stored in different places on different MPC83xx
|
||||||
|
* SoCs, the SoC type has to be supplied along with the clock's identifier.
|
||||||
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
static int retrieve_mode(int clk, int soc_type, struct clk_mode *mode)
|
||||||
|
{
|
||||||
|
switch (clk) {
|
||||||
|
case MPC83XX_CLK_CORE:
|
||||||
|
case MPC83XX_CLK_CSB:
|
||||||
|
case MPC83XX_CLK_QE:
|
||||||
|
case MPC83XX_CLK_BRG:
|
||||||
|
case MPC83XX_CLK_LCLK:
|
||||||
|
case MPC83XX_CLK_I2C2:
|
||||||
|
set_mode(mode, 0, 0, TYPE_SPECIAL);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_MEM:
|
||||||
|
set_mode(mode, 1, 1, TYPE_SPMR_DIRECT_MULTIPLY);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_LBIU:
|
||||||
|
case MPC83XX_CLK_MEM_SEC:
|
||||||
|
set_mode(mode, 0, 0, TYPE_SPMR_DIRECT_MULTIPLY);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_TSEC1:
|
||||||
|
set_mode(mode, 0, 1, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_TSEC2:
|
||||||
|
if (soc_type == SOC_MPC8313) /* I2C and TSEC2 are the same register */
|
||||||
|
set_mode(mode, 2, 3, TYPE_SCCR_STANDARD);
|
||||||
|
else /* FIXME(mario.six@gdsys.cc): This has separate enable/disable bit! */
|
||||||
|
set_mode(mode, 0, 1, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_SDHC:
|
||||||
|
set_mode(mode, 4, 5, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_ENC:
|
||||||
|
set_mode(mode, 6, 7, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_I2C1:
|
||||||
|
if (soc_type == SOC_MPC8349)
|
||||||
|
set_mode(mode, 2, 3, TYPE_SCCR_STANDARD);
|
||||||
|
else /* I2C and ENC are the same register */
|
||||||
|
set_mode(mode, 6, 7, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_PCIEXP1:
|
||||||
|
set_mode(mode, 10, 11, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_PCIEXP2:
|
||||||
|
set_mode(mode, 12, 13, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_USBDR:
|
||||||
|
if (soc_type == SOC_MPC8313 || soc_type == SOC_MPC8349)
|
||||||
|
set_mode(mode, 10, 11, TYPE_SCCR_STANDARD);
|
||||||
|
else
|
||||||
|
set_mode(mode, 8, 9, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_USBMPH:
|
||||||
|
set_mode(mode, 8, 9, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_PCI:
|
||||||
|
set_mode(mode, 15, 15, TYPE_SCCR_ONOFF);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_DMAC:
|
||||||
|
set_mode(mode, 26, 27, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_SATA:
|
||||||
|
/* FIXME(mario.six@gdsys.cc): All SATA controllers must have the same clock ratio */
|
||||||
|
if (soc_type == SOC_MPC8379) {
|
||||||
|
set_mode(mode, 24, 25, TYPE_SCCR_STANDARD);
|
||||||
|
set_mode(mode, 26, 27, TYPE_SCCR_STANDARD);
|
||||||
|
set_mode(mode, 28, 29, TYPE_SCCR_STANDARD);
|
||||||
|
set_mode(mode, 30, 31, TYPE_SCCR_STANDARD);
|
||||||
|
} else {
|
||||||
|
set_mode(mode, 18, 19, TYPE_SCCR_STANDARD);
|
||||||
|
set_mode(mode, 20, 21, TYPE_SCCR_STANDARD);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPC83XX_CLK_TDM:
|
||||||
|
set_mode(mode, 26, 27, TYPE_SCCR_STANDARD);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug("%s: Unknown clock type %d on soc type %d\n",
|
||||||
|
__func__, clk, soc_type);
|
||||||
|
set_mode(mode, 0, 0, TYPE_INVALID);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_spmr() - Read the SPMR (System PLL Mode Register)
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
*
|
||||||
|
* Return: The SPMR value as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline u32 get_spmr(immap_t *im)
|
||||||
|
{
|
||||||
|
u32 res = in_be32(&im->clk.spmr);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_sccr() - Read the SCCR (System Clock Control Register)
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
*
|
||||||
|
* Return: The SCCR value as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline u32 get_sccr(immap_t *im)
|
||||||
|
{
|
||||||
|
u32 res = in_be32(&im->clk.sccr);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_lcrr() - Read the LCRR (Clock Ratio Register)
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
*
|
||||||
|
* Return: The LCRR value as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline u32 get_lcrr(immap_t *im)
|
||||||
|
{
|
||||||
|
u32 res = in_be32(&im->im_lbc.lcrr);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_pci_sync_in() - Read the PCI synchronization clock speed
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
*
|
||||||
|
* Return: The PCI synchronization clock speed value as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline u32 get_pci_sync_in(immap_t *im)
|
||||||
|
{
|
||||||
|
u8 clkin_div;
|
||||||
|
|
||||||
|
clkin_div = (get_spmr(im) & SPMR_CKID) >> SPMR_CKID_SHIFT;
|
||||||
|
return CONFIG_SYS_CLK_FREQ / (1 + clkin_div);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_csb_clk() - Read the CSB (Coheren System Bus) clock speed
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
*
|
||||||
|
* Return: The CSB clock speed value as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline u32 get_csb_clk(immap_t *im)
|
||||||
|
{
|
||||||
|
u8 spmf;
|
||||||
|
|
||||||
|
spmf = (get_spmr(im) & SPMR_SPMF) >> SPMR_SPMF_SHIFT;
|
||||||
|
return CONFIG_SYS_CLK_FREQ * spmf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spmr_field() - Read a specific SPMR field
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
* @mask: A bitmask that describes the bitfield to be read
|
||||||
|
*
|
||||||
|
* Return: The value of the bit field as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline uint spmr_field(immap_t *im, u32 mask)
|
||||||
|
{
|
||||||
|
/* Extract shift from bitmask */
|
||||||
|
uint shift = mask ? ffs(mask) - 1 : 0;
|
||||||
|
|
||||||
|
return (get_spmr(im) & mask) >> shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sccr_field() - Read a specific SCCR field
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
* @mask: A bitmask that describes the bitfield to be read
|
||||||
|
*
|
||||||
|
* Return: The value of the bit field as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline uint sccr_field(immap_t *im, u32 mask)
|
||||||
|
{
|
||||||
|
/* Extract shift from bitmask */
|
||||||
|
uint shift = mask ? ffs(mask) - 1 : 0;
|
||||||
|
|
||||||
|
return (get_sccr(im) & mask) >> shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lcrr_field() - Read a specific LCRR field
|
||||||
|
* @im: Pointer to the MPC83xx main register map in question
|
||||||
|
* @mask: A bitmask that describes the bitfield to be read
|
||||||
|
*
|
||||||
|
* Return: The value of the bit field as a 32-bit number.
|
||||||
|
*/
|
||||||
|
static inline uint lcrr_field(immap_t *im, u32 mask)
|
||||||
|
{
|
||||||
|
/* Extract shift from bitmask */
|
||||||
|
uint shift = mask ? ffs(mask) - 1 : 0;
|
||||||
|
|
||||||
|
return (get_lcrr(im) & mask) >> shift;
|
||||||
|
}
|
|
@ -138,7 +138,7 @@ void *devfdt_get_addr_ptr(struct udevice *dev)
|
||||||
|
|
||||||
void *devfdt_remap_addr_index(struct udevice *dev, int index)
|
void *devfdt_remap_addr_index(struct udevice *dev, int index)
|
||||||
{
|
{
|
||||||
fdt_addr_t addr = devfdt_get_addr(dev);
|
fdt_addr_t addr = devfdt_get_addr_index(dev, index);
|
||||||
|
|
||||||
if (addr == FDT_ADDR_T_NONE)
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -376,6 +376,33 @@ struct device_node *of_find_compatible_node(struct device_node *from,
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int of_device_has_prop_value(const struct device_node *device,
|
||||||
|
const char *propname, const void *propval,
|
||||||
|
int proplen)
|
||||||
|
{
|
||||||
|
struct property *prop = of_find_property(device, propname, NULL);
|
||||||
|
|
||||||
|
if (!prop || !prop->value || prop->length != proplen)
|
||||||
|
return 0;
|
||||||
|
return !memcmp(prop->value, propval, proplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct device_node *of_find_node_by_prop_value(struct device_node *from,
|
||||||
|
const char *propname,
|
||||||
|
const void *propval, int proplen)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
|
||||||
|
for_each_of_allnodes_from(from, np) {
|
||||||
|
if (of_device_has_prop_value(np, propname, propval, proplen) &&
|
||||||
|
of_node_get(np))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
of_node_put(from);
|
||||||
|
|
||||||
|
return np;
|
||||||
|
}
|
||||||
|
|
||||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
struct device_node *of_find_node_by_phandle(phandle handle)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
|
|
@ -777,3 +777,17 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat)
|
||||||
gd->fdt_blob, ofnode_to_offset(from), compat));
|
gd->fdt_blob, ofnode_to_offset(from), compat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ofnode ofnode_by_prop_value(ofnode from, const char *propname,
|
||||||
|
const void *propval, int proplen)
|
||||||
|
{
|
||||||
|
if (of_live_active()) {
|
||||||
|
return np_to_ofnode(of_find_node_by_prop_value(
|
||||||
|
(struct device_node *)ofnode_to_np(from), propname,
|
||||||
|
propval, proplen));
|
||||||
|
} else {
|
||||||
|
return offset_to_ofnode(fdt_node_offset_by_prop_value(
|
||||||
|
gd->fdt_blob, ofnode_to_offset(from),
|
||||||
|
propname, propval, proplen));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -330,10 +330,25 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only)
|
||||||
|
{
|
||||||
|
ofnode node;
|
||||||
|
|
||||||
|
node = ofnode_path(path);
|
||||||
|
if (!ofnode_valid(node))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(OF_LIVE)
|
||||||
|
if (of_live_active())
|
||||||
|
return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
|
||||||
|
#endif
|
||||||
|
return dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset,
|
||||||
|
pre_reloc_only);
|
||||||
|
}
|
||||||
|
|
||||||
int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
|
int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ofnode node;
|
|
||||||
|
|
||||||
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
|
ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -341,21 +356,15 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bind fixed-clock */
|
ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only);
|
||||||
node = ofnode_path("/clocks");
|
if (ret) {
|
||||||
/* if no DT "clocks" node, no need to go further */
|
debug("scan for /clocks failed: %d\n", ret);
|
||||||
if (!ofnode_valid(node))
|
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(OF_LIVE)
|
ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only);
|
||||||
if (of_live_active())
|
|
||||||
ret = dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset,
|
|
||||||
pre_reloc_only);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
debug("dm_scan_fdt_node() failed: %d\n", ret);
|
debug("scan for /firmware failed: %d\n", ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,10 @@ config CPU
|
||||||
multiple CPUs, then normally have to be set up in U-Boot so that
|
multiple CPUs, then normally have to be set up in U-Boot so that
|
||||||
they can work correctly in the OS. This provides a framework for
|
they can work correctly in the OS. This provides a framework for
|
||||||
finding out information about available CPUs and making changes.
|
finding out information about available CPUs and making changes.
|
||||||
|
|
||||||
|
config CPU_MPC83XX
|
||||||
|
bool "Enable MPC83xx CPU driver"
|
||||||
|
depends on CPU
|
||||||
|
select CLK_MPC83XX
|
||||||
|
help
|
||||||
|
Support CPU cores for SoCs of the MPC83xx series.
|
||||||
|
|
|
@ -7,3 +7,5 @@
|
||||||
obj-$(CONFIG_CPU) += cpu-uclass.o
|
obj-$(CONFIG_CPU) += cpu-uclass.o
|
||||||
|
|
||||||
obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
|
obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
|
||||||
|
obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
|
||||||
|
obj-$(CONFIG_SANDBOX) += cpu_sandbox.o
|
||||||
|
|
|
@ -11,6 +11,29 @@
|
||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
#include <dm/root.h>
|
#include <dm/root.h>
|
||||||
|
|
||||||
|
int cpu_probe_all(void)
|
||||||
|
{
|
||||||
|
struct udevice *cpu;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uclass_first_device(UCLASS_CPU, &cpu);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: No CPU found (err = %d)\n", __func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cpu) {
|
||||||
|
ret = uclass_next_device(&cpu);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Error while probing CPU (err = %d)\n",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cpu_get_desc(struct udevice *dev, char *buf, int size)
|
int cpu_get_desc(struct udevice *dev, char *buf, int size)
|
||||||
{
|
{
|
||||||
struct cpu_ops *ops = cpu_get_ops(dev);
|
struct cpu_ops *ops = cpu_get_ops(dev);
|
||||||
|
|
61
drivers/cpu/cpu_sandbox.c
Normal file
61
drivers/cpu/cpu_sandbox.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
|
int cpu_sandbox_get_desc(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
snprintf(buf, size, "LEG Inc. SuperMegaUltraTurbo CPU No. 1");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_sandbox_get_info(struct udevice *dev, struct cpu_info *info)
|
||||||
|
{
|
||||||
|
info->cpu_freq = 42 * 42 * 42 * 42 * 42;
|
||||||
|
info->features = 0x42424242;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_sandbox_get_count(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_sandbox_get_vendor(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
snprintf(buf, size, "Languid Example Garbage Inc.");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct cpu_ops cpu_sandbox_ops = {
|
||||||
|
.get_desc = cpu_sandbox_get_desc,
|
||||||
|
.get_info = cpu_sandbox_get_info,
|
||||||
|
.get_count = cpu_sandbox_get_count,
|
||||||
|
.get_vendor = cpu_sandbox_get_vendor,
|
||||||
|
};
|
||||||
|
|
||||||
|
int cpu_sandbox_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id cpu_sandbox_ids[] = {
|
||||||
|
{ .compatible = "sandbox,cpu_sandbox" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(cpu_sandbox) = {
|
||||||
|
.name = "cpu_sandbox",
|
||||||
|
.id = UCLASS_CPU,
|
||||||
|
.ops = &cpu_sandbox_ops,
|
||||||
|
.of_match = cpu_sandbox_ids,
|
||||||
|
.probe = cpu_sandbox_probe,
|
||||||
|
};
|
349
drivers/cpu/mpc83xx_cpu.c
Normal file
349
drivers/cpu/mpc83xx_cpu.c
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <bitfield.h>
|
||||||
|
#include <clk.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <dm.h>
|
||||||
|
|
||||||
|
#include "mpc83xx_cpu.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mpc83xx_cpu_priv - Private data for MPC83xx CPUs
|
||||||
|
* @e300_type: The e300 core type of the MPC83xx CPU
|
||||||
|
* @family: The MPC83xx family the CPU belongs to
|
||||||
|
* @type: The MPC83xx type of the CPU
|
||||||
|
* @is_e_processor: Flag indicating whether the CPU is a E processor or not
|
||||||
|
* @is_a_variant: Flag indicating whtther the CPU is a A variant or not
|
||||||
|
* @revid: The revision ID of the CPU
|
||||||
|
* @revid.major: The major part of the CPU's revision ID
|
||||||
|
* @revid.minor: The minor part of the CPU's revision ID
|
||||||
|
*/
|
||||||
|
struct mpc83xx_cpu_priv {
|
||||||
|
enum e300_type e300_type;
|
||||||
|
enum mpc83xx_cpu_family family;
|
||||||
|
enum mpc83xx_cpu_type type;
|
||||||
|
bool is_e_processor;
|
||||||
|
bool is_a_variant;
|
||||||
|
struct {
|
||||||
|
uint major;
|
||||||
|
uint minor;
|
||||||
|
} revid;
|
||||||
|
};
|
||||||
|
|
||||||
|
int checkcpu(void)
|
||||||
|
{
|
||||||
|
/* Activate all CPUs from board_f.c */
|
||||||
|
return cpu_probe_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_spridr() - Read SPRIDR (System Part and Revision ID Register) of CPU
|
||||||
|
*
|
||||||
|
* Return: The SPRIDR value
|
||||||
|
*/
|
||||||
|
static inline u32 get_spridr(void)
|
||||||
|
{
|
||||||
|
immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||||
|
|
||||||
|
return in_be32(&immr->sysconf.spridr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determine_type() - Determine CPU family of MPC83xx device
|
||||||
|
* @dev: CPU device from which to read CPU family from
|
||||||
|
*/
|
||||||
|
static inline void determine_family(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
/* Upper 12 bits of PARTID field (bits 0-23 in SPRIDR) */
|
||||||
|
const u32 PARTID_FAMILY_MASK = 0xFFF00000;
|
||||||
|
|
||||||
|
switch (bitfield_extract_by_mask(get_spridr(), PARTID_FAMILY_MASK)) {
|
||||||
|
case 0x810:
|
||||||
|
case 0x811:
|
||||||
|
priv->family = FAMILY_830X;
|
||||||
|
break;
|
||||||
|
case 0x80B:
|
||||||
|
priv->family = FAMILY_831X;
|
||||||
|
break;
|
||||||
|
case 0x806:
|
||||||
|
priv->family = FAMILY_832X;
|
||||||
|
break;
|
||||||
|
case 0x803:
|
||||||
|
priv->family = FAMILY_834X;
|
||||||
|
break;
|
||||||
|
case 0x804:
|
||||||
|
priv->family = FAMILY_836X;
|
||||||
|
break;
|
||||||
|
case 0x80C:
|
||||||
|
priv->family = FAMILY_837X;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priv->family = FAMILY_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determine_type() - Determine CPU type of MPC83xx device
|
||||||
|
* @dev: CPU device from which to read CPU type from
|
||||||
|
*/
|
||||||
|
static inline void determine_type(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
/* Upper 16 bits of PVR (Processor Version Register) */
|
||||||
|
const u32 PCR_UPPER_MASK = 0xFFFF0000;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = bitfield_extract_by_mask(get_spridr(), PCR_UPPER_MASK);
|
||||||
|
|
||||||
|
/* Mask out E-variant bit */
|
||||||
|
switch (val & 0xFFFE) {
|
||||||
|
case 0x8100:
|
||||||
|
priv->type = TYPE_8308;
|
||||||
|
break;
|
||||||
|
case 0x8110:
|
||||||
|
priv->type = TYPE_8309;
|
||||||
|
break;
|
||||||
|
case 0x80B2:
|
||||||
|
priv->type = TYPE_8311;
|
||||||
|
break;
|
||||||
|
case 0x80B0:
|
||||||
|
priv->type = TYPE_8313;
|
||||||
|
break;
|
||||||
|
case 0x80B6:
|
||||||
|
priv->type = TYPE_8314;
|
||||||
|
break;
|
||||||
|
case 0x80B4:
|
||||||
|
priv->type = TYPE_8315;
|
||||||
|
break;
|
||||||
|
case 0x8066:
|
||||||
|
priv->type = TYPE_8321;
|
||||||
|
break;
|
||||||
|
case 0x8062:
|
||||||
|
priv->type = TYPE_8323;
|
||||||
|
break;
|
||||||
|
case 0x8036:
|
||||||
|
priv->type = TYPE_8343;
|
||||||
|
break;
|
||||||
|
case 0x8032:
|
||||||
|
priv->type = TYPE_8347_TBGA;
|
||||||
|
break;
|
||||||
|
case 0x8034:
|
||||||
|
priv->type = TYPE_8347_PBGA;
|
||||||
|
break;
|
||||||
|
case 0x8030:
|
||||||
|
priv->type = TYPE_8349;
|
||||||
|
break;
|
||||||
|
case 0x804A:
|
||||||
|
priv->type = TYPE_8358_TBGA;
|
||||||
|
break;
|
||||||
|
case 0x804E:
|
||||||
|
priv->type = TYPE_8358_PBGA;
|
||||||
|
break;
|
||||||
|
case 0x8048:
|
||||||
|
priv->type = TYPE_8360;
|
||||||
|
break;
|
||||||
|
case 0x80C6:
|
||||||
|
priv->type = TYPE_8377;
|
||||||
|
break;
|
||||||
|
case 0x80C4:
|
||||||
|
priv->type = TYPE_8378;
|
||||||
|
break;
|
||||||
|
case 0x80C2:
|
||||||
|
priv->type = TYPE_8379;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priv->type = TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determine_e300_type() - Determine e300 core type of MPC83xx device
|
||||||
|
* @dev: CPU device from which to read e300 core type from
|
||||||
|
*/
|
||||||
|
static inline void determine_e300_type(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
/* Upper 16 bits of PVR (Processor Version Register) */
|
||||||
|
const u32 PCR_UPPER_MASK = 0xFFFF0000;
|
||||||
|
u32 pvr = get_pvr();
|
||||||
|
|
||||||
|
switch ((pvr & PCR_UPPER_MASK) >> 16) {
|
||||||
|
case 0x8083:
|
||||||
|
priv->e300_type = E300C1;
|
||||||
|
break;
|
||||||
|
case 0x8084:
|
||||||
|
priv->e300_type = E300C2;
|
||||||
|
break;
|
||||||
|
case 0x8085:
|
||||||
|
priv->e300_type = E300C3;
|
||||||
|
break;
|
||||||
|
case 0x8086:
|
||||||
|
priv->e300_type = E300C4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priv->e300_type = E300_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determine_revid() - Determine revision ID of CPU device
|
||||||
|
* @dev: CPU device from which to read revision ID
|
||||||
|
*/
|
||||||
|
static inline void determine_revid(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
u32 REVID_MAJOR_MASK;
|
||||||
|
u32 REVID_MINOR_MASK;
|
||||||
|
u32 spridr = get_spridr();
|
||||||
|
|
||||||
|
if (priv->family == FAMILY_834X) {
|
||||||
|
REVID_MAJOR_MASK = 0x0000FF00;
|
||||||
|
REVID_MINOR_MASK = 0x000000FF;
|
||||||
|
} else {
|
||||||
|
REVID_MAJOR_MASK = 0x000000F0;
|
||||||
|
REVID_MINOR_MASK = 0x0000000F;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->revid.major = bitfield_extract_by_mask(spridr, REVID_MAJOR_MASK);
|
||||||
|
priv->revid.minor = bitfield_extract_by_mask(spridr, REVID_MINOR_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determine_cpu_data() - Determine CPU information from hardware
|
||||||
|
* @dev: CPU device from which to read information
|
||||||
|
*/
|
||||||
|
static void determine_cpu_data(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
const u32 E_FLAG_MASK = 0x00010000;
|
||||||
|
u32 spridr = get_spridr();
|
||||||
|
|
||||||
|
determine_family(dev);
|
||||||
|
determine_type(dev);
|
||||||
|
determine_e300_type(dev);
|
||||||
|
determine_revid(dev);
|
||||||
|
|
||||||
|
if ((priv->family == FAMILY_834X ||
|
||||||
|
priv->family == FAMILY_836X) && priv->revid.major >= 2)
|
||||||
|
priv->is_a_variant = true;
|
||||||
|
|
||||||
|
priv->is_e_processor = !bitfield_extract_by_mask(spridr, E_FLAG_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_cpu_get_desc(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
|
||||||
|
struct clk core_clk;
|
||||||
|
struct clk csb_clk;
|
||||||
|
char core_freq[32];
|
||||||
|
char csb_freq[32];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = clk_get_by_index(dev, 0, &core_clk);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Failed to get core clock (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_get_by_index(dev, 1, &csb_clk);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Failed to get CSB clock (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
determine_cpu_data(dev);
|
||||||
|
|
||||||
|
snprintf(buf, size,
|
||||||
|
"CPU: %s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz\n",
|
||||||
|
e300_names[priv->e300_type],
|
||||||
|
cpu_type_names[priv->type],
|
||||||
|
priv->is_e_processor ? "E" : "",
|
||||||
|
priv->is_a_variant ? "A" : "",
|
||||||
|
priv->revid.major,
|
||||||
|
priv->revid.minor,
|
||||||
|
strmhz(core_freq, clk_get_rate(&core_clk)),
|
||||||
|
strmhz(csb_freq, clk_get_rate(&csb_clk)));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_cpu_get_info(struct udevice *dev, struct cpu_info *info)
|
||||||
|
{
|
||||||
|
struct clk clock;
|
||||||
|
int ret;
|
||||||
|
ulong freq;
|
||||||
|
|
||||||
|
ret = clk_get_by_index(dev, 0, &clock);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Failed to get core clock (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
freq = clk_get_rate(&clock);
|
||||||
|
if (!freq) {
|
||||||
|
debug("%s: Core clock speed is zero\n", dev->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->cpu_freq = freq;
|
||||||
|
info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_cpu_get_count(struct udevice *dev)
|
||||||
|
{
|
||||||
|
/* We have one e300cX core */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_cpu_get_vendor(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
snprintf(buf, size, "NXP");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct cpu_ops mpc83xx_cpu_ops = {
|
||||||
|
.get_desc = mpc83xx_cpu_get_desc,
|
||||||
|
.get_info = mpc83xx_cpu_get_info,
|
||||||
|
.get_count = mpc83xx_cpu_get_count,
|
||||||
|
.get_vendor = mpc83xx_cpu_get_vendor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mpc83xx_cpu_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id mpc83xx_cpu_ids[] = {
|
||||||
|
{ .compatible = "fsl,mpc83xx", },
|
||||||
|
{ .compatible = "fsl,mpc8308", },
|
||||||
|
{ .compatible = "fsl,mpc8309", },
|
||||||
|
{ .compatible = "fsl,mpc8313", },
|
||||||
|
{ .compatible = "fsl,mpc8315", },
|
||||||
|
{ .compatible = "fsl,mpc832x", },
|
||||||
|
{ .compatible = "fsl,mpc8349", },
|
||||||
|
{ .compatible = "fsl,mpc8360", },
|
||||||
|
{ .compatible = "fsl,mpc8379", },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(mpc83xx_cpu) = {
|
||||||
|
.name = "mpc83xx_cpu",
|
||||||
|
.id = UCLASS_CPU,
|
||||||
|
.of_match = mpc83xx_cpu_ids,
|
||||||
|
.probe = mpc83xx_cpu_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mpc83xx_cpu_priv),
|
||||||
|
.ops = &mpc83xx_cpu_ops,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
|
};
|
126
drivers/cpu/mpc83xx_cpu.h
Normal file
126
drivers/cpu/mpc83xx_cpu.h
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MPC83XX_CPU_H_
|
||||||
|
#define _MPC83XX_CPU_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum e300_type - Identifiers for e300 cores
|
||||||
|
* @E300C1: Identifier for e300c1 cores
|
||||||
|
* @E300C2: Identifier for e300c2 cores
|
||||||
|
* @E300C3: Identifier for e300c3 cores
|
||||||
|
* @E300C4: Identifier for e300c4 cores
|
||||||
|
* @E300_UNKNOWN: Identifier for unknown e300 cores
|
||||||
|
*/
|
||||||
|
enum e300_type {
|
||||||
|
E300C1,
|
||||||
|
E300C2,
|
||||||
|
E300C3,
|
||||||
|
E300C4,
|
||||||
|
E300_UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Array mapping the e300 core types to their human-readable names */
|
||||||
|
static const char * const e300_names[] = {
|
||||||
|
[E300C1] = "e300c1",
|
||||||
|
[E300C2] = "e300c2",
|
||||||
|
[E300C3] = "e300c3",
|
||||||
|
[E300C4] = "e300c4",
|
||||||
|
[E300_UNKNOWN] = "Unknown e300",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum mpc83xx_cpu_family - Identifiers for MPC83xx CPU families
|
||||||
|
* @FAMILY_830X: Identifier for the MPC830x CPU family
|
||||||
|
* @FAMILY_831X: Identifier for the MPC831x CPU family
|
||||||
|
* @FAMILY_832X: Identifier for the MPC832x CPU family
|
||||||
|
* @FAMILY_834X: Identifier for the MPC834x CPU family
|
||||||
|
* @FAMILY_836X: Identifier for the MPC836x CPU family
|
||||||
|
* @FAMILY_837X: Identifier for the MPC837x CPU family
|
||||||
|
* @FAMILY_UNKNOWN: Identifier for an unknown MPC83xx CPU family
|
||||||
|
*/
|
||||||
|
enum mpc83xx_cpu_family {
|
||||||
|
FAMILY_830X,
|
||||||
|
FAMILY_831X,
|
||||||
|
FAMILY_832X,
|
||||||
|
FAMILY_834X,
|
||||||
|
FAMILY_836X,
|
||||||
|
FAMILY_837X,
|
||||||
|
FAMILY_UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum mpc83xx_cpu_type - Identifiers for MPC83xx CPU types
|
||||||
|
* @TYPE_8308: Identifier for the MPC8308 CPU type
|
||||||
|
* @TYPE_8309: Identifier for the MPC8309 CPU type
|
||||||
|
* @TYPE_8311: Identifier for the MPC8311 CPU type
|
||||||
|
* @TYPE_8313: Identifier for the MPC8313 CPU type
|
||||||
|
* @TYPE_8314: Identifier for the MPC8314 CPU type
|
||||||
|
* @TYPE_8315: Identifier for the MPC8315 CPU type
|
||||||
|
* @TYPE_8321: Identifier for the MPC8321 CPU type
|
||||||
|
* @TYPE_8323: Identifier for the MPC8323 CPU type
|
||||||
|
* @TYPE_8343: Identifier for the MPC8343 CPU type
|
||||||
|
* @TYPE_8347_TBGA: Identifier for the MPC8347 CPU type (Tape Ball Grid Array
|
||||||
|
* version)
|
||||||
|
* @TYPE_8347_PBGA: Identifier for the MPC8347 CPU type (Plastic Ball Grid Array
|
||||||
|
* version)
|
||||||
|
* @TYPE_8349: Identifier for the MPC8349 CPU type
|
||||||
|
* @TYPE_8358_TBGA: Identifier for the MPC8358 CPU type (Tape Ball Grid Array
|
||||||
|
* version)
|
||||||
|
* @TYPE_8358_PBGA: Identifier for the MPC8358 CPU type (Plastic Ball Grid Array
|
||||||
|
* version)
|
||||||
|
* @TYPE_8360: Identifier for the MPC8360 CPU type
|
||||||
|
* @TYPE_8377: Identifier for the MPC8377 CPU type
|
||||||
|
* @TYPE_8378: Identifier for the MPC8378 CPU type
|
||||||
|
* @TYPE_8379: Identifier for the MPC8379 CPU type
|
||||||
|
* @TYPE_UNKNOWN: Identifier for an unknown MPC83xx CPU type
|
||||||
|
*/
|
||||||
|
enum mpc83xx_cpu_type {
|
||||||
|
TYPE_8308,
|
||||||
|
TYPE_8309,
|
||||||
|
TYPE_8311,
|
||||||
|
TYPE_8313,
|
||||||
|
TYPE_8314,
|
||||||
|
TYPE_8315,
|
||||||
|
TYPE_8321,
|
||||||
|
TYPE_8323,
|
||||||
|
TYPE_8343,
|
||||||
|
TYPE_8347_TBGA,
|
||||||
|
TYPE_8347_PBGA,
|
||||||
|
TYPE_8349,
|
||||||
|
TYPE_8358_TBGA,
|
||||||
|
TYPE_8358_PBGA,
|
||||||
|
TYPE_8360,
|
||||||
|
TYPE_8377,
|
||||||
|
TYPE_8378,
|
||||||
|
TYPE_8379,
|
||||||
|
TYPE_UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Array mapping the MCP83xx CPUs to their human-readable names */
|
||||||
|
static const char * const cpu_type_names[] = {
|
||||||
|
[TYPE_8308] = "8308",
|
||||||
|
[TYPE_8309] = "8309",
|
||||||
|
[TYPE_8311] = "8311",
|
||||||
|
[TYPE_8313] = "8313",
|
||||||
|
[TYPE_8314] = "8314",
|
||||||
|
[TYPE_8315] = "8315",
|
||||||
|
[TYPE_8321] = "8321",
|
||||||
|
[TYPE_8323] = "8323",
|
||||||
|
[TYPE_8343] = "8343",
|
||||||
|
[TYPE_8347_TBGA] = "8347_TBGA",
|
||||||
|
[TYPE_8347_PBGA] = "8347_PBGA",
|
||||||
|
[TYPE_8349] = "8349",
|
||||||
|
[TYPE_8358_TBGA] = "8358_TBGA",
|
||||||
|
[TYPE_8358_PBGA] = "8358_PBGA",
|
||||||
|
[TYPE_8360] = "8360",
|
||||||
|
[TYPE_8377] = "8377",
|
||||||
|
[TYPE_8378] = "8378",
|
||||||
|
[TYPE_8379] = "8379",
|
||||||
|
[TYPE_UNKNOWN] = "Unknown CPU",
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !_MPC83XX_CPU_H_ */
|
|
@ -288,4 +288,11 @@ config GDSYS_IOEP
|
||||||
depends on MISC
|
depends on MISC
|
||||||
help
|
help
|
||||||
Support gdsys FPGA's IO endpoint driver.
|
Support gdsys FPGA's IO endpoint driver.
|
||||||
|
|
||||||
|
config MPC83XX_SERDES
|
||||||
|
bool "Enable MPC83xx serdes driver"
|
||||||
|
depends on MISC
|
||||||
|
help
|
||||||
|
Support for serdes found on MPC83xx SoCs.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -55,3 +55,4 @@ obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o
|
||||||
obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
|
obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
|
||||||
obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
|
obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
|
||||||
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
|
obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
|
||||||
|
obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
|
||||||
|
|
185
drivers/misc/mpc83xx_serdes.c
Normal file
185
drivers/misc/mpc83xx_serdes.c
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*
|
||||||
|
* base on the MPC83xx serdes initialization, which is
|
||||||
|
*
|
||||||
|
* Copyright 2007,2011 Freescale Semiconductor, Inc.
|
||||||
|
* Copyright (C) 2008 MontaVista Software, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <mapmem.h>
|
||||||
|
#include <misc.h>
|
||||||
|
|
||||||
|
#include "mpc83xx_serdes.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mpc83xx_serdes_priv - Private structure for MPC83xx serdes
|
||||||
|
* @regs: The device's register map
|
||||||
|
* @rfcks: Variable to keep the serdes reference clock selection set during
|
||||||
|
* initialization in (is or'd to every value written to SRDSCR4)
|
||||||
|
*/
|
||||||
|
struct mpc83xx_serdes_priv {
|
||||||
|
struct mpc83xx_serdes_regs *regs;
|
||||||
|
u32 rfcks;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup_sata() - Configure the SerDes device to SATA mode
|
||||||
|
* @dev: The device to configure
|
||||||
|
*/
|
||||||
|
static void setup_sata(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_serdes_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Set and clear reset bits */
|
||||||
|
setbits_be32(&priv->regs->srdsrstctl, SRDSRSTCTL_SATA_RESET);
|
||||||
|
udelay(1000);
|
||||||
|
clrbits_be32(&priv->regs->srdsrstctl, SRDSRSTCTL_SATA_RESET);
|
||||||
|
|
||||||
|
/* Configure SRDSCR0 */
|
||||||
|
clrsetbits_be32(&priv->regs->srdscr0,
|
||||||
|
SRDSCR0_TXEQA_MASK | SRDSCR0_TXEQE_MASK,
|
||||||
|
SRDSCR0_TXEQA_SATA | SRDSCR0_TXEQE_SATA);
|
||||||
|
|
||||||
|
/* Configure SRDSCR1 */
|
||||||
|
clrbits_be32(&priv->regs->srdscr1, SRDSCR1_PLLBW);
|
||||||
|
|
||||||
|
/* Configure SRDSCR2 */
|
||||||
|
clrsetbits_be32(&priv->regs->srdscr2,
|
||||||
|
SRDSCR2_SEIC_MASK,
|
||||||
|
SRDSCR2_SEIC_SATA);
|
||||||
|
|
||||||
|
/* Configure SRDSCR3 */
|
||||||
|
out_be32(&priv->regs->srdscr3,
|
||||||
|
SRDSCR3_KFR_SATA | SRDSCR3_KPH_SATA |
|
||||||
|
SRDSCR3_SDFM_SATA_PEX | SRDSCR3_SDTXL_SATA);
|
||||||
|
|
||||||
|
/* Configure SRDSCR4 */
|
||||||
|
out_be32(&priv->regs->srdscr4, priv->rfcks | SRDSCR4_PROT_SATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup_pex() - Configure the SerDes device to PCI Express mode
|
||||||
|
* @dev: The device to configure
|
||||||
|
* @type: The PCI Express type to configure for (x1 or x2)
|
||||||
|
*/
|
||||||
|
static void setup_pex(struct udevice *dev, enum pex_type type)
|
||||||
|
{
|
||||||
|
struct mpc83xx_serdes_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Configure SRDSCR1 */
|
||||||
|
setbits_be32(&priv->regs->srdscr1, SRDSCR1_PLLBW);
|
||||||
|
|
||||||
|
/* Configure SRDSCR2 */
|
||||||
|
clrsetbits_be32(&priv->regs->srdscr2,
|
||||||
|
SRDSCR2_SEIC_MASK,
|
||||||
|
SRDSCR2_SEIC_PEX);
|
||||||
|
|
||||||
|
/* Configure SRDSCR3 */
|
||||||
|
out_be32(&priv->regs->srdscr3, SRDSCR3_SDFM_SATA_PEX);
|
||||||
|
|
||||||
|
/* Configure SRDSCR4 */
|
||||||
|
if (type == PEX_X2)
|
||||||
|
out_be32(&priv->regs->srdscr4,
|
||||||
|
priv->rfcks | SRDSCR4_PROT_PEX | SRDSCR4_PLANE_X2);
|
||||||
|
else
|
||||||
|
out_be32(&priv->regs->srdscr4,
|
||||||
|
priv->rfcks | SRDSCR4_PROT_PEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup_sgmii() - Configure the SerDes device to SGMII mode
|
||||||
|
* @dev: The device to configure
|
||||||
|
*/
|
||||||
|
static void setup_sgmii(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_serdes_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
/* Configure SRDSCR1 */
|
||||||
|
clrbits_be32(&priv->regs->srdscr1, SRDSCR1_PLLBW);
|
||||||
|
|
||||||
|
/* Configure SRDSCR2 */
|
||||||
|
clrsetbits_be32(&priv->regs->srdscr2,
|
||||||
|
SRDSCR2_SEIC_MASK,
|
||||||
|
SRDSCR2_SEIC_SGMII);
|
||||||
|
|
||||||
|
/* Configure SRDSCR3 */
|
||||||
|
out_be32(&priv->regs->srdscr3, 0);
|
||||||
|
|
||||||
|
/* Configure SRDSCR4 */
|
||||||
|
out_be32(&priv->regs->srdscr4, priv->rfcks | SRDSCR4_PROT_SGMII);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_serdes_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mpc83xx_serdes_priv *priv = dev_get_priv(dev);
|
||||||
|
bool vdd;
|
||||||
|
const char *proto;
|
||||||
|
|
||||||
|
priv->regs = map_sysmem(dev_read_addr(dev),
|
||||||
|
sizeof(struct mpc83xx_serdes_regs));
|
||||||
|
|
||||||
|
switch (dev_read_u32_default(dev, "serdes-clk", -1)) {
|
||||||
|
case 100:
|
||||||
|
priv->rfcks = SRDSCR4_RFCKS_100;
|
||||||
|
break;
|
||||||
|
case 125:
|
||||||
|
priv->rfcks = SRDSCR4_RFCKS_125;
|
||||||
|
break;
|
||||||
|
case 150:
|
||||||
|
priv->rfcks = SRDSCR4_RFCKS_150;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug("%s: Could not read serdes clock value\n", dev->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vdd = dev_read_bool(dev, "vdd");
|
||||||
|
|
||||||
|
/* 1.0V corevdd */
|
||||||
|
if (vdd) {
|
||||||
|
/* DPPE/DPPA = 0 */
|
||||||
|
clrbits_be32(&priv->regs->srdscr0, SRDSCR0_DPP_1V2);
|
||||||
|
|
||||||
|
/* VDD = 0 */
|
||||||
|
clrbits_be32(&priv->regs->srdscr0, SRDSCR2_VDD_1V2);
|
||||||
|
}
|
||||||
|
|
||||||
|
proto = dev_read_string(dev, "proto");
|
||||||
|
|
||||||
|
/* protocol specific configuration */
|
||||||
|
if (!strcmp(proto, "sata")) {
|
||||||
|
setup_sata(dev);
|
||||||
|
} else if (!strcmp(proto, "pex")) {
|
||||||
|
setup_pex(dev, PEX_X1);
|
||||||
|
} else if (!strcmp(proto, "pex-x2")) {
|
||||||
|
setup_pex(dev, PEX_X2);
|
||||||
|
} else if (!strcmp(proto, "sgmii")) {
|
||||||
|
setup_sgmii(dev);
|
||||||
|
} else {
|
||||||
|
debug("%s: Invalid protocol value %s\n", dev->name, proto);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do a software reset */
|
||||||
|
setbits_be32(&priv->regs->srdsrstctl, SRDSRSTCTL_RST);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id mpc83xx_serdes_ids[] = {
|
||||||
|
{ .compatible = "fsl,mpc83xx-serdes" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(mpc83xx_serdes) = {
|
||||||
|
.name = "mpc83xx_serdes",
|
||||||
|
.id = UCLASS_MISC,
|
||||||
|
.of_match = mpc83xx_serdes_ids,
|
||||||
|
.probe = mpc83xx_serdes_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mpc83xx_serdes_priv),
|
||||||
|
};
|
232
drivers/misc/mpc83xx_serdes.h
Normal file
232
drivers/misc/mpc83xx_serdes.h
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdscr0_mask - Bit masks for SRDSCR0 (SerDes Control Register 0)
|
||||||
|
* @SRDSCR0_DPPA: Bitmask for the DPPA (diff pk-pk swing for lane A)
|
||||||
|
* field of the SRCSCR0
|
||||||
|
* @SRDSCR0_DPPE: Bitmask for the DPPE (diff pk-pk swing for lane E)
|
||||||
|
* field of the SRCSCR0
|
||||||
|
* @SRDSCR0_DPP_1V2: Combined bitmask to set diff pk-pk swing for both lanes
|
||||||
|
* @SRDSCR0_TXEQA_MASK: Bitmask for the TXEQA (transmit equalization for
|
||||||
|
* lane A) field of the SRCSCR0
|
||||||
|
* @SRDSCR0_TXEQA_SATA: Bitmask to set the TXEQA to the value used for SATA
|
||||||
|
* @SRDSCR0_TXEQE_MASK: Bitmask for the TXEQE (transmit equalization for
|
||||||
|
* lane E) field of the SRCSCR0
|
||||||
|
* @SRDSCR0_TXEQE_SATA: Bitmask to set the TXEQE to the value used for SATA
|
||||||
|
*/
|
||||||
|
enum srdscr0_mask {
|
||||||
|
SRDSCR0_DPPA = BIT(31 - 16),
|
||||||
|
SRDSCR0_DPPE = BIT(31 - 20),
|
||||||
|
SRDSCR0_DPP_1V2 = SRDSCR0_DPPE | SRDSCR0_DPPA,
|
||||||
|
|
||||||
|
SRDSCR0_TXEQA_MASK = 0x00007000,
|
||||||
|
SRDSCR0_TXEQA_SATA = 0x00001000,
|
||||||
|
SRDSCR0_TXEQE_MASK = 0x00000700,
|
||||||
|
SRDSCR0_TXEQE_SATA = 0x00000100,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdscr1_mask - Bit masks for SRDSCR1 (SerDes Control Register 1)
|
||||||
|
* @SRDSCR1_PLLBW: Bitmask for the PLLBW (PLL bandwidth) field of SRDSCR1
|
||||||
|
*/
|
||||||
|
enum srdscr1_mask {
|
||||||
|
SRDSCR1_PLLBW = BIT(31 - 25),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdscr2_mask - Bit masks for SRDSCR2 (SerDes Control Register 2)
|
||||||
|
* @SRDSCR2_VDD_1V2: Bit mask to to set the VDD field of the SCRSCR2
|
||||||
|
* @SRDSCR2_SEICA_MASK: Bitmask for the SEICA (Receiver electrical idle
|
||||||
|
* detection control for lane A) field of the SRCSCR2
|
||||||
|
* @SRDSCR2_SEICE_MASK: Bitmask for the SEICE (Receiver electrical idle
|
||||||
|
* detection control for lane E) field of the SRCSCR2
|
||||||
|
* @SRDSCR2_SEIC_MASK: Combined bitmask to set the receiver electrical idle
|
||||||
|
* detection control for both lanes
|
||||||
|
* @SRDSCR2_SEICA_SATA: Bitmask to set the SEICA field to the value used for
|
||||||
|
* SATA
|
||||||
|
* @SRDSCR2_SEICE_SATA: Bitmask to set the SEICE field to the value used for
|
||||||
|
* SATA
|
||||||
|
* @SRDSCR2_SEIC_SATA: Combined bitmask to set the value of both SEIC fields
|
||||||
|
* to the value used for SATA
|
||||||
|
* @SRDSCR2_SEICA_PEX: Bitmask to set the SEICA field to the value used for
|
||||||
|
* PCI Express
|
||||||
|
* @SRDSCR2_SEICE_PEX: Bitmask to set the SEICE field to the value used for
|
||||||
|
* PCI Express
|
||||||
|
* @SRDSCR2_SEIC_PEX: Combined bitmask to set the value of both SEIC fields
|
||||||
|
* to the value used for PCI Express
|
||||||
|
* @SRDSCR2_SEICA_SGMII: Bitmask to set the SEICA field to the value used for
|
||||||
|
* SGMII
|
||||||
|
* @SRDSCR2_SEICE_SGMII: Bitmask to set the SEICE field to the value used for
|
||||||
|
* SGMII
|
||||||
|
* @SRDSCR2_SEIC_SGMII: Combined bitmask to set the value of both SEIC fields
|
||||||
|
* to the value used for SGMII
|
||||||
|
*/
|
||||||
|
enum srdscr2_mask {
|
||||||
|
SRDSCR2_VDD_1V2 = 0x00800000,
|
||||||
|
|
||||||
|
SRDSCR2_SEICA_MASK = 0x00001c00,
|
||||||
|
SRDSCR2_SEICE_MASK = 0x0000001c,
|
||||||
|
SRDSCR2_SEIC_MASK = SRDSCR2_SEICA_MASK | SRDSCR2_SEICE_MASK,
|
||||||
|
|
||||||
|
SRDSCR2_SEICA_SATA = 0x00001400,
|
||||||
|
SRDSCR2_SEICE_SATA = 0x00000014,
|
||||||
|
SRDSCR2_SEIC_SATA = SRDSCR2_SEICA_SATA | SRDSCR2_SEICE_SATA,
|
||||||
|
|
||||||
|
SRDSCR2_SEICA_PEX = 0x00001000,
|
||||||
|
SRDSCR2_SEICE_PEX = 0x00000010,
|
||||||
|
SRDSCR2_SEIC_PEX = SRDSCR2_SEICA_PEX | SRDSCR2_SEICE_PEX,
|
||||||
|
|
||||||
|
SRDSCR2_SEICA_SGMII = 0x00000100,
|
||||||
|
SRDSCR2_SEICE_SGMII = 0x00000001,
|
||||||
|
SRDSCR2_SEIC_SGMII = SRDSCR2_SEICA_SGMII | SRDSCR2_SEICE_SGMII,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdscr3_mask - Bit masks for SRDSCR3 (SerDes Control Register 3)
|
||||||
|
* @SRDSCR3_KFRA_SATA: Bitmask to set the KFRA field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_KFRE_SATA: Bitmask to set the KFRE field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_KFR_SATA: Combined bitmask to set both KFR fields to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_KPHA_SATA: Bitmask to set the KPHA field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_KPHE_SATA: Bitmask to set the KPHE field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_KPH_SATA: Combined bitmask to set both KPH fields to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_SDFMA_SATA_PEX: Bitmask to set the SDFMA field of SRDSCR3 to the
|
||||||
|
* value used by SATA and PCI Express
|
||||||
|
* @SRDSCR3_SDFME_SATA_PEX: Bitmask to set the SDFME field of SRDSCR3 to the
|
||||||
|
* value used by SATA and PCI Express
|
||||||
|
* @SRDSCR3_SDFM_SATA_PEX: Combined bitmask to set both SDFM fields to the
|
||||||
|
* value used by SATA and PCI Express
|
||||||
|
* @SRDSCR3_SDTXLA_SATA: Bitmask to set the SDTXLA field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_SDTXLE_SATA: Bitmask to set the SDTXLE field of SRDSCR3 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR3_SDTXL_SATA: Combined bitmask to set both SDTXL fields to the
|
||||||
|
* value used by SATA
|
||||||
|
*
|
||||||
|
* KFRA = 'Kfr' gain selection in the CDR for lane A
|
||||||
|
* KFRE = 'Kfr' gain selection in the CDR for lane E
|
||||||
|
* SDFMA = Bandwidth of digital filter for lane A
|
||||||
|
* SDFME = Bandwidth of digital filter for lane E
|
||||||
|
* SDTXLA = Lane A transmitter amplitude levels
|
||||||
|
* SDTXLE = Lane E transmitter amplitude levels
|
||||||
|
*/
|
||||||
|
enum srdscr3_mask {
|
||||||
|
SRDSCR3_KFRA_SATA = 0x10000000,
|
||||||
|
SRDSCR3_KFRE_SATA = 0x00100000,
|
||||||
|
SRDSCR3_KFR_SATA = SRDSCR3_KFRA_SATA | SRDSCR3_KFRE_SATA,
|
||||||
|
|
||||||
|
SRDSCR3_KPHA_SATA = 0x04000000,
|
||||||
|
SRDSCR3_KPHE_SATA = 0x00040000,
|
||||||
|
SRDSCR3_KPH_SATA = SRDSCR3_KPHA_SATA | SRDSCR3_KPHE_SATA,
|
||||||
|
|
||||||
|
SRDSCR3_SDFMA_SATA_PEX = 0x01000000,
|
||||||
|
SRDSCR3_SDFME_SATA_PEX = 0x00010000,
|
||||||
|
SRDSCR3_SDFM_SATA_PEX = SRDSCR3_SDFMA_SATA_PEX | SRDSCR3_SDFME_SATA_PEX,
|
||||||
|
|
||||||
|
SRDSCR3_SDTXLA_SATA = 0x00000500,
|
||||||
|
SRDSCR3_SDTXLE_SATA = 0x00000005,
|
||||||
|
SRDSCR3_SDTXL_SATA = SRDSCR3_SDTXLA_SATA | SRDSCR3_SDTXLE_SATA,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdscr4_mask - Bit masks for SRDSCR4 (SerDes Control Register 4)
|
||||||
|
* @SRDSCR4_PROTA_SATA: Bitmask to set the PROTA field of SRDSCR4 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR4_PROTE_SATA: Bitmask to set the PROTE field of SRDSCR4 to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR4_PROT_SATA: Combined bitmask to set both PROT fields to the
|
||||||
|
* value used by SATA
|
||||||
|
* @SRDSCR4_PROTA_PEX: Bitmask to set the PROTA field of SRDSCR4 to the
|
||||||
|
* value used by PCI Express
|
||||||
|
* @SRDSCR4_PROTE_PEX: Bitmask to set the PROTE field of SRDSCR4 to the
|
||||||
|
* value used by PCI Express
|
||||||
|
* @SRDSCR4_PROT_PEX: Combined bitmask to set both PROT fields to the
|
||||||
|
* value used by PCI Express
|
||||||
|
* @SRDSCR4_PROTA_SGMII: Bitmask to set the PROTA field of SRDSCR4 to the
|
||||||
|
* value used by SGMII
|
||||||
|
* @SRDSCR4_PROTE_SGMII: Bitmask to set the PROTE field of SRDSCR4 to the
|
||||||
|
* value used by SGMII
|
||||||
|
* @SRDSCR4_PROT_SGMII: Combined bitmask to set both PROT fields to the
|
||||||
|
* value used by SGMII
|
||||||
|
* @SRDSCR4_PLANE_X2: Bitmask to set the PLANE field of SRDSCR4
|
||||||
|
* @SRDSCR4_RFCKS_100: Bitmask to set the RFCKS field of SRDSCR4 to the
|
||||||
|
* value 100Mhz
|
||||||
|
* @SRDSCR4_RFCKS_125: Bitmask to set the RFCKS field of SRDSCR4 to the
|
||||||
|
* value 125Mhz
|
||||||
|
* @SRDSCR4_RFCKS_150: Bitmask to set the RFCKS field of SRDSCR4 to the
|
||||||
|
* value 150Mhz
|
||||||
|
*
|
||||||
|
* PROTA = Lane A protocol select
|
||||||
|
* PROTE = Lane E protocol select
|
||||||
|
* PLAME = Number of PCI Express lanes
|
||||||
|
*/
|
||||||
|
enum srdscr4_mask {
|
||||||
|
SRDSCR4_PROTA_SATA = 0x00000800,
|
||||||
|
SRDSCR4_PROTE_SATA = 0x00000008,
|
||||||
|
SRDSCR4_PROT_SATA = SRDSCR4_PROTA_SATA | SRDSCR4_PROTE_SATA,
|
||||||
|
|
||||||
|
SRDSCR4_PROTA_PEX = 0x00000100,
|
||||||
|
SRDSCR4_PROTE_PEX = 0x00000001,
|
||||||
|
SRDSCR4_PROT_PEX = SRDSCR4_PROTA_PEX | SRDSCR4_PROTE_PEX,
|
||||||
|
|
||||||
|
SRDSCR4_PROTA_SGMII = 0x00000500,
|
||||||
|
SRDSCR4_PROTE_SGMII = 0x00000005,
|
||||||
|
SRDSCR4_PROT_SGMII = SRDSCR4_PROTA_SGMII | SRDSCR4_PROTE_SGMII,
|
||||||
|
|
||||||
|
SRDSCR4_PLANE_X2 = 0x01000000,
|
||||||
|
|
||||||
|
SRDSCR4_RFCKS_100 = (0 << 28),
|
||||||
|
SRDSCR4_RFCKS_125 = (1 << 28),
|
||||||
|
SRDSCR4_RFCKS_150 = (3 << 28),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum srdsrstctl_mask - Bit masks for SRDSRSTCTL (SerDes Reset Control Register)
|
||||||
|
* @SRDSRSTCTL_RST: Bitmask for the RST (Software reset) field of the
|
||||||
|
* SRDSRSTCTL
|
||||||
|
* @SRDSRSTCTL_SATA_RESET: Bitmask for the SATA_RESET (SATA reset) field of the
|
||||||
|
* SRDSRSTCTL
|
||||||
|
*/
|
||||||
|
enum srdsrstctl_mask {
|
||||||
|
SRDSRSTCTL_RST = 0x80000000,
|
||||||
|
SRDSRSTCTL_SATA_RESET = 0xf,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mpc83xx_serdes_regs - Register map of the SerDes controller
|
||||||
|
* @srdscr0: SerDes Control Register 0
|
||||||
|
* @srdscr1: SerDes Control Register 1
|
||||||
|
* @srdscr2: SerDes Control Register 2
|
||||||
|
* @srdscr3: SerDes Control Register 3
|
||||||
|
* @srdscr4: SerDes Control Register 4
|
||||||
|
* @fill0: Reserved space in the register map
|
||||||
|
* @srdsrstctl: SerDes Reset Control Register
|
||||||
|
*/
|
||||||
|
struct mpc83xx_serdes_regs {
|
||||||
|
u32 srdscr0;
|
||||||
|
u32 srdscr1;
|
||||||
|
u32 srdscr2;
|
||||||
|
u32 srdscr3;
|
||||||
|
u32 srdscr4;
|
||||||
|
u8 fill0[12];
|
||||||
|
u32 srdsrstctl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum pex_type - Types of PCI Express
|
||||||
|
* @PEX_X1: PCI Express in x1 mode
|
||||||
|
* @PEX_X2: PCI Express in x2 mode
|
||||||
|
*/
|
||||||
|
enum pex_type {
|
||||||
|
PEX_X1,
|
||||||
|
PEX_X2,
|
||||||
|
};
|
|
@ -34,4 +34,13 @@ config STM32_SDRAM
|
||||||
support external memories like sdram, psram & nand.
|
support external memories like sdram, psram & nand.
|
||||||
This driver is for the sdram memory interface with the FMC.
|
This driver is for the sdram memory interface with the FMC.
|
||||||
|
|
||||||
|
config MPC83XX_SDRAM
|
||||||
|
bool "Enable MPC83XX SDRAM support"
|
||||||
|
depends on RAM
|
||||||
|
help
|
||||||
|
Enable support for the internal DDR Memory Controller of the MPC83xx
|
||||||
|
family of SoCs. Both static configurations, as well as configuring
|
||||||
|
the RAM through the use of SPD (Serial Presence Detect) is supported
|
||||||
|
via device tree settings.
|
||||||
|
|
||||||
source "drivers/ram/stm32mp1/Kconfig"
|
source "drivers/ram/stm32mp1/Kconfig"
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
# SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
#
|
||||||
obj-$(CONFIG_RAM) += ram-uclass.o
|
obj-$(CONFIG_RAM) += ram-uclass.o
|
||||||
|
obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
|
||||||
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
|
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
|
||||||
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
|
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
|
||||||
obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
|
obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
|
||||||
|
|
1096
drivers/ram/mpc83xx_sdram.c
Normal file
1096
drivers/ram/mpc83xx_sdram.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -64,4 +64,9 @@ config SYSRESET_X86
|
||||||
help
|
help
|
||||||
Reboot support for generic x86 processor reset.
|
Reboot support for generic x86 processor reset.
|
||||||
|
|
||||||
|
config SYSRESET_MCP83XX
|
||||||
|
bool "Enable support MPC83xx SoC family reboot driver"
|
||||||
|
help
|
||||||
|
Reboot support for NXP MPC83xx SoCs.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -3,15 +3,16 @@
|
||||||
# (C) Copyright 2016 Cadence Design Systems Inc.
|
# (C) Copyright 2016 Cadence Design Systems Inc.
|
||||||
|
|
||||||
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
|
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
|
||||||
|
obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
|
||||||
|
obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
|
||||||
|
obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
|
||||||
|
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
|
||||||
obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
|
obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
|
||||||
|
obj-$(CONFIG_SYSRESET_MCP83XX) += sysreset_mpc83xx.o
|
||||||
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
|
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
|
||||||
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
|
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
|
||||||
obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
|
obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
|
||||||
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
|
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
|
||||||
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
|
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
|
||||||
obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o
|
obj-$(CONFIG_SYSRESET_X86) += sysreset_x86.o
|
||||||
obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
|
|
||||||
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
|
|
||||||
obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
|
|
||||||
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
|
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
|
||||||
obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
|
|
||||||
|
|
|
@ -24,6 +24,16 @@ int sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||||
return ops->request(dev, type);
|
return ops->request(dev, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sysreset_get_status(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
struct sysreset_ops *ops = sysreset_get_ops(dev);
|
||||||
|
|
||||||
|
if (!ops->get_status)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
return ops->get_status(dev, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
int sysreset_walk(enum sysreset_t type)
|
int sysreset_walk(enum sysreset_t type)
|
||||||
{
|
{
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
212
drivers/sysreset/sysreset_mpc83xx.c
Normal file
212
drivers/sysreset/sysreset_mpc83xx.c
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <sysreset.h>
|
||||||
|
#include <wait_bit.h>
|
||||||
|
|
||||||
|
#include "sysreset_mpc83xx.h"
|
||||||
|
|
||||||
|
/* Magic 4-byte word to enable reset ('RSTE' in ASCII) */
|
||||||
|
static const u32 RPR_MAGIC = 0x52535445;
|
||||||
|
/* Wait at most 2000ms for reset control enable bit */
|
||||||
|
static const uint RESET_WAIT_TIMEOUT = 2000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __do_reset() - Execute the system reset
|
||||||
|
*
|
||||||
|
* Return: The functions resets the system, and never returns.
|
||||||
|
*/
|
||||||
|
static int __do_reset(void)
|
||||||
|
{
|
||||||
|
ulong msr;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
|
||||||
|
|
||||||
|
puts("Resetting the board.\n");
|
||||||
|
|
||||||
|
/* Interrupts and MMU off */
|
||||||
|
msr = mfmsr();
|
||||||
|
msr &= ~(MSR_EE | MSR_IR | MSR_DR);
|
||||||
|
mtmsr(msr);
|
||||||
|
|
||||||
|
/* Enable Reset Control Reg */
|
||||||
|
out_be32(&immap->reset.rpr, RPR_MAGIC);
|
||||||
|
sync();
|
||||||
|
isync();
|
||||||
|
|
||||||
|
/* Confirm Reset Control Reg is enabled */
|
||||||
|
res = wait_for_bit_be32(&immap->reset.rcer, RCER_CRE, true,
|
||||||
|
RESET_WAIT_TIMEOUT, false);
|
||||||
|
if (res) {
|
||||||
|
debug("%s: Timed out waiting for reset control to be set\n",
|
||||||
|
__func__);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
udelay(200);
|
||||||
|
|
||||||
|
/* Perform reset, only one bit */
|
||||||
|
out_be32(&immap->reset.rcr, RCR_SWHR);
|
||||||
|
|
||||||
|
/* Never executes */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case SYSRESET_WARM:
|
||||||
|
case SYSRESET_COLD:
|
||||||
|
return __do_reset();
|
||||||
|
default:
|
||||||
|
return -EPROTONOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINPROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print_83xx_arb_event() - Print arbiter events to buffer
|
||||||
|
* @force: Print arbiter events, even if none are indicated by the system
|
||||||
|
* @buf: The buffer to receive the printed arbiter event information
|
||||||
|
* @size: The size of the buffer to receive the printed arbiter event
|
||||||
|
* information in bytes
|
||||||
|
*
|
||||||
|
* Return: Number of bytes printed to buffer, -ve on error
|
||||||
|
*/
|
||||||
|
static int print_83xx_arb_event(bool force, char *buf, int size)
|
||||||
|
{
|
||||||
|
int etype = (gd->arch.arbiter_event_attributes & AEATR_EVENT)
|
||||||
|
>> AEATR_EVENT_SHIFT;
|
||||||
|
int mstr_id = (gd->arch.arbiter_event_attributes & AEATR_MSTR_ID)
|
||||||
|
>> AEATR_MSTR_ID_SHIFT;
|
||||||
|
int tbst = (gd->arch.arbiter_event_attributes & AEATR_TBST)
|
||||||
|
>> AEATR_TBST_SHIFT;
|
||||||
|
int tsize = (gd->arch.arbiter_event_attributes & AEATR_TSIZE)
|
||||||
|
>> AEATR_TSIZE_SHIFT;
|
||||||
|
int ttype = (gd->arch.arbiter_event_attributes & AEATR_TTYPE)
|
||||||
|
>> AEATR_TTYPE_SHIFT;
|
||||||
|
int tsize_val = (tbst << 3) | tsize;
|
||||||
|
int tsize_bytes = tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we don't force output, and there is no event (event address ==
|
||||||
|
* 0), then don't print anything
|
||||||
|
*/
|
||||||
|
if (!force && !gd->arch.arbiter_event_address)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_FULL)) {
|
||||||
|
res = snprintf(buf, size,
|
||||||
|
"Arbiter Event Status:\n"
|
||||||
|
" %s: 0x%08lX\n"
|
||||||
|
" %s: 0x%1x = %s\n"
|
||||||
|
" %s: 0x%02x = %s\n"
|
||||||
|
" %s: 0x%1x = %d bytes\n"
|
||||||
|
" %s: 0x%02x = %s\n",
|
||||||
|
"Event Address", gd->arch.arbiter_event_address,
|
||||||
|
"Event Type", etype, event[etype],
|
||||||
|
"Master ID", mstr_id, master[mstr_id],
|
||||||
|
"Transfer Size", tsize_val, tsize_bytes,
|
||||||
|
"Transfer Type", ttype, transfer[ttype]);
|
||||||
|
} else if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_BRIEF)) {
|
||||||
|
res = snprintf(buf, size,
|
||||||
|
"Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n",
|
||||||
|
gd->arch.arbiter_event_attributes,
|
||||||
|
gd->arch.arbiter_event_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_sysreset_get_status(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
/* Ad-hoc data structure to map RSR bit values to their descriptions */
|
||||||
|
static const struct {
|
||||||
|
/* Bit mask for the bit in question */
|
||||||
|
ulong mask;
|
||||||
|
/* Description of the bitmask in question */
|
||||||
|
char *desc;
|
||||||
|
} bits[] = {
|
||||||
|
{
|
||||||
|
RSR_SWSR, "Software Soft"}, {
|
||||||
|
RSR_SWHR, "Software Hard"}, {
|
||||||
|
RSR_JSRS, "JTAG Soft"}, {
|
||||||
|
RSR_CSHR, "Check Stop"}, {
|
||||||
|
RSR_SWRS, "Software Watchdog"}, {
|
||||||
|
RSR_BMRS, "Bus Monitor"}, {
|
||||||
|
RSR_SRS, "External/Internal Soft"}, {
|
||||||
|
RSR_HRS, "External/Internal Hard"}
|
||||||
|
};
|
||||||
|
int res;
|
||||||
|
ulong rsr = gd->arch.reset_status;
|
||||||
|
int i;
|
||||||
|
char *sep;
|
||||||
|
|
||||||
|
res = snprintf(buf, size, "Reset Status:");
|
||||||
|
if (res < 0) {
|
||||||
|
debug("%s: Could not write reset status message (err = %d)\n",
|
||||||
|
dev->name, res);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += res;
|
||||||
|
size -= res;
|
||||||
|
|
||||||
|
sep = " ";
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bits); i++)
|
||||||
|
/* Print description of set bits */
|
||||||
|
if (rsr & bits[i].mask) {
|
||||||
|
res = snprintf(buf, size, "%s%s%s", sep, bits[i].desc,
|
||||||
|
(i == ARRAY_SIZE(bits) - 1) ? "\n" : "");
|
||||||
|
if (res < 0) {
|
||||||
|
debug("%s: Could not write reset status message (err = %d)\n",
|
||||||
|
dev->name, res);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
buf += res;
|
||||||
|
size -= res;
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO(mario.six@gdsys.cc): Move this into a dedicated
|
||||||
|
* arbiter driver
|
||||||
|
*/
|
||||||
|
if (CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_FULL) ||
|
||||||
|
CONFIG_IS_ENABLED(CONFIG_DISPLAY_AER_BRIEF)) {
|
||||||
|
/*
|
||||||
|
* If there was a bus monitor reset event, we force the arbiter
|
||||||
|
* event to be printed
|
||||||
|
*/
|
||||||
|
res = print_83xx_arb_event(rsr & RSR_BMRS, buf, size);
|
||||||
|
if (res < 0) {
|
||||||
|
debug("%s: Could not write arbiter event message (err = %d)\n",
|
||||||
|
dev->name, res);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
buf += res;
|
||||||
|
size -= res;
|
||||||
|
}
|
||||||
|
snprintf(buf, size, "\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sysreset_ops mpc83xx_sysreset = {
|
||||||
|
.request = mpc83xx_sysreset_request,
|
||||||
|
.get_status = mpc83xx_sysreset_get_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(sysreset_mpc83xx) = {
|
||||||
|
.name = "mpc83xx_sysreset",
|
||||||
|
.id = UCLASS_SYSRESET,
|
||||||
|
.ops = &mpc83xx_sysreset,
|
||||||
|
};
|
103
drivers/sysreset/sysreset_mpc83xx.h
Normal file
103
drivers/sysreset/sysreset_mpc83xx.h
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYSRESET_MPC83XX_H_
|
||||||
|
#define _SYSRESET_MPC83XX_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String array for all possible event types; indexed by the EVENT field of the
|
||||||
|
* AEATR register.
|
||||||
|
*/
|
||||||
|
static const char * const event[] = {
|
||||||
|
"Address Time Out",
|
||||||
|
"Data Time Out",
|
||||||
|
"Address Only Transfer Type",
|
||||||
|
"External Control Word Transfer Type",
|
||||||
|
"Reserved Transfer Type",
|
||||||
|
"Transfer Error",
|
||||||
|
"reserved",
|
||||||
|
"reserved"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String array for all possible master IDs, which reflects the source of the
|
||||||
|
* transaction that caused the error; indexed by the MSTR_ID field of the AEATR
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
static const char * const master[] = {
|
||||||
|
"e300 Core Data Transaction",
|
||||||
|
"reserved",
|
||||||
|
"e300 Core Instruction Fetch",
|
||||||
|
"reserved",
|
||||||
|
"TSEC1",
|
||||||
|
"TSEC2",
|
||||||
|
"USB MPH",
|
||||||
|
"USB DR",
|
||||||
|
"Encryption Core",
|
||||||
|
"I2C Boot Sequencer",
|
||||||
|
"JTAG",
|
||||||
|
"reserved",
|
||||||
|
"eSDHC",
|
||||||
|
"PCI1",
|
||||||
|
"PCI2",
|
||||||
|
"DMA",
|
||||||
|
"QUICC Engine 00",
|
||||||
|
"QUICC Engine 01",
|
||||||
|
"QUICC Engine 10",
|
||||||
|
"QUICC Engine 11",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"SATA1",
|
||||||
|
"SATA2",
|
||||||
|
"SATA3",
|
||||||
|
"SATA4",
|
||||||
|
"reserved",
|
||||||
|
"PCI Express 1",
|
||||||
|
"PCI Express 2",
|
||||||
|
"TDM-DMAC"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String array for all possible transfer types; indexed by the TTYPE field of
|
||||||
|
* the AEATR register.
|
||||||
|
*/
|
||||||
|
static const char * const transfer[] = {
|
||||||
|
"Address-only, Clean Block",
|
||||||
|
"Address-only, lwarx reservation set",
|
||||||
|
"Single-beat or Burst write",
|
||||||
|
"reserved",
|
||||||
|
"Address-only, Flush Block",
|
||||||
|
"reserved",
|
||||||
|
"Burst write",
|
||||||
|
"reserved",
|
||||||
|
"Address-only, sync",
|
||||||
|
"Address-only, tlbsync",
|
||||||
|
"Single-beat or Burst read",
|
||||||
|
"Single-beat or Burst read",
|
||||||
|
"Address-only, Kill Block",
|
||||||
|
"Address-only, icbi",
|
||||||
|
"Burst read",
|
||||||
|
"reserved",
|
||||||
|
"Address-only, eieio",
|
||||||
|
"reserved",
|
||||||
|
"Single-beat write",
|
||||||
|
"reserved",
|
||||||
|
"ecowx - Illegal single-beat write",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"reserved",
|
||||||
|
"Address-only, TLB Invalidate",
|
||||||
|
"reserved",
|
||||||
|
"Single-beat or Burst read",
|
||||||
|
"reserved",
|
||||||
|
"eciwx - Illegal single-beat read",
|
||||||
|
"reserved",
|
||||||
|
"Burst read",
|
||||||
|
"reserved"
|
||||||
|
};
|
||||||
|
#endif /* _SYSRESET_MPC83XX_H_ */
|
|
@ -29,6 +29,13 @@ static int sandbox_warm_sysreset_request(struct udevice *dev,
|
||||||
return -EINPROGRESS;
|
return -EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sandbox_warm_sysreset_get_status(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
strlcpy(buf, "Reset Status: WARM", size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||||
{
|
{
|
||||||
struct sandbox_state *state = state_get_current();
|
struct sandbox_state *state = state_get_current();
|
||||||
|
@ -60,8 +67,16 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||||
return -EINPROGRESS;
|
return -EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sandbox_sysreset_get_status(struct udevice *dev, char *buf, int size)
|
||||||
|
{
|
||||||
|
strlcpy(buf, "Reset Status: COLD", size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct sysreset_ops sandbox_sysreset_ops = {
|
static struct sysreset_ops sandbox_sysreset_ops = {
|
||||||
.request = sandbox_sysreset_request,
|
.request = sandbox_sysreset_request,
|
||||||
|
.get_status = sandbox_sysreset_get_status,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct udevice_id sandbox_sysreset_ids[] = {
|
static const struct udevice_id sandbox_sysreset_ids[] = {
|
||||||
|
@ -78,6 +93,7 @@ U_BOOT_DRIVER(sysreset_sandbox) = {
|
||||||
|
|
||||||
static struct sysreset_ops sandbox_warm_sysreset_ops = {
|
static struct sysreset_ops sandbox_warm_sysreset_ops = {
|
||||||
.request = sandbox_warm_sysreset_request,
|
.request = sandbox_warm_sysreset_request,
|
||||||
|
.get_status = sandbox_warm_sysreset_get_status,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct udevice_id sandbox_warm_sysreset_ids[] = {
|
static const struct udevice_id sandbox_warm_sysreset_ids[] = {
|
||||||
|
|
|
@ -140,4 +140,11 @@ config STM32_TIMER
|
||||||
Select this to enable support for the timer found on
|
Select this to enable support for the timer found on
|
||||||
STM32 devices.
|
STM32 devices.
|
||||||
|
|
||||||
|
config MPC83XX_TIMER
|
||||||
|
bool "MPC83xx timer support"
|
||||||
|
depends on TIMER
|
||||||
|
help
|
||||||
|
Select this to enable support for the timer found on
|
||||||
|
devices based on the MPC83xx family of SoCs.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
# Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
|
# Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
|
||||||
|
|
||||||
obj-y += timer-uclass.o
|
obj-y += timer-uclass.o
|
||||||
|
obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
|
||||||
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
|
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
|
||||||
|
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
|
||||||
|
obj-$(CONFIG_AST_TIMER) += ast_timer.o
|
||||||
|
obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
|
||||||
|
obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
|
||||||
obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o
|
obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o
|
||||||
obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o
|
obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o
|
||||||
obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
|
obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
|
||||||
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
|
|
||||||
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
|
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
|
||||||
obj-$(CONFIG_AST_TIMER) += ast_timer.o
|
|
||||||
obj-$(CONFIG_STI_TIMER) += sti-timer.o
|
|
||||||
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
|
|
||||||
obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
|
|
||||||
obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
|
|
||||||
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
|
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
|
||||||
obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
|
obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
|
||||||
|
obj-$(CONFIG_STI_TIMER) += sti-timer.o
|
||||||
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
|
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
|
||||||
|
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
|
||||||
|
|
249
drivers/timer/mpc83xx_timer.c
Normal file
249
drivers/timer/mpc83xx_timer.c
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include <clk.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <timer.h>
|
||||||
|
#include <watchdog.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct mpc83xx_timer_priv - Private data structure for MPC83xx timer driver
|
||||||
|
* @decrementer_count: Value to which the decrementer register should be re-set
|
||||||
|
* to when a timer interrupt occurs, thus determines the
|
||||||
|
* interrupt frequency (value for 1e6/HZ microseconds)
|
||||||
|
* @timestamp: Counter for the number of timer interrupts that have
|
||||||
|
* occurred (i.e. can be used to trigger events
|
||||||
|
* periodically in the timer interrupt)
|
||||||
|
*/
|
||||||
|
struct mpc83xx_timer_priv {
|
||||||
|
uint decrementer_count;
|
||||||
|
ulong timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitmask for enabling the time base in the SPCR (System Priority
|
||||||
|
* Configuration Register)
|
||||||
|
*/
|
||||||
|
static const u32 SPCR_TBEN_MASK = BIT(31 - 9);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_dec() - Get the value of the decrementer register
|
||||||
|
*
|
||||||
|
* Return: The value of the decrementer register
|
||||||
|
*/
|
||||||
|
static inline unsigned long get_dec(void)
|
||||||
|
{
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
|
asm volatile ("mfdec %0" : "=r" (val) : );
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_dec() - Set the value of the decrementer register
|
||||||
|
* @val: The value of the decrementer register to be set
|
||||||
|
*/
|
||||||
|
static inline void set_dec(unsigned long val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
asm volatile ("mtdec %0"::"r" (val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mftbu() - Get value of TBU (upper time base) register
|
||||||
|
*
|
||||||
|
* Return: Value of the TBU register
|
||||||
|
*/
|
||||||
|
static inline u32 mftbu(void)
|
||||||
|
{
|
||||||
|
u32 rval;
|
||||||
|
|
||||||
|
asm volatile("mftbu %0" : "=r" (rval));
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mftb() - Get value of TBL (lower time base) register
|
||||||
|
*
|
||||||
|
* Return: Value of the TBL register
|
||||||
|
*/
|
||||||
|
static inline u32 mftb(void)
|
||||||
|
{
|
||||||
|
u32 rval;
|
||||||
|
|
||||||
|
asm volatile("mftb %0" : "=r" (rval));
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO(mario.six@gdsys.cc): This should really be done by timer_init, and the
|
||||||
|
* interrupt init should go into a interrupt driver.
|
||||||
|
*/
|
||||||
|
int interrupt_init(void)
|
||||||
|
{
|
||||||
|
immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||||
|
struct udevice *csb;
|
||||||
|
struct udevice *board;
|
||||||
|
struct udevice *timer;
|
||||||
|
struct mpc83xx_timer_priv *timer_priv;
|
||||||
|
struct clk clock;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = uclass_first_device_err(UCLASS_TIMER, &timer);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not find timer device (error: %d)",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_priv = dev_get_priv(timer);
|
||||||
|
|
||||||
|
if (board_get(&board)) {
|
||||||
|
debug("%s: board device could not be fetched.\n", __func__);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board,
|
||||||
|
"csb", &csb);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not retrieve CSB device (error: %d)",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_get_by_index(csb, 0, &clock);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not retrieve clock (error: %d)",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_priv->decrementer_count = (clk_get_rate(&clock) / 4)
|
||||||
|
/ CONFIG_SYS_HZ;
|
||||||
|
/* Enable e300 time base */
|
||||||
|
setbits_be32(&immr->sysconf.spcr, SPCR_TBEN_MASK);
|
||||||
|
|
||||||
|
set_dec(timer_priv->decrementer_count);
|
||||||
|
|
||||||
|
/* Switch on interrupts */
|
||||||
|
set_msr(get_msr() | MSR_EE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timer_interrupt() - Handler for the timer interrupt
|
||||||
|
* @regs: Array of register values
|
||||||
|
*/
|
||||||
|
void timer_interrupt(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
struct udevice *timer = gd->timer;
|
||||||
|
struct mpc83xx_timer_priv *priv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* During initialization, gd->timer might not be set yet, but the timer
|
||||||
|
* interrupt may already be enabled. In this case, wait for the
|
||||||
|
* initialization to complete
|
||||||
|
*/
|
||||||
|
if (!timer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = dev_get_priv(timer);
|
||||||
|
|
||||||
|
/* Restore Decrementer Count */
|
||||||
|
set_dec(priv->decrementer_count);
|
||||||
|
|
||||||
|
priv->timestamp++;
|
||||||
|
|
||||||
|
#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
|
||||||
|
if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
|
||||||
|
WATCHDOG_RESET();
|
||||||
|
#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
|
||||||
|
|
||||||
|
#ifdef CONFIG_LED_STATUS
|
||||||
|
status_led_tick(priv->timestamp);
|
||||||
|
#endif /* CONFIG_LED_STATUS */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SHOW_ACTIVITY
|
||||||
|
board_show_activity(priv->timestamp);
|
||||||
|
#endif /* CONFIG_SHOW_ACTIVITY */
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_ticks(ulong ticks)
|
||||||
|
{
|
||||||
|
ulong end = get_ticks() + ticks;
|
||||||
|
|
||||||
|
while (end > get_ticks())
|
||||||
|
WATCHDOG_RESET();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_timer_get_count(struct udevice *dev, u64 *count)
|
||||||
|
{
|
||||||
|
u32 tbu, tbl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To make sure that no tbl overflow occurred between reading tbl and
|
||||||
|
* tbu, read tbu again, and compare it with the previously read tbu
|
||||||
|
* value: If they're different, a tbl overflow has occurred.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
tbu = mftbu();
|
||||||
|
tbl = mftb();
|
||||||
|
} while (tbu != mftbu());
|
||||||
|
|
||||||
|
*count = (tbu * 0x10000ULL) + tbl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mpc83xx_timer_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct timer_dev_priv *uc_priv = dev->uclass_priv;
|
||||||
|
struct clk clock;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = interrupt_init();
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: interrupt_init failed (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_get_by_index(dev, 0, &clock);
|
||||||
|
if (ret) {
|
||||||
|
debug("%s: Could not retrieve clock (err = %d)\n",
|
||||||
|
dev->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_priv->clock_rate = (clk_get_rate(&clock) + 3L) / 4L;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct timer_ops mpc83xx_timer_ops = {
|
||||||
|
.get_count = mpc83xx_timer_get_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id mpc83xx_timer_ids[] = {
|
||||||
|
{ .compatible = "fsl,mpc83xx-timer" },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(mpc83xx_timer) = {
|
||||||
|
.name = "mpc83xx_timer",
|
||||||
|
.id = UCLASS_TIMER,
|
||||||
|
.of_match = mpc83xx_timer_ids,
|
||||||
|
.probe = mpc83xx_timer_probe,
|
||||||
|
.ops = &mpc83xx_timer_ops,
|
||||||
|
.flags = DM_FLAG_PRE_RELOC,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mpc83xx_timer_priv),
|
||||||
|
};
|
|
@ -9,19 +9,21 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct cpu_platdata - platform data for a CPU
|
* struct cpu_platdata - platform data for a CPU
|
||||||
|
* @cpu_id: Platform-specific way of identifying the CPU.
|
||||||
|
* @ucode_version: Microcode version, if CPU_FEAT_UCODE is set
|
||||||
|
* @device_id: Driver-defined device identifier
|
||||||
|
* @family: DMTF CPU Family identifier
|
||||||
|
* @id: DMTF CPU Processor identifier
|
||||||
*
|
*
|
||||||
* This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU
|
* This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU
|
||||||
* device.
|
* device.
|
||||||
*
|
|
||||||
* @cpu_id: Platform-specific way of identifying the CPU.
|
|
||||||
* @ucode_version: Microcode version, if CPU_FEAT_UCODE is set
|
|
||||||
*/
|
*/
|
||||||
struct cpu_platdata {
|
struct cpu_platdata {
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
int ucode_version;
|
int ucode_version;
|
||||||
ulong device_id;
|
ulong device_id;
|
||||||
u16 family; /* DMTF CPU Family */
|
u16 family;
|
||||||
u32 id[2]; /* DMTF CPU Processor IDs */
|
u32 id[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CPU features - mostly just a placeholder for now */
|
/* CPU features - mostly just a placeholder for now */
|
||||||
|
@ -88,39 +90,46 @@ struct cpu_ops {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_get_desc() - Get a description string for a CPU
|
* cpu_get_desc() - Get a description string for a CPU
|
||||||
*
|
|
||||||
* @dev: Device to check (UCLASS_CPU)
|
* @dev: Device to check (UCLASS_CPU)
|
||||||
* @buf: Buffer to place string
|
* @buf: Buffer to place string
|
||||||
* @size: Size of string space
|
* @size: Size of string space
|
||||||
* @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
|
*
|
||||||
|
* Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error
|
||||||
*/
|
*/
|
||||||
int cpu_get_desc(struct udevice *dev, char *buf, int size);
|
int cpu_get_desc(struct udevice *dev, char *buf, int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_get_info() - Get information about a CPU
|
* cpu_get_info() - Get information about a CPU
|
||||||
*
|
|
||||||
* @dev: Device to check (UCLASS_CPU)
|
* @dev: Device to check (UCLASS_CPU)
|
||||||
* @info: Returns CPU info
|
* @info: Returns CPU info
|
||||||
* @return 0 if OK, -ve on error
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int cpu_get_info(struct udevice *dev, struct cpu_info *info);
|
int cpu_get_info(struct udevice *dev, struct cpu_info *info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_get_count() - Get number of CPUs
|
* cpu_get_count() - Get number of CPUs
|
||||||
*
|
|
||||||
* @dev: Device to check (UCLASS_CPU)
|
* @dev: Device to check (UCLASS_CPU)
|
||||||
* @return CPU count if OK, -ve on error
|
*
|
||||||
|
* Return: CPU count if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int cpu_get_count(struct udevice *dev);
|
int cpu_get_count(struct udevice *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_get_vendor() - Get vendor name of a CPU
|
* cpu_get_vendor() - Get vendor name of a CPU
|
||||||
*
|
|
||||||
* @dev: Device to check (UCLASS_CPU)
|
* @dev: Device to check (UCLASS_CPU)
|
||||||
* @buf: Buffer to place string
|
* @buf: Buffer to place string
|
||||||
* @size: Size of string space
|
* @size: Size of string space
|
||||||
* @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
|
*
|
||||||
|
* Return: 0 if OK, -ENOSPC if buffer is too small, other -ve on error
|
||||||
*/
|
*/
|
||||||
int cpu_get_vendor(struct udevice *dev, char *buf, int size);
|
int cpu_get_vendor(struct udevice *dev, char *buf, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpu_probe_all() - Probe all available CPUs
|
||||||
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int cpu_probe_all(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -193,6 +193,22 @@ static inline struct device_node *of_find_node_by_path(const char *path)
|
||||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||||
const char *type, const char *compatible);
|
const char *type, const char *compatible);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* of_find_node_by_prop_value() - find a node with a given property value
|
||||||
|
*
|
||||||
|
* Find a node based on a property value.
|
||||||
|
* @from: Node to start searching from or NULL. the node you pass will not be
|
||||||
|
* searched, only the next one will; typically, you pass what the previous
|
||||||
|
* call returned.
|
||||||
|
* @propname: property name to check
|
||||||
|
* @propval: property value to search for
|
||||||
|
* @proplen: length of the value in propval
|
||||||
|
* @return node pointer or NULL if not found
|
||||||
|
*/
|
||||||
|
struct device_node *of_find_node_by_prop_value(struct device_node *from,
|
||||||
|
const char *propname,
|
||||||
|
const void *propval,
|
||||||
|
int proplen);
|
||||||
/**
|
/**
|
||||||
* of_find_node_by_phandle() - Find a node given a phandle
|
* of_find_node_by_phandle() - Find a node given a phandle
|
||||||
*
|
*
|
||||||
|
|
|
@ -702,6 +702,20 @@ int ofnode_read_resource_byname(ofnode node, const char *name,
|
||||||
*/
|
*/
|
||||||
ofnode ofnode_by_compatible(ofnode from, const char *compat);
|
ofnode ofnode_by_compatible(ofnode from, const char *compat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ofnode_by_prop_value() - Find the next node with given property value
|
||||||
|
*
|
||||||
|
* Find the next node after @from that has a @propname with a value
|
||||||
|
* @propval and a length @proplen.
|
||||||
|
*
|
||||||
|
* @from: ofnode to start from (use ofnode_null() to start at the
|
||||||
|
* beginning) @propname: property name to check @propval: property value to
|
||||||
|
* search for @proplen: length of the value in propval @return ofnode
|
||||||
|
* found, or ofnode_null() if none
|
||||||
|
*/
|
||||||
|
ofnode ofnode_by_prop_value(ofnode from, const char *propname,
|
||||||
|
const void *propval, int proplen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ofnode_for_each_subnode() - iterate over all subnodes of a parent
|
* ofnode_for_each_subnode() - iterate over all subnodes of a parent
|
||||||
*
|
*
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct udevice;
|
||||||
* @post_probe: Called after a new device is probed
|
* @post_probe: Called after a new device is probed
|
||||||
* @pre_remove: Called before a device is removed
|
* @pre_remove: Called before a device is removed
|
||||||
* @child_post_bind: Called after a child is bound to a device in this uclass
|
* @child_post_bind: Called after a child is bound to a device in this uclass
|
||||||
|
* @child_pre_probe: Called before a child is probed in this uclass
|
||||||
* @init: Called to set up the uclass
|
* @init: Called to set up the uclass
|
||||||
* @destroy: Called to destroy the uclass
|
* @destroy: Called to destroy the uclass
|
||||||
* @priv_auto_alloc_size: If non-zero this is the size of the private data
|
* @priv_auto_alloc_size: If non-zero this is the size of the private data
|
||||||
|
|
33
include/dt-bindings/clk/mpc83xx-clk.h
Normal file
33
include/dt-bindings/clk/mpc83xx-clk.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DT_BINDINGS_MPC83XX_CLK_H
|
||||||
|
#define DT_BINDINGS_MPC83XX_CLK_H
|
||||||
|
#define MPC83XX_CLK_CORE 0
|
||||||
|
#define MPC83XX_CLK_CSB 1
|
||||||
|
#define MPC83XX_CLK_QE 2
|
||||||
|
#define MPC83XX_CLK_BRG 3
|
||||||
|
#define MPC83XX_CLK_LBIU 4
|
||||||
|
#define MPC83XX_CLK_LCLK 5
|
||||||
|
#define MPC83XX_CLK_MEM 6
|
||||||
|
#define MPC83XX_CLK_MEM_SEC 7
|
||||||
|
#define MPC83XX_CLK_ENC 8
|
||||||
|
#define MPC83XX_CLK_I2C1 9
|
||||||
|
#define MPC83XX_CLK_I2C2 10
|
||||||
|
#define MPC83XX_CLK_TDM 11
|
||||||
|
#define MPC83XX_CLK_SDHC 12
|
||||||
|
#define MPC83XX_CLK_TSEC1 13
|
||||||
|
#define MPC83XX_CLK_TSEC2 14
|
||||||
|
#define MPC83XX_CLK_USBDR 15
|
||||||
|
#define MPC83XX_CLK_USBMPH 16
|
||||||
|
#define MPC83XX_CLK_PCIEXP1 17
|
||||||
|
#define MPC83XX_CLK_PCIEXP2 18
|
||||||
|
#define MPC83XX_CLK_SATA 19
|
||||||
|
#define MPC83XX_CLK_DMAC 20
|
||||||
|
#define MPC83XX_CLK_PCI 21
|
||||||
|
/* Count */
|
||||||
|
#define MPC83XX_CLK_COUNT 22
|
||||||
|
#endif /* DT_BINDINGS_MPC83XX_CLK_H */
|
161
include/dt-bindings/memory/mpc83xx-sdram.h
Normal file
161
include/dt-bindings/memory/mpc83xx-sdram.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DT_BINDINGS_MPC83XX_SDRAM_H
|
||||||
|
#define DT_BINDINGS_MPC83XX_SDRAM_H
|
||||||
|
|
||||||
|
/* DDR Control Driver register */
|
||||||
|
|
||||||
|
#define DSO_DISABLE 0
|
||||||
|
#define DSO_ENABLE 1
|
||||||
|
|
||||||
|
#define DSO_P_IMPEDANCE_HIGHEST_Z 0x0
|
||||||
|
#define DSO_P_IMPEDANCE_MUCH_HIGHER_Z 0x8
|
||||||
|
#define DSO_P_IMPEDANCE_HIGHER_Z 0xC
|
||||||
|
#define DSO_P_IMPEDANCE_NOMINAL 0xE
|
||||||
|
#define DSO_P_IMPEDANCE_LOWER_Z 0xF
|
||||||
|
|
||||||
|
#define DSO_N_IMPEDANCE_HIGHEST_Z 0x0
|
||||||
|
#define DSO_N_IMPEDANCE_MUCH_HIGHER_Z 0x8
|
||||||
|
#define DSO_N_IMPEDANCE_HIGHER_Z 0xC
|
||||||
|
#define DSO_N_IMPEDANCE_NOMINAL 0xE
|
||||||
|
#define DSO_N_IMPEDANCE_LOWER_Z 0xF
|
||||||
|
|
||||||
|
#define ODT_TERMINATION_75_OHM 0
|
||||||
|
#define ODT_TERMINATION_150_OHM 1
|
||||||
|
|
||||||
|
#define DDR_TYPE_DDR2_1_8_VOLT 0
|
||||||
|
#define DDR_TYPE_DDR1_2_5_VOLT 1
|
||||||
|
|
||||||
|
#define MVREF_SEL_EXTERNAL 0
|
||||||
|
#define MVREF_SEL_INTERNAL_GVDD 1
|
||||||
|
|
||||||
|
#define M_ODR_ENABLE 0
|
||||||
|
#define M_ODR_DISABLE 1
|
||||||
|
|
||||||
|
/* CS config register */
|
||||||
|
|
||||||
|
#define AUTO_PRECHARGE_ENABLE 0x00800000
|
||||||
|
#define AUTO_PRECHARGE_DISABLE 0x00000000
|
||||||
|
|
||||||
|
#define ODT_RD_NEVER 0x00000000
|
||||||
|
#define ODT_RD_ONLY_CURRENT 0x00100000
|
||||||
|
#define ODT_RD_ONLY_OTHER_CS 0x00200000
|
||||||
|
#define ODT_RD_ONLY_OTHER_DIMM 0x00300000
|
||||||
|
#define ODT_RD_ALL 0x00400000
|
||||||
|
|
||||||
|
#define ODT_WR_NEVER 0x00000000
|
||||||
|
#define ODT_WR_ONLY_CURRENT 0x00010000
|
||||||
|
#define ODT_WR_ONLY_OTHER_CS 0x00020000
|
||||||
|
#define ODT_WR_ONLY_OTHER_DIMM 0x00030000
|
||||||
|
#define ODT_WR_ALL 0x00040000
|
||||||
|
|
||||||
|
/* DDR SDRAM Clock Control register */
|
||||||
|
|
||||||
|
#define CLOCK_ADJUST_025 0x01000000
|
||||||
|
#define CLOCK_ADJUST_05 0x02000000
|
||||||
|
#define CLOCK_ADJUST_075 0x03000000
|
||||||
|
#define CLOCK_ADJUST_1 0x04000000
|
||||||
|
|
||||||
|
#define CASLAT_20 0x3 /* CAS latency = 2.0 */
|
||||||
|
#define CASLAT_25 0x4 /* CAS latency = 2.5 */
|
||||||
|
#define CASLAT_30 0x5 /* CAS latency = 3.0 */
|
||||||
|
#define CASLAT_35 0x6 /* CAS latency = 3.5 */
|
||||||
|
#define CASLAT_40 0x7 /* CAS latency = 4.0 */
|
||||||
|
#define CASLAT_45 0x8 /* CAS latency = 4.5 */
|
||||||
|
#define CASLAT_50 0x9 /* CAS latency = 5.0 */
|
||||||
|
#define CASLAT_55 0xa /* CAS latency = 5.5 */
|
||||||
|
#define CASLAT_60 0xb /* CAS latency = 6.0 */
|
||||||
|
#define CASLAT_65 0xc /* CAS latency = 6.5 */
|
||||||
|
#define CASLAT_70 0xd /* CAS latency = 7.0 */
|
||||||
|
#define CASLAT_75 0xe /* CAS latency = 7.5 */
|
||||||
|
#define CASLAT_80 0xf /* CAS latency = 8.0 */
|
||||||
|
|
||||||
|
/* DDR SDRAM Timing Configuration 2 register */
|
||||||
|
|
||||||
|
#define READ_LAT_PLUS_1 0x0
|
||||||
|
#define READ_LAT 0x2
|
||||||
|
#define READ_LAT_PLUS_1_4 0x3
|
||||||
|
#define READ_LAT_PLUS_1_2 0x4
|
||||||
|
#define READ_LAT_PLUS_3_4 0x5
|
||||||
|
#define READ_LAT_PLUS_5_4 0x7
|
||||||
|
#define READ_LAT_PLUS_3_2 0x8
|
||||||
|
#define READ_LAT_PLUS_7_4 0x9
|
||||||
|
#define READ_LAT_PLUS_2 0xA
|
||||||
|
#define READ_LAT_PLUS_9_4 0xB
|
||||||
|
#define READ_LAT_PLUS_5_2 0xC
|
||||||
|
#define READ_LAT_PLUS_11_4 0xD
|
||||||
|
#define READ_LAT_PLUS_3 0xE
|
||||||
|
#define READ_LAT_PLUS_13_4 0xF
|
||||||
|
#define READ_LAT_PLUS_7_2 0x10
|
||||||
|
#define READ_LAT_PLUS_15_4 0x11
|
||||||
|
#define READ_LAT_PLUS_4 0x12
|
||||||
|
#define READ_LAT_PLUS_17_4 0x13
|
||||||
|
#define READ_LAT_PLUS_9_2 0x14
|
||||||
|
#define READ_LAT_PLUS_19_4 0x15
|
||||||
|
|
||||||
|
#define CLOCK_DELAY_0 0x0
|
||||||
|
#define CLOCK_DELAY_1_4 0x1
|
||||||
|
#define CLOCK_DELAY_1_2 0x2
|
||||||
|
#define CLOCK_DELAY_3_4 0x3
|
||||||
|
#define CLOCK_DELAY_1 0x4
|
||||||
|
#define CLOCK_DELAY_5_4 0x5
|
||||||
|
#define CLOCK_DELAY_3_2 0x6
|
||||||
|
|
||||||
|
/* DDR SDRAM Control Configuration */
|
||||||
|
|
||||||
|
#define SREN_DISABLE 0x0
|
||||||
|
#define SREN_ENABLE 0x1
|
||||||
|
|
||||||
|
#define ECC_DISABLE 0x0
|
||||||
|
#define ECC_ENABLE 0x1
|
||||||
|
|
||||||
|
#define RD_DISABLE 0x0
|
||||||
|
#define RD_ENABLE 0x1
|
||||||
|
|
||||||
|
#define TYPE_DDR1 0x2
|
||||||
|
#define TYPE_DDR2 0x3
|
||||||
|
|
||||||
|
#define DYN_PWR_DISABLE 0x0
|
||||||
|
#define DYN_PWR_ENABLE 0x1
|
||||||
|
|
||||||
|
#define DATA_BUS_WIDTH_16 0x1
|
||||||
|
#define DATA_BUS_WIDTH_32 0x2
|
||||||
|
|
||||||
|
#define NCAP_DISABLE 0x0
|
||||||
|
#define NCAP_ENABLE 0x1
|
||||||
|
|
||||||
|
#define TIMING_1T 0x0
|
||||||
|
#define TIMING_2T 0x1
|
||||||
|
|
||||||
|
#define INTERLEAVE_NONE 0x0
|
||||||
|
#define INTERLEAVE_1_AND_2 0x1
|
||||||
|
|
||||||
|
#define PRECHARGE_MA_10 0x0
|
||||||
|
#define PRECHARGE_MA_8 0x1
|
||||||
|
|
||||||
|
#define STRENGTH_FULL 0x0
|
||||||
|
#define STRENGTH_HALF 0x1
|
||||||
|
|
||||||
|
#define INITIALIZATION_DONT_BYPASS 0x0
|
||||||
|
#define INITIALIZATION_BYPASS 0x1
|
||||||
|
|
||||||
|
/* DDR SDRAM Control Configuration 2 register */
|
||||||
|
|
||||||
|
#define MODE_NORMAL 0x0
|
||||||
|
#define MODE_REFRESH 0x1
|
||||||
|
|
||||||
|
#define DLL_RESET_ENABLE 0x0
|
||||||
|
#define DLL_RESET_DISABLE 0x1
|
||||||
|
|
||||||
|
#define DQS_TRUE 0x0
|
||||||
|
|
||||||
|
#define ODT_ASSERT_NEVER 0x0
|
||||||
|
#define ODT_ASSERT_WRITES 0x1
|
||||||
|
#define ODT_ASSERT_READS 0x2
|
||||||
|
#define ODT_ASSERT_ALWAYS 0x3
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,7 +27,7 @@ void board_init_f(ulong dummy);
|
||||||
* board_f.c for where it is called. If this is not provided, a default
|
* board_f.c for where it is called. If this is not provided, a default
|
||||||
* version (which does nothing) will be used.
|
* version (which does nothing) will be used.
|
||||||
*
|
*
|
||||||
* @return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int arch_cpu_init(void);
|
int arch_cpu_init(void);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ int arch_cpu_init(void);
|
||||||
* relocation. This is similar to arch_cpu_init() but is able to reference
|
* relocation. This is similar to arch_cpu_init() but is able to reference
|
||||||
* devices
|
* devices
|
||||||
*
|
*
|
||||||
* @return 0 if OK, -ve on error
|
* Return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int arch_cpu_init_dm(void);
|
int arch_cpu_init_dm(void);
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ int arch_cpu_init_dm(void);
|
||||||
* board_f.c for where it is called. If this is not provided, a default
|
* board_f.c for where it is called. If this is not provided, a default
|
||||||
* version (which does nothing) will be used.
|
* version (which does nothing) will be used.
|
||||||
*
|
*
|
||||||
* @return: 0 on success, otherwise error
|
* Return: 0 on success, otherwise error
|
||||||
*/
|
*/
|
||||||
int mach_cpu_init(void);
|
int mach_cpu_init(void);
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@ int mach_cpu_init(void);
|
||||||
* Where U-Boot relies on binary blobs to handle part of the system init, this
|
* Where U-Boot relies on binary blobs to handle part of the system init, this
|
||||||
* function can be used to set up the blobs. This is used on some Intel
|
* function can be used to set up the blobs. This is used on some Intel
|
||||||
* platforms.
|
* platforms.
|
||||||
|
*
|
||||||
|
* Return: 0
|
||||||
*/
|
*/
|
||||||
int arch_fsp_init(void);
|
int arch_fsp_init(void);
|
||||||
|
|
||||||
|
@ -78,12 +80,12 @@ int dram_init(void);
|
||||||
* CONFIG_SYS_SDRAM_BASE and the size will be determined by a call to
|
* CONFIG_SYS_SDRAM_BASE and the size will be determined by a call to
|
||||||
* get_effective_memsize().
|
* get_effective_memsize().
|
||||||
*
|
*
|
||||||
* @return 0 if OK, -ve on error
|
* Return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int dram_init_banksize(void);
|
int dram_init_banksize(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserve all necessary stacks
|
* arch_reserve_stacks() - Reserve all necessary stacks
|
||||||
*
|
*
|
||||||
* This is used in generic board init sequence in common/board_f.c. Each
|
* This is used in generic board init sequence in common/board_f.c. Each
|
||||||
* architecture could provide this function to tailor the required stacks.
|
* architecture could provide this function to tailor the required stacks.
|
||||||
|
@ -96,21 +98,29 @@ int dram_init_banksize(void);
|
||||||
* positions of the stack. The stack pointer(s) will be set to this later.
|
* positions of the stack. The stack pointer(s) will be set to this later.
|
||||||
* gd->irq_sp is only required, if the architecture needs it.
|
* gd->irq_sp is only required, if the architecture needs it.
|
||||||
*
|
*
|
||||||
* @return 0 if no error
|
* Return: 0 if no error
|
||||||
*/
|
*/
|
||||||
int arch_reserve_stacks(void);
|
int arch_reserve_stacks(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_cache_f_r() - Turn on the cache in preparation for relocation
|
* init_cache_f_r() - Turn on the cache in preparation for relocation
|
||||||
*
|
*
|
||||||
* @return 0 if OK, -ve on error
|
* Return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int init_cache_f_r(void);
|
int init_cache_f_r(void);
|
||||||
|
|
||||||
|
#if !CONFIG_IS_ENABLED(CPU)
|
||||||
|
/**
|
||||||
|
* print_cpuinfo() - Display information about the CPU
|
||||||
|
*
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
int print_cpuinfo(void);
|
int print_cpuinfo(void);
|
||||||
|
#endif
|
||||||
int timer_init(void);
|
int timer_init(void);
|
||||||
int reserve_mmu(void);
|
int reserve_mmu(void);
|
||||||
int misc_init_f(void);
|
int misc_init_f(void);
|
||||||
|
|
||||||
#if defined(CONFIG_DTB_RESELECT)
|
#if defined(CONFIG_DTB_RESELECT)
|
||||||
int embedded_dtb_select(void);
|
int embedded_dtb_select(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -120,28 +130,28 @@ extern ulong monitor_flash_len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ulong board_init_f_alloc_reserve - allocate reserved area
|
* ulong board_init_f_alloc_reserve - allocate reserved area
|
||||||
|
* @top: top of the reserve area, growing down.
|
||||||
*
|
*
|
||||||
* This function is called by each architecture very early in the start-up
|
* This function is called by each architecture very early in the start-up
|
||||||
* code to allow the C runtime to reserve space on the stack for writable
|
* code to allow the C runtime to reserve space on the stack for writable
|
||||||
* 'globals' such as GD and the malloc arena.
|
* 'globals' such as GD and the malloc arena.
|
||||||
*
|
*
|
||||||
* @top: top of the reserve area, growing down.
|
* Return: bottom of reserved area
|
||||||
* @return: bottom of reserved area
|
|
||||||
*/
|
*/
|
||||||
ulong board_init_f_alloc_reserve(ulong top);
|
ulong board_init_f_alloc_reserve(ulong top);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* board_init_f_init_reserve - initialize the reserved area(s)
|
* board_init_f_init_reserve - initialize the reserved area(s)
|
||||||
|
* @base: top from which reservation was done
|
||||||
*
|
*
|
||||||
* This function is called once the C runtime has allocated the reserved
|
* This function is called once the C runtime has allocated the reserved
|
||||||
* area on the stack. It must initialize the GD at the base of that area.
|
* area on the stack. It must initialize the GD at the base of that area.
|
||||||
*
|
|
||||||
* @base: top from which reservation was done
|
|
||||||
*/
|
*/
|
||||||
void board_init_f_init_reserve(ulong base);
|
void board_init_f_init_reserve(ulong base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* arch_setup_gd() - Set up the global_data pointer
|
* arch_setup_gd() - Set up the global_data pointer
|
||||||
|
* @gd_ptr: Pointer to global data
|
||||||
*
|
*
|
||||||
* This pointer is special in some architectures and cannot easily be assigned
|
* This pointer is special in some architectures and cannot easily be assigned
|
||||||
* to. For example on x86 it is implemented by adding a specific record to its
|
* to. For example on x86 it is implemented by adding a specific record to its
|
||||||
|
@ -149,8 +159,6 @@ void board_init_f_init_reserve(ulong base);
|
||||||
* For most architectures this can simply be:
|
* For most architectures this can simply be:
|
||||||
*
|
*
|
||||||
* gd = gd_ptr;
|
* gd = gd_ptr;
|
||||||
*
|
|
||||||
* @gd_ptr: Pointer to global data
|
|
||||||
*/
|
*/
|
||||||
void arch_setup_gd(gd_t *gd_ptr);
|
void arch_setup_gd(gd_t *gd_ptr);
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,105 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
|
||||||
* Based on bitrev from the Linux kernel, by Akinobu Mita
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LINUX_BITREV_H
|
#ifndef _LINUX_BITREV_H
|
||||||
#define _LINUX_BITREV_H
|
#define _LINUX_BITREV_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
extern u8 const byte_rev_table[256];
|
#ifdef CONFIG_HAVE_ARCH_BITREVERSE
|
||||||
|
#include <asm/bitrev.h>
|
||||||
|
|
||||||
static inline u8 bitrev8(u8 byte)
|
#define __bitrev32 __arch_bitrev32
|
||||||
|
#define __bitrev16 __arch_bitrev16
|
||||||
|
#define __bitrev8 __arch_bitrev8
|
||||||
|
|
||||||
|
#else
|
||||||
|
extern u8 const byte_rev_table[256];
|
||||||
|
static inline u8 __bitrev8(u8 byte)
|
||||||
{
|
{
|
||||||
return byte_rev_table[byte];
|
return byte_rev_table[byte];
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 bitrev16(u16 in);
|
static inline u16 __bitrev16(u16 x)
|
||||||
u32 bitrev32(u32 in);
|
{
|
||||||
|
return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 __bitrev32(u32 x)
|
||||||
|
{
|
||||||
|
return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
|
||||||
|
|
||||||
|
#define __bitrev8x4(x) (__bitrev32(swab32(x)))
|
||||||
|
|
||||||
|
#define __constant_bitrev32(x) \
|
||||||
|
({ \
|
||||||
|
u32 __x = x; \
|
||||||
|
__x = (__x >> 16) | (__x << 16);\
|
||||||
|
__x = ((__x & (u32)0xFF00FF00UL) >> 8) | ((__x & (u32)0x00FF00FFUL) << 8); \
|
||||||
|
__x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \
|
||||||
|
__x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \
|
||||||
|
__x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \
|
||||||
|
__x; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __constant_bitrev16(x) \
|
||||||
|
({ \
|
||||||
|
u16 __x = x; \
|
||||||
|
__x = (__x >> 8) | (__x << 8); \
|
||||||
|
__x = ((__x & (u16)0xF0F0U) >> 4) | ((__x & (u16)0x0F0FU) << 4); \
|
||||||
|
__x = ((__x & (u16)0xCCCCU) >> 2) | ((__x & (u16)0x3333U) << 2); \
|
||||||
|
__x = ((__x & (u16)0xAAAAU) >> 1) | ((__x & (u16)0x5555U) << 1); \
|
||||||
|
__x; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __constant_bitrev8x4(x) \
|
||||||
|
({ \
|
||||||
|
u32 __x = x; \
|
||||||
|
__x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \
|
||||||
|
__x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \
|
||||||
|
__x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \
|
||||||
|
__x; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __constant_bitrev8(x) \
|
||||||
|
({ \
|
||||||
|
u8 __x = x; \
|
||||||
|
__x = (__x >> 4) | (__x << 4); \
|
||||||
|
__x = ((__x & (u8)0xCCU) >> 2) | ((__x & (u8)0x33U) << 2); \
|
||||||
|
__x = ((__x & (u8)0xAAU) >> 1) | ((__x & (u8)0x55U) << 1); \
|
||||||
|
__x; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define bitrev32(x) \
|
||||||
|
({ \
|
||||||
|
u32 __x = x; \
|
||||||
|
__builtin_constant_p(__x) ? \
|
||||||
|
__constant_bitrev32(__x) : \
|
||||||
|
__bitrev32(__x); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define bitrev16(x) \
|
||||||
|
({ \
|
||||||
|
u16 __x = x; \
|
||||||
|
__builtin_constant_p(__x) ? \
|
||||||
|
__constant_bitrev16(__x) : \
|
||||||
|
__bitrev16(__x); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define bitrev8x4(x) \
|
||||||
|
({ \
|
||||||
|
u32 __x = x; \
|
||||||
|
__builtin_constant_p(__x) ? \
|
||||||
|
__constant_bitrev8x4(__x) : \
|
||||||
|
__bitrev8x4(__x); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define bitrev8(x) \
|
||||||
|
({ \
|
||||||
|
u8 __x = x; \
|
||||||
|
__builtin_constant_p(__x) ? \
|
||||||
|
__constant_bitrev8(__x) : \
|
||||||
|
__bitrev8(__x) ; \
|
||||||
|
})
|
||||||
#endif /* _LINUX_BITREV_H */
|
#endif /* _LINUX_BITREV_H */
|
||||||
|
|
|
@ -1110,6 +1110,8 @@
|
||||||
#define CSBNDS_EA 0x000000FF
|
#define CSBNDS_EA 0x000000FF
|
||||||
#define CSBNDS_EA_SHIFT 24
|
#define CSBNDS_EA_SHIFT 24
|
||||||
|
|
||||||
|
#ifndef CONFIG_MPC83XX_SDRAM
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CSn_CONFIG - Chip Select Configuration Register
|
* CSn_CONFIG - Chip Select Configuration Register
|
||||||
*/
|
*/
|
||||||
|
@ -1407,6 +1409,8 @@
|
||||||
#define ECC_ERROR_MAN_SBEC (0xff000000 >> 24)
|
#define ECC_ERROR_MAN_SBEC (0xff000000 >> 24)
|
||||||
#define ECC_ERROR_MAN_SBEC_SHIFT 0
|
#define ECC_ERROR_MAN_SBEC_SHIFT 0
|
||||||
|
|
||||||
|
#endif /* !CONFIG_MPC83XX_SDRAM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CONFIG_ADDRESS - PCI Config Address Register
|
* CONFIG_ADDRESS - PCI Config Address Register
|
||||||
*/
|
*/
|
||||||
|
@ -1510,6 +1514,7 @@
|
||||||
*/
|
*/
|
||||||
#define PMCCR1_POWER_OFF 0x00000020
|
#define PMCCR1_POWER_OFF 0x00000020
|
||||||
|
|
||||||
|
#ifndef CONFIG_RAM
|
||||||
/*
|
/*
|
||||||
* DDRCDR - DDR Control Driver Register
|
* DDRCDR - DDR Control Driver Register
|
||||||
*/
|
*/
|
||||||
|
@ -1531,6 +1536,7 @@
|
||||||
#define DDRCDR_DDR_CFG 0x00040000
|
#define DDRCDR_DDR_CFG 0x00040000
|
||||||
#define DDRCDR_M_ODR 0x00000002
|
#define DDRCDR_M_ODR 0x00000002
|
||||||
#define DDRCDR_Q_DRN 0x00000001
|
#define DDRCDR_Q_DRN 0x00000001
|
||||||
|
#endif /* !CONFIG_RAM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCIE Bridge Register
|
* PCIE Bridge Register
|
||||||
|
|
|
@ -28,6 +28,14 @@ struct sysreset_ops {
|
||||||
* (in which case this method will not actually return)
|
* (in which case this method will not actually return)
|
||||||
*/
|
*/
|
||||||
int (*request)(struct udevice *dev, enum sysreset_t type);
|
int (*request)(struct udevice *dev, enum sysreset_t type);
|
||||||
|
/**
|
||||||
|
* get_status() - get printable reset status information
|
||||||
|
*
|
||||||
|
* @buf: Buffer to receive the textual reset information
|
||||||
|
* @size: Size of the passed buffer
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int (*get_status)(struct udevice *dev, char *buf, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
|
#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
|
||||||
|
@ -40,6 +48,15 @@ struct sysreset_ops {
|
||||||
*/
|
*/
|
||||||
int sysreset_request(struct udevice *dev, enum sysreset_t type);
|
int sysreset_request(struct udevice *dev, enum sysreset_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_status() - get printable reset status information
|
||||||
|
*
|
||||||
|
* @buf: Buffer to receive the textual reset information
|
||||||
|
* @size: Size of the passed buffer
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int sysreset_get_status(struct udevice *dev, char *buf, int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sysreset_walk() - cause a system reset
|
* sysreset_walk() - cause a system reset
|
||||||
*
|
*
|
||||||
|
|
28
lib/bitrev.c
28
lib/bitrev.c
|
@ -1,13 +1,14 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0+
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Based on bitrev from the Linux kernel, by Akinobu Mita
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CONFIG_HAVE_ARCH_BITREVERSE
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
#include <linux/bitrev.h>
|
#include <linux/bitrev.h>
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("Bit ordering reversal functions");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
const u8 byte_rev_table[256] = {
|
const u8 byte_rev_table[256] = {
|
||||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
||||||
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
||||||
|
@ -42,17 +43,6 @@ const u8 byte_rev_table[256] = {
|
||||||
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
|
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
|
||||||
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
|
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(byte_rev_table);
|
||||||
|
|
||||||
u16 bitrev16(u16 x)
|
#endif /* CONFIG_HAVE_ARCH_BITREVERSE */
|
||||||
{
|
|
||||||
return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* bitrev32 - reverse the order of bits in a u32 value
|
|
||||||
* @x: value to be bit-reversed
|
|
||||||
*/
|
|
||||||
u32 bitrev32(u32 x)
|
|
||||||
{
|
|
||||||
return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,4 +47,5 @@ obj-$(CONFIG_WDT) += wdt.o
|
||||||
obj-$(CONFIG_AXI) += axi.o
|
obj-$(CONFIG_AXI) += axi.o
|
||||||
obj-$(CONFIG_MISC) += misc.o
|
obj-$(CONFIG_MISC) += misc.o
|
||||||
obj-$(CONFIG_DM_SERIAL) += serial.o
|
obj-$(CONFIG_DM_SERIAL) += serial.o
|
||||||
|
obj-$(CONFIG_CPU) += cpu.o
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -82,7 +82,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
dm, 3, 1, do_dm,
|
dm, 3, 1, do_dm,
|
||||||
"Driver model low level access",
|
"Driver model low level access",
|
||||||
"tree Dump driver model tree ('*' = activated)\n"
|
"tree Dump driver model tree ('*' = activated)\n"
|
||||||
"dm uclass Dump list of instances for each uclass\n"
|
"dm uclass Dump list of instances for each uclass\n"
|
||||||
"dm devres Dump list of device resources for each device"
|
"dm devres Dump list of device resources for each device"
|
||||||
);
|
);
|
||||||
|
|
45
test/dm/cpu.c
Normal file
45
test/dm/cpu.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2018
|
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <dm/test.h>
|
||||||
|
#include <dm/uclass-internal.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <test/ut.h>
|
||||||
|
|
||||||
|
static int dm_test_cpu(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
char text[128];
|
||||||
|
struct cpu_info info;
|
||||||
|
|
||||||
|
ut_assertok(cpu_probe_all());
|
||||||
|
|
||||||
|
/* Check that cpu_probe_all really activated all CPUs */
|
||||||
|
for (uclass_find_first_device(UCLASS_CPU, &dev);
|
||||||
|
dev;
|
||||||
|
uclass_find_next_device(&dev))
|
||||||
|
ut_assert(dev->flags & DM_FLAG_ACTIVATED);
|
||||||
|
|
||||||
|
ut_assertok(uclass_get_device_by_name(UCLASS_CPU, "cpu-test1", &dev));
|
||||||
|
|
||||||
|
ut_assertok(cpu_get_desc(dev, text, sizeof(text)));
|
||||||
|
ut_assertok(strcmp(text, "LEG Inc. SuperMegaUltraTurbo CPU No. 1"));
|
||||||
|
|
||||||
|
ut_assertok(cpu_get_info(dev, &info));
|
||||||
|
ut_asserteq(info.cpu_freq, 42 * 42 * 42 * 42 * 42);
|
||||||
|
ut_asserteq(info.features, 0x42424242);
|
||||||
|
|
||||||
|
ut_asserteq(cpu_get_count(dev), 42);
|
||||||
|
|
||||||
|
ut_assertok(cpu_get_vendor(dev, text, sizeof(text)));
|
||||||
|
ut_assertok(strcmp(text, "Languid Example Garbage Inc."));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(dm_test_cpu, DM_TESTF_SCAN_FDT);
|
|
@ -15,3 +15,30 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_ofnode_compatible, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
DM_TEST(dm_test_ofnode_compatible, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
const char propname[] = "compatible";
|
||||||
|
const char propval[] = "denx,u-boot-fdt-test";
|
||||||
|
const char *str;
|
||||||
|
ofnode node = ofnode_null();
|
||||||
|
|
||||||
|
/* Find first matching node, there should be at least one */
|
||||||
|
node = ofnode_by_prop_value(node, propname, propval, sizeof(propval));
|
||||||
|
ut_assert(ofnode_valid(node));
|
||||||
|
str = ofnode_read_string(node, propname);
|
||||||
|
ut_assert(str && !strcmp(str, propval));
|
||||||
|
|
||||||
|
/* Find the rest of the matching nodes */
|
||||||
|
while (true) {
|
||||||
|
node = ofnode_by_prop_value(node, propname, propval,
|
||||||
|
sizeof(propval));
|
||||||
|
if (!ofnode_valid(node))
|
||||||
|
break;
|
||||||
|
str = ofnode_read_string(node, propname);
|
||||||
|
ut_assert(str && !strcmp(str, propval));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_ofnode_by_prop_value, DM_TESTF_SCAN_FDT);
|
||||||
|
|
|
@ -45,6 +45,26 @@ static int dm_test_sysreset_base(struct unit_test_state *uts)
|
||||||
}
|
}
|
||||||
DM_TEST(dm_test_sysreset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
DM_TEST(dm_test_sysreset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
static int dm_test_sysreset_get_status(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
char msg[64];
|
||||||
|
|
||||||
|
/* Device 1 is the warm sysreset device */
|
||||||
|
ut_assertok(uclass_get_device(UCLASS_SYSRESET, 1, &dev));
|
||||||
|
ut_assertok(sysreset_get_status(dev, msg, sizeof(msg)));
|
||||||
|
ut_asserteq_str("Reset Status: WARM", msg);
|
||||||
|
|
||||||
|
/* Device 2 is the cold sysreset device */
|
||||||
|
ut_assertok(uclass_get_device(UCLASS_SYSRESET, 2, &dev));
|
||||||
|
ut_assertok(sysreset_get_status(dev, msg, sizeof(msg)));
|
||||||
|
ut_asserteq_str("Reset Status: COLD", msg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(dm_test_sysreset_get_status, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
/* Test that we can walk through the sysreset devices */
|
/* Test that we can walk through the sysreset devices */
|
||||||
static int dm_test_sysreset_walk(struct unit_test_state *uts)
|
static int dm_test_sysreset_walk(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,9 +130,9 @@ called from the U-Boot build system for this reason.
|
||||||
|
|
||||||
Binman considers the output files created by mkimage to be binary blobs
|
Binman considers the output files created by mkimage to be binary blobs
|
||||||
which it can place in an image. Binman does not replace the mkimage tool or
|
which it can place in an image. Binman does not replace the mkimage tool or
|
||||||
this purpose. It would be possible in some situtions to create a new entry
|
this purpose. It would be possible in some situations to create a new entry
|
||||||
type for the images in mkimage, but this would not add functionality. It
|
type for the images in mkimage, but this would not add functionality. It
|
||||||
seems better to use the mkiamge tool to generate binaries and avoid blurring
|
seems better to use the mkimage tool to generate binaries and avoid blurring
|
||||||
the boundaries between building input files (mkimage) and packaging then
|
the boundaries between building input files (mkimage) and packaging then
|
||||||
into a final image (binman).
|
into a final image (binman).
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ Example use of binman for x86
|
||||||
In most cases x86 images have a lot of binary blobs, 'black-box' code
|
In most cases x86 images have a lot of binary blobs, 'black-box' code
|
||||||
provided by Intel which must be run for the platform to work. Typically
|
provided by Intel which must be run for the platform to work. Typically
|
||||||
these blobs are not relocatable and must be placed at fixed areas in the
|
these blobs are not relocatable and must be placed at fixed areas in the
|
||||||
firmare image.
|
firmware image.
|
||||||
|
|
||||||
Currently this is handled by ifdtool, which places microcode, FSP, MRC, VGA
|
Currently this is handled by ifdtool, which places microcode, FSP, MRC, VGA
|
||||||
BIOS, reference code and Intel ME binaries into a u-boot.rom file.
|
BIOS, reference code and Intel ME binaries into a u-boot.rom file.
|
||||||
|
@ -406,7 +406,7 @@ either by using a unit number suffix (u-boot@0, u-boot@1) or by using a
|
||||||
different name for each and specifying the type with the 'type' attribute.
|
different name for each and specifying the type with the 'type' attribute.
|
||||||
|
|
||||||
|
|
||||||
Sections and hiearchical images
|
Sections and hierachical images
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
Sometimes it is convenient to split an image into several pieces, each of which
|
Sometimes it is convenient to split an image into several pieces, each of which
|
||||||
|
|
Loading…
Add table
Reference in a new issue