All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
@ 2018-04-27 12:52 Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Add a RAM driver for the MPC83xx architecture.

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

---

v1 -> v2:
No changes

---
 arch/powerpc/cpu/mpc83xx/spd_sdram.c       |   4 +
 drivers/ram/Kconfig                        |   8 +
 drivers/ram/Makefile                       |   1 +
 drivers/ram/mpc83xx_sdram.c                | 948 +++++++++++++++++++++++++++++
 include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
 include/mpc83xx.h                          |   6 +
 6 files changed, 1110 insertions(+)
 create mode 100644 drivers/ram/mpc83xx_sdram.c
 create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h

diff --git a/arch/powerpc/cpu/mpc83xx/spd_sdram.c b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
index 21ab0153fc..f1e2dbf7c4 100644
--- a/arch/powerpc/cpu/mpc83xx/spd_sdram.c
+++ b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
@@ -11,6 +11,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */

+#ifndef CONFIG_MPC83XX_SDRAM
+
 #include <common.h>
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -925,3 +927,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 496e2b793b..18532e71be 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -34,4 +34,12 @@ 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 is supported via device tree settings.
+
 source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 3820d03aa4..4ad3604d16 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 0000000000..1a73f7b3da
--- /dev/null
+++ b/drivers/ram/mpc83xx_sdram.c
@@ -0,0 +1,948 @@
+#define DEBUG
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <dt-bindings/memory/mpc83xx-sdram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CSCONFIG_ENABLE			0x80000000
+
+#define BANK_BITS_2		0x00000000
+#define BANK_BITS_3		0x00004000
+
+#define ROW_BITS_12		0x00000000
+#define ROW_BITS_13		0x00000100
+#define ROW_BITS_14		0x00000200
+
+#define COL_BITS_8		0x00000000
+#define COL_BITS_9		0x00000001
+#define COL_BITS_10		0x00000002
+#define COL_BITS_11		0x00000003
+
+#define TIMING_CFG3_EXT_REFREC_SHIFT	16
+
+#define TIMING_CFG0_RWT_SHIFT		30
+#define TIMING_CFG0_WRT_SHIFT		28
+#define TIMING_CFG0_RRT_SHIFT		26
+#define TIMING_CFG0_WWT_SHIFT		24
+#define TIMING_CFG0_ACT_PD_EXIT_SHIFT	20
+#define TIMING_CFG0_PRE_PD_EXIT_SHIFT	16
+#define TIMING_CFG0_ODT_PD_EXIT_SHIFT	8
+#define TIMING_CFG0_MRS_CYC_SHIFT	0
+
+#define TIMING_CFG1_PRETOACT_SHIFT	28
+#define TIMING_CFG1_ACTTOPRE_SHIFT	24
+#define TIMING_CFG1_ACTTORW_SHIFT	20
+#define TIMING_CFG1_CASLAT_SHIFT	16
+#define TIMING_CFG1_REFREC_SHIFT	12
+#define TIMING_CFG1_WRREC_SHIFT		8
+#define TIMING_CFG1_ACTTOACT_SHIFT	4
+#define TIMING_CFG1_WRTORD_SHIFT	0
+
+#define TIMING_CFG2_CPO_SHIFT		23
+#define TIMING_CFG2_WR_DATA_DELAY_SHIFT	10
+#define TIMING_CFG2_ADD_LAT_SHIFT	28
+#define TIMING_CFG2_WR_LAT_DELAY_SHIFT	19
+#define TIMING_CFG2_RD_TO_PRE_SHIFT	13
+#define TIMING_CFG2_CKE_PLS_SHIFT	6
+#define TIMING_CFG2_FOUR_ACT_SHIFT	0
+
+#define SDRAM_CFG_SREN_SHIFT		(31 - 1)
+#define SDRAM_CFG_ECC_EN_SHIFT		(31 - 2)
+#define SDRAM_CFG_RD_EN_SHIFT		(31 - 3)
+#define SDRAM_CFG_SDRAM_TYPE_SHIFT	(31 - 7)
+#define SDRAM_CFG_DYN_PWR_SHIFT		(31 - 10)
+#define SDRAM_CFG_DBW_SHIFT		(31 - 12)
+#define SDRAM_CFG_NCAP_SHIFT		(31 - 14)
+#define SDRAM_CFG_2T_EN_SHIFT		(31 - 16)
+#define SDRAM_CFG_BA_INTLV_CTL_SHIFT	(31 - 23)
+#define SDRAM_CFG_PCHB8_SHIFT		(31 - 27)
+#define SDRAM_CFG_HSE_SHIFT		(31 - 28)
+#define SDRAM_CFG_BI_SHIFT		(31 - 31)
+
+#define SDRAM_CFG2_FRC_SR_SHIFT	(31 - 0)
+#define SDRAM_CFG2_DLL_RST_DIS	(31 - 2)
+#define SDRAM_CFG2_DQS_CFG	(31 - 5)
+#define SDRAM_CFG2_ODT_CFG	(31 - 10)
+#define SDRAM_CFG2_NUM_PR	(31 - 19)
+
+#define SDRAM_MODE_ESD_SHIFT		16
+#define SDRAM_MODE_SD_SHIFT		0
+
+#define SDRAM_MODE2_ESD2_SHIFT		(31 - 15)
+#define SDRAM_MODE2_ESD3_SHIFT		(31 - 31)
+
+#define SDRAM_INTERVAL_REFINT_SHIFT	16
+#define SDRAM_INTERVAL_BSTOPRE_SHIFT	0
+
+#define 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("uclass_first_device_err failed: %d\n", ret);
+		return ret;
+	}
+
+	/* Set gd->ram_size? */
+
+	return 0;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+#ifndef CONFIG_VERY_BIG_RAM
+	return gd->ram_size;
+#else
+	/* limit stack to what we can reasonable map */
+	return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+		CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+#endif
+}
+
+struct mpc83xx_sdram_priv {
+	ulong total_size;
+};
+
+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("auto_precharge value invalid.\n");
+		return -EINVAL;
+	}
+
+	odt_rd_cfg = ofnode_read_u32_default(node, "odt_rd_cfg", 0);
+	switch (odt_rd_cfg) {
+#if defined(CONFIG_MPC830x) || defined(CONFIG_MPC831x) || \
+	defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+	case ODT_RD_NEVER:
+	case ODT_RD_ONLY_CURRENT:
+	case ODT_RD_ONLY_OTHER_CS:
+#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+	case ODT_RD_ONLY_OTHER_DIMM:
+#endif
+#endif
+	/* MPC832x only knows this value */
+	case ODT_RD_ALL:
+		break;
+	default:
+		debug("odt_rd_cfg value invalid.\n");
+		return -EINVAL;
+	}
+
+	odt_wr_cfg = ofnode_read_u32_default(node, "odt_wr_cfg", 0);
+	switch (odt_wr_cfg) {
+#if defined(CONFIG_MPC830x) || defined(CONFIG_MPC831x) || \
+	defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+	case ODT_WR_NEVER:
+	case ODT_WR_ONLY_CURRENT:
+	case ODT_WR_ONLY_OTHER_CS:
+#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+	case ODT_WR_ONLY_OTHER_DIMM:
+#endif
+#endif
+	/* MPC832x only knows this value */
+	case ODT_WR_ALL:
+		break;
+	default:
+		debug("odt_wr_cfg value invalid.\n");
+		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("bank_bits value invalid.\n");
+		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("row_bits value invalid.\n");
+		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("col_bits value invalid.\n");
+		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;
+}
+
+int mpc83xx_sdram_spd_init(ofnode node, u32 cs, u32 mapaddr, u32 size)
+{
+	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 res = 0;
+	ofnode subnode;
+	u32 dso, pz_override, nz_override, odt_term, ddr_type, mvref_sel, m_odr;
+	u32 ddrcdr;
+	u32 clock_adjust;
+	u32 ext_refresh_rec, ext_refresh_rec_mask;
+	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;
+	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;
+	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;
+	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;
+	u32 force_self_refresh, dll_reset, dqs_config, odt_config,
+	    posted_refreshes;
+	u32 sdram_cfg2;
+	u32 refresh_interval, precharge_interval, sdmode, esdmode, esdmode2,
+	    esdmode3;
+	u32 sdram_interval;
+	u32 sdram_mode;
+	u32 sdram_mode2;
+
+	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("driver_software_override value invalid.\n");
+		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("p_impedance_override value invalid.\n");
+		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("n_impedance_override value invalid.\n");
+		return -EINVAL;
+	}
+
+	odt_term = dev_read_u32_default(dev, "odt_termination_value", 0);
+	if (odt_term > 1) {
+		debug("odt_termination_value value invalid.\n");
+		return -EINVAL;
+	}
+
+	ddr_type = dev_read_u32_default(dev, "ddr_type", 0);
+	if (ddr_type > 1) {
+		debug("ddr_type value invalid.\n");
+		return -EINVAL;
+	}
+
+	mvref_sel = dev_read_u32_default(dev, "mvref_sel", 0);
+	if (mvref_sel > 1) {
+		debug("mvref_sel value invalid.\n");
+		return -EINVAL;
+	}
+
+	m_odr = dev_read_u32_default(dev, "m_odr", 0);
+	if (mvref_sel > 1) {
+		debug("m_odr value invalid.\n");
+		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("chip select value invalid.\n");
+			return -EINVAL;
+		}
+
+		/* TODO: Sanity check for size. */
+
+		if (ofnode_read_bool(subnode, "read-spd"))
+			res = mpc83xx_sdram_spd_init(subnode, cs, addr, size);
+		else
+			res = mpc83xx_sdram_static_init(subnode, cs, addr,
+							size);
+		if (res)
+			return res;
+	};
+
+	/* TODO: 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("clock_adjust value invalid.\n");
+		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("ext_refresh_rec value invalid.\n");
+		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("read_to_write value invalid.\n");
+		return -EINVAL;
+	}
+
+	write_to_read = dev_read_u32_default(dev, "write_to_read", 0);
+	if (write_to_read > 3) {
+		debug("write_to_read value invalid.\n");
+		return -EINVAL;
+	}
+
+	read_to_read = dev_read_u32_default(dev, "read_to_read", 0);
+	if (read_to_read > 3) {
+		debug("read_to_read value invalid.\n");
+		return -EINVAL;
+	}
+
+	write_to_write = dev_read_u32_default(dev, "write_to_write", 0);
+	if (write_to_write > 3) {
+		debug("write_to_write value invalid.\n");
+		return -EINVAL;
+	}
+
+	active_powerdown_exit =
+		dev_read_u32_default(dev, "active_powerdown_exit", 0);
+	if (active_powerdown_exit > 7) {
+		debug("active_powerdown_exit value invalid.\n");
+		return -EINVAL;
+	}
+
+	precharge_powerdown_exit =
+		dev_read_u32_default(dev, "precharge_powerdown_exit", 0);
+	if (precharge_powerdown_exit > 7) {
+		debug("precharge_powerdown_exit value invalid.\n");
+		return -EINVAL;
+	}
+
+	odt_powerdown_exit = dev_read_u32_default(dev, "odt_powerdown_exit", 0);
+	if (odt_powerdown_exit > 15) {
+		debug("odt_powerdown_exit value invalid.\n");
+		return -EINVAL;
+	}
+
+	mode_reg_set_cycle = dev_read_u32_default(dev, "mode_reg_set_cycle", 0);
+	if (mode_reg_set_cycle > 15) {
+		debug("mode_reg_set_cycle value invalid.\n");
+		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("precharge_to_activate value invalid.\n");
+		return -EINVAL;
+	}
+
+	activate_to_precharge =
+		dev_read_u32_default(dev, "activate_to_precharge", 0);
+	if (activate_to_precharge > 15 || activate_to_precharge == 0) {
+		debug("activate_to_precharge value invalid.\n");
+		return -EINVAL;
+	}
+
+	activate_to_readwrite =
+		dev_read_u32_default(dev, "activate_to_readwrite", 0);
+	if (activate_to_readwrite > 7 || activate_to_readwrite == 0) {
+		debug("activate_to_readwrite value invalid.\n");
+		return -EINVAL;
+	}
+
+	/* TODO: MPC8308 only supports caslat >= 3 clocks */
+	mcas_latency = dev_read_u32_default(dev, "mcas_latency", 0);
+	switch (mcas_latency) {
+	case CASLAT_20:
+	case CASLAT_25:
+	case CASLAT_30:
+	case CASLAT_35:
+	case CASLAT_40:
+	case CASLAT_45:
+	case CASLAT_50:
+		break;
+	default:
+		debug("ext_refresh_rec value invalid.\n");
+		return -EINVAL;
+	}
+
+	refresh_recovery = dev_read_u32_default(dev, "refresh_recovery", 0);
+	if (refresh_recovery > 23 || refresh_recovery < 8) {
+		debug("refresh_recovery value invalid.\n");
+		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("last_data_to_precharge value invalid.\n");
+		return -EINVAL;
+	}
+
+	activate_to_activate =
+		dev_read_u32_default(dev, "activate_to_activate", 0);
+	if (activate_to_activate > 7 || activate_to_activate == 0) {
+		debug("activate_to_activate value invalid.\n");
+		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("last_write_data_to_read value invalid.\n");
+		return -EINVAL;
+	}
+
+	timing_cfg_1 = precharge_to_activate << TIMING_CFG1_PRETOACT_SHIFT |
+		       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("additive_latency value invalid.\n");
+		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("mcas_to_preamble_override value invalid.\n");
+		return -EINVAL;
+	}
+
+	write_latency = dev_read_u32_default(dev, "write_latency", 0);
+	if (write_latency > 7 || write_latency == 0) {
+		debug("write_latency value invalid.\n");
+		return -EINVAL;
+	}
+
+	read_to_precharge = dev_read_u32_default(dev, "read_to_precharge", 0);
+	if (read_to_precharge > 4 || read_to_precharge == 0) {
+		debug("read_to_precharge value invalid.\n");
+		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("write_cmd_to_write_data value invalid.\n");
+		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("minimum_cke_pulse_width value invalid.\n");
+		return -EINVAL;
+	}
+
+	four_activates_window =
+		dev_read_u32_default(dev, "four_activates_window", 0);
+	if (four_activates_window > 20 || four_activates_window == 0) {
+		debug("four_activates_window value invalid.\n");
+		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("self_refresh value invalid.\n");
+		return -EINVAL;
+	}
+
+	ecc = dev_read_u32_default(dev, "ecc", 0);
+	switch (ecc) {
+	case ECC_DISABLE:
+	case ECC_ENABLE:
+		break;
+	default:
+		debug("ecc value invalid.\n");
+		return -EINVAL;
+	}
+
+	registered_dram = dev_read_u32_default(dev, "registered_dram", 0);
+	switch (registered_dram) {
+	case RD_DISABLE:
+	case RD_ENABLE:
+		break;
+	default:
+		debug("registered_dram value invalid.\n");
+		return -EINVAL;
+	}
+
+	sdram_type = dev_read_u32_default(dev, "sdram_type", 0);
+	switch (sdram_type) {
+	case TYPE_DDR1:
+	case TYPE_DDR2:
+		break;
+	default:
+		debug("sdram_type value invalid.\n");
+		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("dynamic_power_management value invalid.\n");
+		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("databus_width value invalid.\n");
+		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("nc_auto_precharge value invalid.\n");
+		return -EINVAL;
+	}
+
+	timing_2t = dev_read_u32_default(dev, "timing_2t", 0);
+	switch (timing_2t) {
+	case TIMING_1T:
+	case TIMING_2T:
+		break;
+	default:
+		debug("timing_2t value invalid.\n");
+		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("bank_interleaving_ctrl value invalid.\n");
+		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("precharge_bit_8 value invalid.\n");
+		return -EINVAL;
+	}
+
+	half_strength = dev_read_u32_default(dev, "half_strength", 0);
+	switch (half_strength) {
+	case STRENGTH_FULL:
+	case STRENGTH_HALF:
+		break;
+	default:
+		debug("half_strength value invalid.\n");
+		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("bypass_initialization value invalid.\n");
+		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("force_self_refresh value invalid.\n");
+		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("dll_reset value invalid.\n");
+		return -EINVAL;
+	}
+
+	dqs_config = dev_read_u32_default(dev, "dqs_config", 0);
+	switch (dqs_config) {
+	case DQS_TRUE:
+		break;
+	default:
+		debug("dqs_config value invalid.\n");
+		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("odt_config value invalid.\n");
+		return -EINVAL;
+	}
+
+	posted_refreshes = dev_read_u32_default(dev, "posted_refreshes", 0);
+	if (posted_refreshes > 8 || posted_refreshes == 0) {
+		debug("posted_refreshes value invalid.\n");
+		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("sdmode value invalid.\n");
+		return -EINVAL;
+	}
+
+	esdmode = dev_read_u32_default(dev, "esdmode", 0);
+	if (esdmode > 0xFFFF) {
+		debug("esdmode value invalid.\n");
+		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("esdmode2 value invalid.\n");
+		return -EINVAL;
+	}
+
+	esdmode3 = dev_read_u32_default(dev, "esdmode3", 0);
+	if (esdmode3 > 0xFFFF) {
+		debug("esdmode3 value invalid.\n");
+		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("refresh_interval value invalid.\n");
+		return -EINVAL;
+	}
+
+	precharge_interval = dev_read_u32_default(dev, "precharge_interval", 0);
+	if (precharge_interval > 0x3FFF) {
+		debug("precharge_interval value invalid.\n");
+		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)
+{
+	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 0000000000..0f970008b6
--- /dev/null
+++ b/include/dt-bindings/memory/mpc83xx-sdram.h
@@ -0,0 +1,143 @@
+#ifndef DT_BINDINGS_MPC83XX_SDRAM_H
+#define DT_BINDINGS_MPC83XX_SDRAM_H
+
+#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_ALL		0x00400000
+#define ODT_WR_NEVER		0x00000000
+#define ODT_WR_ONLY_CURRENT	0x00010000
+#define ODT_WR_ONLY_OTHER_CS	0x00020000
+#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 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_1		0x6 */
+#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 */
+
+#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 b5a0bbf847..26258126d6 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -1111,6 +1111,8 @@
 #define CSBNDS_EA			0x000000FF
 #define CSBNDS_EA_SHIFT			24

+#ifndef CONFIG_MPC83XX_SDRAM
+
 /*
  * CSn_CONFIG - Chip Select Configuration Register
  */
@@ -1408,6 +1410,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
  */
@@ -1511,6 +1515,7 @@
  */
 #define PMCCR1_POWER_OFF		0x00000020

+#ifndef CONFIG_RAM
 /*
  * DDRCDR - DDR Control Driver Register
  */
@@ -1532,6 +1537,7 @@
 #define DDRCDR_DDR_CFG		0x00040000
 #define DDRCDR_M_ODR		0x00000002
 #define DDRCDR_Q_DRN		0x00000001
+#endif /* !CONFIG_RAM */

 /*
  * PCIE Bridge Register
--
2.16.1

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

* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03 19:01   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 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).

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

---

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 0747c52b60..771a325b46 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -25,6 +25,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 393c7be3d8..9e326fefeb 100644
--- a/include/sysreset.h
+++ b/include/sysreset.h
@@ -29,6 +29,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
  *
--
2.16.1

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

* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03 19:01   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 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.

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

---

v1 -> v2:
New in v2

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

diff --git a/common/board_f.c b/common/board_f.c
index ae8bdb7c5c..2df30cd250 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -25,6 +25,7 @@
 #include <relocate.h>
 #include <spi.h>
 #include <status_led.h>
+#include <sysreset.h>
 #include <timer.h>
 #include <trace.h>
 #include <video.h>
@@ -141,6 +142,21 @@ static int display_text_info(void)
 	return 0;
 }

+#ifdef CONFIG_SYSRESET
+static int print_resetinfo(void)
+{
+	struct udevice *dev;
+	char status[256];
+
+	uclass_first_device_err(UCLASS_SYSRESET, &dev);
+
+	if (!sysreset_get_status(dev, status, sizeof(status)))
+		printf("%s", status);
+
+	return 0;
+}
+#endif
+
 static int announce_dram_init(void)
 {
 	puts("DRAM:  ");
@@ -789,6 +805,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.16.1

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

* [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03 19:01   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Add a sysreset driver for the MPC83xx platform.

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

---

v1 -> v2:
New in v2

---
 arch/powerpc/cpu/mpc83xx/cpu.c      |   3 +-
 drivers/sysreset/Kconfig            |   5 ++
 drivers/sysreset/Makefile           |   9 +-
 drivers/sysreset/sysreset_mpc83xx.c | 160 ++++++++++++++++++++++++++++++++++++
 4 files changed, 172 insertions(+), 5 deletions(-)
 create mode 100644 drivers/sysreset/sysreset_mpc83xx.c

diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index 3bdebd845c..9a5c1b7d55 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -116,6 +116,7 @@ int checkcpu(void)
 	return 0;
 }

+#ifndef CONFIG_SYSRESET
 int
 do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
@@ -170,7 +171,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 a6d48e8a66..fd89e5f474 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -37,4 +37,9 @@ config SYSRESET_WATCHDOG
 	help
 	  Reboot support for generic watchdog 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 000c288eeb..faeb4b679f 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -5,11 +5,12 @@
 #

 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_MCP83XX) += sysreset_mpc83xx.o
 obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
 obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
 obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.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 0000000000..110192065e
--- /dev/null
+++ b/drivers/sysreset/sysreset_mpc83xx.c
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sysreset.h>
+
+static void __do_reset(void)
+{
+	ulong msr;
+
+	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, 0x52535445);
+	sync();
+	isync();
+
+	/* confirm Reset Control Reg is enabled */
+
+	while (!(in_be32(&immap->reset.rcer) & RCER_CRE))
+		;
+
+	udelay(200);
+
+	/* perform reset, only one bit */
+	out_be32(&immap->reset.rcr, RCR_SWHR);
+}
+
+int mpc83xx_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+	switch (type) {
+	case SYSRESET_WARM:
+	case SYSRESET_COLD:
+		__do_reset();
+		break;
+	default:
+		return -EPROTONOSUPPORT;
+	}
+
+	return -EINPROGRESS;
+}
+
+#if defined(CONFIG_DISPLAY_AER_FULL)
+static int print_83xx_arb_event(int force)
+{
+	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;
+
+	if (!force && !gd->arch.arbiter_event_address)
+		return 0;
+
+	puts("Arbiter Event Status:\n");
+	printf("       Event Address: 0x%08lX\n",
+	       gd->arch.arbiter_event_address);
+	printf("       Event Type:    0x%1x  = %s\n", etype, event[etype]);
+	printf("       Master ID:     0x%02x = %s\n", mstr_id, master[mstr_id]);
+	printf("       Transfer Size: 0x%1x  = %d bytes\n", (tbst << 3) | tsize,
+	       tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize);
+	printf("       Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]);
+
+	return gd->arch.arbiter_event_address;
+}
+
+#elif defined(CONFIG_DISPLAY_AER_BRIEF)
+
+static int print_83xx_arb_event(int force, char *buf, int size)
+{
+	int res;
+
+	if (!force && !gd->arch.arbiter_event_address)
+		return 0;
+
+	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;
+}
+#endif /* CONFIG_DISPLAY_AER_xxxx */
+
+int mpc83xx_sysreset_get_status(struct udevice *dev, char *buf, int size)
+{
+	int res;
+	static const struct {
+		ulong mask;
+		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"}
+	};
+	static int n = ARRAY_SIZE(bits);
+	ulong rsr = gd->arch.reset_status;
+	int i;
+	char *sep;
+
+	res = snprintf(buf, size, "Reset Status:");
+	if (!res)
+		return -EIO;
+
+	buf += res;
+	size -= res;
+
+	sep = " ";
+	for (i = 0; i < n; i++)
+		if (rsr & bits[i].mask) {
+			res = snprintf(buf, size, "%s%s%s", sep, bits[i].desc, (i == n - 1) ? "\n" : "");
+			buf += res;
+			size -= res;
+			sep = ", ";
+		}
+
+/* TODO(mario.six@gdsys.cc): Move this into a dedicated arbiter driver */
+#if defined(CONFIG_DISPLAY_AER_FULL) || defined(CONFIG_DISPLAY_AER_BRIEF)
+	res = print_83xx_arb_event(rsr & RSR_BMRS, buf, size);
+	buf += res;
+	size -= res;
+#endif
+	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,
+};
--
2.16.1

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

* [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
                   ` (2 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Add a clock driver for the MPC83xx architecture.

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

---

v1 -> v2:
* Added binding of sysreset driver

---
 arch/powerpc/cpu/mpc83xx/speed.c      |   4 +
 arch/powerpc/include/asm/config.h     |   2 +-
 drivers/clk/Kconfig                   |   6 +
 drivers/clk/Makefile                  |   1 +
 drivers/clk/mpc83xx_clk.c             | 430 ++++++++++++++++++++++++++++++++++
 drivers/clk/mpc83xx_clk.h             | 115 +++++++++
 include/dt-bindings/clk/mpc83xx-clk.h |  27 +++
 7 files changed, 584 insertions(+), 1 deletion(-)
 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/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c
index 5498c19e25..c9bdec0bc0 100644
--- a/arch/powerpc/cpu/mpc83xx/speed.c
+++ b/arch/powerpc/cpu/mpc83xx/speed.c
@@ -7,6 +7,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */

+#ifndef CONFIG_CLK_MPC83XX
+
 #include <common.h>
 #include <mpc83xx.h>
 #include <command.h>
@@ -591,3 +593,5 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
 	"print clock configuration",
 	"    clocks"
 );
+
+#endif
diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h
index 39eeb39901..d9dfb670af 100644
--- a/arch/powerpc/include/asm/config.h
+++ b/arch/powerpc/include/asm/config.h
@@ -79,7 +79,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/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c382e8865f..787c061e44 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -89,4 +89,10 @@ source "drivers/clk/exynos/Kconfig"
 source "drivers/clk/at91/Kconfig"
 source "drivers/clk/renesas/Kconfig"

+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 e05c607223..67da125669 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -15,6 +15,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_RENESAS) += renesas/
 obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
 obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o
diff --git a/drivers/clk/mpc83xx_clk.c b/drivers/clk/mpc83xx_clk.c
new file mode 100644
index 0000000000..96f762bfe1
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.c
@@ -0,0 +1,430 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clk/mpc83xx-clk.h>
+
+#include "mpc83xx_clk.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 *speed;
+
+struct mpc83xx_clk_priv {
+	u32 *speed;
+};
+
+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 {
+	u8 low;
+	u8 high;
+	int type;
+};
+
+const struct clk_mode modes[] = {
+
+	[MPC83XX_CLK_CORE] = {0, 0, TYPE_SPECIAL},
+	[MPC83XX_CLK_CSB] = {0, 0, TYPE_SPECIAL},
+	[MPC83XX_CLK_QE] = {0, 0, TYPE_SPECIAL},
+	[MPC83XX_CLK_BRG] = {0, 0, TYPE_SPECIAL},
+	[MPC83XX_CLK_MEM] = {1, 1, TYPE_SPMR_DIRECT_MULTIPLY },
+	[MPC83XX_CLK_LBIU] = {0, 0, TYPE_SPMR_DIRECT_MULTIPLY },
+	[MPC83XX_CLK_LCLK] = {0, 0, TYPE_SPECIAL},
+	[MPC83XX_CLK_MEM_SEC] = {0, 0, TYPE_SPMR_DIRECT_MULTIPLY }, /* The same as LBIU */
+#ifndef CONFIG_MPC8313
+	[MPC83XX_CLK_TSEC1] = {0, 1, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_TSEC2] = {2, 3, TYPE_SCCR_STANDARD },
+#else
+	[MPC83XX_CLK_TSEC1] = {0, 1, TYPE_SCCR_STANDARD }, /* FIXME: This has separate enable/disable bit! */
+	[MPC83XX_CLK_TSEC2] = {0, 1, TYPE_SCCR_STANDARD }, /* FIXME: This has separate enable/disable bit! */
+#endif
+	[MPC83XX_CLK_SDHC] = {4, 5, TYPE_SCCR_STANDARD },
+#ifdef CONFIG_MPC834x
+	[MPC83XX_CLK_ENC] = {6, 7, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_I2C1] = {2, 3, TYPE_SCCR_STANDARD }, /* I2C and TSEC2 are the same register */
+#else
+	[MPC83XX_CLK_ENC] = {6, 7, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_I2C1] = {6, 7, TYPE_SCCR_STANDARD }, /* I2C and ENC are the same register */
+#endif
+	[MPC83XX_CLK_I2C2] = {0, 0, TYPE_SPECIAL },
+	[MPC83XX_CLK_PCIEXP1] = {10, 11, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_PCIEXP2] = {12, 13, TYPE_SCCR_STANDARD },
+#if defined(CONFIG_MPC8313) || defined(CONFIG_MPC834x)
+	[MPC83XX_CLK_USBDR] = {10, 11, TYPE_SCCR_STANDARD },
+#else
+	[MPC83XX_CLK_USBDR] = {8, 9, TYPE_SCCR_STANDARD },
+#endif
+	[MPC83XX_CLK_USBMPH] = {8, 9, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_PCI] = {15, 15, TYPE_SCCR_ONOFF },
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC8309)
+	[MPC83XX_CLK_DMAC] = {26, 27, TYPE_SCCR_STANDARD },
+#endif
+#if 0
+/* FIXME: All SATA controllers must have the same clock ratio */
+#ifdef CONFIG_MPC83XX_SATA_SUPPORT
+#ifdef CONFIG_MPC8379
+	[MPC83XX_CLK_SATA] = {24, 25, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_SATA] = {26, 27, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_SATA] = {28, 29, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_SATA] = {30, 31, TYPE_SCCR_STANDARD },
+#else
+	[MPC83XX_CLK_SATA] = {18, 19, TYPE_SCCR_STANDARD },
+	[MPC83XX_CLK_SATA] = {20, 21, TYPE_SCCR_STANDARD },
+#endif
+#endif
+#endif
+	[MPC83XX_CLK_TDM] = {26, 27, TYPE_SCCR_STANDARD },
+};
+
+int get_clocks(void)
+{
+	return 0;
+}
+
+inline bool is_clk_valid(int id)
+{
+	switch (id) {
+	case MPC83XX_CLK_MEM:
+#if defined(CONFIG_MPC8360)
+	case MPC83XX_CLK_MEM_SEC:
+#endif
+#ifndef CONFIG_MPC830x
+	case MPC83XX_CLK_ENC:
+#endif
+	case MPC83XX_CLK_I2C1:
+#ifdef CONFIG_MPC8315
+	case MPC83XX_CLK_TDM:
+#endif
+#ifdef CONFIG_MPC83XX_SDHC_SUPPORT
+	case MPC83XX_CLK_SDHC:
+#endif
+#ifdef CONFIG_MPC83XX_TSEC1_SUPPORT
+	case MPC83XX_CLK_TSEC1:
+#endif
+#ifdef CONFIG_MPC83XX_TSEC2_SUPPORT
+	case MPC83XX_CLK_TSEC2:
+#endif
+#if !defined(CONFIG_MPC8360)
+	case MPC83XX_CLK_USBDR:
+#endif
+#ifdef CONFIG_MPC834x
+	case MPC83XX_CLK_USBMPH:
+#endif
+#ifdef CONFIG_MPC83XX_PCIE1_SUPPORT
+	case MPC83XX_CLK_PCIEXP1:
+#endif
+#ifdef CONFIG_MPC83XX_PCIE2_SUPPORT
+	case MPC83XX_CLK_PCIEXP2:
+#endif
+#ifdef CONFIG_MPC83XX_SATA_SUPPORT
+	case MPC83XX_CLK_SATA:
+#endif
+#ifdef CONFIG_MPC830x
+	case MPC83XX_CLK_DMAC:
+#endif
+#ifdef CONFIG_MPC83XX_PCI_SUPPORT
+	case MPC83XX_CLK_PCI:
+#endif
+	case MPC83XX_CLK_CSB:
+#ifdef CONFIG_MPC83XX_SECOND_I2C_SUPPORT
+	case MPC83XX_CLK_I2C2:
+#endif
+#if defined(CONFIG_MPC83XX_QUICC_ENGINE) && !defined(CONFIG_MPC8309)
+	case MPC83XX_CLK_QE:
+	case MPC83XX_CLK_BRG:
+#endif
+	case MPC83XX_CLK_LCLK:
+	case MPC83XX_CLK_LBIU:
+	case MPC83XX_CLK_CORE:
+		return true;
+	}
+
+	return false;
+}
+
+static int mpc83xx_clk_request(struct clk *clock)
+{
+	/* Reject requests of clocks that are not available */
+	if (is_clk_valid(clock->id))
+		return 0;
+	else
+		return -ENODEV;
+}
+
+static inline void init_clks(u32 *speed)
+{
+	int i;
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	u32 csb_clk = get_csb_clk(im);
+
+	for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
+		struct clk_mode mode = modes[i];
+		ulong mask;
+
+		if (mode.type == TYPE_INVALID)
+			continue;
+
+		if (mode.type == TYPE_SCCR_STANDARD) {
+			mask = GENMASK(31 - mode.low, 31 - mode.high);
+
+			switch (sccr_field(im, mask, 31 - mode.high)) {
+			case 0:
+				speed[i] = 0;
+				break;
+			case 1:
+				speed[i] = csb_clk;
+				break;
+			case 2:
+				speed[i] = csb_clk / 2;
+				break;
+			case 3:
+				speed[i] = csb_clk / 3;
+				break;
+			default:
+				speed[i] = 0;
+			}
+
+			continue;
+		}
+
+		if (mode.type == TYPE_SPMR_DIRECT_MULTIPLY) {
+			mask = GENMASK(31 - mode.low, 31 - mode.high);
+
+			speed[i] = csb_clk * (1 + sccr_field(im, mask, 31 - mode.high));
+			continue;
+		}
+
+		if (i == MPC83XX_CLK_CSB || i == MPC83XX_CLK_I2C2) {
+			speed[i] = csb_clk; /* i2c-2 clk is equal to csb clk */
+			continue;
+		}
+
+		if (i == MPC83XX_CLK_QE || i == MPC83XX_CLK_BRG) {
+			u32 pci_sync_in = get_pci_sync_in(im);
+			u32 qepmf = spmr_field(im, SPMR_CEPMF, SPMR_CEPMF_SHIFT);
+			u32 qepdf = spmr_field(im, SPMR_CEPDF, SPMR_CEPDF_SHIFT);
+			u32 qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
+
+			if (i == MPC83XX_CLK_QE)
+				speed[i] = qe_clk;
+			else
+				speed[i] = qe_clk / 2;
+
+			continue;
+		}
+
+		if (i == MPC83XX_CLK_LCLK || i == MPC83XX_CLK_LBIU) {
+			u32 lbiu_clk = csb_clk *
+				(1 + spmr_field(im, SPMR_LBIUCM, SPMR_LBIUCM_SHIFT));
+			u32 clkdiv = lcrr_field(im, LCRR_CLKDIV, LCRR_CLKDIV_SHIFT);
+
+			if (i == MPC83XX_CLK_LBIU)
+				speed[i] = lbiu_clk;
+
+			switch (clkdiv) {
+			case 2:
+			case 4:
+			case 8:
+				speed[i] = lbiu_clk / clkdiv;
+				break;
+			default:
+				/* unknown lcrr */
+				speed[i] = 0;
+			}
+
+			continue;
+		}
+
+		if (i == MPC83XX_CLK_CORE) {
+			u8 corepll = spmr_field(im, SPMR_COREPLL, SPMR_COREPLL_SHIFT);
+			u32 corecnf_tab_index = ((corepll & 0x1F) << 2) |
+						((corepll & 0x60) >> 5);
+
+			if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
+				/* corecnf_tab_index is too high, possibly wrong value */
+				speed[i] = 0;
+			}
+
+			switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
+			case _byp:
+			case _x1:
+			case _1x:
+				speed[i] = csb_clk;
+				break;
+			case _1_5x:
+				speed[i] = (3 * csb_clk) / 2;
+				break;
+			case _2x:
+				speed[i] = 2 * csb_clk;
+				break;
+			case _2_5x:
+				speed[i] = (5 * csb_clk) / 2;
+				break;
+			case _3x:
+				speed[i] = 3 * csb_clk;
+				break;
+			default:
+				/* unknown core to csb ratio */
+				speed[i] = 0;
+			}
+
+			continue;
+		}
+	}
+}
+
+static ulong mpc83xx_clk_get_rate(struct clk *clk)
+{
+	struct mpc83xx_clk_priv *priv = dev_get_priv(clk->dev);
+
+	return priv->speed[clk->id];
+}
+
+int get_serial_clock(void)
+{
+	return 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,mpc83xx-clk", },
+	{ /* sentinel */ }
+};
+
+static int mpc83xx_clk_probe(struct udevice *dev)
+{
+	struct mpc83xx_clk_priv *priv = dev_get_priv(dev);
+
+	speed = malloc((MPC83XX_CLK_COUNT + 1) * sizeof(u32));
+	priv->speed = speed;
+	init_clks(priv->speed);
+
+	gd->arch.csb_clk = speed[MPC83XX_CLK_CSB];
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
+	defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x)
+	gd->arch.tsec1_clk = speed[MPC83XX_CLK_TSEC1];
+	gd->arch.tsec2_clk = speed[MPC83XX_CLK_TSEC2];
+	gd->arch.usbdr_clk = speed[MPC83XX_CLK_USBDR];
+#elif defined(CONFIG_MPC8309)
+	gd->arch.usbdr_clk = speed[MPC83XX_CLK_USBDR];
+#endif
+#if defined(CONFIG_MPC834x)
+	gd->arch.usbmph_clk = speed[MPC83XX_CLK_USBMPH];
+#endif
+#if defined(CONFIG_MPC8315)
+	gd->arch.tdm_clk = speed[MPC83XX_CLK_TDM];
+#endif
+#if defined(CONFIG_FSL_ESDHC)
+	gd->arch.sdhc_clk = speed[MPC83XX_CLK_SDHC];
+#endif
+	gd->arch.core_clk = speed[MPC83XX_CLK_CORE];
+	gd->arch.i2c1_clk = speed[MPC83XX_CLK_I2C1];
+#if !defined(CONFIG_MPC832x)
+	gd->arch.i2c2_clk = speed[MPC83XX_CLK_I2C2];
+#endif
+#if !defined(CONFIG_MPC8309)
+	gd->arch.enc_clk = speed[MPC83XX_CLK_ENC];
+#endif
+	gd->arch.lbiu_clk = speed[MPC83XX_CLK_LBIU];
+	gd->arch.lclk_clk = speed[MPC83XX_CLK_LCLK];
+	gd->mem_clk = speed[MPC83XX_CLK_MEM];
+#if defined(CONFIG_MPC8360)
+	gd->arch.mem_sec_clk = speed[MPC83XX_CLK_MEM_SEC];
+#endif
+#if defined(CONFIG_QE)
+	gd->arch.qe_clk = speed[MPC83XX_CLK_QE];
+	gd->arch.brg_clk = speed[MPC83XX_CLK_BRG];
+#endif
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
+	defined(CONFIG_MPC837x)
+	gd->arch.pciexp1_clk = speed[MPC83XX_CLK_PCIEXP1];
+	gd->arch.pciexp2_clk = speed[MPC83XX_CLK_PCIEXP2];
+#endif
+#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315)
+	gd->arch.sata_clk = speed[MPC83XX_CLK_SATA];
+#endif
+	gd->pci_clk = speed[MPC83XX_CLK_PCI];
+	gd->cpu_clk = speed[MPC83XX_CLK_CORE];
+	gd->bus_clk = speed[MPC83XX_CLK_CSB];
+
+	return 0;
+}
+
+static int mpc83xx_clk_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+
+	ret = device_bind_driver(dev, "mpc83xx_sysreset", "sysreset",
+				 &sys_child);
+	if (ret)
+		debug("Warning: No sysreset driver: ret=%d\n", 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];
+
+	for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
+		if (!is_clk_valid(i))
+			continue;
+
+		printf("%s = %s MHz\n", names[i], strmhz(buf, 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 0000000000..75db2f3699
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.h
@@ -0,0 +1,115 @@
+enum {
+	_unk,
+	_off,
+	_byp,
+	_x8,
+	_x4,
+	_x2,
+	_x1,
+	_1x,
+	_1_5x,
+	_2x,
+	_2_5x,
+	_3x
+};
+
+struct corecnf {
+	int core_csb_ratio;
+	int vco_divider;
+};
+
+static struct corecnf corecnf_tab[] = {
+	{_byp, _byp},		/* 0x00 */
+	{_byp, _byp},		/* 0x01 */
+	{_byp, _byp},		/* 0x02 */
+	{_byp, _byp},		/* 0x03 */
+	{_byp, _byp},		/* 0x04 */
+	{_byp, _byp},		/* 0x05 */
+	{_byp, _byp},		/* 0x06 */
+	{_byp, _byp},		/* 0x07 */
+	{_1x, _x2},		/* 0x08 */
+	{_1x, _x4},		/* 0x09 */
+	{_1x, _x8},		/* 0x0A */
+	{_1x, _x8},		/* 0x0B */
+	{_1_5x, _x2},		/* 0x0C */
+	{_1_5x, _x4},		/* 0x0D */
+	{_1_5x, _x8},		/* 0x0E */
+	{_1_5x, _x8},		/* 0x0F */
+	{_2x, _x2},		/* 0x10 */
+	{_2x, _x4},		/* 0x11 */
+	{_2x, _x8},		/* 0x12 */
+	{_2x, _x8},		/* 0x13 */
+	{_2_5x, _x2},		/* 0x14 */
+	{_2_5x, _x4},		/* 0x15 */
+	{_2_5x, _x8},		/* 0x16 */
+	{_2_5x, _x8},		/* 0x17 */
+	{_3x, _x2},		/* 0x18 */
+	{_3x, _x4},		/* 0x19 */
+	{_3x, _x8},		/* 0x1A */
+	{_3x, _x8},		/* 0x1B */
+};
+
+enum reg_type {
+	REG_SCCR,
+	REG_SPMR,
+};
+
+enum mode_type {
+	TYPE_INVALID = 0,
+	TYPE_SCCR_STANDARD,
+	TYPE_SCCR_ONOFF,
+	TYPE_SPMR_DIRECT_MULTIPLY,
+	TYPE_SPECIAL,
+};
+
+static inline u32 get_spmr(immap_t *im)
+{
+	u32 res = in_be32(&im->clk.spmr);
+
+	return res;
+}
+
+static inline u32 get_sccr(immap_t *im)
+{
+	u32 res = in_be32(&im->clk.sccr);
+
+	return res;
+}
+
+static inline u32 get_lcrr(immap_t *im)
+{
+	u32 res = in_be32(&im->im_lbc.lcrr);
+
+	return res;
+}
+
+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);
+}
+
+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;
+}
+
+static inline uint spmr_field(immap_t *im, u32 mask, uint shift)
+{
+	return (get_spmr(im) & mask) >> shift;
+}
+
+static inline uint sccr_field(immap_t *im, u32 mask, uint shift)
+{
+	return (get_sccr(im) & mask) >> shift;
+}
+
+static inline uint lcrr_field(immap_t *im, u32 mask, uint shift)
+{
+	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 0000000000..3e5b2858c0
--- /dev/null
+++ b/include/dt-bindings/clk/mpc83xx-clk.h
@@ -0,0 +1,27 @@
+#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.16.1

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

* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
                   ` (3 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-04-30 23:13   ` Simon Glass
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
  2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
  6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Add a timer driver for the MPC83xx architecture.

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

---

v1 -> v2:
* Removed now-superfluous comments
* Removed usage of uclass_{first,next}_device_compat
* Switched to usage of new board uclass (instead of devinfo)

---
 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  | 160 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 178 insertions(+), 3 deletions(-)
 create mode 100644 drivers/timer/mpc83xx_timer.c

diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index 9a5c1b7d55..376483eda7 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -176,12 +176,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 9a3043abf8..537693e3bc 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -19,13 +19,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 e8784aa16e..56a697d28c 100644
--- a/arch/powerpc/lib/interrupts.c
+++ b/arch/powerpc/lib/interrupts.c
@@ -15,6 +15,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")));

@@ -45,7 +46,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)
 {
@@ -61,6 +62,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 */
@@ -103,3 +105,4 @@ ulong get_timer (ulong base)
 {
 	return (timestamp - base);
 }
+#endif /* !CONFIG_MPC83XX_TIMER */
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896726..1b78ce784a 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -126,4 +126,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 a6e7832154..d35d235195 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -17,3 +17,4 @@ 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_STM32_TIMER)	+= stm32_timer.o
+obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
new file mode 100644
index 0000000000..c3dd306c5b
--- /dev/null
+++ b/drivers/timer/mpc83xx_timer.c
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <timer.h>
+#include <watchdog.h>
+#include <board.h>
+
+struct mpc83xx_timer_priv {
+};
+
+static uint decrementer_count; /* count value for 1e6/HZ microseconds */
+
+static inline unsigned long get_dec(void)
+{
+	unsigned long val;
+
+	asm volatile ("mfdec %0":"=r" (val):);
+
+	return val;
+}
+
+static inline void set_dec(unsigned long val)
+{
+	if (val)
+		asm volatile ("mtdec %0"::"r" (val));
+}
+
+/* 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 clk clock;
+
+	if (get_board(&board))
+		return -ENOENT;
+
+	uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
+	clk_get_by_index(csb, 0, &clock);
+
+	decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
+
+	/* Enable e300 time base */
+
+	setbits_be32(&immr->sysconf.spcr, 0x00400000);
+
+	set_dec(decrementer_count);
+
+	set_msr(get_msr() | MSR_EE);
+
+	return 0;
+}
+
+static volatile ulong timestamp = 0;
+
+void timer_interrupt(struct pt_regs *regs)
+{
+	/* Restore Decrementer Count */
+	set_dec(decrementer_count);
+
+	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(timestamp);
+#endif /* CONFIG_LED_STATUS */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+	board_show_activity(timestamp);
+#endif /* CONFIG_SHOW_ACTIVITY */
+}
+
+ulong get_timer(ulong base)
+{
+	return (timestamp - base);
+}
+
+static inline u32 mftbu(void)
+{
+	u32 rval;
+
+	asm volatile("mftbu %0" : "=r" (rval));
+	return rval;
+}
+
+static inline u32 mftb(void)
+{
+	u32 rval;
+
+	asm volatile("mftb %0" : "=r" (rval));
+	return rval;
+}
+
+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;
+
+	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;
+
+	interrupt_init();
+
+	clk_get_by_index(dev, 0, &clock);
+
+	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,
+};
--
2.16.1

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

* [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
                   ` (4 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
  2018-05-03 19:01   ` Simon Glass
  2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
  6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
  To: u-boot

Includes should be sorted.

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

---

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 2df30cd250..ff7a52705e 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -12,8 +12,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.16.1

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

* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
@ 2018-04-30 23:13   ` Simon Glass
  2018-05-04  6:19     ` Mario Six
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-04-30 23:13 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a timer driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> * Removed now-superfluous comments
> * Removed usage of uclass_{first,next}_device_compat
> * Switched to usage of new board uclass (instead of devinfo)
>
> ---
>  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  | 160 +++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 178 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/timer/mpc83xx_timer.c

Reviewed-by: Simon Glass <sjg@chromium.org>

Please see below.

>
> diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
> index 9a5c1b7d55..376483eda7 100644
> --- a/arch/powerpc/cpu/mpc83xx/cpu.c
> +++ b/arch/powerpc/cpu/mpc83xx/cpu.c
> @@ -176,12 +176,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 9a3043abf8..537693e3bc 100644
> --- a/arch/powerpc/lib/Makefile
> +++ b/arch/powerpc/lib/Makefile
> @@ -19,13 +19,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 e8784aa16e..56a697d28c 100644
> --- a/arch/powerpc/lib/interrupts.c
> +++ b/arch/powerpc/lib/interrupts.c
> @@ -15,6 +15,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")));
>
> @@ -45,7 +46,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)
>  {
> @@ -61,6 +62,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 */
> @@ -103,3 +105,4 @@ ulong get_timer (ulong base)
>  {
>         return (timestamp - base);
>  }
> +#endif /* !CONFIG_MPC83XX_TIMER */
> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> index 2c96896726..1b78ce784a 100644
> --- a/drivers/timer/Kconfig
> +++ b/drivers/timer/Kconfig
> @@ -126,4 +126,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 a6e7832154..d35d235195 100644
> --- a/drivers/timer/Makefile
> +++ b/drivers/timer/Makefile
> @@ -17,3 +17,4 @@ 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_STM32_TIMER)      += stm32_timer.o
> +obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
> diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
> new file mode 100644
> index 0000000000..c3dd306c5b
> --- /dev/null
> +++ b/drivers/timer/mpc83xx_timer.c
> @@ -0,0 +1,160 @@
> +/*
> + * (C) Copyright 2018
> + * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <clk.h>
> +#include <timer.h>
> +#include <watchdog.h>
> +#include <board.h>
> +
> +struct mpc83xx_timer_priv {
> +};
> +
> +static uint decrementer_count; /* count value for 1e6/HZ microseconds */

Have a static var in BSS means it cannot be used before relocation, or
in SPL, right?

> +
> +static inline unsigned long get_dec(void)
> +{
> +       unsigned long val;
> +
> +       asm volatile ("mfdec %0":"=r" (val):);
> +
> +       return val;
> +}
> +
> +static inline void set_dec(unsigned long val)
> +{
> +       if (val)
> +               asm volatile ("mtdec %0"::"r" (val));
> +}
> +
> +/* 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 clk clock;
> +
> +       if (get_board(&board))

debug() ?

> +               return -ENOENT;
> +
> +       uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
> +       clk_get_by_index(csb, 0, &clock);

error checking

> +
> +       decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
> +
> +       /* Enable e300 time base */
> +

Drop blank line

> +       setbits_be32(&immr->sysconf.spcr, 0x00400000);
> +
> +       set_dec(decrementer_count);
> +
> +       set_msr(get_msr() | MSR_EE);
> +
> +       return 0;
> +}
> +
> +static volatile ulong timestamp = 0;
> +
> +void timer_interrupt(struct pt_regs *regs)
> +{
> +       /* Restore Decrementer Count */
> +       set_dec(decrementer_count);
> +
> +       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(timestamp);
> +#endif /* CONFIG_LED_STATUS */
> +
> +#ifdef CONFIG_SHOW_ACTIVITY
> +       board_show_activity(timestamp);
> +#endif /* CONFIG_SHOW_ACTIVITY */
> +}
> +
> +ulong get_timer(ulong base)
> +{
> +       return (timestamp - base);
> +}
> +
> +static inline u32 mftbu(void)
> +{
> +       u32 rval;
> +
> +       asm volatile("mftbu %0" : "=r" (rval));
> +       return rval;
> +}
> +
> +static inline u32 mftb(void)
> +{
> +       u32 rval;
> +
> +       asm volatile("mftb %0" : "=r" (rval));
> +       return rval;
> +}
> +
> +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;
> +
> +       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;
> +
> +       interrupt_init();
> +
> +       clk_get_by_index(dev, 0, &clock);
> +
> +       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,
> +};
> --
> 2.16.1
>

Regards,
Simon

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

* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
  2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
                   ` (5 preceding siblings ...)
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
@ 2018-05-03 19:01 ` Simon Glass
  2018-05-04  8:04   ` Mario Six
  6 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a RAM driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> No changes
>
> ---
>  arch/powerpc/cpu/mpc83xx/spd_sdram.c       |   4 +
>  drivers/ram/Kconfig                        |   8 +
>  drivers/ram/Makefile                       |   1 +
>  drivers/ram/mpc83xx_sdram.c                | 948 +++++++++++++++++++++++++++++
>  include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
>  include/mpc83xx.h                          |   6 +
>  6 files changed, 1110 insertions(+)
>  create mode 100644 drivers/ram/mpc83xx_sdram.c
>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>

Reviewed-by: Simon Glass <sjg@chromium.org>

Question below

[..]

> new file mode 100644
> index 0000000000..1a73f7b3da
> --- /dev/null
> +++ b/drivers/ram/mpc83xx_sdram.c
> @@ -0,0 +1,948 @@
> +#define DEBUG
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <asm/io.h>
> +#include <dt-bindings/memory/mpc83xx-sdram.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define CSCONFIG_ENABLE                        0x80000000
> +
> +#define BANK_BITS_2            0x00000000
> +#define BANK_BITS_3            0x00004000
> +
> +#define ROW_BITS_12            0x00000000
> +#define ROW_BITS_13            0x00000100
> +#define ROW_BITS_14            0x00000200
> +
> +#define COL_BITS_8             0x00000000
> +#define COL_BITS_9             0x00000001
> +#define COL_BITS_10            0x00000002
> +#define COL_BITS_11            0x00000003
> +
> +#define TIMING_CFG3_EXT_REFREC_SHIFT   16
> +
> +#define TIMING_CFG0_RWT_SHIFT          30
> +#define TIMING_CFG0_WRT_SHIFT          28
> +#define TIMING_CFG0_RRT_SHIFT          26
> +#define TIMING_CFG0_WWT_SHIFT          24
> +#define TIMING_CFG0_ACT_PD_EXIT_SHIFT  20
> +#define TIMING_CFG0_PRE_PD_EXIT_SHIFT  16
> +#define TIMING_CFG0_ODT_PD_EXIT_SHIFT  8
> +#define TIMING_CFG0_MRS_CYC_SHIFT      0
> +
> +#define TIMING_CFG1_PRETOACT_SHIFT     28
> +#define TIMING_CFG1_ACTTOPRE_SHIFT     24
> +#define TIMING_CFG1_ACTTORW_SHIFT      20
> +#define TIMING_CFG1_CASLAT_SHIFT       16
> +#define TIMING_CFG1_REFREC_SHIFT       12
> +#define TIMING_CFG1_WRREC_SHIFT                8
> +#define TIMING_CFG1_ACTTOACT_SHIFT     4
> +#define TIMING_CFG1_WRTORD_SHIFT       0
> +
> +#define TIMING_CFG2_CPO_SHIFT          23
> +#define TIMING_CFG2_WR_DATA_DELAY_SHIFT        10
> +#define TIMING_CFG2_ADD_LAT_SHIFT      28
> +#define TIMING_CFG2_WR_LAT_DELAY_SHIFT 19
> +#define TIMING_CFG2_RD_TO_PRE_SHIFT    13
> +#define TIMING_CFG2_CKE_PLS_SHIFT      6
> +#define TIMING_CFG2_FOUR_ACT_SHIFT     0
> +
> +#define SDRAM_CFG_SREN_SHIFT           (31 - 1)
> +#define SDRAM_CFG_ECC_EN_SHIFT         (31 - 2)
> +#define SDRAM_CFG_RD_EN_SHIFT          (31 - 3)
> +#define SDRAM_CFG_SDRAM_TYPE_SHIFT     (31 - 7)
> +#define SDRAM_CFG_DYN_PWR_SHIFT                (31 - 10)
> +#define SDRAM_CFG_DBW_SHIFT            (31 - 12)
> +#define SDRAM_CFG_NCAP_SHIFT           (31 - 14)
> +#define SDRAM_CFG_2T_EN_SHIFT          (31 - 16)
> +#define SDRAM_CFG_BA_INTLV_CTL_SHIFT   (31 - 23)
> +#define SDRAM_CFG_PCHB8_SHIFT          (31 - 27)
> +#define SDRAM_CFG_HSE_SHIFT            (31 - 28)
> +#define SDRAM_CFG_BI_SHIFT             (31 - 31)
> +
> +#define SDRAM_CFG2_FRC_SR_SHIFT        (31 - 0)
> +#define SDRAM_CFG2_DLL_RST_DIS (31 - 2)
> +#define SDRAM_CFG2_DQS_CFG     (31 - 5)
> +#define SDRAM_CFG2_ODT_CFG     (31 - 10)
> +#define SDRAM_CFG2_NUM_PR      (31 - 19)
> +
> +#define SDRAM_MODE_ESD_SHIFT           16
> +#define SDRAM_MODE_SD_SHIFT            0
> +
> +#define SDRAM_MODE2_ESD2_SHIFT         (31 - 15)
> +#define SDRAM_MODE2_ESD3_SHIFT         (31 - 31)
> +
> +#define SDRAM_INTERVAL_REFINT_SHIFT    16
> +#define SDRAM_INTERVAL_BSTOPRE_SHIFT   0
> +
> +#define 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("uclass_first_device_err failed: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* Set gd->ram_size? */
> +
> +       return 0;
> +}
> +
> +phys_size_t get_effective_memsize(void)
> +{
> +#ifndef CONFIG_VERY_BIG_RAM

Can this (and the #ifdefs below in this file) be converted to

if (IS_ENABLED(CONFIG_...))

instead, to increase build coverage?

Regards,
Simon

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

* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
@ 2018-05-03 19:01   ` Simon Glass
  2018-05-04  8:06     ` Mario Six
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
  To: u-boot

On 27 April 2018 at 06:52, 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).
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
>  include/sysreset.h                 | 17 +++++++++++++++++
>  2 files changed, 27 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

Can you add a test for sandbox?

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

* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
@ 2018-05-03 19:01   ` Simon Glass
  2018-05-04  8:10     ` Mario Six
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 27 April 2018 at 06:52, 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.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  common/board_f.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

nit below

>
> diff --git a/common/board_f.c b/common/board_f.c
> index ae8bdb7c5c..2df30cd250 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -25,6 +25,7 @@
>  #include <relocate.h>
>  #include <spi.h>
>  #include <status_led.h>
> +#include <sysreset.h>
>  #include <timer.h>
>  #include <trace.h>
>  #include <video.h>
> @@ -141,6 +142,21 @@ static int display_text_info(void)
>         return 0;
>  }
>
> +#ifdef CONFIG_SYSRESET
> +static int print_resetinfo(void)
> +{
> +       struct udevice *dev;
> +       char status[256];
> +
> +       uclass_first_device_err(UCLASS_SYSRESET, &dev);

Should check the result and only call the function below if it is 0.

> +
> +       if (!sysreset_get_status(dev, status, sizeof(status)))
> +               printf("%s", status);
> +
> +       return 0;
> +}
> +#endif
> +

Regards,
Simon

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

* [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
@ 2018-05-03 19:01   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
  To: u-boot

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a sysreset driver for the MPC83xx platform.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  arch/powerpc/cpu/mpc83xx/cpu.c      |   3 +-
>  drivers/sysreset/Kconfig            |   5 ++
>  drivers/sysreset/Makefile           |   9 +-
>  drivers/sysreset/sysreset_mpc83xx.c | 160 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 172 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/sysreset/sysreset_mpc83xx.c

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes
  2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
@ 2018-05-03 19:01   ` Simon Glass
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
  To: u-boot

On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Includes should be sorted.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
>  common/board_f.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
  2018-04-30 23:13   ` Simon Glass
@ 2018-05-04  6:19     ` Mario Six
  0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04  6:19 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, May 1, 2018 at 1:13 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a timer driver for the MPC83xx architecture.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> * Removed now-superfluous comments
>> * Removed usage of uclass_{first,next}_device_compat
>> * Switched to usage of new board uclass (instead of devinfo)
>>
>> ---
>>  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  | 160 +++++++++++++++++++++++++++++++++++++++++
>>  6 files changed, 178 insertions(+), 3 deletions(-)
>>  create mode 100644 drivers/timer/mpc83xx_timer.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please see below.
>
>>
>> diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
>> index 9a5c1b7d55..376483eda7 100644
>> --- a/arch/powerpc/cpu/mpc83xx/cpu.c
>> +++ b/arch/powerpc/cpu/mpc83xx/cpu.c
>> @@ -176,12 +176,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 9a3043abf8..537693e3bc 100644
>> --- a/arch/powerpc/lib/Makefile
>> +++ b/arch/powerpc/lib/Makefile
>> @@ -19,13 +19,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 e8784aa16e..56a697d28c 100644
>> --- a/arch/powerpc/lib/interrupts.c
>> +++ b/arch/powerpc/lib/interrupts.c
>> @@ -15,6 +15,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")));
>>
>> @@ -45,7 +46,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)
>>  {
>> @@ -61,6 +62,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 */
>> @@ -103,3 +105,4 @@ ulong get_timer (ulong base)
>>  {
>>         return (timestamp - base);
>>  }
>> +#endif /* !CONFIG_MPC83XX_TIMER */
>> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
>> index 2c96896726..1b78ce784a 100644
>> --- a/drivers/timer/Kconfig
>> +++ b/drivers/timer/Kconfig
>> @@ -126,4 +126,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 a6e7832154..d35d235195 100644
>> --- a/drivers/timer/Makefile
>> +++ b/drivers/timer/Makefile
>> @@ -17,3 +17,4 @@ 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_STM32_TIMER)      += stm32_timer.o
>> +obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
>> diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
>> new file mode 100644
>> index 0000000000..c3dd306c5b
>> --- /dev/null
>> +++ b/drivers/timer/mpc83xx_timer.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * (C) Copyright 2018
>> + * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <clk.h>
>> +#include <timer.h>
>> +#include <watchdog.h>
>> +#include <board.h>
>> +
>> +struct mpc83xx_timer_priv {
>> +};
>> +
>> +static uint decrementer_count; /* count value for 1e6/HZ microseconds */
>
> Have a static var in BSS means it cannot be used before relocation, or
> in SPL, right?
>

True; same with the timestamp variable a bit below. I copied that part verbatim
from arch/powerpc/lib/interrupts.c, so that's a general problem with the
powerpc arch. I see that x86 keeps, e.g. the clock rate in the global data. I
think this might be a way around this (two ulongs will hopefully still fit in
the GD).

>> +
>> +static inline unsigned long get_dec(void)
>> +{
>> +       unsigned long val;
>> +
>> +       asm volatile ("mfdec %0":"=r" (val):);
>> +
>> +       return val;
>> +}
>> +
>> +static inline void set_dec(unsigned long val)
>> +{
>> +       if (val)
>> +               asm volatile ("mtdec %0"::"r" (val));
>> +}
>> +
>> +/* 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 clk clock;
>> +
>> +       if (get_board(&board))
>
> debug() ?
>

Indeed; will be fixed in v3.

>> +               return -ENOENT;
>> +
>> +       uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
>> +       clk_get_by_index(csb, 0, &clock);
>
> error checking
>

Will be fixed in v3.

>> +
>> +       decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
>> +
>> +       /* Enable e300 time base */
>> +
>
> Drop blank line
>

Will be fixed in v3.

>> +       setbits_be32(&immr->sysconf.spcr, 0x00400000);
>> +
>> +       set_dec(decrementer_count);
>> +
>> +       set_msr(get_msr() | MSR_EE);
>> +
>> +       return 0;
>> +}
>> +
>> +static volatile ulong timestamp = 0;
>> +
>> +void timer_interrupt(struct pt_regs *regs)
>> +{
>> +       /* Restore Decrementer Count */
>> +       set_dec(decrementer_count);
>> +
>> +       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(timestamp);
>> +#endif /* CONFIG_LED_STATUS */
>> +
>> +#ifdef CONFIG_SHOW_ACTIVITY
>> +       board_show_activity(timestamp);
>> +#endif /* CONFIG_SHOW_ACTIVITY */
>> +}
>> +
>> +ulong get_timer(ulong base)
>> +{
>> +       return (timestamp - base);
>> +}
>> +
>> +static inline u32 mftbu(void)
>> +{
>> +       u32 rval;
>> +
>> +       asm volatile("mftbu %0" : "=r" (rval));
>> +       return rval;
>> +}
>> +
>> +static inline u32 mftb(void)
>> +{
>> +       u32 rval;
>> +
>> +       asm volatile("mftb %0" : "=r" (rval));
>> +       return rval;
>> +}
>> +
>> +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;
>> +
>> +       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;
>> +
>> +       interrupt_init();
>> +
>> +       clk_get_by_index(dev, 0, &clock);
>> +
>> +       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,
>> +};
>> --
>> 2.16.1
>>
>
> Regards,
> Simon

Best regards,
Mario

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

* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
  2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
@ 2018-05-04  8:04   ` Mario Six
  2018-05-04 21:37     ` Simon Glass
  0 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-05-04  8:04 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a RAM driver for the MPC83xx architecture.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> No changes
>>
>> ---
>>  arch/powerpc/cpu/mpc83xx/spd_sdram.c       |   4 +
>>  drivers/ram/Kconfig                        |   8 +
>>  drivers/ram/Makefile                       |   1 +
>>  drivers/ram/mpc83xx_sdram.c                | 948 +++++++++++++++++++++++++++++
>>  include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
>>  include/mpc83xx.h                          |   6 +
>>  6 files changed, 1110 insertions(+)
>>  create mode 100644 drivers/ram/mpc83xx_sdram.c
>>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>>
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Question below
>
> [..]
>
>> new file mode 100644
>> index 0000000000..1a73f7b3da
>> --- /dev/null
>> +++ b/drivers/ram/mpc83xx_sdram.c
>> @@ -0,0 +1,948 @@
>> +#define DEBUG
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <ram.h>
>> +#include <asm/io.h>
>> +#include <dt-bindings/memory/mpc83xx-sdram.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define CSCONFIG_ENABLE                        0x80000000
>> +
>> +#define BANK_BITS_2            0x00000000
>> +#define BANK_BITS_3            0x00004000
>> +
>> +#define ROW_BITS_12            0x00000000
>> +#define ROW_BITS_13            0x00000100
>> +#define ROW_BITS_14            0x00000200
>> +
>> +#define COL_BITS_8             0x00000000
>> +#define COL_BITS_9             0x00000001
>> +#define COL_BITS_10            0x00000002
>> +#define COL_BITS_11            0x00000003
>> +
>> +#define TIMING_CFG3_EXT_REFREC_SHIFT   16
>> +
>> +#define TIMING_CFG0_RWT_SHIFT          30
>> +#define TIMING_CFG0_WRT_SHIFT          28
>> +#define TIMING_CFG0_RRT_SHIFT          26
>> +#define TIMING_CFG0_WWT_SHIFT          24
>> +#define TIMING_CFG0_ACT_PD_EXIT_SHIFT  20
>> +#define TIMING_CFG0_PRE_PD_EXIT_SHIFT  16
>> +#define TIMING_CFG0_ODT_PD_EXIT_SHIFT  8
>> +#define TIMING_CFG0_MRS_CYC_SHIFT      0
>> +
>> +#define TIMING_CFG1_PRETOACT_SHIFT     28
>> +#define TIMING_CFG1_ACTTOPRE_SHIFT     24
>> +#define TIMING_CFG1_ACTTORW_SHIFT      20
>> +#define TIMING_CFG1_CASLAT_SHIFT       16
>> +#define TIMING_CFG1_REFREC_SHIFT       12
>> +#define TIMING_CFG1_WRREC_SHIFT                8
>> +#define TIMING_CFG1_ACTTOACT_SHIFT     4
>> +#define TIMING_CFG1_WRTORD_SHIFT       0
>> +
>> +#define TIMING_CFG2_CPO_SHIFT          23
>> +#define TIMING_CFG2_WR_DATA_DELAY_SHIFT        10
>> +#define TIMING_CFG2_ADD_LAT_SHIFT      28
>> +#define TIMING_CFG2_WR_LAT_DELAY_SHIFT 19
>> +#define TIMING_CFG2_RD_TO_PRE_SHIFT    13
>> +#define TIMING_CFG2_CKE_PLS_SHIFT      6
>> +#define TIMING_CFG2_FOUR_ACT_SHIFT     0
>> +
>> +#define SDRAM_CFG_SREN_SHIFT           (31 - 1)
>> +#define SDRAM_CFG_ECC_EN_SHIFT         (31 - 2)
>> +#define SDRAM_CFG_RD_EN_SHIFT          (31 - 3)
>> +#define SDRAM_CFG_SDRAM_TYPE_SHIFT     (31 - 7)
>> +#define SDRAM_CFG_DYN_PWR_SHIFT                (31 - 10)
>> +#define SDRAM_CFG_DBW_SHIFT            (31 - 12)
>> +#define SDRAM_CFG_NCAP_SHIFT           (31 - 14)
>> +#define SDRAM_CFG_2T_EN_SHIFT          (31 - 16)
>> +#define SDRAM_CFG_BA_INTLV_CTL_SHIFT   (31 - 23)
>> +#define SDRAM_CFG_PCHB8_SHIFT          (31 - 27)
>> +#define SDRAM_CFG_HSE_SHIFT            (31 - 28)
>> +#define SDRAM_CFG_BI_SHIFT             (31 - 31)
>> +
>> +#define SDRAM_CFG2_FRC_SR_SHIFT        (31 - 0)
>> +#define SDRAM_CFG2_DLL_RST_DIS (31 - 2)
>> +#define SDRAM_CFG2_DQS_CFG     (31 - 5)
>> +#define SDRAM_CFG2_ODT_CFG     (31 - 10)
>> +#define SDRAM_CFG2_NUM_PR      (31 - 19)
>> +
>> +#define SDRAM_MODE_ESD_SHIFT           16
>> +#define SDRAM_MODE_SD_SHIFT            0
>> +
>> +#define SDRAM_MODE2_ESD2_SHIFT         (31 - 15)
>> +#define SDRAM_MODE2_ESD3_SHIFT         (31 - 31)
>> +
>> +#define SDRAM_INTERVAL_REFINT_SHIFT    16
>> +#define SDRAM_INTERVAL_BSTOPRE_SHIFT   0
>> +
>> +#define 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("uclass_first_device_err failed: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /* Set gd->ram_size? */
>> +
>> +       return 0;
>> +}
>> +
>> +phys_size_t get_effective_memsize(void)
>> +{
>> +#ifndef CONFIG_VERY_BIG_RAM
>
> Can this (and the #ifdefs below in this file) be converted to
>
> if (IS_ENABLED(CONFIG_...))
>
> instead, to increase build coverage?
>

Yes, no problem, will convert for v3.

By the way, is this a practice that's generally encouraged, or is it just
useful in special cases such as this one?

> Regards,
> Simon

Best regards,
Mario

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

* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
  2018-05-03 19:01   ` Simon Glass
@ 2018-05-04  8:06     ` Mario Six
  0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04  8:06 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> On 27 April 2018 at 06:52, 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).
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>>  drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
>>  include/sysreset.h                 | 17 +++++++++++++++++
>>  2 files changed, 27 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Can you add a test for sandbox?

OK, will add a test in v3.

Best regards,
Mario

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

* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
  2018-05-03 19:01   ` Simon Glass
@ 2018-05-04  8:10     ` Mario Six
  0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04  8:10 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, 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.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>>  common/board_f.c | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> nit below
>
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index ae8bdb7c5c..2df30cd250 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -25,6 +25,7 @@
>>  #include <relocate.h>
>>  #include <spi.h>
>>  #include <status_led.h>
>> +#include <sysreset.h>
>>  #include <timer.h>
>>  #include <trace.h>
>>  #include <video.h>
>> @@ -141,6 +142,21 @@ static int display_text_info(void)
>>         return 0;
>>  }
>>
>> +#ifdef CONFIG_SYSRESET
>> +static int print_resetinfo(void)
>> +{
>> +       struct udevice *dev;
>> +       char status[256];
>> +
>> +       uclass_first_device_err(UCLASS_SYSRESET, &dev);
>
> Should check the result and only call the function below if it is 0.
>

Yes, I found that one myself when I tried to run the sandbox tests again.

Will be fixed in v3.

>> +
>> +       if (!sysreset_get_status(dev, status, sizeof(status)))
>> +               printf("%s", status);
>> +
>> +       return 0;
>> +}
>> +#endif
>> +
>
> Regards,
> Simon

Best regards,
Mario

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

* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
  2018-05-04  8:04   ` Mario Six
@ 2018-05-04 21:37     ` Simon Glass
  2018-05-04 21:57       ` Tom Rini
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-04 21:37 UTC (permalink / raw)
  To: u-boot

+Tom for question below

Hi Mario,

On 4 May 2018 at 02:04, Mario Six <mario.six@gdsys.cc> wrote:
> Hi Simon,
>
> On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Mario,
>>
>> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>>> Add a RAM driver for the MPC83xx architecture.
>>>
>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>
>>> ---
>>>
>>> v1 -> v2:
>>> No changes
>>>
>>> ---
>>>  arch/powerpc/cpu/mpc83xx/spd_sdram.c       |   4 +
>>>  drivers/ram/Kconfig                        |   8 +
>>>  drivers/ram/Makefile                       |   1 +
>>>  drivers/ram/mpc83xx_sdram.c                | 948
+++++++++++++++++++++++++++++
>>>  include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
>>>  include/mpc83xx.h                          |   6 +
>>>  6 files changed, 1110 insertions(+)
>>>  create mode 100644 drivers/ram/mpc83xx_sdram.c
>>>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>>>
>>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>
>> Question below
>>
[..]

>>> +
>>> +phys_size_t get_effective_memsize(void)
>>> +{
>>> +#ifndef CONFIG_VERY_BIG_RAM
>>
>> Can this (and the #ifdefs below in this file) be converted to
>>
>> if (IS_ENABLED(CONFIG_...))
>>
>> instead, to increase build coverage?
>>
>
> Yes, no problem, will convert for v3.
>
> By the way, is this a practice that's generally encouraged, or is it just
> useful in special cases such as this one?

I think it is better in most cases as I don't really like #ifdefs in the
code when they are easy to remove:
- visually confusing particularly where there is more than one term in the
#if
- creates multiple builds of the code, reducing build coverage for sandbox
- can sometimes be replaced with empty static inline functions, or even
build up logic (e.g. of_live_active() and its callers)

Tom, do you have any thoughts on this one?

Regards,
Simon

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

* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
  2018-05-04 21:37     ` Simon Glass
@ 2018-05-04 21:57       ` Tom Rini
  0 siblings, 0 replies; 19+ messages in thread
From: Tom Rini @ 2018-05-04 21:57 UTC (permalink / raw)
  To: u-boot

On Fri, May 04, 2018 at 09:37:54PM +0000, Simon Glass wrote:
> +Tom for question below
> 
> Hi Mario,
> 
> On 4 May 2018 at 02:04, Mario Six <mario.six@gdsys.cc> wrote:
> > Hi Simon,
> >
> > On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> >> Hi Mario,
> >>
> >> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> >>> Add a RAM driver for the MPC83xx architecture.
> >>>
> >>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> >>>
> >>> ---
> >>>
> >>> v1 -> v2:
> >>> No changes
> >>>
> >>> ---
> >>>  arch/powerpc/cpu/mpc83xx/spd_sdram.c       |   4 +
> >>>  drivers/ram/Kconfig                        |   8 +
> >>>  drivers/ram/Makefile                       |   1 +
> >>>  drivers/ram/mpc83xx_sdram.c                | 948
> +++++++++++++++++++++++++++++
> >>>  include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
> >>>  include/mpc83xx.h                          |   6 +
> >>>  6 files changed, 1110 insertions(+)
> >>>  create mode 100644 drivers/ram/mpc83xx_sdram.c
> >>>  create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
> >>>
> >>
> >> Reviewed-by: Simon Glass <sjg@chromium.org>
> >>
> >> Question below
> >>
> [..]
> 
> >>> +
> >>> +phys_size_t get_effective_memsize(void)
> >>> +{
> >>> +#ifndef CONFIG_VERY_BIG_RAM
> >>
> >> Can this (and the #ifdefs below in this file) be converted to
> >>
> >> if (IS_ENABLED(CONFIG_...))
> >>
> >> instead, to increase build coverage?
> >>
> >
> > Yes, no problem, will convert for v3.
> >
> > By the way, is this a practice that's generally encouraged, or is it just
> > useful in special cases such as this one?
> 
> I think it is better in most cases as I don't really like #ifdefs in the
> code when they are easy to remove:
> - visually confusing particularly where there is more than one term in the
> #if
> - creates multiple builds of the code, reducing build coverage for sandbox
> - can sometimes be replaced with empty static inline functions, or even
> build up logic (e.g. of_live_active() and its callers)
> 
> Tom, do you have any thoughts on this one?

Can this even be built for sandbox?  If yes, we should do what we can to
increase build coverage (and coverity coverage).  Otherwise I don't
think that if (CONFIG_IS_ENABLED(FOO)) is always better.  If we're
talking about:
#ifdef FOO
    if (bar) {
        ...
    }
#endif

Then yes, testing for CONFIG_IS_ENABLED(FOO) && bar is great.  Or:
#ifdef FOO
    ... a few lines ...
#endif

It's also good.  But if we're talking about a lot of lines, I think the
added indent doesn't help and can start making it a bit harder with
additional wrap.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180504/245d0ac3/attachment.sig>

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

end of thread, other threads:[~2018-05-04 21:57 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
2018-05-03 19:01   ` Simon Glass
2018-05-04  8:06     ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
2018-05-03 19:01   ` Simon Glass
2018-05-04  8:10     ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
2018-05-03 19:01   ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
2018-04-30 23:13   ` Simon Glass
2018-05-04  6:19     ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
2018-05-03 19:01   ` Simon Glass
2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
2018-05-04  8:04   ` Mario Six
2018-05-04 21:37     ` Simon Glass
2018-05-04 21:57       ` Tom Rini

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.