All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx
@ 2018-08-06  8:23 Mario Six
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros Mario Six
                   ` (16 more replies)
  0 siblings, 17 replies; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a RAM driver for the MPC83xx architecture.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Switched preprocessor constants to C constants
    * Improved error reporting
    * Added driver binding file
    * Added full documentation
    
    v2 -> v3:
    * Converted some #ifdefs to if (IS_ENABLED(...))
    * Added driver files to MAINTAINERS
    
    v1 -> v2:
    No changes

 .../bindings/ram/fsl,mpc83xx-mem-controller.txt    |  314 ++++++
 MAINTAINERS                                        |    2 +
 arch/powerpc/cpu/mpc83xx/spd_sdram.c               |    4 +
 drivers/ram/Kconfig                                |    9 +
 drivers/ram/Makefile                               |    1 +
 drivers/ram/mpc83xx_sdram.c                        | 1096 ++++++++++++++++++++
 include/dt-bindings/memory/mpc83xx-sdram.h         |  161 +++
 include/mpc83xx.h                                  |    6 +
 8 files changed, 1593 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt
 create mode 100644 drivers/ram/mpc83xx_sdram.c
 create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h

diff --git a/Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt b/Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt
new file mode 100644
index 00000000000..da01fe908de
--- /dev/null
+++ b/Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt
@@ -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 at 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 at 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>;
+	};
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 1bd583c9753..57329e878ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -495,6 +495,8 @@ POWERPC MPC83XX
 M:	Mario Six <mario.six@gdsys.cc>
 S:	Maintained
 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:	arch/powerpc/cpu/mpc83xx/
 F:	arch/powerpc/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/spd_sdram.c b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
index bbc8ef03c7b..328a018eb6f 100644
--- a/arch/powerpc/cpu/mpc83xx/spd_sdram.c
+++ b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
@@ -10,6 +10,8 @@
  * Xianghua Xiao (X.Xiao at motorola.com)
  */
 
+#ifndef CONFIG_MPC83XX_SDRAM
+
 #include <common.h>
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -924,3 +926,5 @@ void ddr_enable_ecc(unsigned int dram_size)
 	__asm__ __volatile__ ("isync");
 }
 #endif	/* CONFIG_DDR_ECC */
+
+#endif /* !CONFIG_MPC83XX_SDRAM */
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 496e2b793bd..54bb4b419f0 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -34,4 +34,13 @@ config STM32_SDRAM
 	  support external memories like sdram, psram & nand.
 	  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"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 3820d03aa41..4ad3604d163 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -5,6 +5,7 @@
 # SPDX-License-Identifier:      GPL-2.0+
 #
 obj-$(CONFIG_RAM) += ram-uclass.o
+obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
 obj-$(CONFIG_SANDBOX) += sandbox_ram.o
 obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
 obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
diff --git a/drivers/ram/mpc83xx_sdram.c b/drivers/ram/mpc83xx_sdram.c
new file mode 100644
index 00000000000..441baeb6f1a
--- /dev/null
+++ b/drivers/ram/mpc83xx_sdram.c
@@ -0,0 +1,1096 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <dt-bindings/memory/mpc83xx-sdram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Masks for the CS config register */
+static const u32 CSCONFIG_ENABLE = 0x80000000;
+
+static const u32 BANK_BITS_2;
+static const u32 BANK_BITS_3 = 0x00004000;
+
+static const u32 ROW_BITS_12;
+static const u32 ROW_BITS_13 = 0x00000100;
+static const u32 ROW_BITS_14 = 0x00000200;
+
+static const u32 COL_BITS_8;
+static const u32 COL_BITS_9  = 0x00000001;
+static const u32 COL_BITS_10 = 0x00000002;
+static const u32 COL_BITS_11 = 0x00000003;
+
+/* Shifts for the DDR SDRAM Timing Configuration 3 register */
+static const uint TIMING_CFG3_EXT_REFREC_SHIFT = (31 - 15);
+
+/* Shifts for the DDR SDRAM Timing Configuration 0 register */
+static const uint TIMING_CFG0_RWT_SHIFT         = (31 - 1);
+static const uint TIMING_CFG0_WRT_SHIFT         = (31 - 3);
+static const uint TIMING_CFG0_RRT_SHIFT         = (31 - 5);
+static const uint TIMING_CFG0_WWT_SHIFT         = (31 - 7);
+static const uint TIMING_CFG0_ACT_PD_EXIT_SHIFT = (31 - 11);
+static const uint TIMING_CFG0_PRE_PD_EXIT_SHIFT = (31 - 15);
+static const uint TIMING_CFG0_ODT_PD_EXIT_SHIFT = (31 - 23);
+static const uint TIMING_CFG0_MRS_CYC_SHIFT     = (31 - 31);
+
+/* Shifts for the DDR SDRAM Timing Configuration 1 register */
+static const uint TIMING_CFG1_PRETOACT_SHIFT = (31 - 3);
+static const uint TIMING_CFG1_ACTTOPRE_SHIFT = (31 - 7);
+static const uint TIMING_CFG1_ACTTORW_SHIFT  = (31 - 11);
+static const uint TIMING_CFG1_CASLAT_SHIFT   = (31 - 15);
+static const uint TIMING_CFG1_REFREC_SHIFT   = (31 - 19);
+static const uint TIMING_CFG1_WRREC_SHIFT    = (31 - 23);
+static const uint TIMING_CFG1_ACTTOACT_SHIFT = (31 - 27);
+static const uint TIMING_CFG1_WRTORD_SHIFT   = (31 - 31);
+
+/* Shifts for the DDR SDRAM Timing Configuration 2 register */
+static const uint TIMING_CFG2_CPO_SHIFT	          = (31 - 8);
+static const uint TIMING_CFG2_WR_DATA_DELAY_SHIFT = (31 - 21);
+static const uint TIMING_CFG2_ADD_LAT_SHIFT       = (31 - 3);
+static const uint TIMING_CFG2_WR_LAT_DELAY_SHIFT  = (31 - 12);
+static const uint TIMING_CFG2_RD_TO_PRE_SHIFT     = (31 - 18);
+static const uint TIMING_CFG2_CKE_PLS_SHIFT       = (31 - 25);
+static const uint TIMING_CFG2_FOUR_ACT_SHIFT;
+
+/* Shifts for the DDR SDRAM Control Configuration register */
+static const uint SDRAM_CFG_SREN_SHIFT         = (31 - 1);
+static const uint SDRAM_CFG_ECC_EN_SHIFT       = (31 - 2);
+static const uint SDRAM_CFG_RD_EN_SHIFT        = (31 - 3);
+static const uint SDRAM_CFG_SDRAM_TYPE_SHIFT   = (31 - 7);
+static const uint SDRAM_CFG_DYN_PWR_SHIFT      = (31 - 10);
+static const uint SDRAM_CFG_DBW_SHIFT          = (31 - 12);
+static const uint SDRAM_CFG_NCAP_SHIFT         = (31 - 14);
+static const uint SDRAM_CFG_2T_EN_SHIFT        = (31 - 16);
+static const uint SDRAM_CFG_BA_INTLV_CTL_SHIFT = (31 - 23);
+static const uint SDRAM_CFG_PCHB8_SHIFT        = (31 - 27);
+static const uint SDRAM_CFG_HSE_SHIFT          = (31 - 28);
+static const uint SDRAM_CFG_BI_SHIFT           = (31 - 31);
+
+/* Shifts for the DDR SDRAM Control Configuration 2 register */
+static const uint SDRAM_CFG2_FRC_SR_SHIFT = (31 - 0);
+static const uint SDRAM_CFG2_DLL_RST_DIS  = (31 - 2);
+static const uint SDRAM_CFG2_DQS_CFG      = (31 - 5);
+static const uint SDRAM_CFG2_ODT_CFG      = (31 - 10);
+static const uint SDRAM_CFG2_NUM_PR       = (31 - 19);
+
+/* Shifts for the DDR SDRAM Mode register */
+static const uint SDRAM_MODE_ESD_SHIFT = (31 - 15);
+static const uint SDRAM_MODE_SD_SHIFT  = (31 - 31);
+
+/* Shifts for the DDR SDRAM Mode 2 register */
+static const uint SDRAM_MODE2_ESD2_SHIFT = (31 - 15);
+static const uint SDRAM_MODE2_ESD3_SHIFT = (31 - 31);
+
+/* Shifts for the DDR SDRAM Interval Configuration register */
+static const uint SDRAM_INTERVAL_REFINT_SHIFT  = (31 - 15);
+static const uint SDRAM_INTERVAL_BSTOPRE_SHIFT = (31 - 31);
+
+/* Mask for the DDR SDRAM Mode Control register */
+static const u32 SDRAM_CFG_MEM_EN = 0x80000000;
+
+int dram_init(void)
+{
+	struct udevice *ram_ctrl;
+	int ret;
+
+	/* Current assumption: There is only one RAM controller */
+	ret = uclass_first_device_err(UCLASS_RAM, &ram_ctrl);
+	if (ret) {
+		debug("%s: uclass_first_device_err failed: %d\n",
+		      __func__, ret);
+		return ret;
+	}
+
+	/* FIXME(mario.six at gdsys.cc): Set gd->ram_size? */
+
+	return 0;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	if (!IS_ENABLED(CONFIG_VERY_BIG_RAM))
+		return gd->ram_size;
+
+	/* Limit stack to what we can reasonable map */
+	return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+		CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+}
+
+/**
+ * struct mpc83xx_sdram_priv - Private data for MPC83xx RAM controllers
+ * @total_size: The total size of all RAM modules associated with this RAM
+ *		controller in bytes
+ */
+struct mpc83xx_sdram_priv {
+	ulong total_size;
+};
+
+/**
+ * mpc83xx_sdram_static_init() - Statically initialize a RAM module.
+ * @node:    Device tree node associated with ths module in question
+ * @cs:      The chip select to use for this RAM module
+ * @mapaddr: The address where the RAM module should be mapped
+ * @size:    The size of the RAM module to be mapped in bytes
+ *
+ * Return: 0 if OK, -ve on error
+ */
+static int mpc83xx_sdram_static_init(ofnode node, u32 cs, u32 mapaddr, u32 size)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	u32 msize = size;
+	u32 msize_log2 = __ilog2(msize);
+	u32 auto_precharge, odt_rd_cfg, odt_wr_cfg, bank_bits, row_bits,
+	    col_bits;
+	u32 bank_bits_mask, row_bits_mask, col_bits_mask;
+
+	/* Configure the DDR local access window */
+	out_be32(&im->sysconf.ddrlaw[cs].bar, mapaddr & 0xfffff000);
+	out_be32(&im->sysconf.ddrlaw[cs].ar, LBLAWAR_EN | (msize_log2 - 1));
+
+	out_be32(&im->ddr.csbnds[cs].csbnds, (msize - 1) >> 24);
+
+	auto_precharge = ofnode_read_u32_default(node, "auto_precharge", 0);
+	switch (auto_precharge) {
+	case AUTO_PRECHARGE_ENABLE:
+	case AUTO_PRECHARGE_DISABLE:
+		break;
+	default:
+		debug("%s: auto_precharge value %d invalid.\n",
+		      ofnode_get_name(node), auto_precharge);
+		return -EINVAL;
+	}
+
+	odt_rd_cfg = ofnode_read_u32_default(node, "odt_rd_cfg", 0);
+	switch (odt_rd_cfg) {
+	case ODT_RD_ONLY_OTHER_DIMM:
+		if (!IS_ENABLED(CONFIG_MPC8360) &&
+		    !IS_ENABLED(CONFIG_MPC837x)) {
+			debug("%s: odt_rd_cfg value %d invalid.\n",
+			      ofnode_get_name(node), odt_rd_cfg);
+			return -EINVAL;
+		}
+		/* fall through */
+	case ODT_RD_NEVER:
+	case ODT_RD_ONLY_CURRENT:
+	case ODT_RD_ONLY_OTHER_CS:
+		if (!IS_ENABLED(CONFIG_MPC830x) &&
+		    !IS_ENABLED(CONFIG_MPC831x) &&
+		    !IS_ENABLED(CONFIG_MPC8360) &&
+		    !IS_ENABLED(CONFIG_MPC837x)) {
+			debug("%s: odt_rd_cfg value %d invalid.\n",
+			      ofnode_get_name(node), odt_rd_cfg);
+			return -EINVAL;
+		}
+		/* fall through */
+	/* Only MPC832x knows this value */
+	case ODT_RD_ALL:
+		break;
+	default:
+		debug("%s: odt_rd_cfg value %d invalid.\n",
+		      ofnode_get_name(node), odt_rd_cfg);
+		return -EINVAL;
+	}
+
+	odt_wr_cfg = ofnode_read_u32_default(node, "odt_wr_cfg", 0);
+	switch (odt_wr_cfg) {
+	case ODT_WR_ONLY_OTHER_DIMM:
+		if (!IS_ENABLED(CONFIG_MPC8360) &&
+		    !IS_ENABLED(CONFIG_MPC837x)) {
+			debug("%s: odt_wr_cfg value %d invalid.\n",
+			      ofnode_get_name(node), odt_wr_cfg);
+			return -EINVAL;
+		}
+		/* fall through */
+	case ODT_WR_NEVER:
+	case ODT_WR_ONLY_CURRENT:
+	case ODT_WR_ONLY_OTHER_CS:
+		if (!IS_ENABLED(CONFIG_MPC830x) &&
+		    !IS_ENABLED(CONFIG_MPC831x) &&
+		    !IS_ENABLED(CONFIG_MPC8360) &&
+		    !IS_ENABLED(CONFIG_MPC837x)) {
+			debug("%s: odt_wr_cfg value %d invalid.\n",
+			      ofnode_get_name(node), odt_wr_cfg);
+			return -EINVAL;
+		}
+		/* fall through */
+	/* MPC832x only knows this value */
+	case ODT_WR_ALL:
+		break;
+	default:
+		debug("%s: odt_wr_cfg value %d invalid.\n",
+		      ofnode_get_name(node), odt_wr_cfg);
+		return -EINVAL;
+	}
+
+	bank_bits = ofnode_read_u32_default(node, "bank_bits", 0);
+	switch (bank_bits) {
+	case 2:
+		bank_bits_mask = BANK_BITS_2;
+		break;
+	case 3:
+		bank_bits_mask = BANK_BITS_3;
+		break;
+	default:
+		debug("%s: bank_bits value %d invalid.\n",
+		      ofnode_get_name(node), bank_bits);
+		return -EINVAL;
+	}
+
+	row_bits = ofnode_read_u32_default(node, "row_bits", 0);
+	switch (row_bits) {
+	case 12:
+		row_bits_mask = ROW_BITS_12;
+		break;
+	case 13:
+		row_bits_mask = ROW_BITS_13;
+		break;
+	case 14:
+		row_bits_mask = ROW_BITS_14;
+		break;
+	default:
+		debug("%s: row_bits value %d invalid.\n",
+		      ofnode_get_name(node), row_bits);
+		return -EINVAL;
+	}
+
+	col_bits = ofnode_read_u32_default(node, "col_bits", 0);
+	switch (col_bits) {
+	case 8:
+		col_bits_mask = COL_BITS_8;
+		break;
+	case 9:
+		col_bits_mask = COL_BITS_9;
+		break;
+	case 10:
+		col_bits_mask = COL_BITS_10;
+		break;
+	case 11:
+		col_bits_mask = COL_BITS_11;
+		break;
+	default:
+		debug("%s: col_bits value %d invalid.\n",
+		      ofnode_get_name(node), col_bits);
+		return -EINVAL;
+	}
+
+	/* Write CS config value */
+	out_be32(&im->ddr.cs_config[cs], CSCONFIG_ENABLE | auto_precharge |
+					 odt_rd_cfg | odt_wr_cfg |
+					 bank_bits_mask | row_bits_mask |
+					 col_bits_mask);
+	return 0;
+}
+
+/**
+ * mpc83xx_sdram_spd_init() - Initialize a RAM module using a SPD flash.
+ * @node:    Device tree node associated with ths module in question
+ * @cs:      The chip select to use for this RAM module
+ * @mapaddr: The address where the RAM module should be mapped
+ * @size:    The size of the RAM module to be mapped in bytes
+ *
+ * Return: 0 if OK, -ve on error
+ */
+static int mpc83xx_sdram_spd_init(ofnode node, u32 cs, u32 mapaddr, u32 size)
+{
+	/* TODO(mario.six at gdsys.cc): Implement */
+	return 0;
+}
+
+static int mpc83xx_sdram_ofdata_to_platdata(struct udevice *dev)
+{
+	return 0;
+}
+
+static int mpc83xx_sdram_probe(struct udevice *dev)
+{
+	struct mpc83xx_sdram_priv *priv = dev_get_priv(dev);
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	int ret = 0;
+	ofnode subnode;
+	/* DDR control driver register values */
+	u32 dso, pz_override, nz_override, odt_term, ddr_type, mvref_sel, m_odr;
+	u32 ddrcdr;
+	/* DDR SDRAM Clock Control register values */
+	u32 clock_adjust;
+	/* DDR SDRAM Timing Configuration 3 register values */
+	u32 ext_refresh_rec, ext_refresh_rec_mask;
+	/* DDR SDRAM Timing Configuration 0 register values */
+	u32 read_to_write, write_to_read, read_to_read, write_to_write,
+	    active_powerdown_exit, precharge_powerdown_exit,
+	    odt_powerdown_exit, mode_reg_set_cycle;
+	u32 timing_cfg_0;
+	/* DDR SDRAM Timing Configuration 1 register values */
+	u32 precharge_to_activate, activate_to_precharge,
+	    activate_to_readwrite, mcas_latency, refresh_recovery,
+	    last_data_to_precharge, activate_to_activate,
+	    last_write_data_to_read;
+	u32 timing_cfg_1;
+	/* DDR SDRAM Timing Configuration 2 register values */
+	u32 additive_latency, mcas_to_preamble_override, write_latency,
+	    read_to_precharge, write_cmd_to_write_data,
+	    minimum_cke_pulse_width, four_activates_window;
+	u32 timing_cfg_2;
+	/* DDR SDRAM Control Configuration register values */
+	u32 self_refresh, ecc, registered_dram, sdram_type,
+	    dynamic_power_management, databus_width, nc_auto_precharge,
+	    timing_2t, bank_interleaving_ctrl, precharge_bit_8, half_strength,
+	    bypass_initialization;
+	u32 sdram_cfg;
+	/* DDR SDRAM Control Configuration 2 register values */
+	u32 force_self_refresh, dll_reset, dqs_config, odt_config,
+	    posted_refreshes;
+	u32 sdram_cfg2;
+	/* DDR SDRAM Mode Configuration register values */
+	u32 sdmode, esdmode;
+	u32 sdram_mode;
+	/* DDR SDRAM Mode Configuration 2 register values */
+	u32 esdmode2, esdmode3;
+	u32 sdram_mode2;
+	/* DDR SDRAM Interval Configuration register values */
+	u32 refresh_interval, precharge_interval;
+	u32 sdram_interval;
+
+	priv->total_size = 0;
+
+	/* Disable both banks initially (might be re-enabled in loop below) */
+	out_be32(&im->ddr.cs_config[0], 0);
+	out_be32(&im->ddr.cs_config[1], 0);
+
+	dso = dev_read_u32_default(dev, "driver_software_override", 0);
+	if (dso > 1) {
+		debug("%s: driver_software_override value %d invalid.\n",
+		      dev->name, dso);
+		return -EINVAL;
+	}
+
+	pz_override = dev_read_u32_default(dev, "p_impedance_override", 0);
+
+	switch (pz_override) {
+	case DSO_P_IMPEDANCE_HIGHEST_Z:
+	case DSO_P_IMPEDANCE_MUCH_HIGHER_Z:
+	case DSO_P_IMPEDANCE_HIGHER_Z:
+	case DSO_P_IMPEDANCE_NOMINAL:
+	case DSO_P_IMPEDANCE_LOWER_Z:
+		break;
+	default:
+		debug("%s: p_impedance_override value %d invalid.\n",
+		      dev->name, pz_override);
+		return -EINVAL;
+	}
+
+	nz_override = dev_read_u32_default(dev, "n_impedance_override", 0);
+
+	switch (nz_override) {
+	case DSO_N_IMPEDANCE_HIGHEST_Z:
+	case DSO_N_IMPEDANCE_MUCH_HIGHER_Z:
+	case DSO_N_IMPEDANCE_HIGHER_Z:
+	case DSO_N_IMPEDANCE_NOMINAL:
+	case DSO_N_IMPEDANCE_LOWER_Z:
+		break;
+	default:
+		debug("%s: n_impedance_override value %d invalid.\n",
+		      dev->name, nz_override);
+		return -EINVAL;
+	}
+
+	odt_term = dev_read_u32_default(dev, "odt_termination_value", 0);
+	if (odt_term > 1) {
+		debug("%s: odt_termination_value value %d invalid.\n",
+		      dev->name, odt_term);
+		return -EINVAL;
+	}
+
+	ddr_type = dev_read_u32_default(dev, "ddr_type", 0);
+	if (ddr_type > 1) {
+		debug("%s: ddr_type value %d invalid.\n",
+		      dev->name, ddr_type);
+		return -EINVAL;
+	}
+
+	mvref_sel = dev_read_u32_default(dev, "mvref_sel", 0);
+	if (mvref_sel > 1) {
+		debug("%s: mvref_sel value %d invalid.\n",
+		      dev->name, mvref_sel);
+		return -EINVAL;
+	}
+
+	m_odr = dev_read_u32_default(dev, "m_odr", 0);
+	if (mvref_sel > 1) {
+		debug("%s: m_odr value %d invalid.\n",
+		      dev->name, m_odr);
+		return -EINVAL;
+	}
+
+	ddrcdr = dso << (31 - 1) |
+		 pz_override << (31 - 5) |
+		 nz_override << (31 - 9) |
+		 odt_term << (31 - 12) |
+		 ddr_type << (31 - 13) |
+		 mvref_sel << (31 - 29) |
+		 m_odr << (31 - 30) | 1;
+
+	/* Configure the DDR control driver register */
+	out_be32(&im->sysconf.ddrcdr, ddrcdr);
+
+	dev_for_each_subnode(subnode, dev) {
+		u32 val[3];
+		u32 cs, addr, size;
+
+		/* CS, map address, size -> three values */
+		ofnode_read_u32_array(subnode, "reg", val, 3);
+
+		cs = val[0];
+		addr = val[1];
+		size = val[2];
+
+		if (cs > 1) {
+			debug("%s: chip select value %d invalid.\n",
+			      dev->name, cs);
+			return -EINVAL;
+		}
+
+		/* TODO(mario.six at gdsys.cc): Sanity check for size. */
+
+		if (ofnode_read_bool(subnode, "read-spd"))
+			ret = mpc83xx_sdram_spd_init(subnode, cs, addr, size);
+		else
+			ret = mpc83xx_sdram_static_init(subnode, cs, addr,
+							size);
+		if (ret) {
+			debug("%s: RAM init failed.\n", dev->name);
+			return ret;
+		}
+	};
+
+	/*
+	 * TODO(mario.six at gdsys.cc): This should only occur for static
+	 *			     configuration
+	 */
+
+	clock_adjust = dev_read_u32_default(dev, "clock_adjust", 0);
+	switch (clock_adjust) {
+	case CLOCK_ADJUST_025:
+	case CLOCK_ADJUST_05:
+	case CLOCK_ADJUST_075:
+	case CLOCK_ADJUST_1:
+		break;
+	default:
+		debug("%s: clock_adjust value %d invalid.\n",
+		      dev->name, clock_adjust);
+		return -EINVAL;
+	}
+
+	/* Configure the DDR SDRAM Clock Control register */
+	out_be32(&im->ddr.sdram_clk_cntl, clock_adjust);
+
+	ext_refresh_rec = dev_read_u32_default(dev, "ext_refresh_rec", 0);
+	switch (ext_refresh_rec) {
+	case 0:
+		ext_refresh_rec_mask = 0 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 16:
+		ext_refresh_rec_mask = 1 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 32:
+		ext_refresh_rec_mask = 2 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 48:
+		ext_refresh_rec_mask = 3 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 64:
+		ext_refresh_rec_mask = 4 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 80:
+		ext_refresh_rec_mask = 5 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 96:
+		ext_refresh_rec_mask = 6 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	case 112:
+		ext_refresh_rec_mask = 7 << TIMING_CFG3_EXT_REFREC_SHIFT;
+		break;
+	default:
+		debug("%s: ext_refresh_rec value %d invalid.\n",
+		      dev->name, ext_refresh_rec);
+		return -EINVAL;
+	}
+
+	/* Configure the DDR SDRAM Timing Configuration 3 register */
+	out_be32(&im->ddr.timing_cfg_3, ext_refresh_rec_mask);
+
+	read_to_write = dev_read_u32_default(dev, "read_to_write", 0);
+	if (read_to_write > 3) {
+		debug("%s: read_to_write value %d invalid.\n",
+		      dev->name, read_to_write);
+		return -EINVAL;
+	}
+
+	write_to_read = dev_read_u32_default(dev, "write_to_read", 0);
+	if (write_to_read > 3) {
+		debug("%s: write_to_read value %d invalid.\n",
+		      dev->name, write_to_read);
+		return -EINVAL;
+	}
+
+	read_to_read = dev_read_u32_default(dev, "read_to_read", 0);
+	if (read_to_read > 3) {
+		debug("%s: read_to_read value %d invalid.\n",
+		      dev->name, read_to_read);
+		return -EINVAL;
+	}
+
+	write_to_write = dev_read_u32_default(dev, "write_to_write", 0);
+	if (write_to_write > 3) {
+		debug("%s: write_to_write value %d invalid.\n",
+		      dev->name, write_to_write);
+		return -EINVAL;
+	}
+
+	active_powerdown_exit =
+		dev_read_u32_default(dev, "active_powerdown_exit", 0);
+	if (active_powerdown_exit > 7) {
+		debug("%s: active_powerdown_exit value %d invalid.\n",
+		      dev->name, active_powerdown_exit);
+		return -EINVAL;
+	}
+
+	precharge_powerdown_exit =
+		dev_read_u32_default(dev, "precharge_powerdown_exit", 0);
+	if (precharge_powerdown_exit > 7) {
+		debug("%s: precharge_powerdown_exit value %d invalid.\n",
+		      dev->name, precharge_powerdown_exit);
+		return -EINVAL;
+	}
+
+	odt_powerdown_exit = dev_read_u32_default(dev, "odt_powerdown_exit", 0);
+	if (odt_powerdown_exit > 15) {
+		debug("%s: odt_powerdown_exit value %d invalid.\n",
+		      dev->name, odt_powerdown_exit);
+		return -EINVAL;
+	}
+
+	mode_reg_set_cycle = dev_read_u32_default(dev, "mode_reg_set_cycle", 0);
+	if (mode_reg_set_cycle > 15) {
+		debug("%s: mode_reg_set_cycle value %d invalid.\n",
+		      dev->name, mode_reg_set_cycle);
+		return -EINVAL;
+	}
+
+	timing_cfg_0 = read_to_write << TIMING_CFG0_RWT_SHIFT |
+		       write_to_read << TIMING_CFG0_WRT_SHIFT |
+		       read_to_read << TIMING_CFG0_RRT_SHIFT |
+		       write_to_write << TIMING_CFG0_WWT_SHIFT |
+		       active_powerdown_exit << TIMING_CFG0_ACT_PD_EXIT_SHIFT |
+		       precharge_powerdown_exit << TIMING_CFG0_PRE_PD_EXIT_SHIFT |
+		       odt_powerdown_exit << TIMING_CFG0_ODT_PD_EXIT_SHIFT |
+		       mode_reg_set_cycle << TIMING_CFG0_MRS_CYC_SHIFT;
+
+	out_be32(&im->ddr.timing_cfg_0, timing_cfg_0);
+
+	precharge_to_activate =
+		dev_read_u32_default(dev, "precharge_to_activate", 0);
+	if (precharge_to_activate > 7 || precharge_to_activate == 0) {
+		debug("%s: precharge_to_activate value %d invalid.\n",
+		      dev->name, precharge_to_activate);
+		return -EINVAL;
+	}
+
+	activate_to_precharge =
+		dev_read_u32_default(dev, "activate_to_precharge", 0);
+	if (activate_to_precharge > 19) {
+		debug("%s: activate_to_precharge value %d invalid.\n",
+		      dev->name, activate_to_precharge);
+		return -EINVAL;
+	}
+
+	activate_to_readwrite =
+		dev_read_u32_default(dev, "activate_to_readwrite", 0);
+	if (activate_to_readwrite > 7 || activate_to_readwrite == 0) {
+		debug("%s: activate_to_readwrite value %d invalid.\n",
+		      dev->name, activate_to_readwrite);
+		return -EINVAL;
+	}
+
+	mcas_latency = dev_read_u32_default(dev, "mcas_latency", 0);
+	switch (mcas_latency) {
+	case CASLAT_20:
+	case CASLAT_25:
+		if (!IS_ENABLED(CONFIG_ARCH_MPC8308)) {
+			debug("%s: MCAS latency < 3.0 unsupported on MPC8308\n",
+			      dev->name);
+			return -EINVAL;
+		}
+		/* fall through */
+	case CASLAT_30:
+	case CASLAT_35:
+	case CASLAT_40:
+	case CASLAT_45:
+	case CASLAT_50:
+	case CASLAT_55:
+	case CASLAT_60:
+	case CASLAT_65:
+	case CASLAT_70:
+	case CASLAT_75:
+	case CASLAT_80:
+		break;
+	default:
+		debug("%s: mcas_latency value %d invalid.\n",
+		      dev->name, mcas_latency);
+		return -EINVAL;
+	}
+
+	refresh_recovery = dev_read_u32_default(dev, "refresh_recovery", 0);
+	if (refresh_recovery > 23 || refresh_recovery < 8) {
+		debug("%s: refresh_recovery value %d invalid.\n",
+		      dev->name, refresh_recovery);
+		return -EINVAL;
+	}
+
+	last_data_to_precharge =
+		dev_read_u32_default(dev, "last_data_to_precharge", 0);
+	if (last_data_to_precharge > 7 || last_data_to_precharge == 0) {
+		debug("%s: last_data_to_precharge value %d invalid.\n",
+		      dev->name, last_data_to_precharge);
+		return -EINVAL;
+	}
+
+	activate_to_activate =
+		dev_read_u32_default(dev, "activate_to_activate", 0);
+	if (activate_to_activate > 7 || activate_to_activate == 0) {
+		debug("%s: activate_to_activate value %d invalid.\n",
+		      dev->name, activate_to_activate);
+		return -EINVAL;
+	}
+
+	last_write_data_to_read =
+		dev_read_u32_default(dev, "last_write_data_to_read", 0);
+	if (last_write_data_to_read > 7 || last_write_data_to_read == 0) {
+		debug("%s: last_write_data_to_read value %d invalid.\n",
+		      dev->name, last_write_data_to_read);
+		return -EINVAL;
+	}
+
+	timing_cfg_1 = precharge_to_activate << TIMING_CFG1_PRETOACT_SHIFT |
+		       (activate_to_precharge > 15 ?
+			activate_to_precharge - 16 :
+			activate_to_precharge) << TIMING_CFG1_ACTTOPRE_SHIFT |
+		       activate_to_readwrite << TIMING_CFG1_ACTTORW_SHIFT |
+		       mcas_latency << TIMING_CFG1_CASLAT_SHIFT |
+		       (refresh_recovery - 8) << TIMING_CFG1_REFREC_SHIFT |
+		       last_data_to_precharge << TIMING_CFG1_WRREC_SHIFT |
+		       activate_to_activate << TIMING_CFG1_ACTTOACT_SHIFT |
+		       last_write_data_to_read << TIMING_CFG1_WRTORD_SHIFT;
+
+	/* Configure the DDR SDRAM Timing Configuration 1 register */
+	out_be32(&im->ddr.timing_cfg_1, timing_cfg_1);
+
+	additive_latency = dev_read_u32_default(dev, "additive_latency", 0);
+	if (additive_latency > 5) {
+		debug("%s: additive_latency value %d invalid.\n",
+		      dev->name, additive_latency);
+		return -EINVAL;
+	}
+
+	mcas_to_preamble_override =
+		dev_read_u32_default(dev, "mcas_to_preamble_override", 0);
+	switch (mcas_to_preamble_override) {
+	case READ_LAT_PLUS_1:
+	case READ_LAT:
+	case READ_LAT_PLUS_1_4:
+	case READ_LAT_PLUS_1_2:
+	case READ_LAT_PLUS_3_4:
+	case READ_LAT_PLUS_5_4:
+	case READ_LAT_PLUS_3_2:
+	case READ_LAT_PLUS_7_4:
+	case READ_LAT_PLUS_2:
+	case READ_LAT_PLUS_9_4:
+	case READ_LAT_PLUS_5_2:
+	case READ_LAT_PLUS_11_4:
+	case READ_LAT_PLUS_3:
+	case READ_LAT_PLUS_13_4:
+	case READ_LAT_PLUS_7_2:
+	case READ_LAT_PLUS_15_4:
+	case READ_LAT_PLUS_4:
+	case READ_LAT_PLUS_17_4:
+	case READ_LAT_PLUS_9_2:
+	case READ_LAT_PLUS_19_4:
+		break;
+	default:
+		debug("%s: mcas_to_preamble_override value %d invalid.\n",
+		      dev->name, mcas_to_preamble_override);
+		return -EINVAL;
+	}
+
+	write_latency = dev_read_u32_default(dev, "write_latency", 0);
+	if (write_latency > 7 || write_latency == 0) {
+		debug("%s: write_latency value %d invalid.\n",
+		      dev->name, write_latency);
+		return -EINVAL;
+	}
+
+	read_to_precharge = dev_read_u32_default(dev, "read_to_precharge", 0);
+	if (read_to_precharge > 4 || read_to_precharge == 0) {
+		debug("%s: read_to_precharge value %d invalid.\n",
+		      dev->name, read_to_precharge);
+		return -EINVAL;
+	}
+
+	write_cmd_to_write_data =
+		dev_read_u32_default(dev, "write_cmd_to_write_data", 0);
+	switch (write_cmd_to_write_data) {
+	case CLOCK_DELAY_0:
+	case CLOCK_DELAY_1_4:
+	case CLOCK_DELAY_1_2:
+	case CLOCK_DELAY_3_4:
+	case CLOCK_DELAY_1:
+	case CLOCK_DELAY_5_4:
+	case CLOCK_DELAY_3_2:
+		break;
+	default:
+		debug("%s: write_cmd_to_write_data value %d invalid.\n",
+		      dev->name, write_cmd_to_write_data);
+		return -EINVAL;
+	}
+
+	minimum_cke_pulse_width =
+		dev_read_u32_default(dev, "minimum_cke_pulse_width", 0);
+	if (minimum_cke_pulse_width > 4 || minimum_cke_pulse_width == 0) {
+		debug("%s: minimum_cke_pulse_width value %d invalid.\n",
+		      dev->name, minimum_cke_pulse_width);
+		return -EINVAL;
+	}
+
+	four_activates_window =
+		dev_read_u32_default(dev, "four_activates_window", 0);
+	if (four_activates_window > 20 || four_activates_window == 0) {
+		debug("%s: four_activates_window value %d invalid.\n",
+		      dev->name, four_activates_window);
+		return -EINVAL;
+	}
+
+	timing_cfg_2 = additive_latency << TIMING_CFG2_ADD_LAT_SHIFT |
+		       mcas_to_preamble_override << TIMING_CFG2_CPO_SHIFT |
+		       write_latency << TIMING_CFG2_WR_LAT_DELAY_SHIFT |
+		       read_to_precharge << TIMING_CFG2_RD_TO_PRE_SHIFT |
+		       write_cmd_to_write_data << TIMING_CFG2_WR_DATA_DELAY_SHIFT |
+		       minimum_cke_pulse_width << TIMING_CFG2_CKE_PLS_SHIFT |
+		       four_activates_window << TIMING_CFG2_FOUR_ACT_SHIFT;
+
+	out_be32(&im->ddr.timing_cfg_2, timing_cfg_2);
+
+	self_refresh = dev_read_u32_default(dev, "self_refresh", 0);
+	switch (self_refresh) {
+	case SREN_DISABLE:
+	case SREN_ENABLE:
+		break;
+	default:
+		debug("%s: self_refresh value %d invalid.\n",
+		      dev->name, self_refresh);
+		return -EINVAL;
+	}
+
+	ecc = dev_read_u32_default(dev, "ecc", 0);
+	switch (ecc) {
+	case ECC_DISABLE:
+	case ECC_ENABLE:
+		break;
+	default:
+		debug("%s: ecc value %d invalid.\n", dev->name, ecc);
+		return -EINVAL;
+	}
+
+	registered_dram = dev_read_u32_default(dev, "registered_dram", 0);
+	switch (registered_dram) {
+	case RD_DISABLE:
+	case RD_ENABLE:
+		break;
+	default:
+		debug("%s: registered_dram value %d invalid.\n",
+		      dev->name, registered_dram);
+		return -EINVAL;
+	}
+
+	sdram_type = dev_read_u32_default(dev, "sdram_type", 0);
+	switch (sdram_type) {
+	case TYPE_DDR1:
+	case TYPE_DDR2:
+		break;
+	default:
+		debug("%s: sdram_type value %d invalid.\n",
+		      dev->name, sdram_type);
+		return -EINVAL;
+	}
+
+	dynamic_power_management =
+		dev_read_u32_default(dev, "dynamic_power_management", 0);
+	switch (dynamic_power_management) {
+	case DYN_PWR_DISABLE:
+	case DYN_PWR_ENABLE:
+		break;
+	default:
+		debug("%s: dynamic_power_management value %d invalid.\n",
+		      dev->name, dynamic_power_management);
+		return -EINVAL;
+	}
+
+	databus_width = dev_read_u32_default(dev, "databus_width", 0);
+	switch (databus_width) {
+	case DATA_BUS_WIDTH_16:
+	case DATA_BUS_WIDTH_32:
+		break;
+	default:
+		debug("%s: databus_width value %d invalid.\n",
+		      dev->name, databus_width);
+		return -EINVAL;
+	}
+
+	nc_auto_precharge = dev_read_u32_default(dev, "nc_auto_precharge", 0);
+	switch (nc_auto_precharge) {
+	case NCAP_DISABLE:
+	case NCAP_ENABLE:
+		break;
+	default:
+		debug("%s: nc_auto_precharge value %d invalid.\n",
+		      dev->name, nc_auto_precharge);
+		return -EINVAL;
+	}
+
+	timing_2t = dev_read_u32_default(dev, "timing_2t", 0);
+	switch (timing_2t) {
+	case TIMING_1T:
+	case TIMING_2T:
+		break;
+	default:
+		debug("%s: timing_2t value %d invalid.\n",
+		      dev->name, timing_2t);
+		return -EINVAL;
+	}
+
+	bank_interleaving_ctrl =
+		dev_read_u32_default(dev, "bank_interleaving_ctrl", 0);
+	switch (bank_interleaving_ctrl) {
+	case INTERLEAVE_NONE:
+	case INTERLEAVE_1_AND_2:
+		break;
+	default:
+		debug("%s: bank_interleaving_ctrl value %d invalid.\n",
+		      dev->name, bank_interleaving_ctrl);
+		return -EINVAL;
+	}
+
+	precharge_bit_8 = dev_read_u32_default(dev, "precharge_bit_8", 0);
+	switch (precharge_bit_8) {
+	case PRECHARGE_MA_10:
+	case PRECHARGE_MA_8:
+		break;
+	default:
+		debug("%s: precharge_bit_8 value %d invalid.\n",
+		      dev->name, precharge_bit_8);
+		return -EINVAL;
+	}
+
+	half_strength = dev_read_u32_default(dev, "half_strength", 0);
+	switch (half_strength) {
+	case STRENGTH_FULL:
+	case STRENGTH_HALF:
+		break;
+	default:
+		debug("%s: half_strength value %d invalid.\n",
+		      dev->name, half_strength);
+		return -EINVAL;
+	}
+
+	bypass_initialization =
+		dev_read_u32_default(dev, "bypass_initialization", 0);
+	switch (bypass_initialization) {
+	case INITIALIZATION_DONT_BYPASS:
+	case INITIALIZATION_BYPASS:
+		break;
+	default:
+		debug("%s: bypass_initialization value %d invalid.\n",
+		      dev->name, bypass_initialization);
+		return -EINVAL;
+	}
+
+	sdram_cfg = self_refresh << SDRAM_CFG_SREN_SHIFT |
+		    ecc << SDRAM_CFG_ECC_EN_SHIFT |
+		    registered_dram << SDRAM_CFG_RD_EN_SHIFT |
+		    sdram_type << SDRAM_CFG_SDRAM_TYPE_SHIFT |
+		    dynamic_power_management << SDRAM_CFG_DYN_PWR_SHIFT |
+		    databus_width << SDRAM_CFG_DBW_SHIFT |
+		    nc_auto_precharge << SDRAM_CFG_NCAP_SHIFT |
+		    timing_2t << SDRAM_CFG_2T_EN_SHIFT |
+		    bank_interleaving_ctrl << SDRAM_CFG_BA_INTLV_CTL_SHIFT |
+		    precharge_bit_8 << SDRAM_CFG_PCHB8_SHIFT |
+		    half_strength << SDRAM_CFG_HSE_SHIFT |
+		    bypass_initialization << SDRAM_CFG_BI_SHIFT;
+
+	out_be32(&im->ddr.sdram_cfg, sdram_cfg);
+
+	force_self_refresh = dev_read_u32_default(dev, "force_self_refresh", 0);
+	switch (force_self_refresh) {
+	case MODE_NORMAL:
+	case MODE_REFRESH:
+		break;
+	default:
+		debug("%s: force_self_refresh value %d invalid.\n",
+		      dev->name, force_self_refresh);
+		return -EINVAL;
+	}
+
+	dll_reset = dev_read_u32_default(dev, "dll_reset", 0);
+	switch (dll_reset) {
+	case DLL_RESET_ENABLE:
+	case DLL_RESET_DISABLE:
+		break;
+	default:
+		debug("%s: dll_reset value %d invalid.\n",
+		      dev->name, dll_reset);
+		return -EINVAL;
+	}
+
+	dqs_config = dev_read_u32_default(dev, "dqs_config", 0);
+	switch (dqs_config) {
+	case DQS_TRUE:
+		break;
+	default:
+		debug("%s: dqs_config value %d invalid.\n",
+		      dev->name, dqs_config);
+		return -EINVAL;
+	}
+
+	odt_config = dev_read_u32_default(dev, "odt_config", 0);
+	switch (odt_config) {
+	case ODT_ASSERT_NEVER:
+	case ODT_ASSERT_WRITES:
+	case ODT_ASSERT_READS:
+	case ODT_ASSERT_ALWAYS:
+		break;
+	default:
+		debug("%s: odt_config value %d invalid.\n",
+		      dev->name, odt_config);
+		return -EINVAL;
+	}
+
+	posted_refreshes = dev_read_u32_default(dev, "posted_refreshes", 0);
+	if (posted_refreshes > 8 || posted_refreshes == 0) {
+		debug("%s: posted_refreshes value %d invalid.\n",
+		      dev->name, posted_refreshes);
+		return -EINVAL;
+	}
+
+	sdram_cfg2 = force_self_refresh << SDRAM_CFG2_FRC_SR_SHIFT |
+		     dll_reset << SDRAM_CFG2_DLL_RST_DIS |
+		     dqs_config << SDRAM_CFG2_DQS_CFG |
+		     odt_config << SDRAM_CFG2_ODT_CFG |
+		     posted_refreshes << SDRAM_CFG2_NUM_PR;
+
+	out_be32(&im->ddr.sdram_cfg2, sdram_cfg2);
+
+	sdmode = dev_read_u32_default(dev, "sdmode", 0);
+	if (sdmode > 0xFFFF) {
+		debug("%s: sdmode value %d invalid.\n",
+		      dev->name, sdmode);
+		return -EINVAL;
+	}
+
+	esdmode = dev_read_u32_default(dev, "esdmode", 0);
+	if (esdmode > 0xFFFF) {
+		debug("%s: esdmode value %d invalid.\n", dev->name, esdmode);
+		return -EINVAL;
+	}
+
+	sdram_mode = sdmode << SDRAM_MODE_SD_SHIFT |
+		     esdmode << SDRAM_MODE_ESD_SHIFT;
+
+	out_be32(&im->ddr.sdram_mode, sdram_mode);
+
+	esdmode2 = dev_read_u32_default(dev, "esdmode2", 0);
+	if (esdmode2 > 0xFFFF) {
+		debug("%s: esdmode2 value %d invalid.\n", dev->name, esdmode2);
+		return -EINVAL;
+	}
+
+	esdmode3 = dev_read_u32_default(dev, "esdmode3", 0);
+	if (esdmode3 > 0xFFFF) {
+		debug("%s: esdmode3 value %d invalid.\n", dev->name, esdmode3);
+		return -EINVAL;
+	}
+
+	sdram_mode2 = esdmode2 << SDRAM_MODE2_ESD2_SHIFT |
+		      esdmode3 << SDRAM_MODE2_ESD3_SHIFT;
+
+	out_be32(&im->ddr.sdram_mode2, sdram_mode2);
+
+	refresh_interval = dev_read_u32_default(dev, "refresh_interval", 0);
+	if (refresh_interval > 0xFFFF) {
+		debug("%s: refresh_interval value %d invalid.\n",
+		      dev->name, refresh_interval);
+		return -EINVAL;
+	}
+
+	precharge_interval = dev_read_u32_default(dev, "precharge_interval", 0);
+	if (precharge_interval > 0x3FFF) {
+		debug("%s: precharge_interval value %d invalid.\n",
+		      dev->name, precharge_interval);
+		return -EINVAL;
+	}
+
+	sdram_interval = refresh_interval << SDRAM_INTERVAL_REFINT_SHIFT |
+			 precharge_interval << SDRAM_INTERVAL_BSTOPRE_SHIFT;
+
+	out_be32(&im->ddr.sdram_interval, sdram_interval);
+	sync();
+
+	/* Enable DDR controller */
+	setbits_be32(&im->ddr.sdram_cfg, SDRAM_CFG_MEM_EN);
+	sync();
+
+	dev_for_each_subnode(subnode, dev) {
+		u32 val[3];
+		u32 addr, size;
+
+		/* CS, map address, size -> three values */
+		ofnode_read_u32_array(subnode, "reg", val, 3);
+
+		addr = val[1];
+		size = val[2];
+
+		priv->total_size += get_ram_size((long int *)addr, size);
+	};
+
+	gd->ram_size = priv->total_size;
+
+	return 0;
+}
+
+static int mpc83xx_sdram_get_info(struct udevice *dev, struct ram_info *info)
+{
+	/* TODO(mario.six at gdsys.cc): Implement */
+	return 0;
+}
+
+static struct ram_ops mpc83xx_sdram_ops = {
+	.get_info = mpc83xx_sdram_get_info,
+};
+
+static const struct udevice_id mpc83xx_sdram_ids[] = {
+	{ .compatible = "fsl,mpc83xx-mem-controller" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mpc83xx_sdram) = {
+	.name = "mpc83xx_sdram",
+	.id = UCLASS_RAM,
+	.of_match = mpc83xx_sdram_ids,
+	.ops = &mpc83xx_sdram_ops,
+	.ofdata_to_platdata = mpc83xx_sdram_ofdata_to_platdata,
+	.probe = mpc83xx_sdram_probe,
+	.priv_auto_alloc_size = sizeof(struct mpc83xx_sdram_priv),
+};
diff --git a/include/dt-bindings/memory/mpc83xx-sdram.h b/include/dt-bindings/memory/mpc83xx-sdram.h
new file mode 100644
index 00000000000..7d4ce01cc48
--- /dev/null
+++ b/include/dt-bindings/memory/mpc83xx-sdram.h
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index e1e50ab6b50..a4c5bd38376 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -1110,6 +1110,8 @@
 #define CSBNDS_EA			0x000000FF
 #define CSBNDS_EA_SHIFT			24
 
+#ifndef CONFIG_MPC83XX_SDRAM
+
 /*
  * CSn_CONFIG - Chip Select Configuration Register
  */
@@ -1407,6 +1409,8 @@
 #define ECC_ERROR_MAN_SBEC		(0xff000000 >> 24)
 #define ECC_ERROR_MAN_SBEC_SHIFT	0
 
+#endif /* !CONFIG_MPC83XX_SDRAM */
+
 /*
  * CONFIG_ADDRESS - PCI Config Address Register
  */
@@ -1510,6 +1514,7 @@
  */
 #define PMCCR1_POWER_OFF		0x00000020
 
+#ifndef CONFIG_RAM
 /*
  * DDRCDR - DDR Control Driver Register
  */
@@ -1531,6 +1536,7 @@
 #define DDRCDR_DDR_CFG		0x00040000
 #define DDRCDR_M_ODR		0x00000002
 #define DDRCDR_Q_DRN		0x00000001
+#endif /* !CONFIG_RAM */
 
 /*
  * PCIE Bridge Register
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method Mario Six
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Define the read*_*/write*_* macros for the PowerPC platform to be able
to use the macros in wait_bit.h.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 arch/powerpc/include/asm/io.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 34fbfdf1cf0..6d76e3e99cc 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -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 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)
 {
 #ifdef CONFIG_ADDR_MAP
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status Mario Six
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

It's useful to have the reset status of the SoC printed out during reset
(e.g. to learn whether the reset was caused by software or a watchdog).

As a first step to implement this, add a get_status method to the
sysreset class, which enables the caller to get printable information
about the reset status (akin to get_desc in the CPU uclass).

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    No changes
    
    v2 -> v3:
    No changes
    
    v1 -> v2:
    New in v2

 drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
 include/sysreset.h                 | 17 +++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index b918365e73a..06ef0ed96c7 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -24,6 +24,16 @@ int sysreset_request(struct udevice *dev, enum sysreset_t 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)
 {
 	struct udevice *dev;
diff --git a/include/sysreset.h b/include/sysreset.h
index 81318bdbf5d..a5c0b74a473 100644
--- a/include/sysreset.h
+++ b/include/sysreset.h
@@ -28,6 +28,14 @@ struct sysreset_ops {
 	 *		(in which case this method will not actually return)
 	 */
 	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)
@@ -41,6 +49,15 @@ struct sysreset_ops {
 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
  *
  * This works through the available sysreset devices until it finds one that can
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros Mario Six
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing Mario Six
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add some tests for sysreset_get_status.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Switched to usage of strlcpy
    
    v2 -> v3:
    New in v3.

 drivers/sysreset/sysreset_sandbox.c | 16 ++++++++++++++++
 test/dm/sysreset.c                  | 20 ++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index f12c4e84198..75004d9f774 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -29,6 +29,13 @@ static int sandbox_warm_sysreset_request(struct udevice *dev,
 	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)
 {
 	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;
 }
 
+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 = {
 	.request	= sandbox_sysreset_request,
+	.get_status	= sandbox_sysreset_get_status,
 };
 
 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 = {
 	.request	= sandbox_warm_sysreset_request,
+	.get_status	= sandbox_warm_sysreset_get_status,
 };
 
 static const struct udevice_id sandbox_warm_sysreset_ids[] = {
diff --git a/test/dm/sysreset.c b/test/dm/sysreset.c
index 33a8bfb33c4..04d4621d9e1 100644
--- a/test/dm/sysreset.c
+++ b/test/dm/sysreset.c
@@ -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);
 
+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 */
 static int dm_test_sysreset_walk(struct unit_test_state *uts)
 {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (2 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver Mario Six
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

To print the reset status during boot, add a method print_resetinfo to
board_f, which is called in init_sequence_f[], that gets the reset
information from the sysreset driver (assuming there is only one seems
reasonable), and prints it.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    No changes
    
    v2 -> v3:
    * Improved behavior and error handling
    
    v1 -> v2:
    New in v2

 common/board_f.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/common/board_f.c b/common/board_f.c
index 88d770071c3..3871839a2db 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -24,6 +24,7 @@
 #include <relocate.h>
 #include <spi.h>
 #include <status_led.h>
+#include <sysreset.h>
 #include <timer.h>
 #include <trace.h>
 #include <video.h>
@@ -140,6 +141,30 @@ static int display_text_info(void)
 	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
+
 static int announce_dram_init(void)
 {
 	puts("DRAM:  ");
@@ -790,6 +815,9 @@ static const init_fnc_t init_sequence_f[] = {
 #if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
 	checkcpu,
 #endif
+#if defined(CONFIG_SYSRESET)
+	print_resetinfo,
+#endif
 #if defined(CONFIG_DISPLAY_CPUINFO)
 	print_cpuinfo,		/* display cpu info (and speed) */
 #endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (3 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver Mario Six
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a sysreset driver for the MPC83xx platform.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Fixed style violation
    * Added full documentation
    * Switched to wait_for_bit_be32 usage
    * Improved error handling and debug printing
    * Minimized usage of preprocessor
    
    v2 -> v3:
    * Added driver file to MAINTAINERS
    
    v1 -> v2:
    New in v2

 MAINTAINERS                         |   2 +
 arch/powerpc/cpu/mpc83xx/cpu.c      |   3 +-
 drivers/sysreset/Kconfig            |   5 +
 drivers/sysreset/Makefile           |   9 +-
 drivers/sysreset/sysreset_mpc83xx.c | 212 ++++++++++++++++++++++++++++++++++++
 drivers/sysreset/sysreset_mpc83xx.h | 103 ++++++++++++++++++
 6 files changed, 329 insertions(+), 5 deletions(-)
 create mode 100644 drivers/sysreset/sysreset_mpc83xx.c
 create mode 100644 drivers/sysreset/sysreset_mpc83xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 57329e878ae..801e47897f6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -497,6 +497,8 @@ S:	Maintained
 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:	arch/powerpc/cpu/mpc83xx/
 F:	arch/powerpc/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index 82370b54301..e1d2f2f07cb 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -115,6 +115,7 @@ int checkcpu(void)
 	return 0;
 }
 
+#ifndef CONFIG_SYSRESET
 int
 do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
@@ -169,7 +170,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 
 	return 1;
 }
-
+#endif
 
 /*
  * Get timebase clock frequency (like cpu_clk in Hz)
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 9b2fda4d251..ca03d165a52 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -57,4 +57,9 @@ config SYSRESET_X86
 	help
 	  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
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 707f1d74691..3a2ddf4cd73 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -3,14 +3,15 @@
 # (C) Copyright 2016 Cadence Design Systems Inc.
 
 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_MCP83XX) += sysreset_mpc83xx.o
 obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
 obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
 obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.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_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_mpc83xx.c b/drivers/sysreset/sysreset_mpc83xx.c
new file mode 100644
index 00000000000..9092764e0b1
--- /dev/null
+++ b/drivers/sysreset/sysreset_mpc83xx.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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 at 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,
+};
diff --git a/drivers/sysreset/sysreset_mpc83xx.h b/drivers/sysreset/sysreset_mpc83xx.h
new file mode 100644
index 00000000000..dc3c05921f2
--- /dev/null
+++ b/drivers/sysreset/sysreset_mpc83xx.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (4 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries Mario Six
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a clock driver for the MPC83xx architecture.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Gotten rid of all #ifdefs (SoC is now determined by compatible string)
    * Added MPC83xx-wide functions to get properties of SoCs
    * Gotten rid of most clock variables in global data
    * Marked more files as static
    * Improved error handling and debug reporting
    * Simplified bitmask handling
    * Added binding file
    * Added full documentation
    
    v2 -> v3:
    * Added driver files to MAINTAINERS
    
    v1 -> v2:
    * Added binding of sysreset driver

 .../devicetree/bindings/clk/fsl,mpc83xx-clk.txt    |  23 ++
 MAINTAINERS                                        |   3 +
 arch/powerpc/cpu/mpc83xx/speed.c                   |   4 +
 arch/powerpc/include/asm/arch-mpc83xx/soc.h        |  74 ++++
 arch/powerpc/include/asm/config.h                  |   2 +-
 arch/powerpc/include/asm/global_data.h             |   4 +
 drivers/clk/Kconfig                                |   6 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/mpc83xx_clk.c                          | 410 +++++++++++++++++++++
 drivers/clk/mpc83xx_clk.h                          | 379 +++++++++++++++++++
 include/dt-bindings/clk/mpc83xx-clk.h              |  33 ++
 11 files changed, 938 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
 create mode 100644 arch/powerpc/include/asm/arch-mpc83xx/soc.h
 create mode 100644 drivers/clk/mpc83xx_clk.c
 create mode 100644 drivers/clk/mpc83xx_clk.h
 create mode 100644 include/dt-bindings/clk/mpc83xx-clk.h

diff --git a/Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt b/Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
new file mode 100644
index 00000000000..8313da85076
--- /dev/null
+++ b/Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
@@ -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>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 801e47897f6..7710989ea4f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -499,6 +499,9 @@ 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:	arch/powerpc/cpu/mpc83xx/
 F:	arch/powerpc/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c
index f0945281cd2..39bc1c53406 100644
--- a/arch/powerpc/cpu/mpc83xx/speed.c
+++ b/arch/powerpc/cpu/mpc83xx/speed.c
@@ -6,6 +6,8 @@
  * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
  */
 
+#ifndef CONFIG_CLK_MPC83XX
+
 #include <common.h>
 #include <mpc83xx.h>
 #include <command.h>
@@ -590,3 +592,5 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
 	"print clock configuration",
 	"    clocks"
 );
+
+#endif
diff --git a/arch/powerpc/include/asm/arch-mpc83xx/soc.h b/arch/powerpc/include/asm/arch-mpc83xx/soc.h
new file mode 100644
index 00000000000..39bf7d5a7f9
--- /dev/null
+++ b/arch/powerpc/include/asm/arch-mpc83xx/soc.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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_ */
diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h
index bf11f40e231..849a69acedc 100644
--- a/arch/powerpc/include/asm/config.h
+++ b/arch/powerpc/include/asm/config.h
@@ -75,7 +75,7 @@
 /* All PPC boards must swap IDE bytes */
 #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
  * clock here.
diff --git a/arch/powerpc/include/asm/global_data.h b/arch/powerpc/include/asm/global_data.h
index 07d5beaf0e9..d00cee95fbb 100644
--- a/arch/powerpc/include/asm/global_data.h
+++ b/arch/powerpc/include/asm/global_data.h
@@ -30,6 +30,9 @@ struct arch_global_data {
 #endif
 	/* TODO: sjg at chromium.org: Should these be unslgned long? */
 #if defined(CONFIG_MPC83xx)
+#ifdef CONFIG_CLK_MPC83XX
+	u32 core_clk;
+#else
 	/* There are other clocks in the MPC83XX */
 	u32 csb_clk;
 # if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
@@ -62,6 +65,7 @@ struct arch_global_data {
 	u32 mem_sec_clk;
 # endif /* CONFIG_MPC8360 */
 #endif
+#endif
 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
 	u32 lbc_clk;
 	void *cpu;
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 18bf8a6d28b..65720a1a19a 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -99,4 +99,10 @@ config ICS8N3QV01
 	  Crystal Oscillator). The output frequency can be programmed via an
 	  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
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 146283c7232..ae9c9373f5d 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
+obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
 obj-$(CONFIG_CLK_OWL) += owl/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
 obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
diff --git a/drivers/clk/mpc83xx_clk.c b/drivers/clk/mpc83xx_clk.c
new file mode 100644
index 00000000000..489004190eb
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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",
+	   ""
+);
diff --git a/drivers/clk/mpc83xx_clk.h b/drivers/clk/mpc83xx_clk.h
new file mode 100644
index 00000000000..7fb88029204
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.h
@@ -0,0 +1,379 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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 at 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 at 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;
+}
diff --git a/include/dt-bindings/clk/mpc83xx-clk.h b/include/dt-bindings/clk/mpc83xx-clk.h
new file mode 100644
index 00000000000..db4ea15cf42
--- /dev/null
+++ b/include/dt-bindings/clk/mpc83xx-clk.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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 */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (5 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver Mario Six
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Makefile entries should be sorted.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 drivers/timer/Makefile | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index ee2fcb1fa71..71c54048540 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -3,16 +3,16 @@
 # Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
 
 obj-y += timer-uclass.o
+obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
-obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence-ttc.o
-obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
-obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_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_AST_TIMER)	+= ast_timer.o
 obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
-obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
+obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence-ttc.o
+obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
+obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_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_X86_TSC_TIMER)	+= tsc_timer.o
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (6 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:57   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes Mario Six
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a timer driver for the MPC83xx architecture.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Removed superfluous get_timer (switched to usage of standard function)
    * Improved error handling and debug reporting
    * Added full documentation
    
    v2 -> v3:
    * Got rid of the static variables
    * Added driver files to MAINTAINERS
    
    v1 -> v2:
    * Removed now-superfluous comments
    * Removed usage of uclass_{first,next}_device_compat
    * Switched to usage of new board uclass (instead of devinfo)

 .../bindings/timer/fsl,mpc83xx-timer.txt           |  21 ++
 MAINTAINERS                                        |   1 +
 arch/powerpc/cpu/mpc83xx/cpu.c                     |   4 +-
 arch/powerpc/lib/Makefile                          |   4 +
 arch/powerpc/lib/interrupts.c                      |   5 +-
 drivers/timer/Kconfig                              |   7 +
 drivers/timer/Makefile                             |   1 +
 drivers/timer/mpc83xx_timer.c                      | 249 +++++++++++++++++++++
 8 files changed, 289 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/fsl,mpc83xx-timer.txt
 create mode 100644 drivers/timer/mpc83xx_timer.c

diff --git a/Documentation/devicetree/bindings/timer/fsl,mpc83xx-timer.txt b/Documentation/devicetree/bindings/timer/fsl,mpc83xx-timer.txt
new file mode 100644
index 00000000000..608d24110ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/fsl,mpc83xx-timer.txt
@@ -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>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 7710989ea4f..58a8f8da7ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -502,6 +502,7 @@ 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:	arch/powerpc/cpu/mpc83xx/
 F:	arch/powerpc/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index e1d2f2f07cb..ffb42415feb 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -175,12 +175,12 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 /*
  * Get timebase clock frequency (like cpu_clk in Hz)
  */
-
+#ifndef CONFIG_TIMER
 unsigned long get_tbclk(void)
 {
 	return (gd->bus_clk + 3L) / 4L;
 }
-
+#endif
 
 #if defined(CONFIG_WATCHDOG)
 void watchdog_reset (void)
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index c3acefaea7e..8ac49bdd060 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -17,13 +17,17 @@ endif
 
 ifdef MINIMAL
 obj-y += cache.o time.o
+ifndef CONFIG_TIMER
 obj-y += ticks.o
+endif
 else
 
 obj-y	+= ppcstring.o
 
 obj-y	+= ppccache.o
+ifndef CONFIG_TIMER
 obj-y	+= ticks.o
+endif
 obj-y	+= reloc.o
 
 obj-$(CONFIG_BAT_RW) += bat_rw.o
diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c
index f63e5cf799b..19682cfcfad 100644
--- a/arch/powerpc/lib/interrupts.c
+++ b/arch/powerpc/lib/interrupts.c
@@ -14,6 +14,7 @@
 #include <status_led.h>
 #endif
 
+#ifndef CONFIG_MPC83XX_TIMER
 #ifdef CONFIG_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)
 		asm volatile ("mtdec %0"::"r" (val));
 }
-
+#endif /* !CONFIG_MPC83XX_TIMER */
 
 void enable_interrupts (void)
 {
@@ -60,6 +61,7 @@ int disable_interrupts (void)
 	return ((msr & MSR_EE) != 0);
 }
 
+#ifndef CONFIG_MPC83XX_TIMER
 int interrupt_init (void)
 {
 	/* call cpu specific function from $(CPU)/interrupts.c */
@@ -102,3 +104,4 @@ ulong get_timer (ulong base)
 {
 	return (timestamp - base);
 }
+#endif /* !CONFIG_MPC83XX_TIMER */
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 8a31397553d..c7909bd6e52 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -133,4 +133,11 @@ config STM32_TIMER
 	  Select this to enable support for the timer found on
 	  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
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 71c54048540..bcc14342b1a 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -10,6 +10,7 @@ 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_MPC83XX_TIMER) += mpc83xx_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
 obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
new file mode 100644
index 00000000000..84a9ab072a9
--- /dev/null
+++ b/drivers/timer/mpc83xx_timer.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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 at 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),
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (7 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 11/17] init: Fix documentation Mario Six
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Includes should be sorted.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    No changes
    
    v2 -> v3:
    No changes
    
    v1 -> v2:
    New in v2

 common/board_f.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/board_f.c b/common/board_f.c
index 3871839a2db..afafec5e4d0 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -11,8 +11,8 @@
 
 #include <common.h>
 #include <console.h>
-#include <environment.h>
 #include <dm.h>
+#include <environment.h>
 #include <fdtdec.h>
 #include <fs.h>
 #include <i2c.h>
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 11/17] init: Fix documentation
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (8 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active Mario Six
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

The documentation in init.h is not in kernel-doc format. Fix this.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 include/init.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/include/init.h b/include/init.h
index f114a889631..a58d7a6917f 100644
--- a/include/init.h
+++ b/include/init.h
@@ -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
  * version (which does nothing) will be used.
  *
- * @return: 0 on success, otherwise error
+ * Return: 0 on success, otherwise error
  */
 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
  * devices
  *
- * @return 0 if OK, -ve on error
+ * Return: 0 if OK, -ve on error
  */
 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
  * version (which does nothing) will be used.
  *
- * @return: 0 on success, otherwise error
+ * Return: 0 on success, otherwise error
  */
 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
  * function can be used to set up the blobs. This is used on some Intel
  * platforms.
+ *
+ * Return: 0
  */
 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
  * get_effective_memsize().
  *
- * @return 0 if OK, -ve on error
+ * Return: 0 if OK, -ve on error
  */
 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
  * architecture could provide this function to tailor the required stacks.
@@ -96,14 +98,14 @@ int dram_init_banksize(void);
  * 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.
  *
- * @return 0 if no error
+ * Return: 0 if no error
  */
 int arch_reserve_stacks(void);
 
 /**
  * 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);
 
@@ -111,6 +113,7 @@ int print_cpuinfo(void);
 int timer_init(void);
 int reserve_mmu(void);
 int misc_init_f(void);
+
 #if defined(CONFIG_DTB_RESELECT)
 int embedded_dtb_select(void);
 #endif
@@ -120,28 +123,28 @@ extern ulong monitor_flash_len;
 
 /**
  * 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
  * code to allow the C runtime to reserve space on the stack for writable
  * '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);
 
 /**
  * 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
  * 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);
 
 /**
  * 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
  * to. For example on x86 it is implemented by adding a specific record to its
@@ -149,8 +152,6 @@ void board_init_f_init_reserve(ulong base);
  * For most architectures this can simply be:
  *
  *    gd = gd_ptr;
- *
- * @gd_ptr:	Pointer to global data
  */
 void arch_setup_gd(gd_t *gd_ptr);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (9 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 11/17] init: Fix documentation Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-19 15:29   ` Simon Glass
  2018-10-12 14:00   ` Stefan Roese
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation Mario Six
                   ` (5 subsequent siblings)
  16 siblings, 2 replies; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

When the DM CPU drivers are active, printing information about a CPU
should be delegated to a matching driver.

Hence, add a static print_cpuinfo that implements this delegation when
DM CPU drivers are active.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Print error if CPU description could not be retrieved
    * Improved error handling and debug reporting
    * Added documentation
    
    v2 -> v3:
    No changes
    
    v1 -> v2:
    New in v2

 common/board_f.c | 28 ++++++++++++++++++++++++++++
 include/init.h   |  7 +++++++
 2 files changed, 35 insertions(+)

diff --git a/common/board_f.c b/common/board_f.c
index afafec5e4d0..fcc89df8160 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <console.h>
+#include <cpu.h>
 #include <dm.h>
 #include <environment.h>
 #include <fdtdec.h>
@@ -165,6 +166,33 @@ static int print_resetinfo(void)
 }
 #endif
 
+#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_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)
 {
 	puts("DRAM:  ");
diff --git a/include/init.h b/include/init.h
index a58d7a6917f..a76d747b035 100644
--- a/include/init.h
+++ b/include/init.h
@@ -109,7 +109,14 @@ int arch_reserve_stacks(void);
  */
 int init_cache_f_r(void);
 
+#ifndef CONFIG_CPU
+/**
+ * print_cpuinfo() - Display information about the CPU
+ *
+ * Return: 0 if OK, -ve on error
+ */
 int print_cpuinfo(void);
+#endif
 int timer_init(void);
 int reserve_mmu(void);
 int misc_init_f(void);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (10 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:56   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method Mario Six
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Documentation in cpu.h is not in kernel-doc format. Change it to comply
with it.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 include/cpu.h | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/include/cpu.h b/include/cpu.h
index 5cc7c5abd72..22467cb9b3a 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -9,19 +9,21 @@
 
 /**
  * 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
  * device.
- *
- * @cpu_id:	Platform-specific way of identifying the CPU.
- * @ucode_version: Microcode version, if CPU_FEAT_UCODE is set
  */
 struct cpu_platdata {
 	int cpu_id;
 	int ucode_version;
 	ulong device_id;
-	u16 family;		/* DMTF CPU Family */
-	u32 id[2];		/* DMTF CPU Processor IDs */
+	u16 family;
+	u32 id[2];
 };
 
 /* CPU features - mostly just a placeholder for now */
@@ -88,38 +90,38 @@ struct cpu_ops {
 
 /**
  * cpu_get_desc() - Get a description string for a CPU
- *
  * @dev:	Device to check (UCLASS_CPU)
  * @buf:	Buffer to place string
  * @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);
 
 /**
  * cpu_get_info() - Get information about a CPU
- *
  * @dev:	Device to check (UCLASS_CPU)
  * @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);
 
 /**
  * cpu_get_count() - Get number of CPUs
- *
  * @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);
 
 /**
  * cpu_get_vendor() - Get vendor name of a CPU
- *
  * @dev:	Device to check (UCLASS_CPU)
  * @buf:	Buffer to place string
  * @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);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (11 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass Mario Six
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a method to probe all CPUs of the board.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 drivers/cpu/cpu-uclass.c | 23 +++++++++++++++++++++++
 include/cpu.h            |  7 +++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index f362eb11e72..457f77b7c89 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -11,6 +11,29 @@
 #include <dm/lists.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)
 {
 	struct cpu_ops *ops = cpu_get_ops(dev);
diff --git a/include/cpu.h b/include/cpu.h
index 22467cb9b3a..367c5f46a00 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -125,4 +125,11 @@ int cpu_get_count(struct udevice *dev);
  */
 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
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (12 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:55   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver Mario Six
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a sandbox CPU driver, and some tests for the CPU uclass.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    New in v4

 arch/sandbox/dts/test.dts | 12 ++++++++++
 drivers/cpu/Makefile      |  1 +
 drivers/cpu/cpu_sandbox.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 test/dm/Makefile          |  1 +
 test/dm/cpu.c             | 45 ++++++++++++++++++++++++++++++++++
 5 files changed, 120 insertions(+)
 create mode 100644 drivers/cpu/cpu_sandbox.c
 create mode 100644 test/dm/cpu.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 137679abea9..527af1aee11 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -283,6 +283,18 @@
 		mbox-names = "other", "test";
 	};
 
+	cpu-test1 {
+		compatible = "sandbox,cpu_sandbox";
+	};
+
+	cpu-test2 {
+		compatible = "sandbox,cpu_sandbox";
+	};
+
+	cpu-test3 {
+		compatible = "sandbox,cpu_sandbox";
+	};
+
 	mmc2 {
 		compatible = "sandbox,mmc";
 	};
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index db515f6f177..980c68f44d0 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -7,3 +7,4 @@
 obj-$(CONFIG_CPU) += cpu-uclass.o
 
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
+obj-$(CONFIG_SANDBOX) += cpu_sandbox.o
diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c
new file mode 100644
index 00000000000..ff87e8adca3
--- /dev/null
+++ b/drivers/cpu/cpu_sandbox.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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,
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index d2ed96c6153..c3bb26bb974 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -44,4 +44,5 @@ obj-$(CONFIG_DM_VIDEO) += video.o
 obj-$(CONFIG_ADC) += adc.o
 obj-$(CONFIG_SPMI) += spmi.o
 obj-$(CONFIG_WDT) += wdt.o
+obj-$(CONFIG_CPU) += cpu.o
 endif
diff --git a/test/dm/cpu.c b/test/dm/cpu.c
new file mode 100644
index 00000000000..f5f1caef716
--- /dev/null
+++ b/test/dm/cpu.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (13 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:57   ` Simon Glass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver Mario Six
  2018-08-17 14:16 ` [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Simon Glass
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a CPU driver for the MPC83xx architecture.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Fixed style violations
    * Switched to using cpu_probe_all method
    * Switched to bitfield macros
    * Moved mpc83xx_cpu_info fields into mpc83xx_cpu_priv
    * Fixed CPU family determination
    * Improved error checking and debug reporting
    * Added forgotten compatible strings
    * Added full documentation
    * Simplified revid determination
    
    v2 -> v3:
    * Added driver files to MAINTAINERS
    
    v1 -> v2:
    * Removed cpu_print_info
    * Fixed CPU info printing
    * Removed usage of uclass_{first,next}_device_compat
    * Removed printing of reset status

 .../devicetree/bindings/cpu/fsl,mpc83xx.txt        |  34 ++
 MAINTAINERS                                        |   2 +
 arch/powerpc/cpu/mpc83xx/cpu.c                     |   2 +
 arch/powerpc/cpu/mpc83xx/cpu_init.c                |   2 +
 arch/powerpc/include/asm/processor.h               |   2 +
 drivers/cpu/Kconfig                                |   7 +
 drivers/cpu/Makefile                               |   1 +
 drivers/cpu/mpc83xx_cpu.c                          | 349 +++++++++++++++++++++
 drivers/cpu/mpc83xx_cpu.h                          | 126 ++++++++
 9 files changed, 525 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
 create mode 100644 drivers/cpu/mpc83xx_cpu.c
 create mode 100644 drivers/cpu/mpc83xx_cpu.h

diff --git a/Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt b/Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
new file mode 100644
index 00000000000..ac563d906ac
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
@@ -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 at 0 {
+		compatible = "fsl,mpc8315";
+		clocks = <&socclocks MPC83XX_CLK_CORE
+		          &socclocks MPC83XX_CLK_CSB>;
+	};
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 58a8f8da7ba..a502b0bbf4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -503,6 +503,8 @@ 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:	arch/powerpc/cpu/mpc83xx/
 F:	arch/powerpc/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index ffb42415feb..b29f271e9bc 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -25,6 +25,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_CPU_MPC83XX
 int checkcpu(void)
 {
 	volatile immap_t *immr;
@@ -114,6 +115,7 @@ int checkcpu(void)
 
 	return 0;
 }
+#endif
 
 #ifndef CONFIG_SYSRESET
 int
diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c
index fcac9f63a81..1555205e069 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c
@@ -464,6 +464,7 @@ static int print_83xx_arb_event(int force)
 }
 #endif /* CONFIG_DISPLAY_AER_xxxx */
 
+#ifndef CONFIG_CPU_MPC83XX
 /*
  * Figure out the cause of the reset
  */
@@ -505,3 +506,4 @@ int prt_83xx_rsr(void)
 
 	return 0;
 }
+#endif
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 6fbe8c46b31..f97ce48cc27 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -1325,7 +1325,9 @@ void ll_puts(const char *);
 /* In misc.c */
 void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 
+#ifndef CONFIG_CPU_MPC83XX
 int prt_83xx_rsr(void);
+#endif
 
 #endif /* ndef ASSEMBLY*/
 
diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig
index 0d1424d38e9..d4052005e24 100644
--- a/drivers/cpu/Kconfig
+++ b/drivers/cpu/Kconfig
@@ -6,3 +6,10 @@ config CPU
 	  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
 	  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.
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 980c68f44d0..f452ee404e5 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -7,4 +7,5 @@
 obj-$(CONFIG_CPU) += cpu-uclass.o
 
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
+obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o
 obj-$(CONFIG_SANDBOX) += cpu_sandbox.o
diff --git a/drivers/cpu/mpc83xx_cpu.c b/drivers/cpu/mpc83xx_cpu.c
new file mode 100644
index 00000000000..31717afaec4
--- /dev/null
+++ b/drivers/cpu/mpc83xx_cpu.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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,
+};
diff --git a/drivers/cpu/mpc83xx_cpu.h b/drivers/cpu/mpc83xx_cpu.h
new file mode 100644
index 00000000000..2aaa4e18844
--- /dev/null
+++ b/drivers/cpu/mpc83xx_cpu.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (14 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver Mario Six
@ 2018-08-06  8:23 ` Mario Six
  2018-09-28 15:57   ` Simon Glass
  2018-08-17 14:16 ` [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Simon Glass
  16 siblings, 1 reply; 43+ messages in thread
From: Mario Six @ 2018-08-06  8:23 UTC (permalink / raw)
  To: u-boot

Add a driver to configure the SerDes (Serializer/Deserializer) lanes on
the MPC83xx architecture.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

Notes:
    v3 -> v4:
    * Added full documentation
    * Introduced separate local header file
    * Added error debug output
    
    v2 -> v3:
    * Added driver file to MAINTAINERS
    
    v1 -> v2:
    No changes

 .../bindings/misc/fsl,mpc83xx-serdes.txt           |  24 +++
 MAINTAINERS                                        |   1 +
 arch/powerpc/cpu/mpc83xx/serdes.c                  |   4 +
 arch/powerpc/include/asm/fsl_mpc83xx_serdes.h      |   4 +
 drivers/misc/Kconfig                               |   7 +
 drivers/misc/Makefile                              |   1 +
 drivers/misc/mpc83xx_serdes.c                      | 185 ++++++++++++++++
 drivers/misc/mpc83xx_serdes.h                      | 232 +++++++++++++++++++++
 8 files changed, 458 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/fsl,mpc83xx-serdes.txt
 create mode 100644 drivers/misc/mpc83xx_serdes.c
 create mode 100644 drivers/misc/mpc83xx_serdes.h

diff --git a/Documentation/devicetree/bindings/misc/fsl,mpc83xx-serdes.txt b/Documentation/devicetree/bindings/misc/fsl,mpc83xx-serdes.txt
new file mode 100644
index 00000000000..64a9b5b154b
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/fsl,mpc83xx-serdes.txt
@@ -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 at e3000 {
+	reg = <0xe3000 0x200>;
+	compatible = "fsl,mpc83xx-serdes";
+	proto = "pex";
+	serdes-clk = <100>;
+	vdd;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index a502b0bbf4e..5540b140137 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -505,6 +505,7 @@ 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/include/asm/arch-mpc83xx/
 
diff --git a/arch/powerpc/cpu/mpc83xx/serdes.c b/arch/powerpc/cpu/mpc83xx/serdes.c
index 982a4475f00..8242f952653 100644
--- a/arch/powerpc/cpu/mpc83xx/serdes.c
+++ b/arch/powerpc/cpu/mpc83xx/serdes.c
@@ -8,6 +8,8 @@
  * Author: Li Yang <leoli@freescale.com>
  */
 
+#ifndef CONFIG_MPC83XX_SERDES
+
 #include <config.h>
 #include <common.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;
 	out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
 }
+
+#endif /* !CONFIG_MPC83XX_SERDES */
diff --git a/arch/powerpc/include/asm/fsl_mpc83xx_serdes.h b/arch/powerpc/include/asm/fsl_mpc83xx_serdes.h
index e51d060d6a7..a02b5992654 100644
--- a/arch/powerpc/include/asm/fsl_mpc83xx_serdes.h
+++ b/arch/powerpc/include/asm/fsl_mpc83xx_serdes.h
@@ -6,6 +6,8 @@
 #ifndef __FSL_MPC83XX_SERDES_H
 #define __FSL_MPC83XX_SERDES_H
 
+#ifndef CONFIG_MPC83XX_SERDES
+
 #include <config.h>
 
 #define FSL_SERDES_CLK_100		(0 << 28)
@@ -19,4 +21,6 @@
 
 extern void fsl_setup_serdes(u32 offset, char proto, u32 rfcks, char vdd);
 
+#endif /* !CONFIG_MPC83XX_SERDES */
+
 #endif /* __FSL_MPC83XX_SERDES_H */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c031dfde9d4..a479e4eec56 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -277,4 +277,11 @@ config GDSYS_RXAUI_CTRL
 	depends on MISC
 	help
 	  Support gdsys FPGA's RXAUI control.
+
+config MPC83XX_SERDES
+	bool "Enable MPC83xx serdes driver"
+	depends on MISC
+	help
+	  Support for serdes found on MPC83xx SoCs.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4ce9d213f06..e2c2b763b7a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
 obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o
 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
 obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
+obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
diff --git a/drivers/misc/mpc83xx_serdes.c b/drivers/misc/mpc83xx_serdes.c
new file mode 100644
index 00000000000..d572dda3c19
--- /dev/null
+++ b/drivers/misc/mpc83xx_serdes.c
@@ -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),
+};
diff --git a/drivers/misc/mpc83xx_serdes.h b/drivers/misc/mpc83xx_serdes.h
new file mode 100644
index 00000000000..89ea1dbab73
--- /dev/null
+++ b/drivers/misc/mpc83xx_serdes.h
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at 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,
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx
  2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
                   ` (15 preceding siblings ...)
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver Mario Six
@ 2018-08-17 14:16 ` Simon Glass
  2018-09-28 15:55   ` Simon Glass
  16 siblings, 1 reply; 43+ messages in thread
From: Simon Glass @ 2018-08-17 14:16 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 6 August 2018 at 02:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a RAM driver for the MPC83xx architecture.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Switched preprocessor constants to C constants
>     * Improved error reporting
>     * Added driver binding file
>     * Added full documentation
>
>     v2 -> v3:
>     * Converted some #ifdefs to if (IS_ENABLED(...))
>     * Added driver files to MAINTAINERS
>
>     v1 -> v2:
>     No changes
>
>  .../bindings/ram/fsl,mpc83xx-mem-controller.txt    |  314 ++++++
>  MAINTAINERS                                        |    2 +
>  arch/powerpc/cpu/mpc83xx/spd_sdram.c               |    4 +
>  drivers/ram/Kconfig                                |    9 +
>  drivers/ram/Makefile                               |    1 +
>  drivers/ram/mpc83xx_sdram.c                        | 1096 ++++++++++++++++++++
>  include/dt-bindings/memory/mpc83xx-sdram.h         |  161 +++
>  include/mpc83xx.h                                  |    6 +
>  8 files changed, 1593 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt
>  create mode 100644 drivers/ram/mpc83xx_sdram.c
>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h

This series has ended up assigned to me in patchwork.

We are at RC2 now so I can pull it into u-boot-dm/next. But if you
have other plans for the series, please let me know.

Regards,
Simon

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active Mario Six
@ 2018-09-19 15:29   ` Simon Glass
  2018-09-21  6:56     ` Mario Six
  2018-10-12 14:00   ` Stefan Roese
  1 sibling, 1 reply; 43+ messages in thread
From: Simon Glass @ 2018-09-19 15:29 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 6 August 2018 at 02:23, Mario Six <mario.six@gdsys.cc> wrote:
> When the DM CPU drivers are active, printing information about a CPU
> should be delegated to a matching driver.
>
> Hence, add a static print_cpuinfo that implements this delegation when
> DM CPU drivers are active.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Print error if CPU description could not be retrieved
>     * Improved error handling and debug reporting
>     * Added documentation
>
>     v2 -> v3:
>     No changes
>
>     v1 -> v2:
>     New in v2
>
>  common/board_f.c | 28 ++++++++++++++++++++++++++++
>  include/init.h   |  7 +++++++
>  2 files changed, 35 insertions(+)
>

I have applied this, but with a change to use CONFIG_IS_ENABLED(CPU).

At present chromebook_link64 calls print_cpuinfo() from SPL, so we
need something like this.

Perhaps a better fix is to move the function into common/init ?

Regards,
Simon

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-09-19 15:29   ` Simon Glass
@ 2018-09-21  6:56     ` Mario Six
  0 siblings, 0 replies; 43+ messages in thread
From: Mario Six @ 2018-09-21  6:56 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Sep 19, 2018 at 5:30 PM Simon Glass <sjg@chromium.org> wrote:
>
> Hi Mario,
>
> On 6 August 2018 at 02:23, Mario Six <mario.six@gdsys.cc> wrote:
> > When the DM CPU drivers are active, printing information about a CPU
> > should be delegated to a matching driver.
> >
> > Hence, add a static print_cpuinfo that implements this delegation when
> > DM CPU drivers are active.
> >
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> > Signed-off-by: Mario Six <mario.six@gdsys.cc>
> > ---
> >
> > Notes:
> >     v3 -> v4:
> >     * Print error if CPU description could not be retrieved
> >     * Improved error handling and debug reporting
> >     * Added documentation
> >
> >     v2 -> v3:
> >     No changes
> >
> >     v1 -> v2:
> >     New in v2
> >
> >  common/board_f.c | 28 ++++++++++++++++++++++++++++
> >  include/init.h   |  7 +++++++
> >  2 files changed, 35 insertions(+)
> >
>
> I have applied this, but with a change to use CONFIG_IS_ENABLED(CPU).
>
> At present chromebook_link64 calls print_cpuinfo() from SPL, so we
> need something like this.
>
> Perhaps a better fix is to move the function into common/init ?
>

Yeah, sounds reasonable. I'll look into it.

> Regards,
> Simon
>

Best regards,
Mario

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx
  2018-08-17 14:16 ` [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Simon Glass
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 17 August 2018 at 07:16, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 6 August 2018 at 02:23, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a RAM driver for the MPC83xx architecture.
>>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>> Notes:
>>     v3 -> v4:
>>     * Switched preprocessor constants to C constants
>>     * Improved error reporting
>>     * Added driver binding file
>>     * Added full documentation
>>
>>     v2 -> v3:
>>     * Converted some #ifdefs to if (IS_ENABLED(...))
>>     * Added driver files to MAINTAINERS
>>
>>     v1 -> v2:
>>     No changes
>>
>>  .../bindings/ram/fsl,mpc83xx-mem-controller.txt    |  314 ++++++
>>  MAINTAINERS                                        |    2 +
>>  arch/powerpc/cpu/mpc83xx/spd_sdram.c               |    4 +
>>  drivers/ram/Kconfig                                |    9 +
>>  drivers/ram/Makefile                               |    1 +
>>  drivers/ram/mpc83xx_sdram.c                        | 1096 ++++++++++++++++++++
>>  include/dt-bindings/memory/mpc83xx-sdram.h         |  161 +++
>>  include/mpc83xx.h                                  |    6 +
>>  8 files changed, 1593 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/ram/fsl,mpc83xx-mem-controller.txt
>>  create mode 100644 drivers/ram/mpc83xx_sdram.c
>>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>
> This series has ended up assigned to me in patchwork.
>
> We are at RC2 now so I can pull it into u-boot-dm/next. But if you
> have other plans for the series, please let me know.
>

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Define the read*_*/write*_* macros for the PowerPC platform to be able
> to use the macros in wait_bit.h.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  arch/powerpc/include/asm/io.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> It's useful to have the reset status of the SoC printed out during reset
> (e.g. to learn whether the reset was caused by software or a watchdog).
>
> As a first step to implement this, add a get_status method to the
> sysreset class, which enables the caller to get printable information
> about the reset status (akin to get_desc in the CPU uclass).
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     No changes
>
>     v2 -> v3:
>     No changes
>
>     v1 -> v2:
>     New in v2
>
>  drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
>  include/sysreset.h                 | 17 +++++++++++++++++
>  2 files changed, 27 insertions(+)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add some tests for sysreset_get_status.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Switched to usage of strlcpy
>
>     v2 -> v3:
>     New in v3.
>
>  drivers/sysreset/sysreset_sandbox.c | 16 ++++++++++++++++
>  test/dm/sysreset.c                  | 20 ++++++++++++++++++++
>  2 files changed, 36 insertions(+)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Makefile entries should be sorted.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  drivers/timer/Makefile | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Includes should be sorted.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     No changes
>
>     v2 -> v3:
>     No changes
>
>     v1 -> v2:
>     New in v2
>
>  common/board_f.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a sandbox CPU driver, and some tests for the CPU uclass.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  arch/sandbox/dts/test.dts | 12 ++++++++++
>  drivers/cpu/Makefile      |  1 +
>  drivers/cpu/cpu_sandbox.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
>  test/dm/Makefile          |  1 +
>  test/dm/cpu.c             | 45 ++++++++++++++++++++++++++++++++++
>  5 files changed, 120 insertions(+)
>  create mode 100644 drivers/cpu/cpu_sandbox.c
>  create mode 100644 test/dm/cpu.c'

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 11/17] init: Fix documentation
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 11/17] init: Fix documentation Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> The documentation in init.h is not in kernel-doc format. Fix this.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  include/init.h | 27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a clock driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Gotten rid of all #ifdefs (SoC is now determined by compatible string)
>     * Added MPC83xx-wide functions to get properties of SoCs
>     * Gotten rid of most clock variables in global data
>     * Marked more files as static
>     * Improved error handling and debug reporting
>     * Simplified bitmask handling
>     * Added binding file
>     * Added full documentation
>
>     v2 -> v3:
>     * Added driver files to MAINTAINERS
>
>     v1 -> v2:
>     * Added binding of sysreset driver
>
>  .../devicetree/bindings/clk/fsl,mpc83xx-clk.txt    |  23 ++
>  MAINTAINERS                                        |   3 +
>  arch/powerpc/cpu/mpc83xx/speed.c                   |   4 +
>  arch/powerpc/include/asm/arch-mpc83xx/soc.h        |  74 ++++
>  arch/powerpc/include/asm/config.h                  |   2 +-
>  arch/powerpc/include/asm/global_data.h             |   4 +
>  drivers/clk/Kconfig                                |   6 +
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/mpc83xx_clk.c                          | 410 +++++++++++++++++++++
>  drivers/clk/mpc83xx_clk.h                          | 379 +++++++++++++++++++
>  include/dt-bindings/clk/mpc83xx-clk.h              |  33 ++
>  11 files changed, 938 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/clk/fsl,mpc83xx-clk.txt
>  create mode 100644 arch/powerpc/include/asm/arch-mpc83xx/soc.h
>  create mode 100644 drivers/clk/mpc83xx_clk.c
>  create mode 100644 drivers/clk/mpc83xx_clk.h
>  create mode 100644 include/dt-bindings/clk/mpc83xx-clk.h

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> To print the reset status during boot, add a method print_resetinfo to
> board_f, which is called in init_sequence_f[], that gets the reset
> information from the sysreset driver (assuming there is only one seems
> reasonable), and prints it.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     No changes
>
>     v2 -> v3:
>     * Improved behavior and error handling
>
>     v1 -> v2:
>     New in v2
>
>  common/board_f.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a sysreset driver for the MPC83xx platform.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Fixed style violation
>     * Added full documentation
>     * Switched to wait_for_bit_be32 usage
>     * Improved error handling and debug printing
>     * Minimized usage of preprocessor
>
>     v2 -> v3:
>     * Added driver file to MAINTAINERS
>
>     v1 -> v2:
>     New in v2
>
>  MAINTAINERS                         |   2 +
>  arch/powerpc/cpu/mpc83xx/cpu.c      |   3 +-
>  drivers/sysreset/Kconfig            |   5 +
>  drivers/sysreset/Makefile           |   9 +-
>  drivers/sysreset/sysreset_mpc83xx.c | 212 ++++++++++++++++++++++++++++++++++++
>  drivers/sysreset/sysreset_mpc83xx.h | 103 ++++++++++++++++++
>  6 files changed, 329 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/sysreset/sysreset_mpc83xx.c
>  create mode 100644 drivers/sysreset/sysreset_mpc83xx.h

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method Mario Six
@ 2018-09-28 15:55   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:55 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a method to probe all CPUs of the board.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  drivers/cpu/cpu-uclass.c | 23 +++++++++++++++++++++++
>  include/cpu.h            |  7 +++++++
>  2 files changed, 30 insertions(+)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation Mario Six
@ 2018-09-28 15:56   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:56 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Documentation in cpu.h is not in kernel-doc format. Change it to comply
> with it.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     New in v4
>
>  include/cpu.h | 28 +++++++++++++++-------------
>  1 file changed, 15 insertions(+), 13 deletions(-)

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver Mario Six
@ 2018-09-28 15:57   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:57 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a timer driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Removed superfluous get_timer (switched to usage of standard function)
>     * Improved error handling and debug reporting
>     * Added full documentation
>
>     v2 -> v3:
>     * Got rid of the static variables
>     * Added driver files to MAINTAINERS
>
>     v1 -> v2:
>     * Removed now-superfluous comments
>     * Removed usage of uclass_{first,next}_device_compat
>     * Switched to usage of new board uclass (instead of devinfo)
>
>  .../bindings/timer/fsl,mpc83xx-timer.txt           |  21 ++
>  MAINTAINERS                                        |   1 +
>  arch/powerpc/cpu/mpc83xx/cpu.c                     |   4 +-
>  arch/powerpc/lib/Makefile                          |   4 +
>  arch/powerpc/lib/interrupts.c                      |   5 +-
>  drivers/timer/Kconfig                              |   7 +
>  drivers/timer/Makefile                             |   1 +
>  drivers/timer/mpc83xx_timer.c                      | 249 +++++++++++++++++++++
>  8 files changed, 289 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/timer/fsl,mpc83xx-timer.txt
>  create mode 100644 drivers/timer/mpc83xx_timer.c

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver Mario Six
@ 2018-09-28 15:57   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:57 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a CPU driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Fixed style violations
>     * Switched to using cpu_probe_all method
>     * Switched to bitfield macros
>     * Moved mpc83xx_cpu_info fields into mpc83xx_cpu_priv
>     * Fixed CPU family determination
>     * Improved error checking and debug reporting
>     * Added forgotten compatible strings
>     * Added full documentation
>     * Simplified revid determination
>
>     v2 -> v3:
>     * Added driver files to MAINTAINERS
>
>     v1 -> v2:
>     * Removed cpu_print_info
>     * Fixed CPU info printing
>     * Removed usage of uclass_{first,next}_device_compat
>     * Removed printing of reset status
>
>  .../devicetree/bindings/cpu/fsl,mpc83xx.txt        |  34 ++
>  MAINTAINERS                                        |   2 +
>  arch/powerpc/cpu/mpc83xx/cpu.c                     |   2 +
>  arch/powerpc/cpu/mpc83xx/cpu_init.c                |   2 +
>  arch/powerpc/include/asm/processor.h               |   2 +
>  drivers/cpu/Kconfig                                |   7 +
>  drivers/cpu/Makefile                               |   1 +
>  drivers/cpu/mpc83xx_cpu.c                          | 349 +++++++++++++++++++++
>  drivers/cpu/mpc83xx_cpu.h                          | 126 ++++++++
>  9 files changed, 525 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/cpu/fsl,mpc83xx.txt
>  create mode 100644 drivers/cpu/mpc83xx_cpu.c
>  create mode 100644 drivers/cpu/mpc83xx_cpu.h

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver Mario Six
@ 2018-09-28 15:57   ` Simon Glass
  0 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2018-09-28 15:57 UTC (permalink / raw)
  To: u-boot

On 6 August 2018 at 01:23, Mario Six <mario.six@gdsys.cc> wrote:
> Add a driver to configure the SerDes (Serializer/Deserializer) lanes on
> the MPC83xx architecture.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
> Notes:
>     v3 -> v4:
>     * Added full documentation
>     * Introduced separate local header file
>     * Added error debug output
>
>     v2 -> v3:
>     * Added driver file to MAINTAINERS
>
>     v1 -> v2:
>     No changes
>
>  .../bindings/misc/fsl,mpc83xx-serdes.txt           |  24 +++
>  MAINTAINERS                                        |   1 +
>  arch/powerpc/cpu/mpc83xx/serdes.c                  |   4 +
>  arch/powerpc/include/asm/fsl_mpc83xx_serdes.h      |   4 +
>  drivers/misc/Kconfig                               |   7 +
>  drivers/misc/Makefile                              |   1 +
>  drivers/misc/mpc83xx_serdes.c                      | 185 ++++++++++++++++
>  drivers/misc/mpc83xx_serdes.h                      | 232 +++++++++++++++++++++
>  8 files changed, 458 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/fsl,mpc83xx-serdes.txt
>  create mode 100644 drivers/misc/mpc83xx_serdes.c
>  create mode 100644 drivers/misc/mpc83xx_serdes.h

Applied to u-boot-dm, and now in mainline, thanks!

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-08-06  8:23 ` [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active Mario Six
  2018-09-19 15:29   ` Simon Glass
@ 2018-10-12 14:00   ` Stefan Roese
  2018-10-12 15:34     ` Bin Meng
  1 sibling, 1 reply; 43+ messages in thread
From: Stefan Roese @ 2018-10-12 14:00 UTC (permalink / raw)
  To: u-boot

Hi!

I just tested the latest U-Boot version on one of my x86
platforms (Baytrail theadorable-x86-dfi-bt700_defconfig).
Unfortunately this patch break the board port, resulting in
this output:

U-Boot 2018.11-rc1-00268-g1f7888b626 (Oct 12 2018 - 15:23:52 +0200)

initcall sequence fff5aa40 failed at call fff129bc (err=-19)
### ERROR ### Please RESET the board ###

This is related to the fact that this platform does not support
a proper DM CPU driver. When I revert this patch, all is fine
again:

U-Boot 2018.11-rc1-00269-g82e3eecc2b (Oct 12 2018 - 15:50:36 +0200)

CPU: x86_64, vendor Intel, device 30679h
DRAM:  4 GiB
MMC:   pci_mmc: 0, pci_mmc: 1, pci_mmc: 2
Loading Environment from SPI Flash... SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
OK
Model: theadorable-x86-DFI-BT700
...

How should we proceed with this patch. Since multiple boards /
platforms could be affected (I remember this also hitting me
with my latest MIPS port), we should probably revert this patch
for this upcoming release.

Thoughts?

Thanks,
Stefan

On 06.08.2018 10:23, Mario Six wrote:
> When the DM CPU drivers are active, printing information about a CPU
> should be delegated to a matching driver.
> 
> Hence, add a static print_cpuinfo that implements this delegation when
> DM CPU drivers are active.
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
> 
> Notes:
>      v3 -> v4:
>      * Print error if CPU description could not be retrieved
>      * Improved error handling and debug reporting
>      * Added documentation
>      
>      v2 -> v3:
>      No changes
>      
>      v1 -> v2:
>      New in v2
> 
>   common/board_f.c | 28 ++++++++++++++++++++++++++++
>   include/init.h   |  7 +++++++
>   2 files changed, 35 insertions(+)
> 
> diff --git a/common/board_f.c b/common/board_f.c
> index afafec5e4d0..fcc89df8160 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -11,6 +11,7 @@
>   
>   #include <common.h>
>   #include <console.h>
> +#include <cpu.h>
>   #include <dm.h>
>   #include <environment.h>
>   #include <fdtdec.h>
> @@ -165,6 +166,33 @@ static int print_resetinfo(void)
>   }
>   #endif
>   
> +#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_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)
>   {
>   	puts("DRAM:  ");
> diff --git a/include/init.h b/include/init.h
> index a58d7a6917f..a76d747b035 100644
> --- a/include/init.h
> +++ b/include/init.h
> @@ -109,7 +109,14 @@ int arch_reserve_stacks(void);
>    */
>   int init_cache_f_r(void);
>   
> +#ifndef CONFIG_CPU
> +/**
> + * print_cpuinfo() - Display information about the CPU
> + *
> + * Return: 0 if OK, -ve on error
> + */
>   int print_cpuinfo(void);
> +#endif
>   int timer_init(void);
>   int reserve_mmu(void);
>   int misc_init_f(void);
> 

Viele Grüße,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-10-12 14:00   ` Stefan Roese
@ 2018-10-12 15:34     ` Bin Meng
  2018-10-13  7:59       ` Stefan Roese
  2018-11-03 20:45       ` Andy Shevchenko
  0 siblings, 2 replies; 43+ messages in thread
From: Bin Meng @ 2018-10-12 15:34 UTC (permalink / raw)
  To: u-boot

Hi Stefan,

On Fri, Oct 12, 2018 at 10:00 PM Stefan Roese <sr@denx.de> wrote:
>
> Hi!
>
> I just tested the latest U-Boot version on one of my x86
> platforms (Baytrail theadorable-x86-dfi-bt700_defconfig).
> Unfortunately this patch break the board port, resulting in
> this output:
>
> U-Boot 2018.11-rc1-00268-g1f7888b626 (Oct 12 2018 - 15:23:52 +0200)
>
> initcall sequence fff5aa40 failed at call fff129bc (err=-19)
> ### ERROR ### Please RESET the board ###
>
> This is related to the fact that this platform does not support
> a proper DM CPU driver. When I revert this patch, all is fine
> again:
>
> U-Boot 2018.11-rc1-00269-g82e3eecc2b (Oct 12 2018 - 15:50:36 +0200)
>
> CPU: x86_64, vendor Intel, device 30679h
> DRAM:  4 GiB
> MMC:   pci_mmc: 0, pci_mmc: 1, pci_mmc: 2
> Loading Environment from SPI Flash... SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
> OK
> Model: theadorable-x86-DFI-BT700
> ...
>
> How should we proceed with this patch. Since multiple boards /
> platforms could be affected (I remember this also hitting me
> with my latest MIPS port), we should probably revert this patch
> for this upcoming release.
>
> Thoughts?
>

Thanks for testing and reporting this! I suspect the following patch
can resolve this:

diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
index 56e9813..2eb9172 100644
--- a/arch/x86/cpu/baytrail/cpu.c
+++ b/arch/x86/cpu/baytrail/cpu.c
@@ -203,4 +203,5 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
        .bind           = cpu_x86_bind,
        .probe          = cpu_x86_baytrail_probe,
        .ops            = &cpu_x86_baytrail_ops,
+       .flags          = DM_FLAG_PRE_RELOC,
 }

This patch needs to be applied on top of u-boot-x86/dm-fixes. Could
you please have a try?

I was not aware Mario's changes broke the Baytrail boards too! I was
only testing on QEMU x86 before.

Regards,
Bin

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-10-12 15:34     ` Bin Meng
@ 2018-10-13  7:59       ` Stefan Roese
  2018-11-03 20:45       ` Andy Shevchenko
  1 sibling, 0 replies; 43+ messages in thread
From: Stefan Roese @ 2018-10-13  7:59 UTC (permalink / raw)
  To: u-boot

Hi Bin,

On 12.10.2018 17:34, Bin Meng wrote:
> On Fri, Oct 12, 2018 at 10:00 PM Stefan Roese <sr@denx.de> wrote:
>>
>> Hi!
>>
>> I just tested the latest U-Boot version on one of my x86
>> platforms (Baytrail theadorable-x86-dfi-bt700_defconfig).
>> Unfortunately this patch break the board port, resulting in
>> this output:
>>
>> U-Boot 2018.11-rc1-00268-g1f7888b626 (Oct 12 2018 - 15:23:52 +0200)
>>
>> initcall sequence fff5aa40 failed at call fff129bc (err=-19)
>> ### ERROR ### Please RESET the board ###
>>
>> This is related to the fact that this platform does not support
>> a proper DM CPU driver. When I revert this patch, all is fine
>> again:
>>
>> U-Boot 2018.11-rc1-00269-g82e3eecc2b (Oct 12 2018 - 15:50:36 +0200)
>>
>> CPU: x86_64, vendor Intel, device 30679h
>> DRAM:  4 GiB
>> MMC:   pci_mmc: 0, pci_mmc: 1, pci_mmc: 2
>> Loading Environment from SPI Flash... SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
>> OK
>> Model: theadorable-x86-DFI-BT700
>> ...
>>
>> How should we proceed with this patch. Since multiple boards /
>> platforms could be affected (I remember this also hitting me
>> with my latest MIPS port), we should probably revert this patch
>> for this upcoming release.
>>
>> Thoughts?
>>
> 
> Thanks for testing and reporting this! I suspect the following patch
> can resolve this:
> 
> diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
> index 56e9813..2eb9172 100644
> --- a/arch/x86/cpu/baytrail/cpu.c
> +++ b/arch/x86/cpu/baytrail/cpu.c
> @@ -203,4 +203,5 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
>          .bind           = cpu_x86_bind,
>          .probe          = cpu_x86_baytrail_probe,
>          .ops            = &cpu_x86_baytrail_ops,
> +       .flags          = DM_FLAG_PRE_RELOC,
>   }
> 
> This patch needs to be applied on top of u-boot-x86/dm-fixes. Could
> you please have a try?

I've applied your patches from u-boot-x86/dm-fixes and added
the .flag as suggested above. And yes, this fixes this issue.

Many thanks for the quick help,
Stefan

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-10-12 15:34     ` Bin Meng
  2018-10-13  7:59       ` Stefan Roese
@ 2018-11-03 20:45       ` Andy Shevchenko
  2018-11-03 20:51         ` Andy Shevchenko
  1 sibling, 1 reply; 43+ messages in thread
From: Andy Shevchenko @ 2018-11-03 20:45 UTC (permalink / raw)
  To: u-boot

On Fri, Oct 12, 2018 at 6:34 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> On Fri, Oct 12, 2018 at 10:00 PM Stefan Roese <sr@denx.de> wrote:

> diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
> index 56e9813..2eb9172 100644
> --- a/arch/x86/cpu/baytrail/cpu.c
> +++ b/arch/x86/cpu/baytrail/cpu.c
> @@ -203,4 +203,5 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
>         .bind           = cpu_x86_bind,
>         .probe          = cpu_x86_baytrail_probe,
>         .ops            = &cpu_x86_baytrail_ops,

> +       .flags          = DM_FLAG_PRE_RELOC,

This has to be done for all x86 boards I suppose?
Actually I don't see this in the v2018.11-rc3.

>  }
>
> This patch needs to be applied on top of u-boot-x86/dm-fixes. Could
> you please have a try?
>
> I was not aware Mario's changes broke the Baytrail boards too! I was
> only testing on QEMU x86 before.

Not only.
Edison board is broken by this patch.

This must be fixed before release, or better just to revert the patch ASAP.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-11-03 20:45       ` Andy Shevchenko
@ 2018-11-03 20:51         ` Andy Shevchenko
  2018-11-04 14:18           ` Bin Meng
  0 siblings, 1 reply; 43+ messages in thread
From: Andy Shevchenko @ 2018-11-03 20:51 UTC (permalink / raw)
  To: u-boot

On Sat, Nov 3, 2018 at 10:45 PM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Fri, Oct 12, 2018 at 6:34 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> > On Fri, Oct 12, 2018 at 10:00 PM Stefan Roese <sr@denx.de> wrote:
>
> > diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
> > index 56e9813..2eb9172 100644
> > --- a/arch/x86/cpu/baytrail/cpu.c
> > +++ b/arch/x86/cpu/baytrail/cpu.c
> > @@ -203,4 +203,5 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
> >         .bind           = cpu_x86_bind,
> >         .probe          = cpu_x86_baytrail_probe,
> >         .ops            = &cpu_x86_baytrail_ops,
>
> > +       .flags          = DM_FLAG_PRE_RELOC,
>
> This has to be done for all x86 boards I suppose?
> Actually I don't see this in the v2018.11-rc3.

Adding this to arch/x86/cpu/cpu_x86.c does NOT fix the problem!

> >  }
> >
> > This patch needs to be applied on top of u-boot-x86/dm-fixes. Could
> > you please have a try?
> >
> > I was not aware Mario's changes broke the Baytrail boards too! I was
> > only testing on QEMU x86 before.
>
> Not only.
> Edison board is broken by this patch.
>
> This must be fixed before release, or better just to revert the patch ASAP.

Please, revert, if there is no quick cure.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-11-03 20:51         ` Andy Shevchenko
@ 2018-11-04 14:18           ` Bin Meng
  2018-11-04 14:30             ` Andy Shevchenko
  0 siblings, 1 reply; 43+ messages in thread
From: Bin Meng @ 2018-11-04 14:18 UTC (permalink / raw)
  To: u-boot

Hi Andy,

On Sun, Nov 4, 2018 at 4:51 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
>
> On Sat, Nov 3, 2018 at 10:45 PM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
> >
> > On Fri, Oct 12, 2018 at 6:34 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > On Fri, Oct 12, 2018 at 10:00 PM Stefan Roese <sr@denx.de> wrote:
> >
> > > diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
> > > index 56e9813..2eb9172 100644
> > > --- a/arch/x86/cpu/baytrail/cpu.c
> > > +++ b/arch/x86/cpu/baytrail/cpu.c
> > > @@ -203,4 +203,5 @@ U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
> > >         .bind           = cpu_x86_bind,
> > >         .probe          = cpu_x86_baytrail_probe,
> > >         .ops            = &cpu_x86_baytrail_ops,
> >
> > > +       .flags          = DM_FLAG_PRE_RELOC,
> >
> > This has to be done for all x86 boards I suppose?
> > Actually I don't see this in the v2018.11-rc3.
>
> Adding this to arch/x86/cpu/cpu_x86.c does NOT fix the problem!
>

This patch needs to be applied on top of u-boot-dm/master. I already
sent out email to Simon for PR for v2018.11.

> > >  }
> > >
> > > This patch needs to be applied on top of u-boot-x86/dm-fixes. Could
> > > you please have a try?
> > >
> > > I was not aware Mario's changes broke the Baytrail boards too! I was
> > > only testing on QEMU x86 before.
> >
> > Not only.
> > Edison board is broken by this patch.
> >
> > This must be fixed before release, or better just to revert the patch ASAP.
>
> Please, revert, if there is no quick cure.

Regards,
Bin

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active
  2018-11-04 14:18           ` Bin Meng
@ 2018-11-04 14:30             ` Andy Shevchenko
  0 siblings, 0 replies; 43+ messages in thread
From: Andy Shevchenko @ 2018-11-04 14:30 UTC (permalink / raw)
  To: u-boot

On Sun, Nov 4, 2018 at 4:18 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> On Sun, Nov 4, 2018 at 4:51 AM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
> > On Sat, Nov 3, 2018 at 10:45 PM Andy Shevchenko
> > <andy.shevchenko@gmail.com> wrote:
> > > On Fri, Oct 12, 2018 at 6:34 PM Bin Meng <bmeng.cn@gmail.com> wrote:

> > > > +       .flags          = DM_FLAG_PRE_RELOC,
> > >
> > > This has to be done for all x86 boards I suppose?
> > > Actually I don't see this in the v2018.11-rc3.
> >
> > Adding this to arch/x86/cpu/cpu_x86.c does NOT fix the problem!
> >
>
> This patch needs to be applied on top of u-boot-dm/master. I already
> sent out email to Simon for PR for v2018.11.

Ah, I missed that. OK, I will give a shot next week.
Thanks!

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2018-11-04 14:30 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-06  8:23 [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Mario Six
2018-08-06  8:23 ` [U-Boot] [PATCH v4 02/17] powerpc: Add read*_*/write*_* macros Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 03/17] sysreset: Add get_status method Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 04/17] test: Add tests for sysreset_get_status Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 05/17] board_f: Add reset status printing Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 06/17] mpc83xx: Add sysreset driver Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 07/17] clk: Add MPC83xx clock driver Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 08/17] timer: Sort Makefile entries Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 09/17] timer: Add MPC83xx timer driver Mario Six
2018-09-28 15:57   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 10/17] common: board_f: Sort includes Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 11/17] init: Fix documentation Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 12/17] board_f: Use static print_cpuinfo if CONFIG_CPU is active Mario Six
2018-09-19 15:29   ` Simon Glass
2018-09-21  6:56     ` Mario Six
2018-10-12 14:00   ` Stefan Roese
2018-10-12 15:34     ` Bin Meng
2018-10-13  7:59       ` Stefan Roese
2018-11-03 20:45       ` Andy Shevchenko
2018-11-03 20:51         ` Andy Shevchenko
2018-11-04 14:18           ` Bin Meng
2018-11-04 14:30             ` Andy Shevchenko
2018-08-06  8:23 ` [U-Boot] [PATCH v4 13/17] cpu: Fix cpu.h documentation Mario Six
2018-09-28 15:56   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 14/17] cpu: Add cpu_probe_all method Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 15/17] test: Add tests for CPU uclass Mario Six
2018-09-28 15:55   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 16/17] cpu: Add MPC83xx CPU driver Mario Six
2018-09-28 15:57   ` Simon Glass
2018-08-06  8:23 ` [U-Boot] [PATCH v4 17/17] misc: Add MPC83xx serdes driver Mario Six
2018-09-28 15:57   ` Simon Glass
2018-08-17 14:16 ` [U-Boot] [PATCH v4 01/17] ram: Add driver for MPC83xx Simon Glass
2018-09-28 15:55   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.