Skip to contentSkip to conversation

rockchip: Add support for cros_ec keyboard

PATCH New Simon Glass 2 participants 101 messages Jan 22, 2016

Subsystems (12)
lore
Share & tools
lore
#0 lore raw

v9 cover rockchip: Add support for cros_ec keyboard

This series provides a number of new features and improvements leading to enabling the keyboard (via Chrome OS EC) on jerry. This is conneected via SPI and uses its own message protocol.

Features and fixes are needed in the rockchip code to make this work include:
- RK808 PMIC and regulator driver
- Fixes and improvements to the i2c and SPI drivers
- A full implementation of the GPIO driver
- Additional clock support
- Additional pinctrl support

The series moves a few rockchip boards to use the full pinctrl driver. I'm not sure this is a great idea, as it slows down start-up noticeably. It is currently needed for the display series (to come), but I intend to change that.

Changes in v9:
- Rebase to upstream/master

Changes in v2:
- Update call to clk_get_by_index()
- Update call to clk_get_by_index()
- Update call to clk_get_by_index()
- Add an assert for clk_devp

Simon Glass (49):
dm: core: Don't set pinctrl for pinctrl devices
dm: pinctrl: Add a function to parse PIN_CONFIG flags
dm: pmic: Add 'reg status' to show all regulators
dts: Bring in pinctrl device tree binding
power: Add base support for the RK808 PMIC
power: Add support for RK808 regulators
dm: Add a power sequencing uclass
rockchip: Avoid using MMC code when not booting from MMC
rockchip: Convert the PMU IOMUX registers into an array
rockchip: mmc: Use a pwrseq device if available
rockchip: Correct the defconfig order
rockchip: Use pwrseq for MMC start-up on jerry
rockchip: jerry: Disable pmic-int-1 setup to avoid a hang
rockchip: Use a separate clock ID for clocks
rockchip: clock: Rename the general clock variable to gclk_rate
rockchip: clk: Add a function to get a peripheral clock rate
rockchip: clock: Add a function to find a clock by ID
rockchip: i2c: Update the driver to use the new clock ID
rockchip: spi: Update the driver to use the new clock ID
rockchip: spi: Avoid setting the pinctrl twice
rockchip: mmc: Update the driver to use the new clock ID
rockchip: pinctrl: Add a full pinctrl driver
rockchip: Move firefly and jerry to use the full pinctrl
rockchip: jerry: Enable the RK808 PMIC and regulator
rockchip: Disable simple-bus in SPL for firefly-rk3288, jerry
rockchip: jerry: Drop unused options
gpio: Allow 's' as an abbreviation for 'status'
cros_ec: Disable the Chrome OS EC in SPL
dm: i2c: Allow muxes to be enabled for SPL separately
spi: Correct device tree usage in spi_flash_decode_fdt()
dm: power: Allow regulators to be omitted from SPL
dm: pinctrl: Add a way for a GPIO driver to obtain a pin function
dm: core: Export uclass_find_device_by_of_offset()
dm: power: Tidy up debugging output and return values
dm: power: Allow regulators to not implement all operations
dm: clk: Add a simple version of clk_get_by_index()
rockchip: sdram: Use the rk_clr/setreg() interface
rockchip: reset: Use the rk_clr/setreg() interface
rockchip: spi: Remember the last speed to avoid re-setting it
rockchip: spi: Correct the bus init code
rockchip: clk: Make rkclk_get_clk() SoC-specific
rockchip: pinctrl: Reduce the size for SPL
rockchip: pinctrl: Implement the get_gpio_mux() method
rockchip: gpio: Read the GPIO value correctly
rockchip: gpio: Implement the get_function() method
rockchip: spi: Implement the delays
rockchip: spi: Correct chip-enable code
rockchip: spi: Remove the explicit pinctrl setting
rockchip: jerry: Enable the Chrome OS EC

 arch/arm/dts/rk3288-veyron-chromebook.dtsi         |   4 +
 arch/arm/dts/rk3288-veyron.dtsi                    |  20 +-
 arch/arm/include/asm/arch-rockchip/clock.h         |  12 +
 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h    |  12 +-
 arch/arm/mach-rockchip/Makefile                    |   1 -
 arch/arm/mach-rockchip/common.c                    |  28 --
 arch/arm/mach-rockchip/rk3288-board-spl.c          |   2 +
 arch/arm/mach-rockchip/rk3288/reset_rk3288.c       |   4 +-
 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c       |   7 +-
 common/cmd_gpio.c                                  |   2 +-
 common/cmd_regulator.c                             |  66 ++++-
 configs/chromebook_jerry_defconfig                 |  25 +-
 configs/firefly-rk3288_defconfig                   |   7 +-
 .../pinctrl/pinctrl-bindings.txt                   | 236 ++++++++++++++++
 drivers/clk/clk-uclass.c                           |  18 +-
 drivers/clk/clk_rk3036.c                           |  33 ++-
 drivers/clk/clk_rk3288.c                           | 157 ++++++++---
 drivers/core/device.c                              |   6 +-
 drivers/core/uclass.c                              |   4 +-
 drivers/gpio/rk_gpio.c                             |  42 ++-
 drivers/i2c/Makefile                               |   4 +-
 drivers/i2c/muxes/Kconfig                          |   9 +
 drivers/i2c/muxes/Makefile                         |   2 +-
 drivers/i2c/rk_i2c.c                               |  38 +--
 drivers/misc/Kconfig                               |  18 ++
 drivers/misc/Makefile                              |   3 +
 drivers/misc/pwrseq-uclass.c                       |  24 ++
 drivers/mmc/rockchip_dw_mmc.c                      |  60 +++-
 drivers/mtd/spi/spi_flash.c                        |   9 +-
 drivers/pinctrl/pinctrl-uclass.c                   |  22 ++
 drivers/pinctrl/rockchip/pinctrl_rk3288.c          | 290 +++++++++++++++++++-
 drivers/power/pmic/Kconfig                         |  30 ++
 drivers/power/pmic/Makefile                        |   1 +
 drivers/power/pmic/pmic-uclass.c                   |  13 +-
 drivers/power/pmic/rk808.c                         | 102 +++++++
 drivers/power/regulator/Kconfig                    |  18 ++
 drivers/power/regulator/Makefile                   |   5 +-
 drivers/power/regulator/regulator-uclass.c         |   4 +-
 drivers/power/regulator/rk808.c                    | 301 +++++++++++++++++++++
 drivers/spi/rk_spi.c                               |  84 +++---
 include/configs/chromebook_jerry.h                 |   9 +
 include/configs/firefly-rk3288.h                   |   2 +
 include/configs/rk3288_common.h                    |   8 +
 include/dm/pinctrl.h                               |  45 +++
 include/dm/uclass-id.h                             |   1 +
 include/dm/uclass-internal.h                       |  16 ++
 include/power/rk808_pmic.h                         |  77 ++++++
 include/pwrseq.h                                   |  18 ++
 48 files changed, 1691 insertions(+), 208 deletions(-)
 delete mode 100644 arch/arm/mach-rockchip/common.c
 create mode 100644 doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt
 create mode 100644 drivers/misc/pwrseq-uclass.c
 create mode 100644 drivers/power/pmic/rk808.c
 create mode 100644 drivers/power/regulator/rk808.c
 create mode 100644 include/power/rk808_pmic.h
 create mode 100644 include/pwrseq.h
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#1 lore raw

PATCH v9 1/49 dm: core: Don't set pinctrl for pinctrl devices

There is sort-of race condition when a pinctrl device is probed. The pinctrl function is called which may end up using the same device as is being probed. This results in operations being used before the device is actually probed.

For now, disallow pinctrl operations on pinctrl devices while probing. An alternative solution would be to move the operation to later in the device_probe() function (for pinctrl devices only) but this needs more thought.

---

Changes in v9: None
Changes in v2: None

 drivers/core/device.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/core/device.c +4 -2
index 1e5584a..f5def35 100644
@@ -299,9 +299,11 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
 
 	/*
 	 * Process pinctrl for everything except the root device, and
-	 * continue regardless of the result of pinctrl.
+	 * continue regardless of the result of pinctrl. Don't process pinctrl
+	 * settings for pinctrl devices since the device may not yet be
+	 * probed.
 	 */
-	if (dev->parent)
+	if (dev->parent && device_get_uclass_id(dev) != UCLASS_PINCTRL)
 		pinctrl_select_state(dev, "default");
 
 	ret = uclass_pre_probe_device(dev);
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#2 lore raw

PATCH v9 1/49 dm: core: Don't set pinctrl for pinctrl devices

Quoted 10 lines · Simon Glass

There is sort-of race condition when a pinctrl device is probed. The pinctrl function is called which may end up using the same device as is being probed. This results in operations being used before the device is actually probed.

For now, disallow pinctrl operations on pinctrl devices while probing. An alternative solution would be to move the operation to later in the device_probe() function (for pinctrl devices only) but this needs more thought.

Quoted 7 lines

---

Changes in v9: None
Changes in v2: None

 drivers/core/device.c | 6 ++++--

Applied to u-boot-rockchip.

#3 lore raw

PATCH v9 2/49 dm: pinctrl: Add a function to parse PIN_CONFIG flags

In reply to Simon Glass

Add a function which produces a flags word from a few common PIN_CONFIG settings. This is useful for simple pinctrl drivers that don't need to worry about drive strength, etc.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/pinctrl-uclass.c | 12 ++++++++++++
 include/dm/pinctrl.h             | 13 +++++++++++++
 2 files changed, 25 insertions(+)
drivers/pinctrl/pinctrl-uclass.c +12 -0
index c42b312..1acbfaf 100644
@@ -15,6 +15,18 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int pinctrl_decode_pin_config(const void *blob, int node)
+{
+	int flags = 0;
+
+	if (fdtdec_get_bool(blob, node, "bias-pull-up"))
+		flags |= 1 << PIN_CONFIG_BIAS_PULL_UP;
+	else if (fdtdec_get_bool(blob, node, "bias-pull-down"))
+		flags |= 1 << PIN_CONFIG_BIAS_PULL_DOWN;
+
+	return flags;
+}
+
 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
 /**
  * pinctrl_config_one() - apply pinctrl settings for a single node
include/dm/pinctrl.h +13 -0
index f6025f6..5cd4503 100644
@@ -284,4 +284,17 @@ int pinctrl_request_noflags(struct udevice *dev, int func);
  */
 int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
 
+/**
+ * pinctrl_decode_pin_config() - decode pin configuration flags
+ *
+ * This decodes some of the PIN_CONFIG values into flags, with each value
+ * being (1 << pin_cfg). This does not support things with values like the
+ * slew rate.
+ *
+ * @blob:	Device tree blob
+ * @node:	Node containing the PIN_CONFIG values
+ * @return decoded flag value, or -ve on error
+ */
+int pinctrl_decode_pin_config(const void *blob, int node);
+
 #endif /* __PINCTRL_H */
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#4 lore raw

PATCH v9 2/49 dm: pinctrl: Add a function to parse PIN_CONFIG flags

Quoted 5 lines · Simon Glass

Add a function which produces a flags word from a few common PIN_CONFIG settings. This is useful for simple pinctrl drivers that don't need to worry about drive strength, etc.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/pinctrl-uclass.c | 12 ++++++++++++
 include/dm/pinctrl.h             | 13 +++++++++++++
 2 files changed, 25 insertions(+)

Applied to u-boot-rockchip.

#5 lore raw

PATCH v9 3/49 dm: pmic: Add 'reg status' to show all regulators

In reply to Simon Glass

It is convenient to be able to see the status of all regulators in a list. Add this feature to the 'reg status' command.

---

Changes in v9: None
Changes in v2: None

 common/cmd_regulator.c | 66 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 56 insertions(+), 10 deletions(-)
common/cmd_regulator.c +56 -10
index 793f08e..bfea6e0 100644
@@ -180,18 +180,13 @@ static int do_info(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	return CMD_RET_SUCCESS;
 }
 
-static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static void do_status_detail(struct udevice *dev,
+			     struct dm_regulator_uclass_platdata *uc_pdata)
 {
-	struct dm_regulator_uclass_platdata *uc_pdata;
-	int current, value, mode, ret;
-	const char *mode_name = NULL;
-	struct udevice *dev;
+	int current, value, mode;
+	const char *mode_name;
 	bool enabled;
 
-	ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
-	if (ret)
-		return ret;
-
 	printf("Regulator %s status:\n", uc_pdata->name);
 
 	enabled = regulator_get_enable(dev);
@@ -206,6 +201,57 @@ static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	mode = regulator_get_mode(dev);
 	mode_name = get_mode_name(uc_pdata->mode, uc_pdata->mode_count, mode);
 	constraint(" * mode id:", mode, mode_name);
+}
+
+static void do_status_line(struct udevice *dev)
+{
+	struct dm_regulator_uclass_platdata *pdata;
+	int current, value, mode;
+	const char *mode_name;
+	bool enabled;
+
+	pdata = dev_get_uclass_platdata(dev);
+	enabled = regulator_get_enable(dev);
+	value = regulator_get_value(dev);
+	current = regulator_get_current(dev);
+	mode = regulator_get_mode(dev);
+	mode_name = get_mode_name(pdata->mode, pdata->mode_count, mode);
+	printf("%-20s %-10s ", pdata->name, enabled ? "enabled" : "disabled");
+	if (value >= 0)
+		printf("%10d ", value);
+	else
+		printf("%10s ", "-");
+	if (current >= 0)
+		printf("%10d ", current);
+	else
+		printf("%10s ", "-");
+	if (mode >= 0)
+		printf("%-10s", mode_name);
+	else
+		printf("%-10s", "-");
+	printf("\n");
+}
+
+static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct dm_regulator_uclass_platdata *uc_pdata;
+	struct udevice *dev;
+	int ret;
+
+	if (currdev && (argc < 2 || strcmp(argv[1], "-a"))) {
+		ret = curr_dev_and_platdata(&dev, &uc_pdata, true);
+		if (ret)
+			return CMD_RET_FAILURE;
+		do_status_detail(dev, uc_pdata);
+		return 0;
+	}
+
+	/* Show all of them in a list, probing them as needed */
+	printf("%-20s %-10s %10s %10s %-10s\n", "Name", "Enabled", "uV", "mA",
+	       "Mode");
+	for (ret = uclass_first_device(UCLASS_REGULATOR, &dev); dev;
+	     ret = uclass_next_device(&dev))
+		do_status_line(dev);
 
 	return CMD_RET_SUCCESS;
 }
@@ -400,7 +446,7 @@ U_BOOT_CMD(regulator, CONFIG_SYS_MAXARGS, 1, do_regulator,
 	"list             - list UCLASS regulator devices\n"
 	"regulator dev [regulator-name] - show/[set] operating regulator device\n"
 	"regulator info                 - print constraints info\n"
-	"regulator status               - print operating status\n"
+	"regulator status [-a]          - print operating status [for all]\n"
 	"regulator value [val] [-f]     - print/[set] voltage value [uV] (force)\n"
 	"regulator current [val]        - print/[set] current value [uA]\n"
 	"regulator mode [id]            - print/[set] operating mode id\n"
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#6 lore raw

PATCH v9 3/49 dm: pmic: Add 'reg status' to show all regulators

Quoted 11 lines · Simon Glass

It is convenient to be able to see the status of all regulators in a list. Add this feature to the 'reg status' command.

---

Changes in v9: None
Changes in v2: None

 common/cmd_regulator.c | 66 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 56 insertions(+), 10 deletions(-)

Applied to u-boot-rockchip.

#7 lore raw

PATCH v9 4/49 dts: Bring in pinctrl device tree binding

In reply to Simon Glass

Add this binding file since we now use it in U-Boot.

---

Changes in v9: None
Changes in v2: None

 .../pinctrl/pinctrl-bindings.txt                   | 236 +++++++++++++++++++++
 1 file changed, 236 insertions(+)
 create mode 100644 doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt
doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt new file +236 -0
new file mode 100644
index 0000000..b73c96d
@@ -0,0 +1,236 @@
+== Introduction ==
+
+Hardware modules that control pin multiplexing or configuration parameters
+such as pull-up/down, tri-state, drive-strength etc are designated as pin
+controllers. Each pin controller must be represented as a node in device tree,
+just like any other hardware module.
+
+Hardware modules whose signals are affected by pin configuration are
+designated client devices. Again, each client device must be represented as a
+node in device tree, just like any other hardware module.
+
+For a client device to operate correctly, certain pin controllers must
+set up certain specific pin configurations. Some client devices need a
+single static pin configuration, e.g. set up during initialization. Others
+need to reconfigure pins at run-time, for example to tri-state pins when the
+device is inactive. Hence, each client device can define a set of named
+states. The number and names of those states is defined by the client device's
+own binding.
+
+The common pinctrl bindings defined in this file provide an infrastructure
+for client device device tree nodes to map those state names to the pin
+configuration used by those states.
+
+Note that pin controllers themselves may also be client devices of themselves.
+For example, a pin controller may set up its own "active" state when the
+driver loads. This would allow representing a board's static pin configuration
+in a single place, rather than splitting it across multiple client device
+nodes. The decision to do this or not somewhat rests with the author of
+individual board device tree files, and any requirements imposed by the
+bindings for the individual client devices in use by that board, i.e. whether
+they require certain specific named states for dynamic pin configuration.
+
+== Pinctrl client devices ==
+
+For each client device individually, every pin state is assigned an integer
+ID. These numbers start at 0, and are contiguous. For each state ID, a unique
+property exists to define the pin configuration. Each state may also be
+assigned a name. When names are used, another property exists to map from
+those names to the integer IDs.
+
+Each client device's own binding determines the set of states that must be
+defined in its device tree node, and whether to define the set of state
+IDs that must be provided, or whether to define the set of state names that
+must be provided.
+
+Required properties:
+pinctrl-0:	List of phandles, each pointing at a pin configuration
+		node. These referenced pin configuration nodes must be child
+		nodes of the pin controller that they configure. Multiple
+		entries may exist in this list so that multiple pin
+		controllers may be configured, or so that a state may be built
+		from multiple nodes for a single pin controller, each
+		contributing part of the overall configuration. See the next
+		section of this document for details of the format of these
+		pin configuration nodes.
+
+		In some cases, it may be useful to define a state, but for it
+		to be empty. This may be required when a common IP block is
+		used in an SoC either without a pin controller, or where the
+		pin controller does not affect the HW module in question. If
+		the binding for that IP block requires certain pin states to
+		exist, they must still be defined, but may be left empty.
+
+Optional properties:
+pinctrl-1:	List of phandles, each pointing at a pin configuration
+		node within a pin controller.
+...
+pinctrl-n:	List of phandles, each pointing at a pin configuration
+		node within a pin controller.
+pinctrl-names:	The list of names to assign states. List entry 0 defines the
+		name for integer state ID 0, list entry 1 for state ID 1, and
+		so on.
+
+For example:
+
+	/* For a client device requiring named states */
+	device {
+		pinctrl-names = "active", "idle";
+		pinctrl-0 = <&state_0_node_a>;
+		pinctrl-1 = <&state_1_node_a &state_1_node_b>;
+	};
+
+	/* For the same device if using state IDs */
+	device {
+		pinctrl-0 = <&state_0_node_a>;
+		pinctrl-1 = <&state_1_node_a &state_1_node_b>;
+	};
+
+	/*
+	 * For an IP block whose binding supports pin configuration,
+	 * but in use on an SoC that doesn't have any pin control hardware
+	 */
+	device {
+		pinctrl-names = "active", "idle";
+		pinctrl-0 = <>;
+		pinctrl-1 = <>;
+	};
+
+== Pin controller devices ==
+
+Pin controller devices should contain the pin configuration nodes that client
+devices reference.
+
+For example:
+
+	pincontroller {
+		... /* Standard DT properties for the device itself elided */
+
+		state_0_node_a {
+			...
+		};
+		state_1_node_a {
+			...
+		};
+		state_1_node_b {
+			...
+		};
+	}
+
+The contents of each of those pin configuration child nodes is defined
+entirely by the binding for the individual pin controller device. There
+exists no common standard for this content.
+
+The pin configuration nodes need not be direct children of the pin controller
+device; they may be grandchildren, for example. Whether this is legal, and
+whether there is any interaction between the child and intermediate parent
+nodes, is again defined entirely by the binding for the individual pin
+controller device.
+
+== Generic pin multiplexing node content ==
+
+pin multiplexing nodes:
+
+function		- the mux function to select
+groups			- the list of groups to select with this function
+			  (either this or "pins" must be specified)
+pins			- the list of pins to select with this function (either
+			  this or "groups" must be specified)
+
+Example:
+
+state_0_node_a {
+	uart0 {
+		function = "uart0";
+		groups = "u0rxtx", "u0rtscts";
+	};
+};
+state_1_node_a {
+	spi0 {
+		function = "spi0";
+		groups = "spi0pins";
+	};
+};
+state_2_node_a {
+	function = "i2c0";
+	pins = "mfio29", "mfio30";
+};
+
+== Generic pin configuration node content ==
+
+Many data items that are represented in a pin configuration node are common
+and generic. Pin control bindings should use the properties defined below
+where they are applicable; not all of these properties are relevant or useful
+for all hardware or binding structures. Each individual binding document
+should state which of these generic properties, if any, are used, and the
+structure of the DT nodes that contain these properties.
+
+Supported generic properties are:
+
+pins			- the list of pins that properties in the node
+			  apply to (either this or "group" has to be
+			  specified)
+group			- the group to apply the properties to, if the driver
+			  supports configuration of whole groups rather than
+			  individual pins (either this or "pins" has to be
+			  specified)
+bias-disable		- disable any pin bias
+bias-high-impedance	- high impedance mode ("third-state", "floating")
+bias-bus-hold		- latch weakly
+bias-pull-up		- pull up the pin
+bias-pull-down		- pull down the pin
+bias-pull-pin-default	- use pin-default pull state
+drive-push-pull		- drive actively high and low
+drive-open-drain	- drive with open drain
+drive-open-source	- drive with open source
+drive-strength		- sink or source at most X mA
+input-enable		- enable input on pin (no effect on output)
+input-disable		- disable input on pin (no effect on output)
+input-schmitt-enable	- enable schmitt-trigger mode
+input-schmitt-disable	- disable schmitt-trigger mode
+input-debounce		- debounce mode with debound time X
+power-source		- select between different power supplies
+low-power-enable	- enable low power mode
+low-power-disable	- disable low power mode
+output-low		- set the pin to output mode with low level
+output-high		- set the pin to output mode with high level
+slew-rate		- set the slew rate
+
+For example:
+
+state_0_node_a {
+	cts_rxd {
+		pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
+		bias-pull-up;
+	};
+};
+state_1_node_a {
+	rts_txd {
+		pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
+		output-high;
+	};
+};
+state_2_node_a {
+	foo {
+		group = "foo-group";
+		bias-pull-up;
+	};
+};
+
+Some of the generic properties take arguments. For those that do, the
+arguments are described below.
+
+- pins takes a list of pin names or IDs as a required argument. The specific
+  binding for the hardware defines:
+  - Whether the entries are integers or strings, and their meaning.
+
+- bias-pull-up, -down and -pin-default take as optional argument on hardware
+  supporting it the pull strength in Ohm. bias-disable will disable the pull.
+
+- drive-strength takes as argument the target strength in mA.
+
+- input-debounce takes the debounce time in usec as argument
+  or 0 to disable debouncing
+
+More in-depth documentation on these parameters can be found in
+<include/linux/pinctrl/pinconf-generic.h>
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#8 lore raw

PATCH v9 4/49 dts: Bring in pinctrl device tree binding

Quoted 11 lines · Simon Glass

Add this binding file since we now use it in U-Boot.

---

Changes in v9: None
Changes in v2: None

 .../pinctrl/pinctrl-bindings.txt                   | 236 +++++++++++++++++++++
 1 file changed, 236 insertions(+)
 create mode 100644 doc/device-tree-bindings/pinctrl/pinctrl-bindings.txt

Applied to u-boot-rockchip.

#9 lore raw

PATCH v9 5/49 power: Add base support for the RK808 PMIC

In reply to Simon Glass

This Rockchip PMIC provides features suitable for battery-powered applications. It is commonly used with Rockchip SoCs.

Add a driver which provides register access. The regulator driver will use this.

---

Changes in v9: None
Changes in v2: None

 drivers/power/pmic/Kconfig  |  9 +++++
 drivers/power/pmic/Makefile |  1 +
 drivers/power/pmic/rk808.c  | 96 +++++++++++++++++++++++++++++++++++++++++++++
 include/power/rk808_pmic.h  | 77 ++++++++++++++++++++++++++++++++++++
 4 files changed, 183 insertions(+)
 create mode 100644 drivers/power/pmic/rk808.c
 create mode 100644 include/power/rk808_pmic.h
drivers/power/pmic/Kconfig +9 -0
index fb29843..8be3c07 100644
@@ -33,6 +33,15 @@ config DM_PMIC_MAX77686
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_RK808
+	bool "Enable support for Rockchip PMIC RK808"
+	depends on DM_PMIC
+	---help---
+	The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
+	an RTC and two low Rds (resistance (drain to source)) switches. It is
+	accessed via an I2C interface. The device is used with Rockchip SoCs.
+	This driver implements register read/write operations.
+
 config PMIC_S2MPS11
 	bool "Enable Driver Model for PMIC Samsung S2MPS11"
 	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 91e78f8..c6e8d0c 100644
@@ -11,6 +11,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
 obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
+obj-$(CONFIG_PMIC_RK808) += rk808.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
 
drivers/power/pmic/rk808.c new file +96 -0

96 lines not on this page · raw message

include/power/rk808_pmic.h new file +77 -0

77 lines not on this page · raw message

Signature · 1 line
2.7.0.rc3.207.g0ac5344
#10 lore raw

PATCH v9 5/49 power: Add base support for the RK808 PMIC

Quoted 12 lines · Simon Glass

This Rockchip PMIC provides features suitable for battery-powered applications. It is commonly used with Rockchip SoCs.

Add a driver which provides register access. The regulator driver will use this.

---

Changes in v9: None
Changes in v2: None

Quoted 7 lines
 drivers/power/pmic/Kconfig  |  9 +++++
 drivers/power/pmic/Makefile |  1 +
 drivers/power/pmic/rk808.c  | 96 +++++++++++++++++++++++++++++++++++++++++++++
 include/power/rk808_pmic.h  | 77 ++++++++++++++++++++++++++++++++++++
 4 files changed, 183 insertions(+)
 create mode 100644 drivers/power/pmic/rk808.c
 create mode 100644 include/power/rk808_pmic.h

Applied to u-boot-rockchip.

#11 lore raw

PATCH v9 6/49 power: Add support for RK808 regulators

In reply to Simon Glass

Add regulator support for the RK808 PMIC. It integrated 4 BUCKs and 8 LDOs all of which are supported by this driver.

---

Changes in v9: None
Changes in v2: None

 drivers/power/regulator/Kconfig  |   9 ++
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/rk808.c  | 301 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 drivers/power/regulator/rk808.c
drivers/power/regulator/Kconfig +9 -0
index 434dd02..8f638a9 100644
@@ -49,6 +49,15 @@ config DM_REGULATOR_FIXED
 	features for fixed value regulators. The driver implements get/set api
 	for enable and get only for voltage value.
 
+config REGULATOR_RK808
+	bool "Enable driver for RK808 regulators"
+	depends on DM_REGULATOR && PMIC_RK808
+	---help---
+	Enable support for the regulator functions of the RK808 PMIC. The
+	driver implements get/set api for the various BUCKS and LDOs supported
+	by the PMIC device. This driver is controlled by a device tree node
+	which includes voltage limits.
+
 config REGULATOR_S5M8767
 	bool "Enable support for S5M8767 regulator"
 	depends on DM_REGULATOR && PMIC_S5M8767
drivers/power/regulator/Makefile +1 -0
index c85978e..0d18c2b 100644
@@ -10,6 +10,7 @@ obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
 obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
 obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
 obj-$(CONFIG_DM_REGULATOR_FIXED) += fixed.o
+obj-$(CONFIG_REGULATOR_RK808) += rk808.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
drivers/power/regulator/rk808.c new file +301 -0

301 lines not on this page · raw message

Signature · 1 line
2.7.0.rc3.207.g0ac5344
#12 lore raw

PATCH v9 6/49 power: Add support for RK808 regulators

Quoted 6 lines · Simon Glass

Add regulator support for the RK808 PMIC. It integrated 4 BUCKs and 8 LDOs all of which are supported by this driver.

---

Quoted 8 lines

Changes in v9: None
Changes in v2: None

 drivers/power/regulator/Kconfig  |   9 ++
 drivers/power/regulator/Makefile |   1 +
 drivers/power/regulator/rk808.c  | 301 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 drivers/power/regulator/rk808.c

Applied to u-boot-rockchip.

#13 lore raw

PATCH v9 7/49 dm: Add a power sequencing uclass

In reply to Simon Glass

Some devices need special sequences to be used when starting up. Add a uclass for this. Drivers can be added to provide specific features as needed.

---

Changes in v9: None
Changes in v2: None

 drivers/misc/Kconfig         | 18 ++++++++++++++++++
 drivers/misc/Makefile        |  1 +
 drivers/misc/pwrseq-uclass.c | 24 ++++++++++++++++++++++++
 include/dm/uclass-id.h       |  1 +
 include/pwrseq.h             | 18 ++++++++++++++++++
 5 files changed, 62 insertions(+)
 create mode 100644 drivers/misc/pwrseq-uclass.c
 create mode 100644 include/pwrseq.h
drivers/misc/Kconfig +18 -0
index b92da4e..cba2363 100644
@@ -90,6 +90,24 @@ config MXC_OCOTP
 	  Programmable memory pages that are stored on the some
 	  Freescale i.MX processors.
 
+config PWRSEQ
+	bool "Enable power-sequencing drivers"
+	depends on DM
+	help
+	  Power-sequencing drivers provide support for controlling power for
+	  devices. They are typically referenced by a phandle from another
+	  device. When the device is started up, its power sequence can be
+	  initiated.
+
+config SPL_PWRSEQ
+	bool "Enable power-sequencing drivers for SPL"
+	depends on PWRSEQ
+	help
+	  Power-sequencing drivers provide support for controlling power for
+	  devices. They are typically referenced by a phandle from another
+	  device. When the device is started up, its power sequence can be
+	  initiated.
+
 config PCA9551_LED
 	bool "Enable PCA9551 LED driver"
 	help
drivers/misc/Makefile +1 -0
index aa137f5..fc8eb6f 100644
@@ -24,6 +24,7 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
 obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
 obj-$(CONFIG_NS87308) += ns87308.o
 obj-$(CONFIG_PDSP188x) += pdsp188x.o
+obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_SANDBOX) += reset_sandbox.o
 ifdef CONFIG_DM_I2C
 obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
drivers/misc/pwrseq-uclass.c new file +24 -0
new file mode 100644
index 0000000..8ed2ad4
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pwrseq.h>
+
+int pwrseq_set_power(struct udevice *dev, bool enable)
+{
+	struct pwrseq_ops *ops = pwrseq_get_ops(dev);
+
+	if (!ops->set_power)
+		return -ENOSYS;
+
+	return ops->set_power(dev, enable);
+}
+
+UCLASS_DRIVER(pwrseq) = {
+	.id		= UCLASS_PWRSEQ,
+	.name		= "pwrseq",
+};
include/dm/uclass-id.h +1 -0
index a0a3a79..b5f43ae 100644
@@ -51,6 +51,7 @@ enum uclass_id {
 	UCLASS_PINCTRL,		/* Pinctrl (pin muxing/configuration) device */
 	UCLASS_PINCONFIG,	/* Pin configuration node device */
 	UCLASS_PMIC,		/* PMIC I/O device */
+	UCLASS_PWRSEQ,		/* Power sequence device */
 	UCLASS_REGULATOR,	/* Regulator device */
 	UCLASS_RESET,		/* Reset device */
 	UCLASS_REMOTEPROC,	/* Remote Processor device */
include/pwrseq.h new file +18 -0
new file mode 100644
index 0000000..b934f29
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __pwrseq_h
+#define __pwrseq_h
+
+struct pwrseq_ops {
+	int (*set_power)(struct udevice *dev, bool enable);
+};
+
+#define pwrseq_get_ops(dev)	((struct pwrseq_ops *)(dev)->driver->ops)
+
+int pwrseq_set_power(struct udevice *dev, bool enable);
+
+#endif
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#14 lore raw

PATCH v9 7/49 dm: Add a power sequencing uclass

Quoted 10 lines · Simon Glass

Some devices need special sequences to be used when starting up. Add a uclass for this. Drivers can be added to provide specific features as needed.

---

Changes in v9: None
Changes in v2: None

Quoted 8 lines
 drivers/misc/Kconfig         | 18 ++++++++++++++++++
 drivers/misc/Makefile        |  1 +
 drivers/misc/pwrseq-uclass.c | 24 ++++++++++++++++++++++++
 include/dm/uclass-id.h       |  1 +
 include/pwrseq.h             | 18 ++++++++++++++++++
 5 files changed, 62 insertions(+)
 create mode 100644 drivers/misc/pwrseq-uclass.c
 create mode 100644 include/pwrseq.h

Applied to u-boot-rockchip.

#15 lore raw

PATCH v9 8/49 rockchip: Avoid using MMC code when not booting from MMC

In reply to Simon Glass

This saves some code space in SPL which is useful on jerry.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288-board-spl.c | 2 ++
 1 file changed, 2 insertions(+)
arch/arm/mach-rockchip/rk3288-board-spl.c +2 -0
index 8199cad..b2c5729 100644
@@ -113,6 +113,7 @@ static void configure_l2ctlr(void)
 
 static int configure_emmc(struct udevice *pinctrl)
 {
+#ifdef CONFIG_SPL_MMC_SUPPORT
 	struct gpio_desc desc;
 	int ret;
 
@@ -142,6 +143,7 @@ static int configure_emmc(struct udevice *pinctrl)
 		debug("gpio value ret=%d\n", ret);
 		return ret;
 	}
+#endif
 
 	return 0;
 }
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#16 lore raw

PATCH v9 8/49 rockchip: Avoid using MMC code when not booting from MMC

Quoted 10 lines · Simon Glass

This saves some code space in SPL which is useful on jerry.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288-board-spl.c | 2 ++
 1 file changed, 2 insertions(+)

Applied to u-boot-rockchip.

#17 lore raw

PATCH v9 9/49 rockchip: Convert the PMU IOMUX registers into an array

In reply to Simon Glass

This is easier to deal with when using generic code since it allows us to use a register index instead of naming each register.

Adjust it, adding an enum to improve readability.

---

Changes in v9: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h | 12 ++++++++----
 drivers/pinctrl/rockchip/pinctrl_rk3288.c       |  4 ++--
 2 files changed, 10 insertions(+), 6 deletions(-)
arch/arm/include/asm/arch-rockchip/pmu_rk3288.h +8 -4
index 12fa685..081675e 100644
@@ -46,14 +46,18 @@ struct rk3288_pmu {
 	u32 gpio_op;
 
 	u32 gpio0_sel18;	/* 0x80 */
-	u32 gpio0a_iomux;
-	u32 gpio0b_iomux;
-	u32 gpio0c_iomux;
-	u32 gpio0d_iomux;
+	u32 gpio0_iomux[4];	/* a, b, c, d */
 	u32 sys_reg[4];
 };
 check_member(rk3288_pmu, sys_reg[3], 0x00a0);
 
+enum {
+	PMU_GPIO0_A	= 0,
+	PMU_GPIO0_B,
+	PMU_GPIO0_C,
+	PMU_GPIO0_D,
+};
+
 /* PMU_GPIO0_B_IOMUX */
 enum {
 	GPIO0_B7_SHIFT		= 14,
drivers/pinctrl/rockchip/pinctrl_rk3288.c +2 -2
index c432a00..ec3c4fe 100644
@@ -56,10 +56,10 @@ static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
 {
 	switch (i2c_id) {
 	case PERIPH_ID_I2C0:
-		clrsetbits_le32(&pmu->gpio0b_iomux,
+		clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_B],
 				GPIO0_B7_MASK << GPIO0_B7_SHIFT,
 				GPIO0_B7_I2C0PMU_SDA << GPIO0_B7_SHIFT);
-		clrsetbits_le32(&pmu->gpio0b_iomux,
+		clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_C],
 				GPIO0_C0_MASK << GPIO0_C0_SHIFT,
 				GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT);
 		break;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#18 lore raw

PATCH v9 9/49 rockchip: Convert the PMU IOMUX registers into an array

Quoted 6 lines · Simon Glass

This is easier to deal with when using generic code since it allows us to use a register index instead of naming each register.

Adjust it, adding an enum to improve readability.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/pmu_rk3288.h | 12 ++++++++----
 drivers/pinctrl/rockchip/pinctrl_rk3288.c       |  4 ++--
 2 files changed, 10 insertions(+), 6 deletions(-)

Applied to u-boot-rockchip.

#19 lore raw

PATCH v9 10/49 rockchip: mmc: Use a pwrseq device if available

In reply to Simon Glass

Use the pwrseq uclass to find a suitable power sequence for the MMC device. If this is enabled in the device tree, we will pick it up automatically.

---

Changes in v9: None
Changes in v2: None

 drivers/mmc/rockchip_dw_mmc.c | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
drivers/mmc/rockchip_dw_mmc.c +47 -0
index 9b4268e..080c831 100644
@@ -9,7 +9,9 @@
 #include <dm.h>
 #include <dwmmc.h>
 #include <errno.h>
+#include <pwrseq.h>
 #include <syscon.h>
+#include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/periph.h>
 #include <linux/err.h>
@@ -64,6 +66,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
 	struct dwmci_host *host = &priv->host;
+	struct udevice *pwr_dev __maybe_unused;
 	u32 minmax[2];
 	int ret;
 	int fifo_depth;
@@ -90,6 +93,16 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
 	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "fifo-mode"))
 		host->fifo_mode = true;
 
+#ifdef CONFIG_PWRSEQ
+	/* Enable power if needed */
+	ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
+					   &pwr_dev);
+	if (!ret) {
+		ret = pwrseq_set_power(pwr_dev, true);
+		if (ret)
+			return ret;
+	}
+#endif
 	ret = add_dwmci(host, minmax[1], minmax[0]);
 	if (ret)
 		return ret;
@@ -112,3 +125,37 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
 	.probe		= rockchip_dwmmc_probe,
 	.priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
 };
+
+#ifdef CONFIG_PWRSEQ
+static int rockchip_dwmmc_pwrseq_set_power(struct udevice *dev, bool enable)
+{
+	struct gpio_desc reset;
+	int ret;
+
+	ret = gpio_request_by_name(dev, "reset-gpios", 0, &reset, GPIOD_IS_OUT);
+	if (ret)
+		return ret;
+	dm_gpio_set_value(&reset, 1);
+	udelay(1);
+	dm_gpio_set_value(&reset, 0);
+	udelay(200);
+
+	return 0;
+}
+
+static const struct pwrseq_ops rockchip_dwmmc_pwrseq_ops = {
+	.set_power	= rockchip_dwmmc_pwrseq_set_power,
+};
+
+static const struct udevice_id rockchip_dwmmc_pwrseq_ids[] = {
+	{ .compatible = "mmc-pwrseq-emmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_dwmmc_pwrseq_drv) = {
+	.name		= "mmc_pwrseq_emmc",
+	.id		= UCLASS_PWRSEQ,
+	.of_match	= rockchip_dwmmc_pwrseq_ids,
+	.ops		= &rockchip_dwmmc_pwrseq_ops,
+};
+#endif
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#20 lore raw

PATCH v9 10/49 rockchip: mmc: Use a pwrseq device if available

Quoted 11 lines · Simon Glass

Use the pwrseq uclass to find a suitable power sequence for the MMC device. If this is enabled in the device tree, we will pick it up automatically.

---

Changes in v9: None
Changes in v2: None

 drivers/mmc/rockchip_dw_mmc.c | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

Applied to u-boot-rockchip.

#21 lore raw

PATCH v9 11/49 rockchip: Correct the defconfig order

In reply to Simon Glass

This has got out of sequence somehow. Fix it.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 6 +++---
 configs/firefly-rk3288_defconfig   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)
configs/chromebook_jerry_defconfig +3 -3
index a515d8d..39cd9d6 100644
@@ -4,9 +4,9 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_CHROMEBOOK_JERRY=y
 CONFIG_SPL_STACK_R_ADDR=0x80000
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="rk3288-jerry"
 CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PMIC=y
@@ -15,11 +15,11 @@ CONFIG_SPL_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
-CONFIG_SPL_SYSCON=y
 CONFIG_LED=y
 CONFIG_SPL_LED=y
 CONFIG_LED_GPIO=y
@@ -42,8 +42,8 @@ CONFIG_DEBUG_UART_BASE=0xff690000
 CONFIG_DEBUG_UART_CLOCK=24000000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYS_NS16550=y
+CONFIG_ROCKCHIP_SPI=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
-CONFIG_ROCKCHIP_SPI=y
configs/firefly-rk3288_defconfig +2 -2
index be4ca88..f41c241 100644
@@ -4,9 +4,9 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_FIREFLY_RK3288=y
 CONFIG_SPL_STACK_R_ADDR=0x80000
-CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_DEFAULT_DEVICE_TREE="rk3288-firefly"
 CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PMIC=y
@@ -15,11 +15,11 @@ CONFIG_SPL_OF_CONTROL=y
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
-CONFIG_SPL_SYSCON=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_RESET=y
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#22 lore raw

PATCH v9 11/49 rockchip: Correct the defconfig order

Quoted 11 lines · Simon Glass

This has got out of sequence somehow. Fix it.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 6 +++---
 configs/firefly-rk3288_defconfig   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

Applied to u-boot-rockchip.

#23 lore raw

PATCH v9 12/49 rockchip: Use pwrseq for MMC start-up on jerry

In reply to Simon Glass

This is defined in the device tree in Linux. Copy over the settings so that this can be used instead of hard-coding the reset line.

---

Changes in v9: None
Changes in v2: None

 arch/arm/dts/rk3288-veyron.dtsi    | 15 +++++++++++----
 configs/chromebook_jerry_defconfig |  1 +
 include/configs/rk3288_common.h    |  1 +
 3 files changed, 13 insertions(+), 4 deletions(-)
arch/arm/dts/rk3288-veyron.dtsi +11 -4
index 7e37158..12404ff 100644
@@ -106,6 +106,13 @@
 		priority = /bits/ 8 <200>;
 	};
 
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		pinctrl-0 = <&emmc_reset>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
+	};
+
 	sound {
 		compatible = "rockchip,rockchip-audio-max98090";
 		rockchip,model = "ROCKCHIP-I2S";
@@ -259,11 +266,12 @@
 	bus-width = <8>;
 	cap-mmc-highspeed;
 	mmc-hs200-1_8v;
+	mmc-pwrseq = <&emmc_pwrseq>;
 	disable-wp;
 	non-removable;
 	num-slots = <1>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_deassert_reset>;
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8 &emmc_pwr>;
 	status = "okay";
 };
 
@@ -671,9 +679,8 @@
 	};
 
 	emmc {
-		/* Make sure eMMC is not in reset */
-		emmc_deassert_reset: emmc-deassert-reset {
-			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_up>;
+		emmc_reset: emmc-reset {
+			rockchip,pins = <2 9 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 
 		/*
configs/chromebook_jerry_defconfig +1 -0
index 39cd9d6..456b6ea 100644
@@ -23,6 +23,7 @@ CONFIG_SYS_I2C_ROCKCHIP=y
 CONFIG_LED=y
 CONFIG_SPL_LED=y
 CONFIG_LED_GPIO=y
+CONFIG_PWRSEQ=y
 CONFIG_RESET=y
 CONFIG_DM_MMC=y
 CONFIG_ROCKCHIP_DWMMC=y
include/configs/rk3288_common.h +1 -0
index 238711a..f47573b 100644
@@ -26,6 +26,7 @@
 #define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMER_BASE + 8)
 
 #define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
 #define CONFIG_SPL_LIBCOMMON_SUPPORT
 #define CONFIG_SPL_LIBGENERIC_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#24 lore raw

PATCH v9 12/49 rockchip: Use pwrseq for MMC start-up on jerry

Quoted 6 lines · Simon Glass

This is defined in the device tree in Linux. Copy over the settings so that this can be used instead of hard-coding the reset line.

---

Quoted 7 lines

Changes in v9: None
Changes in v2: None

 arch/arm/dts/rk3288-veyron.dtsi    | 15 +++++++++++----
 configs/chromebook_jerry_defconfig |  1 +
 include/configs/rk3288_common.h    |  1 +
 3 files changed, 13 insertions(+), 4 deletions(-)

Applied to u-boot-rockchip.

#25 lore raw

PATCH v9 13/49 rockchip: jerry: Disable pmic-int-1 setup to avoid a hang

In reply to Simon Glass

This hangs when activated (by probing the PMIC). Disable it for now until we understand the root cause.

---

Changes in v9: None
Changes in v2: None

 arch/arm/dts/rk3288-veyron.dtsi | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/dts/rk3288-veyron.dtsi +4 -1
index 12404ff..a31e00e 100644
@@ -715,7 +715,10 @@
 
 	pmic {
 		pmic_int_l: pmic-int-l {
-			rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+			/*
+			 * Causes jerry to hang when probing bus 0
+			 * rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
+			 */
 		};
 	};
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#26 lore raw

PATCH v9 13/49 rockchip: jerry: Disable pmic-int-1 setup to avoid a hang

Quoted 11 lines · Simon Glass

This hangs when activated (by probing the PMIC). Disable it for now until we understand the root cause.

---

Changes in v9: None
Changes in v2: None

 arch/arm/dts/rk3288-veyron.dtsi | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

#27 lore raw

PATCH v9 14/49 rockchip: Use a separate clock ID for clocks

In reply to Simon Glass

At present we use the same peripheral ID for clocks and pinctrl. While this works it is probably better to use the device tree clock binding ID for clocks. We can use the clk_get_by_index() function to find this.

Update the clock drivers and the code that uses them.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

 configs/chromebook_jerry_defconfig |  1 +
 configs/firefly-rk3288_defconfig   |  1 +
 drivers/clk/clk_rk3036.c           | 16 +++++-----
 drivers/clk/clk_rk3288.c           | 63 +++++++++++++++++++++-----------------
 drivers/mmc/rockchip_dw_mmc.c      | 13 +++-----
 5 files changed, 50 insertions(+), 44 deletions(-)
configs/chromebook_jerry_defconfig +1 -0
index 456b6ea..5535105 100644
@@ -12,6 +12,7 @@ CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent"
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
configs/firefly-rk3288_defconfig +1 -0
index f41c241..5b26a3d 100644
@@ -12,6 +12,7 @@ CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
 CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent"
 CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
drivers/clk/clk_rk3036.c +8 -8
index f650810..dfecc24 100644
@@ -13,8 +13,8 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/cru_rk3036.h>
 #include <asm/arch/hardware.h>
-#include <asm/arch/periph.h>
 #include <dm/lists.h>
+#include <dt-bindings/clock/rk3036-cru.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -233,19 +233,19 @@ static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
 }
 
 static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
-				  enum periph_id periph)
+				  int periph)
 {
 	uint src_rate;
 	uint div, mux;
 	u32 con;
 
 	switch (periph) {
-	case PERIPH_ID_EMMC:
+	case HCLK_EMMC:
 		con = readl(&cru->cru_clksel_con[12]);
 		mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
 		div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
 		break;
-	case PERIPH_ID_SDCARD:
+	case HCLK_SDIO:
 		con = readl(&cru->cru_clksel_con[12]);
 		mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
 		div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
@@ -259,7 +259,7 @@ static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
 }
 
 static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
-				  enum periph_id periph, uint freq)
+				  int periph, uint freq)
 {
 	int src_clk_div;
 	int mux;
@@ -277,14 +277,14 @@ static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
 	}
 
 	switch (periph) {
-	case PERIPH_ID_EMMC:
+	case HCLK_EMMC:
 		rk_clrsetreg(&cru->cru_clksel_con[12],
 			     EMMC_PLL_MASK << EMMC_PLL_SHIFT |
 			     EMMC_DIV_MASK << EMMC_DIV_SHIFT,
 			     mux << EMMC_PLL_SHIFT |
 			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
 		break;
-	case PERIPH_ID_SDCARD:
+	case HCLK_SDIO:
 		rk_clrsetreg(&cru->cru_clksel_con[11],
 			     MMC0_PLL_MASK << MMC0_PLL_SHIFT |
 			     MMC0_DIV_MASK << MMC0_DIV_SHIFT,
@@ -320,7 +320,7 @@ static ulong rk3036_set_periph_rate(struct udevice *dev, int periph, ulong rate)
 	ulong new_rate;
 
 	switch (periph) {
-	case PERIPH_ID_EMMC:
+	case HCLK_EMMC:
 		new_rate = rockchip_mmc_set_clk(priv->cru, clk_get_rate(dev),
 						periph, rate);
 		break;
drivers/clk/clk_rk3288.c +35 -28

164 lines not on this page · raw message

drivers/mmc/rockchip_dw_mmc.c +5 -8
index 080c831..cb9e104 100644
@@ -20,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct rockchip_dwmmc_priv {
 	struct udevice *clk;
-	struct rk3288_grf *grf;
+	int periph;
 	struct dwmci_host host;
 };
 
@@ -30,8 +30,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq)
 	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
 	int ret;
 
-	ret = clk_set_periph_rate(priv->clk, PERIPH_ID_SDMMC0 + host->dev_index,
-				  freq);
+	ret = clk_set_periph_rate(priv->clk, priv->periph, freq);
 	if (ret < 0) {
 		debug("%s: err=%d\n", __func__, ret);
 		return ret;
@@ -71,12 +70,10 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
 	int ret;
 	int fifo_depth;
 
-	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	if (IS_ERR(priv->grf))
-		return PTR_ERR(priv->grf);
-	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk);
-	if (ret)
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret < 0)
 		return ret;
+	priv->periph = ret;
 
 	if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
 				 "clock-freq-min-max", minmax, 2))
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#28 lore raw

PATCH v9 14/49 rockchip: Use a separate clock ID for clocks

Quoted 13 lines · Simon Glass

At present we use the same peripheral ID for clocks and pinctrl. While this works it is probably better to use the device tree clock binding ID for clocks. We can use the clk_get_by_index() function to find this.

Update the clock drivers and the code that uses them.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

Quoted 6 lines
 configs/chromebook_jerry_defconfig |  1 +
 configs/firefly-rk3288_defconfig   |  1 +
 drivers/clk/clk_rk3036.c           | 16 +++++-----
 drivers/clk/clk_rk3288.c           | 63 +++++++++++++++++++++-----------------
 drivers/mmc/rockchip_dw_mmc.c      | 13 +++-----
 5 files changed, 50 insertions(+), 44 deletions(-)

Applied to u-boot-rockchip.

#29 lore raw

PATCH v9 15/49 rockchip: clock: Rename the general clock variable to gclk_rate

In reply to Simon Glass

The current name is confusing and a bit verbose. Rename it.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/clk/clk_rk3288.c +12 -12
index e410e7d1..49c2bdf 100644
@@ -363,7 +363,7 @@ static ulong rk3288_clk_set_rate(struct udevice *dev, ulong rate)
 	return 0;
 }
 
-static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
+static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
 				  int periph)
 {
 	uint src_rate;
@@ -390,18 +390,18 @@ static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
 		return -EINVAL;
 	}
 
-	src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : clk_general_rate;
+	src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : gclk_rate;
 	return DIV_TO_RATE(src_rate, div);
 }
 
-static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
+static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
 				  int  periph, uint freq)
 {
 	int src_clk_div;
 	int mux;
 
-	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
-	src_clk_div = RATE_TO_DIV(clk_general_rate, freq);
+	debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+	src_clk_div = RATE_TO_DIV(gclk_rate, freq);
 
 	if (src_clk_div > 0x3f) {
 		src_clk_div = RATE_TO_DIV(OSC_HZ, freq);
@@ -439,10 +439,10 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
 		return -EINVAL;
 	}
 
-	return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+	return rockchip_mmc_get_clk(cru, gclk_rate, periph);
 }
 
-static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
+static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate,
 				  int periph)
 {
 	uint div, mux;
@@ -469,16 +469,16 @@ static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint clk_general_rate,
 	}
 	assert(mux == SPI0_PLL_SELECT_GENERAL);
 
-	return DIV_TO_RATE(clk_general_rate, div);
+	return DIV_TO_RATE(gclk_rate, div);
 }
 
-static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
+static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
 				  int periph, uint freq)
 {
 	int src_clk_div;
 
-	debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
-	src_clk_div = RATE_TO_DIV(clk_general_rate, freq);
+	debug("%s: clk_general_rate=%u\n", __func__, gclk_rate);
+	src_clk_div = RATE_TO_DIV(gclk_rate, freq);
 	switch (periph) {
 	case SCLK_SPI0:
 		rk_clrsetreg(&cru->cru_clksel_con[25],
@@ -505,7 +505,7 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint clk_general_rate,
 		return -EINVAL;
 	}
 
-	return rockchip_spi_get_clk(cru, clk_general_rate, periph);
+	return rockchip_spi_get_clk(cru, gclk_rate, periph);
 }
 
 static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#30 lore raw

PATCH v9 15/49 rockchip: clock: Rename the general clock variable to gclk_rate

Quoted 10 lines · Simon Glass

The current name is confusing and a bit verbose. Rename it.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

Applied to u-boot-rockchip.

#31 lore raw

PATCH v9 16/49 rockchip: clk: Add a function to get a peripheral clock rate

In reply to Simon Glass

It is useful to be able to read the rate of a peripheral clock. Add a handler for that.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
drivers/clk/clk_rk3288.c +37 -0
index 49c2bdf..df5c38c 100644
@@ -508,6 +508,42 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
 	return rockchip_spi_get_clk(cru, gclk_rate, periph);
 }
 
+static ulong rk3288_get_periph_rate(struct udevice *dev, int periph)
+{
+	struct rk3288_clk_priv *priv = dev_get_priv(dev);
+	struct udevice *gclk;
+	ulong new_rate, gclk_rate;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &gclk);
+	if (ret)
+		return ret;
+	gclk_rate = clk_get_rate(gclk);
+	switch (periph) {
+	case HCLK_EMMC:
+	case HCLK_SDIO0:
+	case HCLK_SDIO1:
+		new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, periph);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+	case SCLK_SPI2:
+		new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, periph);
+		break;
+	case PCLK_I2C0:
+	case PCLK_I2C1:
+	case PCLK_I2C2:
+	case PCLK_I2C3:
+	case PCLK_I2C4:
+	case PCLK_I2C5:
+		return gclk_rate;
+	default:
+		return -ENOENT;
+	}
+
+	return new_rate;
+}
+
 static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
 {
 	struct rk3288_clk_priv *priv = dev_get_priv(dev);
@@ -543,6 +579,7 @@ static struct clk_ops rk3288_clk_ops = {
 	.get_rate	= rk3288_clk_get_rate,
 	.set_rate	= rk3288_clk_set_rate,
 	.set_periph_rate = rk3288_set_periph_rate,
+	.get_periph_rate = rk3288_get_periph_rate,
 };
 
 static int rk3288_clk_probe(struct udevice *dev)
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#32 lore raw

PATCH v9 16/49 rockchip: clk: Add a function to get a peripheral clock rate

Quoted 11 lines · Simon Glass

It is useful to be able to read the rate of a peripheral clock. Add a handler for that.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Applied to u-boot-rockchip.

#33 lore raw

PATCH v9 17/49 rockchip: clock: Add a function to find a clock by ID

In reply to Simon Glass

The current approach of using uclass_get_device() is error-prone. Another clock (for example a fixed-clock) may cause it to break. Add a function that does a proper search.

---

Changes in v9: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/clock.h | 12 ++++++++++++
 drivers/clk/clk_rk3288.c                   | 24 ++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)
arch/arm/include/asm/arch-rockchip/clock.h +12 -0
index 8a0376c..a9ea268 100644
@@ -62,4 +62,16 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
  */
 void *rockchip_get_cru(void);
 
+/**
+ * rkclk_get_clk() - get a pointer to a given clock
+ *
+ * This is an internal function - use outside the clock subsystem indicates
+ * that work is needed!
+ *
+ * @clk_id:	Clock requested
+ * @devp:	Returns a pointer to that clock
+ * @return 0 if OK, -ve on error
+ */
+int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp);
+
 #endif
drivers/clk/clk_rk3288.c +22 -2
index df5c38c..fdc5347 100644
@@ -15,7 +15,9 @@
 #include <asm/arch/grf_rk3288.h>
 #include <asm/arch/hardware.h>
 #include <dt-bindings/clock/rk3288-cru.h>
+#include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <dm/uclass-internal.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -139,6 +141,24 @@ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
 
+int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp)
+{
+	struct udevice *dev;
+
+	for (uclass_find_first_device(UCLASS_CLK, &dev);
+	     dev;
+	     uclass_find_next_device(&dev)) {
+		struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+
+		if (plat->clk_id == clk_id) {
+			*devp = dev;
+			return device_probe(dev);
+		}
+	}
+
+	return -ENODEV;
+}
+
 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
 			 const struct pll_div *div)
 {
@@ -515,7 +535,7 @@ static ulong rk3288_get_periph_rate(struct udevice *dev, int periph)
 	ulong new_rate, gclk_rate;
 	int ret;
 
-	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &gclk);
+	ret = rkclk_get_clk(CLK_GENERAL, &gclk);
 	if (ret)
 		return ret;
 	gclk_rate = clk_get_rate(gclk);
@@ -551,7 +571,7 @@ static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
 	ulong new_rate, gclk_rate;
 	int ret;
 
-	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &gclk);
+	ret = rkclk_get_clk(CLK_GENERAL, &gclk);
 	if (ret)
 		return ret;
 	gclk_rate = clk_get_rate(gclk);
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#34 lore raw

PATCH v9 17/49 rockchip: clock: Add a function to find a clock by ID

Quoted 5 lines · Simon Glass

The current approach of using uclass_get_device() is error-prone. Another clock (for example a fixed-clock) may cause it to break. Add a function that does a proper search.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 arch/arm/include/asm/arch-rockchip/clock.h | 12 ++++++++++++
 drivers/clk/clk_rk3288.c                   | 24 ++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

#35 lore raw

PATCH v9 18/49 rockchip: i2c: Update the driver to use the new clock ID

In reply to Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

 drivers/i2c/rk_i2c.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)
drivers/i2c/rk_i2c.c +22 -16
index ebdba35..3fceade 100644
@@ -30,10 +30,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct rk_i2c {
 	struct udevice *clk;
-	struct udevice *pinctrl;
 	struct i2c_regs *regs;
 	unsigned int speed;
-	enum periph_id id;
+	int clk_id;
 };
 
 static inline void rk_i2c_get_div(int div, int *divh, int *divl)
@@ -56,7 +55,7 @@ static void rk_i2c_set_clk(struct rk_i2c *i2c, uint32_t scl_rate)
 	int div, divl, divh;
 
 	/* First get i2c rate from pclk */
-	i2c_rate = clk_get_periph_rate(i2c->clk, i2c->id);
+	i2c_rate = clk_get_periph_rate(i2c->clk, i2c->clk_id);
 
 	div = DIV_ROUND_UP(i2c_rate, scl_rate * 8) - 2;
 	divh = 0;
@@ -352,23 +351,29 @@ int rockchip_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 	return 0;
 }
 
-static int rockchip_i2c_probe(struct udevice *bus)
+static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus)
 {
-	struct rk_i2c *i2c = dev_get_priv(bus);
+	struct rk_i2c *priv = dev_get_priv(bus);
 	int ret;
 
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &i2c->pinctrl);
-	if (ret)
-		return ret;
-	ret = uclass_get_device(UCLASS_CLK, 0, &i2c->clk);
-	if (ret)
-		return ret;
-	ret = pinctrl_get_periph_id(i2c->pinctrl, bus);
-	if (ret < 0)
+	ret = clk_get_by_index(bus, 0, &priv->clk);
+	if (ret < 0) {
+		debug("%s: Could not get clock for %s: %d\n", __func__,
+		      bus->name, ret);
 		return ret;
-	i2c->id = ret;
-	i2c->regs = (void *)dev_get_addr(bus);
-	return pinctrl_request(i2c->pinctrl, i2c->id, 0);
+	}
+	priv->clk_id = ret;
+
+	return 0;
+}
+
+static int rockchip_i2c_probe(struct udevice *bus)
+{
+	struct rk_i2c *priv = dev_get_priv(bus);
+
+	priv->regs = (void *)dev_get_addr(bus);
+
+	return 0;
 }
 
 static const struct dm_i2c_ops rockchip_i2c_ops = {
@@ -385,6 +390,7 @@ U_BOOT_DRIVER(i2c_rockchip) = {
 	.name	= "i2c_rockchip",
 	.id	= UCLASS_I2C,
 	.of_match = rockchip_i2c_ids,
+	.ofdata_to_platdata = rockchip_i2c_ofdata_to_platdata,
 	.probe	= rockchip_i2c_probe,
 	.priv_auto_alloc_size = sizeof(struct rk_i2c),
 	.ops	= &rockchip_i2c_ops,
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#36 lore raw

PATCH v9 18/49 rockchip: i2c: Update the driver to use the new clock ID

Hello Simon,

Am 22.01.2016 um 03:43 schrieb Simon Glass:

Quoted 11 lines

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

  drivers/i2c/rk_i2c.c | 38 ++++++++++++++++++++++----------------
  1 file changed, 22 insertions(+), 16 deletions(-)

Thanks!

bye,
Heiko

Quoted 77 lines
drivers/i2c/rk_i2c.c +22 -16
index ebdba35..3fceade 100644
@@ -30,10 +30,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
  struct rk_i2c {
  	struct udevice *clk;
-	struct udevice *pinctrl;
  	struct i2c_regs *regs;
  	unsigned int speed;
-	enum periph_id id;
+	int clk_id;
  };
 
  static inline void rk_i2c_get_div(int div, int *divh, int *divl)
@@ -56,7 +55,7 @@ static void rk_i2c_set_clk(struct rk_i2c *i2c, uint32_t scl_rate)
  	int div, divl, divh;
 
  	/* First get i2c rate from pclk */
-	i2c_rate = clk_get_periph_rate(i2c->clk, i2c->id);
+	i2c_rate = clk_get_periph_rate(i2c->clk, i2c->clk_id);
 
  	div = DIV_ROUND_UP(i2c_rate, scl_rate * 8) - 2;
  	divh = 0;
@@ -352,23 +351,29 @@ int rockchip_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
  	return 0;
  }
 
-static int rockchip_i2c_probe(struct udevice *bus)
+static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus)
  {
-	struct rk_i2c *i2c = dev_get_priv(bus);
+	struct rk_i2c *priv = dev_get_priv(bus);
  	int ret;
 
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &i2c->pinctrl);
-	if (ret)
-		return ret;
-	ret = uclass_get_device(UCLASS_CLK, 0, &i2c->clk);
-	if (ret)
-		return ret;
-	ret = pinctrl_get_periph_id(i2c->pinctrl, bus);
-	if (ret < 0)
+	ret = clk_get_by_index(bus, 0, &priv->clk);
+	if (ret < 0) {
+		debug("%s: Could not get clock for %s: %d\n", __func__,
+		      bus->name, ret);
  		return ret;
-	i2c->id = ret;
-	i2c->regs = (void *)dev_get_addr(bus);
-	return pinctrl_request(i2c->pinctrl, i2c->id, 0);
+	}
+	priv->clk_id = ret;
+
+	return 0;
+}
+
+static int rockchip_i2c_probe(struct udevice *bus)
+{
+	struct rk_i2c *priv = dev_get_priv(bus);
+
+	priv->regs = (void *)dev_get_addr(bus);
+
+	return 0;
  }
 
  static const struct dm_i2c_ops rockchip_i2c_ops = {
@@ -385,6 +390,7 @@ U_BOOT_DRIVER(i2c_rockchip) = {
  	.name	= "i2c_rockchip",
  	.id	= UCLASS_I2C,
  	.of_match = rockchip_i2c_ids,
+	.ofdata_to_platdata = rockchip_i2c_ofdata_to_platdata,
  	.probe	= rockchip_i2c_probe,
  	.priv_auto_alloc_size = sizeof(struct rk_i2c),
  	.ops	= &rockchip_i2c_ops,
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#37 lore raw

PATCH v9 18/49 rockchip: i2c: Update the driver to use the new clock ID

In reply to Simon Glass
Quoted 11 lines · Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

 drivers/i2c/rk_i2c.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

Applied to u-boot-rockchip.

#38 lore raw

PATCH v9 19/49 rockchip: spi: Update the driver to use the new clock ID

In reply to Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

 drivers/spi/rk_spi.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)
drivers/spi/rk_spi.c +17 -15
index 242a83b..62434be 100644
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define DEBUG_RK_SPI	0
 
 struct rockchip_spi_platdata {
-	enum periph_id periph_id;
+	int periph_id;
 	struct udevice *pinctrl;
 	s32 frequency;		/* Default clock frequency, -1 for none */
 	fdt_addr_t base;
@@ -36,10 +36,10 @@ struct rockchip_spi_platdata {
 
 struct rockchip_spi_priv {
 	struct rockchip_spi *regs;
-	struct udevice *clk_gpll;
+	struct udevice *clk;
+	int clk_id;
 	unsigned int max_freq;
 	unsigned int mode;
-	enum periph_id periph_id;	/* Peripheral ID for this device */
 	ulong last_transaction_us;	/* Time of last transaction end */
 	u8 bits_per_word;		/* max 16 bits per word */
 	u8 n_bytes;
@@ -114,6 +114,7 @@ static void spi_cs_deactivate(struct rockchip_spi *regs, uint cs)
 static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
 {
 	struct rockchip_spi_platdata *plat = bus->platdata;
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
 	const void *blob = gd->fdt_blob;
 	int node = bus->of_offset;
 	int ret;
@@ -127,16 +128,23 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
 	if (ret < 0) {
 		debug("%s: Could not get peripheral ID for %s: %d\n", __func__,
 		      bus->name, ret);
-		return -FDT_ERR_NOTFOUND;
+		return ret;
 	}
 	plat->periph_id = ret;
+	ret = clk_get_by_index(bus, 0, &priv->clk);
+	if (ret < 0) {
+		debug("%s: Could not get clock for %s: %d\n", __func__,
+		      bus->name, ret);
+		return ret;
+	}
+	priv->clk_id = ret;
 
 	plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
-					50000000);
+					 50000000);
 	plat->deactivate_delay_us = fdtdec_get_int(blob, node,
 					"spi-deactivate-delay", 0);
-	debug("%s: base=%lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
-	      __func__, plat->base, plat->periph_id, plat->frequency,
+	debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
+	      __func__, (uint)plat->base, plat->periph_id, plat->frequency,
 	      plat->deactivate_delay_us);
 
 	return 0;
@@ -153,18 +161,12 @@ static int rockchip_spi_probe(struct udevice *bus)
 
 	priv->last_transaction_us = timer_get_us();
 	priv->max_freq = plat->frequency;
-	priv->periph_id = plat->periph_id;
-	ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &priv->clk_gpll);
-	if (ret) {
-		debug("%s: Failed to find CLK_GENERAL: %d\n", __func__, ret);
-		return ret;
-	}
 
 	/*
 	 * Use 99 MHz as our clock since it divides nicely into 594 MHz which
 	 * is the assumed speed for CLK_GENERAL.
 	 */
-	ret = clk_set_periph_rate(priv->clk_gpll, plat->periph_id, 99000000);
+	ret = clk_set_periph_rate(priv->clk, priv->clk_id, 99000000);
 	if (ret < 0) {
 		debug("%s: Failed to set clock: %d\n", __func__, ret);
 		return ret;
@@ -248,7 +250,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 
 	writel(ctrlr0, &regs->ctrlr0);
 
-	ret = pinctrl_request(plat->pinctrl, priv->periph_id, slave_plat->cs);
+	ret = pinctrl_request(plat->pinctrl, plat->periph_id, slave_plat->cs);
 	if (ret) {
 		debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
 		return ret;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#39 lore raw

PATCH v9 19/49 rockchip: spi: Update the driver to use the new clock ID

Quoted 11 lines · Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2:
- Update call to clk_get_by_index()

 drivers/spi/rk_spi.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

Applied to u-boot-rockchip.

#40 lore raw

PATCH v9 20/49 rockchip: spi: Avoid setting the pinctrl twice

In reply to Simon Glass

If full pinctrl is enabled we don't need to manually set the pinctrl in the driver. It will happen automatically. Adjust the code to suit - we will still use manual mode in SPL.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/spi/rk_spi.c +6 -3
index 62434be..2b58393 100644
@@ -182,13 +182,15 @@ static int rockchip_spi_probe(struct udevice *bus)
 static int rockchip_spi_claim_bus(struct udevice *dev)
 {
 	struct udevice *bus = dev->parent;
-	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
 	struct rockchip_spi_priv *priv = dev_get_priv(bus);
 	struct rockchip_spi *regs = priv->regs;
-	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 	u8 spi_dfs, spi_tf;
 	uint ctrlr0;
+#if !CONFIG_IS_ENABLED(PINCTRL_FULL)
+	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
+	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 	int ret;
+#endif
 
 	/* Disable the SPI hardware */
 	rkspi_enable_chip(regs, 0);
@@ -249,12 +251,13 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 	ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
 
 	writel(ctrlr0, &regs->ctrlr0);
-
+#if !CONFIG_IS_ENABLED(PINCTRL_FULL)
 	ret = pinctrl_request(plat->pinctrl, plat->periph_id, slave_plat->cs);
 	if (ret) {
 		debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
 		return ret;
 	}
+#endif
 
 	return 0;
 }
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#41 lore raw

PATCH v9 20/49 rockchip: spi: Avoid setting the pinctrl twice

Quoted 4 lines · Simon Glass

If full pinctrl is enabled we don't need to manually set the pinctrl in the driver. It will happen automatically. Adjust the code to suit - we will still use manual mode in SPL.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip.

#42 lore raw

PATCH v9 21/49 rockchip: mmc: Update the driver to use the new clock ID

In reply to Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk_rk3288.c +1 -1
index fdc5347..d294788 100644
@@ -541,8 +541,8 @@ static ulong rk3288_get_periph_rate(struct udevice *dev, int periph)
 	gclk_rate = clk_get_rate(gclk);
 	switch (periph) {
 	case HCLK_EMMC:
+	case HCLK_SDMMC:
 	case HCLK_SDIO0:
-	case HCLK_SDIO1:
 		new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, periph);
 		break;
 	case SCLK_SPI0:
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#43 lore raw

PATCH v9 21/49 rockchip: mmc: Update the driver to use the new clock ID

Quoted 10 lines · Simon Glass

We can use the new clk_get_by_index() function to get the correct clock.

---

Changes in v9: None
Changes in v2: None

 drivers/clk/clk_rk3288.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-rockchip.

#44 lore raw

PATCH v9 22/49 rockchip: pinctrl: Add a full pinctrl driver

In reply to Simon Glass

We can make use of the device tree to configure pinctrl settings. Add this support for the driver so we can use it in U-Boot proper.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 230 +++++++++++++++++++++++++++++-
 1 file changed, 229 insertions(+), 1 deletion(-)
drivers/pinctrl/rockchip/pinctrl_rk3288.c +229 -1
index ec3c4fe..0e7721e 100644
@@ -24,8 +24,103 @@ DECLARE_GLOBAL_DATA_PTR;
 struct rk3288_pinctrl_priv {
 	struct rk3288_grf *grf;
 	struct rk3288_pmu *pmu;
+	int num_banks;
 };
 
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY		BIT(0)
+#define IOMUX_WIDTH_4BIT	BIT(1)
+#define IOMUX_SOURCE_PMU	BIT(2)
+#define IOMUX_UNROUTED		BIT(3)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ *	    an initial offset value the relevant source offset can be reset
+ *	    to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+	u8 type;
+	s16 offset;
+};
+
+/**
+ * @reg: register offset of the gpio bank
+ * @nr_pins: number of pins in this bank
+ * @bank_num: number of the bank, to account for holes
+ * @name: name of the bank
+ * @iomux: array describing the 4 iomux sources of the bank
+ */
+struct rockchip_pin_bank {
+	u16 reg;
+	u8 nr_pins;
+	u8 bank_num;
+	char *name;
+	struct rockchip_iomux iomux[4];
+};
+
+#define PIN_BANK(id, pins, label)			\
+	{						\
+		.bank_num	= id,			\
+		.nr_pins	= pins,			\
+		.name		= label,		\
+		.iomux		= {			\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+		},					\
+	}
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.iomux		= {					\
+			{ .type = iom0, .offset = -1 },			\
+			{ .type = iom1, .offset = -1 },			\
+			{ .type = iom2, .offset = -1 },			\
+			{ .type = iom3, .offset = -1 },			\
+		},							\
+	}
+
+#ifndef CONFIG_SPL_BUILD
+static struct rockchip_pin_bank rk3288_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_UNROUTED
+			    ),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
+					     IOMUX_UNROUTED,
+					     IOMUX_UNROUTED,
+					     0
+			    ),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     0,
+					     0
+			    ),
+	PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
+					     0,
+					     0,
+					     IOMUX_UNROUTED
+			    ),
+	PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
+	PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
+					     0,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_UNROUTED
+			    ),
+	PIN_BANK(8, 16, "gpio8"),
+};
+#endif
+
 static void pinctrl_rk3288_pwm_config(struct rk3288_grf *grf, int pwm_id)
 {
 	switch (pwm_id) {
@@ -410,7 +505,106 @@ static int rk3288_pinctrl_set_state_simple(struct udevice *dev,
 	return rk3288_pinctrl_request(dev, func, 0);
 }
 
+#ifndef CONFIG_SPL_BUILD
+static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
+				   int muxval, int flags)
+{
+	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+	struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum];
+	uint shift, muxnum, ind = index;
+	u32 *addr;
+
+	debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
+	for (muxnum = 0; muxnum < 4; muxnum++) {
+		struct rockchip_iomux *mux = &bank->iomux[muxnum];
+		uint mask;
+
+		if (ind >= 8) {
+			ind -= 8;
+			continue;
+		}
+
+		if (mux->type & IOMUX_SOURCE_PMU)
+			addr = priv->pmu->gpio0_iomux;
+		else
+			addr = (u32 *)priv->grf - 4;
+		addr += mux->offset;
+		shift = ind & 7;
+		if (mux->type & IOMUX_WIDTH_4BIT) {
+			mask = 0xf;
+			shift *= 4;
+			if (shift >= 16) {
+				shift -= 16;
+				addr++;
+			}
+		} else {
+			mask = 3;
+			shift *= 2;
+		}
+
+		debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
+		      mask, shift);
+		rk_clrsetreg(addr, mask << shift, muxval << shift);
+		break;
+	}
+	if (flags) {
+		uint val = 0;
+
+		if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
+			val = 1;
+		else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
+			val = 2;
+		shift = (index & 7) * 2;
+		ind = index >> 3;
+		if (banknum == 0)
+			addr = &priv->pmu->gpio0pull[ind];
+		else
+			addr = &priv->grf->gpio1_p[banknum - 1][ind];
+		debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
+		      shift);
+		rk_clrsetreg(addr, 3 << shift, val << shift);
+	}
+
+	return 0;
+}
+
+static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+	const void *blob = gd->fdt_blob;
+	int pcfg_node, ret, flags, count, i;
+	u32 cell[40], *ptr;
+
+	debug("%s: %s %s\n", __func__, dev->name, config->name);
+	ret = fdtdec_get_int_array_count(blob, config->of_offset,
+					 "rockchip,pins", cell,
+					 ARRAY_SIZE(cell));
+	if (ret < 0) {
+		debug("%s: bad array %d\n", __func__, ret);
+		return -EINVAL;
+	}
+	count = ret;
+	for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
+		pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
+		if (pcfg_node < 0)
+			return -EINVAL;
+		flags = pinctrl_decode_pin_config(blob, pcfg_node);
+		if (flags < 0)
+			return flags;
+
+		ret = rk3288_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
+					      flags);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif
+
 static struct pinctrl_ops rk3288_pinctrl_ops = {
+#ifndef CONFIG_SPL_BUILD
+	.set_state	= rk3288_pinctrl_set_state,
+#endif
 	.set_state_simple	= rk3288_pinctrl_set_state_simple,
 	.request	= rk3288_pinctrl_request,
 	.get_periph_id	= rk3288_pinctrl_get_periph_id,
@@ -422,15 +616,49 @@ static int rk3288_pinctrl_bind(struct udevice *dev)
 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
+#ifndef CONFIG_SPL_BUILD
+static int rk3288_pinctrl_parse_tables(struct rk3288_pinctrl_priv *priv,
+				       struct rockchip_pin_bank *banks,
+				       int count)
+{
+	struct rockchip_pin_bank *bank;
+	uint reg, muxnum, banknum;
+
+	reg = 0;
+	for (banknum = 0; banknum < count; banknum++) {
+		bank = &banks[banknum];
+		bank->reg = reg;
+		debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
+		for (muxnum = 0; muxnum < 4; muxnum++) {
+			struct rockchip_iomux *mux = &bank->iomux[muxnum];
+
+			if (!(mux->type & IOMUX_UNROUTED))
+				mux->offset = reg;
+			if (mux->type & IOMUX_WIDTH_4BIT)
+				reg += 2;
+			else
+				reg += 1;
+		}
+	}
+
+	return 0;
+}
+#endif
+
 static int rk3288_pinctrl_probe(struct udevice *dev)
 {
 	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+	int ret = 0;
 
 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 	priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
 	debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
+#ifndef CONFIG_SPL_BUILD
+	ret = rk3288_pinctrl_parse_tables(priv, rk3288_pin_banks,
+					  ARRAY_SIZE(rk3288_pin_banks));
+#endif
 
-	return 0;
+	return ret;
 }
 
 static const struct udevice_id rk3288_pinctrl_ids[] = {
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#45 lore raw

PATCH v9 22/49 rockchip: pinctrl: Add a full pinctrl driver

Quoted 11 lines · Simon Glass

We can make use of the device tree to configure pinctrl settings. Add this support for the driver so we can use it in U-Boot proper.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 230 +++++++++++++++++++++++++++++-
 1 file changed, 229 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

#46 lore raw

PATCH v9 23/49 rockchip: Move firefly and jerry to use the full pinctrl

In reply to Simon Glass

Use the full pinctrl driver in U-Boot proper.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 1 -
 configs/firefly-rk3288_defconfig   | 1 -
 2 files changed, 2 deletions(-)
configs/chromebook_jerry_defconfig +0 -1
index 5535105..1e5edc9 100644
@@ -29,7 +29,6 @@ CONFIG_RESET=y
 CONFIG_DM_MMC=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_FULL is not set
 CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
 CONFIG_ROCKCHIP_PINCTRL=y
configs/firefly-rk3288_defconfig +0 -1
index 5b26a3d..7d8ca6c 100644
@@ -27,7 +27,6 @@ CONFIG_RESET=y
 CONFIG_DM_MMC=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_FULL is not set
 CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
 CONFIG_ROCKCHIP_PINCTRL=y
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#47 lore raw

PATCH v9 23/49 rockchip: Move firefly and jerry to use the full pinctrl

Quoted 11 lines · Simon Glass

Use the full pinctrl driver in U-Boot proper.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 1 -
 configs/firefly-rk3288_defconfig   | 1 -
 2 files changed, 2 deletions(-)

Applied to u-boot-rockchip.

#48 lore raw

PATCH v9 24/49 rockchip: jerry: Enable the RK808 PMIC and regulator

In reply to Simon Glass

Enable this PMIC and regulator, which is used on jerry.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 2 ++
 1 file changed, 2 insertions(+)
configs/chromebook_jerry_defconfig +2 -0
index 1e5edc9..a0af6ec 100644
@@ -34,8 +34,10 @@ CONFIG_SPL_PINCTRL=y
 CONFIG_ROCKCHIP_PINCTRL=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_ACT8846=y
+CONFIG_PMIC_RK808=y
 CONFIG_DM_REGULATOR=y
 CONFIG_REGULATOR_ACT8846=y
+CONFIG_REGULATOR_RK808=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
 CONFIG_DEBUG_UART=y
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#49 lore raw

PATCH v9 24/49 rockchip: jerry: Enable the RK808 PMIC and regulator

Quoted 10 lines · Simon Glass

Enable this PMIC and regulator, which is used on jerry.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 2 ++
 1 file changed, 2 insertions(+)

Applied to u-boot-rockchip.

#50 lore raw

PATCH v9 25/49 rockchip: Disable simple-bus in SPL for firefly-rk3288, jerry

In reply to Simon Glass

This is not needed for booting, so drop it from SPL to save about 300 bytes.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 1 +
 configs/firefly-rk3288_defconfig   | 1 +
 2 files changed, 2 insertions(+)
configs/chromebook_jerry_defconfig +1 -0
index a0af6ec..99f6161 100644
@@ -17,6 +17,7 @@ CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_SPL_SYSCON=y
+# CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
configs/firefly-rk3288_defconfig +1 -0
index 7d8ca6c..d8db532 100644
@@ -17,6 +17,7 @@ CONFIG_REGMAP=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
 CONFIG_SPL_SYSCON=y
+# CONFIG_SPL_SIMPLE_BUS is not set
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#51 lore raw

PATCH v9 25/49 rockchip: Disable simple-bus in SPL for firefly-rk3288, jerry

Quoted 11 lines · Simon Glass

This is not needed for booting, so drop it from SPL to save about 300 bytes.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 1 +
 configs/firefly-rk3288_defconfig   | 1 +
 2 files changed, 2 insertions(+)

Applied to u-boot-rockchip.

#52 lore raw

PATCH v9 26/49 rockchip: jerry: Drop unused options

In reply to Simon Glass

To reduce the SPL image size, drop the LED features. Jerry does not have an LED and we can leave out GPIO support also.

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 5 -----
 include/configs/chromebook_jerry.h | 2 ++
 2 files changed, 2 insertions(+), 5 deletions(-)
configs/chromebook_jerry_defconfig +0 -5
index 99f6161..ceec6f5 100644
@@ -22,9 +22,6 @@ CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
-CONFIG_LED=y
-CONFIG_SPL_LED=y
-CONFIG_LED_GPIO=y
 CONFIG_PWRSEQ=y
 CONFIG_RESET=y
 CONFIG_DM_MMC=y
@@ -34,10 +31,8 @@ CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
 CONFIG_ROCKCHIP_PINCTRL=y
 CONFIG_DM_PMIC=y
-CONFIG_PMIC_ACT8846=y
 CONFIG_PMIC_RK808=y
 CONFIG_DM_REGULATOR=y
-CONFIG_REGULATOR_ACT8846=y
 CONFIG_REGULATOR_RK808=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
include/configs/chromebook_jerry.h +2 -0
index e29d776..78c06af 100644
@@ -15,4 +15,6 @@
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPI_FLASH_GIGADEVICE
 
+#undef CONFIG_SPL_GPIO_SUPPORT
+
 #endif
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#53 lore raw

PATCH v9 26/49 rockchip: jerry: Drop unused options

Quoted 4 lines · Simon Glass

To reduce the SPL image size, drop the LED features. Jerry does not have an LED and we can leave out GPIO support also.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 configs/chromebook_jerry_defconfig | 5 -----
 include/configs/chromebook_jerry.h | 2 ++
 2 files changed, 2 insertions(+), 5 deletions(-)

Applied to u-boot-rockchip.

#54 lore raw

PATCH v9 27/49 gpio: Allow 's' as an abbreviation for 'status'

In reply to Simon Glass

The 'gpio' command allows abbreviations for most subcommands. Allow them for 'status' also.

---

Changes in v9: None
Changes in v2: None

 common/cmd_gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
common/cmd_gpio.c +1 -1
index 65d6df4..bb0f63a 100644
@@ -141,7 +141,7 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 	if (argc > 0)
 		str_gpio = *argv;
-	if (!strcmp(str_cmd, "status")) {
+	if (!strncmp(str_cmd, "status", 1)) {
 		/* Support deprecated gpio_status() */
 #ifdef gpio_status
 		gpio_status();
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#55 lore raw

PATCH v9 27/49 gpio: Allow 's' as an abbreviation for 'status'

Quoted 11 lines · Simon Glass

The 'gpio' command allows abbreviations for most subcommands. Allow them for 'status' also.

---

Changes in v9: None
Changes in v2: None

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

Applied to u-boot-rockchip.

#56 lore raw

PATCH v9 28/49 cros_ec: Disable the Chrome OS EC in SPL

In reply to Simon Glass

This is not used in SPL so don't allow it to be built there, even if I2C is enabled in SPL.

---

Changes in v9: None
Changes in v2: None

 drivers/misc/Makefile | 2 ++
 1 file changed, 2 insertions(+)
drivers/misc/Makefile +2 -0
index fc8eb6f..cd4846b 100644
@@ -10,11 +10,13 @@ obj-$(CONFIG_ALI152X) += ali512x.o
 obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
 obj-$(CONFIG_DS4510)  += ds4510.o
 obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
+ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
 obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
 obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
 obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
+endif
 obj-$(CONFIG_FSL_DEBUG_SERVER) += fsl_debug_server.o
 obj-$(CONFIG_FSL_IIM) += fsl_iim.o
 obj-$(CONFIG_GPIO_LED) += gpio_led.o
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#57 lore raw

PATCH v9 28/49 cros_ec: Disable the Chrome OS EC in SPL

Quoted 11 lines · Simon Glass

This is not used in SPL so don't allow it to be built there, even if I2C is enabled in SPL.

---

Changes in v9: None
Changes in v2: None

 drivers/misc/Makefile | 2 ++
 1 file changed, 2 insertions(+)

Applied to u-boot-rockchip.

#58 lore raw

PATCH v9 29/49 dm: i2c: Allow muxes to be enabled for SPL separately

In reply to Simon Glass

Since I2C muxes are seldom needed in SPL, and the code for this increases the size somewhat, add a separate option to enable I2C muxes for SPL.

---

Changes in v9: None
Changes in v2: None

 drivers/i2c/Makefile       | 4 ++--
 drivers/i2c/muxes/Kconfig  | 9 +++++++++
 drivers/i2c/muxes/Makefile | 2 +-
 3 files changed, 12 insertions(+), 3 deletions(-)
drivers/i2c/Makefile +2 -2
index 811ad9b..bbbc0dc 100644
@@ -7,8 +7,8 @@
 obj-$(CONFIG_DM_I2C) += i2c-uclass.o
 obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o
 obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o
-obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
-obj-$(CONFIG_I2C_CROS_EC_LDO) += cros_ec_ldo.o
+obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
+obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o
 
 obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
 obj-$(CONFIG_I2C_MV) += mv_i2c.o
drivers/i2c/muxes/Kconfig +9 -0
index 913093d..f959d9d 100644
@@ -7,6 +7,15 @@ config I2C_MUX
 	  bus select is handled automatically when that bus is accessed,
 	  using a suitable I2C MUX driver.
 
+config SPL_I2C_MUX
+	bool "Support I2C multiplexers on SPL"
+	depends on I2C_MUX
+	help
+	  This enables I2C buses to be multiplexed, so that you can select
+	  one of several buses using some sort of control mechanism. The
+	  bus select is handled automatically when that bus is accessed,
+	  using a suitable I2C MUX driver.
+
 config I2C_ARB_GPIO_CHALLENGE
 	bool "GPIO-based I2C arbitration"
 	depends on I2C_MUX
drivers/i2c/muxes/Makefile +1 -1
index 612cc27..47c1240 100644
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
-obj-$(CONFIG_I2C_MUX) += i2c-mux-uclass.o
+obj-$(CONFIG_$(SPL_)I2C_MUX) += i2c-mux-uclass.o
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#59 lore raw

PATCH v9 29/49 dm: i2c: Allow muxes to be enabled for SPL separately

Hello Simon,

Am 22.01.2016 um 03:43 schrieb Simon Glass:

Quoted 6 lines

Since I2C muxes are seldom needed in SPL, and the code for this increases the size somewhat, add a separate option to enable I2C muxes for SPL.

---

Quoted 7 lines

Changes in v9: None
Changes in v2: None

  drivers/i2c/Makefile       | 4 ++--
  drivers/i2c/muxes/Kconfig  | 9 +++++++++
  drivers/i2c/muxes/Makefile | 2 +-
  3 files changed, 12 insertions(+), 3 deletions(-)

Thanks!

bye,
Heiko

Quoted 47 lines
drivers/i2c/Makefile +2 -2
index 811ad9b..bbbc0dc 100644
@@ -7,8 +7,8 @@
  obj-$(CONFIG_DM_I2C) += i2c-uclass.o
  obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o
  obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o
-obj-$(CONFIG_I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
-obj-$(CONFIG_I2C_CROS_EC_LDO) += cros_ec_ldo.o
+obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
+obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o
 
  obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
  obj-$(CONFIG_I2C_MV) += mv_i2c.o
drivers/i2c/muxes/Kconfig +9 -0
index 913093d..f959d9d 100644
@@ -7,6 +7,15 @@ config I2C_MUX
  	  bus select is handled automatically when that bus is accessed,
  	  using a suitable I2C MUX driver.
 
+config SPL_I2C_MUX
+	bool "Support I2C multiplexers on SPL"
+	depends on I2C_MUX
+	help
+	  This enables I2C buses to be multiplexed, so that you can select
+	  one of several buses using some sort of control mechanism. The
+	  bus select is handled automatically when that bus is accessed,
+	  using a suitable I2C MUX driver.
+
  config I2C_ARB_GPIO_CHALLENGE
  	bool "GPIO-based I2C arbitration"
  	depends on I2C_MUX
drivers/i2c/muxes/Makefile +1 -1
index 612cc27..47c1240 100644
@@ -4,4 +4,4 @@
  # SPDX-License-Identifier:	GPL-2.0+
  #
  obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
-obj-$(CONFIG_I2C_MUX) += i2c-mux-uclass.o
+obj-$(CONFIG_$(SPL_)I2C_MUX) += i2c-mux-uclass.o
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#60 lore raw

PATCH v9 29/49 dm: i2c: Allow muxes to be enabled for SPL separately

Quoted 19 lines · Heiko Schocher

Hello Simon,

Am 22.01.2016 um 03:43 schrieb Simon Glass:

Quoted 7 lines

Since I2C muxes are seldom needed in SPL, and the code for this increases the size somewhat, add a separate option to enable I2C muxes for SPL.

---

Quoted 7 lines

Changes in v9: None
Changes in v2: None

  drivers/i2c/Makefile       | 4 ++--
  drivers/i2c/muxes/Kconfig  | 9 +++++++++
  drivers/i2c/muxes/Makefile | 2 +-
  3 files changed, 12 insertions(+), 3 deletions(-)
Quoted 3 lines

Thanks!

Applied to u-boot-rockchip.

#61 lore raw

PATCH v9 30/49 spi: Correct device tree usage in spi_flash_decode_fdt()

In reply to Simon Glass

This function currently searches the entire device tree for a node that it thinks is relevant. But the node is known and is passed in. Correct the code and enable it only with driver model, since only driver-model boards will use it.

This avoids bringing in a large number of strings from fdtdec.

---

Changes in v9: None
Changes in v2: None

 drivers/mtd/spi/spi_flash.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/mtd/spi/spi_flash.c +3 -6
index a567414..8a60c72 100644
@@ -939,14 +939,10 @@ static int set_quad_mode(struct spi_flash *flash, u8 idcode0)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
 {
+#ifdef CONFIG_DM_SPI_FLASH
 	fdt_addr_t addr;
 	fdt_size_t size;
-	int node;
-
-	/* If there is no node, do nothing */
-	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
-	if (node < 0)
-		return 0;
+	int node = flash->dev->of_offset;
 
 	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
 	if (addr == FDT_ADDR_T_NONE) {
@@ -959,6 +955,7 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
 		return -1;
 	}
 	flash->memory_map = map_sysmem(addr, size);
+#endif
 
 	return 0;
 }
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#62 lore raw

PATCH v9 30/49 spi: Correct device tree usage in spi_flash_decode_fdt()

Quoted 7 lines · Simon Glass

This function currently searches the entire device tree for a node that it thinks is relevant. But the node is known and is passed in. Correct the code and enable it only with driver model, since only driver-model boards will use it.

This avoids bringing in a large number of strings from fdtdec.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/mtd/spi/spi_flash.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

Applied to u-boot-rockchip.

#63 lore raw

PATCH v9 31/49 dm: power: Allow regulators to be omitted from SPL

In reply to Simon Glass

For some boards the pmic interface is useful but the regulator interface (which comes with it) is too large. Allow them to be separated such that SPL can decide which it needs.

---

Changes in v9: None
Changes in v2: None

 drivers/power/pmic/Kconfig       | 21 +++++++++++++++++++++
 drivers/power/pmic/pmic-uclass.c |  2 ++
 drivers/power/regulator/Kconfig  |  9 +++++++++
 drivers/power/regulator/Makefile |  4 ++--
 4 files changed, 34 insertions(+), 2 deletions(-)
drivers/power/pmic/Kconfig +21 -0
index 8be3c07..7f69ae1 100644
@@ -10,6 +10,27 @@ config DM_PMIC
 	- 'drivers/power/pmic/pmic-uclass.c'
 	- 'include/power/pmic.h'
 
+config PMIC_CHILDREN
+	bool "Allow child devices for PMICs"
+	depends on DM_PMIC
+	default y
+	---help---
+	This allows PMICs to support child devices (such as regulators) in
+	SPL. This adds quite a bit of code so if you are not using this
+	feature you can turn it off. Most likely you should turn it on for
+	U-Boot proper.
+
+config SPL_PMIC_CHILDREN
+	bool "Allow child devices for PMICs in SPL"
+	depends on DM_PMIC
+	default y
+	---help---
+	This allows PMICs to support child devices (such as regulators) in
+	SPL. This adds quite a bit of code so if you are not using this
+	feature you can turn it off. In this case you may need a 'back door'
+	to call your regulator code (e.g. see rk808.c for direct functions
+	for use in SPL).
+
 config PMIC_ACT8846
 	bool "Enable support for the active-semi 8846 PMIC"
 	depends on DM_PMIC && DM_I2C
drivers/power/pmic/pmic-uclass.c +2 -0
index 49709f3..8b19998 100644
@@ -18,6 +18,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
 int pmic_bind_children(struct udevice *pmic, int offset,
 		       const struct pmic_child_info *child_info)
 {
@@ -84,6 +85,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
 	debug("Bound: %d childs for PMIC: '%s'\n", bind_count, pmic->name);
 	return bind_count;
 }
+#endif
 
 int pmic_get(const char *name, struct udevice **devp)
 {
drivers/power/regulator/Kconfig +9 -0
index 8f638a9..465ff3f 100644
@@ -16,6 +16,15 @@ config DM_REGULATOR
 	for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_node()
 	otherwise. Detailed information can be found in the header file.
 
+config SPL_DM_REGULATOR
+	bool "Enable regulators for SPL"
+	depends on DM_REGULATOR
+	---help---
+	Regulators are seldom needed in SPL. Even if they are accessed, some
+	code space can be saved by accessing the PMIC registers directly.
+	Enable this option if you need regulators in SPL and can cope with
+	the extra code size.
+
 config REGULATOR_ACT8846
 	bool "Enable driver for ACT8846 regulator"
 	depends on DM_REGULATOR && PMIC_ACT8846
drivers/power/regulator/Makefile +2 -2
index 0d18c2b..1590d85 100644
@@ -5,11 +5,11 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR) += regulator-uclass.o
 obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
 obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
 obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o
-obj-$(CONFIG_DM_REGULATOR_FIXED) += fixed.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_FIXED) += fixed.o
 obj-$(CONFIG_REGULATOR_RK808) += rk808.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#64 lore raw

PATCH v9 31/49 dm: power: Allow regulators to be omitted from SPL

Quoted 7 lines · Simon Glass

For some boards the pmic interface is useful but the regulator interface (which comes with it) is too large. Allow them to be separated such that SPL can decide which it needs.

---

Quoted 8 lines

Changes in v9: None
Changes in v2: None

 drivers/power/pmic/Kconfig       | 21 +++++++++++++++++++++
 drivers/power/pmic/pmic-uclass.c |  2 ++
 drivers/power/regulator/Kconfig  |  9 +++++++++
 drivers/power/regulator/Makefile |  4 ++--
 4 files changed, 34 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

#65 lore raw

PATCH v9 32/49 dm: pinctrl: Add a way for a GPIO driver to obtain a pin function

In reply to Simon Glass

GPIO drivers want to be able to show if a pin is enabled for input, output, or is being used by another function. Some drivers can easily find this and the code is included in the driver. For some SoCs this is more complex. Conceptually this should be handled by pinctrl rather than GPIO. Most pinctrl drivers will have this feature anyway.

Add a method by which a GPIO driver can obtain the pin mux value given a GPIO reference. This avoids repeating the code in two places.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/pinctrl-uclass.c | 10 ++++++++++
 include/dm/pinctrl.h             | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
drivers/pinctrl/pinctrl-uclass.c +10 -0
index 1acbfaf..ccc5d30 100644
@@ -246,6 +246,16 @@ int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph)
 	return ops->get_periph_id(dev, periph);
 }
 
+int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index)
+{
+	struct pinctrl_ops *ops = pinctrl_get_ops(dev);
+
+	if (!ops->get_gpio_mux)
+		return -ENOSYS;
+
+	return ops->get_gpio_mux(dev, banknum, index);
+}
+
 /**
  * pinconfig_post-bind() - post binding for PINCTRL uclass
  * Recursively bind child nodes as pinconfig devices in case of full pinctrl.
include/dm/pinctrl.h +32 -0
index 5cd4503..0eb4b92 100644
@@ -114,6 +114,22 @@ struct pinctrl_ops {
 	* @return peripheral ID of @periph, or -ENOENT on error
 	*/
 	int (*get_periph_id)(struct udevice *dev, struct udevice *periph);
+
+	/**
+	 * get_gpio_mux() - get the mux value for a particular GPIO
+	 *
+	 * This allows the raw mux value for a GPIO to be obtained. It is
+	 * useful for displaying the function being used by that GPIO, such
+	 * as with the 'gpio' command. This function is internal to the GPIO
+	 * subsystem and should not be used by generic code. Typically it is
+	 * used by a GPIO driver with knowledge of the SoC pinctrl setup.
+	 *
+	* @dev:		Pinctrl device to use
+	* @banknum:	GPIO bank number
+	* @index:	GPIO index within the bank
+	* @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
+	 */
+	int (*get_gpio_mux)(struct udevice *dev, int banknum, int index);
 };
 
 #define pinctrl_get_ops(dev)	((struct pinctrl_ops *)(dev)->driver->ops)
@@ -297,4 +313,20 @@ int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
  */
 int pinctrl_decode_pin_config(const void *blob, int node);
 
+/**
+ * pinctrl_get_gpio_mux() - get the mux value for a particular GPIO
+ *
+ * This allows the raw mux value for a GPIO to be obtained. It is
+ * useful for displaying the function being used by that GPIO, such
+ * as with the 'gpio' command. This function is internal to the GPIO
+ * subsystem and should not be used by generic code. Typically it is
+ * used by a GPIO driver with knowledge of the SoC pinctrl setup.
+ *
+ * @dev:	Pinctrl device to use
+ * @banknum:	GPIO bank number
+ * @index:	GPIO index within the bank
+ * @return mux value (SoC-specific, e.g. 0 for input, 1 for output)
+*/
+int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index);
+
 #endif /* __PINCTRL_H */
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#66 lore raw

PATCH v9 32/49 dm: pinctrl: Add a way for a GPIO driver to obtain a pin function

Quoted 10 lines · Simon Glass

GPIO drivers want to be able to show if a pin is enabled for input, output, or is being used by another function. Some drivers can easily find this and the code is included in the driver. For some SoCs this is more complex. Conceptually this should be handled by pinctrl rather than GPIO. Most pinctrl drivers will have this feature anyway.

Add a method by which a GPIO driver can obtain the pin mux value given a GPIO reference. This avoids repeating the code in two places.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/pinctrl-uclass.c | 10 ++++++++++
 include/dm/pinctrl.h             | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

Applied to u-boot-rockchip.

#67 lore raw

PATCH v9 33/49 dm: core: Export uclass_find_device_by_of_offset()

In reply to Simon Glass

It is sometimes useful to be able to find a device before probing it, perhaps to set up some platform data for it. Allow finding by of_offset also.

---

Changes in v9: None
Changes in v2: None

 drivers/core/uclass.c        |  4 ++--
 include/dm/uclass-internal.h | 16 ++++++++++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)
drivers/core/uclass.c +2 -2
index e1acefe..12095e7 100644
@@ -254,8 +254,8 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 	return -ENODEV;
 }
 
-static int uclass_find_device_by_of_offset(enum uclass_id id, int node,
-					   struct udevice **devp)
+int uclass_find_device_by_of_offset(enum uclass_id id, int node,
+				    struct udevice **devp)
 {
 	struct uclass *uc;
 	struct udevice *dev;
include/dm/uclass-internal.h +16 -0
index b51e1da..ad284b8 100644
@@ -99,6 +99,22 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
 			      bool find_req_seq, struct udevice **devp);
 
 /**
+ * uclass_find_device_by_of_offset() - Find a uclass device by device tree node
+ *
+ * This searches the devices in the uclass for one attached to the given
+ * device tree node.
+ *
+ * The device is NOT probed, it is merely returned.
+ *
+ * @id: ID to look up
+ * @node: Device tree offset to search for (if -ve then -ENODEV is returned)
+ * @devp: Returns pointer to device (there is only one for each node)
+ * @return 0 if OK, -ve on error
+ */
+int uclass_find_device_by_of_offset(enum uclass_id id, int node,
+				    struct udevice **devp);
+
+/**
  * uclass_bind_device() - Associate device with a uclass
  *
  * Connect the device into uclass's list of devices.
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#68 lore raw

PATCH v9 33/49 dm: core: Export uclass_find_device_by_of_offset()

Quoted 5 lines · Simon Glass

It is sometimes useful to be able to find a device before probing it, perhaps to set up some platform data for it. Allow finding by of_offset also.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/core/uclass.c        |  4 ++--
 include/dm/uclass-internal.h | 16 ++++++++++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

#69 lore raw

PATCH v9 34/49 dm: power: Tidy up debugging output and return values

In reply to Simon Glass

The currect PMIC debugging is a little confusing. Adjust it so that it is clear whether the operation succeeded or failed. Also, avoid creating a new error return value when a perfectly good one is already available.

---

Changes in v9: None
Changes in v2: None

 drivers/power/pmic/pmic-uclass.c           | 11 ++++++++---
 drivers/power/pmic/rk808.c                 | 14 ++++++++++----
 drivers/power/regulator/regulator-uclass.c |  2 +-
 3 files changed, 19 insertions(+), 8 deletions(-)
drivers/power/pmic/pmic-uclass.c +8 -3
index 8b19998..7211026 100644
@@ -133,8 +133,9 @@ int pmic_reg_read(struct udevice *dev, uint reg)
 	u8 byte;
 	int ret;
 
+	debug("%s: reg=%x", __func__, reg);
 	ret = pmic_read(dev, reg, &byte, 1);
-	debug("%s: reg=%x, value=%x\n", __func__, reg, byte);
+	debug(", value=%x, ret=%d\n", byte, ret);
 
 	return ret ? ret : byte;
 }
@@ -142,9 +143,13 @@ int pmic_reg_read(struct udevice *dev, uint reg)
 int pmic_reg_write(struct udevice *dev, uint reg, uint value)
 {
 	u8 byte = value;
+	int ret;
+
+	debug("%s: reg=%x, value=%x", __func__, reg, value);
+	ret = pmic_write(dev, reg, &byte, 1);
+	debug(", ret=%d\n", ret);
 
-	debug("%s: reg=%x, value=%x\n", __func__, reg, value);
-	return pmic_write(dev, reg, &byte, 1);
+	return ret;
 }
 
 int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
drivers/power/pmic/rk808.c +10 -4
index 11d5f07..770f471 100644
@@ -30,9 +30,12 @@ static int rk808_reg_count(struct udevice *dev)
 static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
 			  int len)
 {
-	if (dm_i2c_write(dev, reg, buff, len)) {
+	int ret;
+
+	ret = dm_i2c_write(dev, reg, buff, len);
+	if (ret) {
 		debug("write error to device: %p register: %#x!", dev, reg);
-		return -EIO;
+		return ret;
 	}
 
 	return 0;
@@ -40,9 +43,12 @@ static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
 
 static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 {
-	if (dm_i2c_read(dev, reg, buff, len)) {
+	int ret;
+
+	ret = dm_i2c_read(dev, reg, buff, len);
+	if (ret) {
 		debug("read error from device: %p register: %#x!", dev, reg);
-		return -EIO;
+		return ret;
 	}
 
 	return 0;
drivers/power/regulator/regulator-uclass.c +1 -1
index 4241a4c..fec2886 100644
@@ -178,7 +178,7 @@ static void regulator_show(struct udevice *dev, int ret)
 		printf("; set %d uA", uc_pdata->min_uA);
 	printf("; enabling");
 	if (ret)
-		printf(" (ret: %d)\n", ret);
+		printf(" (ret: %d)", ret);
 	printf("\n");
 }
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#70 lore raw

PATCH v9 34/49 dm: power: Tidy up debugging output and return values

Quoted 7 lines · Simon Glass

The currect PMIC debugging is a little confusing. Adjust it so that it is clear whether the operation succeeded or failed. Also, avoid creating a new error return value when a perfectly good one is already available.

---

Quoted 7 lines

Changes in v9: None
Changes in v2: None

 drivers/power/pmic/pmic-uclass.c           | 11 ++++++++---
 drivers/power/pmic/rk808.c                 | 14 ++++++++++----
 drivers/power/regulator/regulator-uclass.c |  2 +-
 3 files changed, 19 insertions(+), 8 deletions(-)

Applied to u-boot-rockchip.

#71 lore raw

PATCH v9 35/49 dm: power: Allow regulators to not implement all operations

In reply to Simon Glass

Some regulators will not implement any operations (e.g. fixed regulators). This is not an error, so allow the autoset process to continue when one of these regulators is found.

---

Changes in v9: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/power/regulator/regulator-uclass.c +2 -0
index fec2886..9fe07f2 100644
@@ -334,6 +334,8 @@ int regulators_enable_boot_on(bool verbose)
 		}
 		if (verbose)
 			regulator_show(dev, ret);
+		if (ret == -ENOSYS)
+			ret = 0;
 	}
 
 	return ret;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#72 lore raw

PATCH v9 35/49 dm: power: Allow regulators to not implement all operations

Quoted 4 lines · Simon Glass

Some regulators will not implement any operations (e.g. fixed regulators). This is not an error, so allow the autoset process to continue when one of these regulators is found.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/power/regulator/regulator-uclass.c | 2 ++
 1 file changed, 2 insertions(+)

Applied to u-boot-rockchip.

#73 lore raw

PATCH v9 36/49 dm: clk: Add a simple version of clk_get_by_index()

In reply to Simon Glass

This function adds quite a bit of code to SPL and we probably don't need all the features in SPL. Add a simple version (for SPL only) to save space.

---

Changes in v9: None
Changes in v2:
- Add an assert for clk_devp

 drivers/clk/clk-uclass.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
drivers/clk/clk-uclass.c +17 -1
index 8a4c568..b483c1e 100644
@@ -67,8 +67,23 @@ ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate)
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp)
 {
-	struct fdtdec_phandle_args args;
 	int ret;
+#ifdef CONFIG_SPL_BUILD
+	u32 cell[2];
+
+	if (index != 0)
+		return -ENOSYS;
+	assert(*clk_devp);
+	ret = uclass_get_device(UCLASS_CLK, 0, clk_devp);
+	if (ret)
+		return ret;
+	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
+				   cell, 2);
+	if (ret)
+		return ret;
+	return cell[1];
+#else
+	struct fdtdec_phandle_args args;
 
 	assert(*clk_devp);
 	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
@@ -87,6 +102,7 @@ int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp)
 		return ret;
 	}
 	return args.args_count > 0 ? args.args[0] : 0;
+#endif
 }
 #endif
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#74 lore raw

PATCH v9 36/49 dm: clk: Add a simple version of clk_get_by_index()

Quoted 4 lines · Simon Glass

This function adds quite a bit of code to SPL and we probably don't need all the features in SPL. Add a simple version (for SPL only) to save space.

Quoted 8 lines

---

Changes in v9: None
Changes in v2:
- Add an assert for clk_devp

 drivers/clk/clk-uclass.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

#75 lore raw

PATCH v9 37/49 rockchip: sdram: Use the rk_clr/setreg() interface

In reply to Simon Glass

Use this function in preference to the macro.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +3 -4
index 09017cc..5da04b9 100644
@@ -400,7 +400,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
 
 	if (n == 1) {
 		setbits_le32(&pctl->ppcfg, 1);
-		writel(RK_SETBITS(1 << (8 + channel)), &grf->soc_con0);
+		rk_setreg(&grf->soc_con0, 1 << (8 + channel));
 		setbits_le32(&msch->ddrtiming, 1 << 31);
 		/* Data Byte disable*/
 		clrbits_le32(&publ->datx8[2].dxgcr, 1);
@@ -410,7 +410,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
 		setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
 	} else {
 		clrbits_le32(&pctl->ppcfg, 1);
-		writel(RK_CLRBITS(1 << (8 + channel)), &grf->soc_con0);
+		rk_clrreg(&grf->soc_con0, 1 << (8 + channel));
 		clrbits_le32(&msch->ddrtiming, 1 << 31);
 		/* Data Byte enable*/
 		setbits_le32(&publ->datx8[2].dxgcr, 1);
@@ -571,8 +571,7 @@ static void dram_all_config(const struct dram_info *dram,
 		dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
 	}
 	writel(sys_reg, &dram->pmu->sys_reg[2]);
-	writel(RK_CLRSETBITS(0x1F, sdram_params->base.stride),
-	       &dram->sgrf->soc_con2);
+	rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
 }
 
 static int sdram_init(const struct dram_info *dram,
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#76 lore raw

PATCH v9 37/49 rockchip: sdram: Use the rk_clr/setreg() interface

Quoted 10 lines · Simon Glass

Use this function in preference to the macro.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

Applied to u-boot-rockchip.

#77 lore raw

PATCH v9 38/49 rockchip: reset: Use the rk_clr/setreg() interface

In reply to Simon Glass

Use this function in preference to the macro.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/reset_rk3288.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-rockchip/rk3288/reset_rk3288.c +2 -2
index 7affd11..bf7540a 100644
@@ -22,11 +22,11 @@ int rk3288_reset_request(struct udevice *dev, enum reset_t type)
 		return PTR_ERR(cru);
 	switch (type) {
 	case RESET_WARM:
-		writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+		rk_clrreg(&cru->cru_mode_con, 0xffff);
 		writel(0xeca8, &cru->cru_glb_srst_snd_value);
 		break;
 	case RESET_COLD:
-		writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+		rk_clrreg(&cru->cru_mode_con, 0xffff);
 		writel(0xfdb9, &cru->cru_glb_srst_fst_value);
 		break;
 	default:
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#78 lore raw

PATCH v9 38/49 rockchip: reset: Use the rk_clr/setreg() interface

Quoted 10 lines · Simon Glass

Use this function in preference to the macro.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/rk3288/reset_rk3288.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

#79 lore raw

PATCH v9 39/49 rockchip: spi: Remember the last speed to avoid re-setting it

In reply to Simon Glass

Rather than changing the clock to the same value on every transaction, remember the last value and don't adjust the clock unless it is necessary.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/spi/rk_spi.c +4 -1
index 2b58393..aaf139d 100644
@@ -44,6 +44,7 @@ struct rockchip_spi_priv {
 	u8 bits_per_word;		/* max 16 bits per word */
 	u8 n_bytes;
 	unsigned int speed_hz;
+	unsigned int last_speed_hz;
 	unsigned int tmode;
 	uint input_rate;
 };
@@ -82,6 +83,7 @@ static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
 	debug("spi speed %u, div %u\n", speed, clk_div);
 
 	writel(clk_div, &priv->regs->baudr);
+	priv->last_speed_hz = speed;
 }
 
 static int rkspi_wait_till_not_busy(struct rockchip_spi *regs)
@@ -212,7 +214,8 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 		return -EPROTONOSUPPORT;
 	}
 
-	rkspi_set_clk(priv, priv->speed_hz);
+	if (priv->speed_hz != priv->last_speed_hz)
+		rkspi_set_clk(priv, priv->speed_hz);
 
 	/* Operation Mode */
 	ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#80 lore raw

PATCH v9 39/49 rockchip: spi: Remember the last speed to avoid re-setting it

Quoted 11 lines · Simon Glass

Rather than changing the clock to the same value on every transaction, remember the last value and don't adjust the clock unless it is necessary.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

#81 lore raw

PATCH v9 40/49 rockchip: spi: Correct the bus init code

In reply to Simon Glass

Two of the init values are created locally so cannot be out of range. The masking is unnecessary and in one case is incorrect. Fix it.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/spi/rk_spi.c +2 -2
index aaf139d..3418f9b 100644
@@ -221,7 +221,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 	ctrlr0 = OMOD_MASTER << OMOD_SHIFT;
 
 	/* Data Frame Size */
-	ctrlr0 |= spi_dfs & DFS_MASK << DFS_SHIFT;
+	ctrlr0 |= spi_dfs << DFS_SHIFT;
 
 	/* set SPI mode 0..3 */
 	if (priv->mode & SPI_CPOL)
@@ -242,7 +242,7 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 	ctrlr0 |= FBM_MSB << FBM_SHIFT;
 
 	/* Byte and Halfword Transform */
-	ctrlr0 |= (spi_tf & HALF_WORD_MASK) << HALF_WORD_TX_SHIFT;
+	ctrlr0 |= spi_tf << HALF_WORD_TX_SHIFT;
 
 	/* Rxd Sample Delay */
 	ctrlr0 |= 0 << RXDSD_SHIFT;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#82 lore raw

PATCH v9 40/49 rockchip: spi: Correct the bus init code

Quoted 11 lines · Simon Glass

Two of the init values are created locally so cannot be out of range. The masking is unnecessary and in one case is incorrect. Fix it.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Applied to u-boot-rockchip.

#83 lore raw

PATCH v9 41/49 rockchip: clk: Make rkclk_get_clk() SoC-specific

In reply to Simon Glass

The current method assumes that clocks are numbered from 0 and we can determine a clock by its number. It is safer to use an ID in the clock's platform data to avoid the situation where another clock is bound before the one we expect.

Move the existing code into rk3036 since it still works there. Add a new implementation for rk3288.

---

Changes in v9: None
Changes in v2: None

 arch/arm/mach-rockchip/Makefile |  1 -
 arch/arm/mach-rockchip/common.c | 28 ----------------------------
 drivers/clk/clk_rk3036.c        | 17 +++++++++++++++++
 drivers/clk/clk_rk3288.c        | 13 +++++++++++++
 4 files changed, 30 insertions(+), 29 deletions(-)
 delete mode 100644 arch/arm/mach-rockchip/common.c
arch/arm/mach-rockchip/Makefile +0 -1
index 1cc4a96..55567cb 100644
@@ -11,6 +11,5 @@ else
 obj-$(CONFIG_ROCKCHIP_RK3288) += board.o
 endif
 obj-y += rk_timer.o
-obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
arch/arm/mach-rockchip/common.c deleted +0 -28
deleted file mode 100644
index fc7ac72..0000000
@@ -1,28 +0,0 @@
-/*
- * (C) Copyright 2015 Google, Inc
- *
- * SPDX-License-Identifier:     GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <fdtdec.h>
-#include <linux/err.h>
-
-void *rockchip_get_cru(void)
-{
-	struct udevice *dev;
-	fdt_addr_t addr;
-	int ret;
-
-	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	addr = dev_get_addr(dev);
-	if (addr == FDT_ADDR_T_NONE)
-		return ERR_PTR(-EINVAL);
-
-	return (void *)addr;
-}
drivers/clk/clk_rk3036.c +17 -0
index dfecc24..bd5f22a 100644
@@ -57,6 +57,23 @@ static inline unsigned int log2(unsigned int value)
 	return fls(value) - 1;
 }
 
+void *rockchip_get_cru(void)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return ERR_PTR(-EINVAL);
+
+	return (void *)addr;
+}
+
 static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
 			 const struct pll_div *div)
 {
drivers/clk/clk_rk3288.c +13 -0
index d294788..5a8f175 100644
@@ -159,6 +159,19 @@ int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp)
 	return -ENODEV;
 }
 
+void *rockchip_get_cru(void)
+{
+	struct rk3288_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rkclk_get_clk(CLK_GENERAL, &dev);
+	if (ret)
+		return ERR_PTR(ret);
+	priv = dev_get_priv(dev);
+	return priv->cru;
+}
+
 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
 			 const struct pll_div *div)
 {
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#84 lore raw

PATCH v9 41/49 rockchip: clk: Make rkclk_get_clk() SoC-specific

Quoted 14 lines · Simon Glass

The current method assumes that clocks are numbered from 0 and we can determine a clock by its number. It is safer to use an ID in the clock's platform data to avoid the situation where another clock is bound before the one we expect.

Move the existing code into rk3036 since it still works there. Add a new implementation for rk3288.

---

Changes in v9: None
Changes in v2: None

Quoted 6 lines
 arch/arm/mach-rockchip/Makefile |  1 -
 arch/arm/mach-rockchip/common.c | 28 ----------------------------
 drivers/clk/clk_rk3036.c        | 17 +++++++++++++++++
 drivers/clk/clk_rk3288.c        | 13 +++++++++++++
 4 files changed, 30 insertions(+), 29 deletions(-)
 delete mode 100644 arch/arm/mach-rockchip/common.c

Applied to u-boot-rockchip.

#85 lore raw

PATCH v9 42/49 rockchip: pinctrl: Reduce the size for SPL

In reply to Simon Glass

This file has many features that are not needed by SPL. Use #ifdef to remove the unused features and reduce the code size.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/pinctrl/rockchip/pinctrl_rk3288.c +17 -3
index 0e7721e..53b8cf2 100644
@@ -158,6 +158,7 @@ static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
 				GPIO0_C0_MASK << GPIO0_C0_SHIFT,
 				GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT);
 		break;
+#ifndef CONFIG_SPL_BUILD
 	case PERIPH_ID_I2C1:
 		rk_clrsetreg(&grf->gpio8a_iomux,
 			     GPIO8A4_MASK << GPIO8A4_SHIFT |
@@ -194,12 +195,14 @@ static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
 			     GPIO7C4_MASK << GPIO7C4_SHIFT,
 			     GPIO7C4_I2C5HDMI_SCL << GPIO7C4_SHIFT);
 		break;
+#endif
 	default:
 		debug("i2c id = %d iomux error!\n", i2c_id);
 		break;
 	}
 }
 
+#ifndef CONFIG_SPL_BUILD
 static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id)
 {
 	switch (lcd_id) {
@@ -219,11 +222,13 @@ static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id)
 		break;
 	}
 }
+#endif
 
 static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf,
 				     enum periph_id spi_id, int cs)
 {
 	switch (spi_id) {
+#ifndef CONFIG_SPL_BUILD
 	case PERIPH_ID_SPI0:
 		switch (cs) {
 		case 0:
@@ -260,6 +265,7 @@ static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf,
 			     GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT |
 			     GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT);
 		break;
+#endif
 	case PERIPH_ID_SPI2:
 		switch (cs) {
 		case 0:
@@ -297,6 +303,7 @@ err:
 static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
 {
 	switch (uart_id) {
+#ifndef CONFIG_SPL_BUILD
 	case PERIPH_ID_UART_BT:
 		rk_clrsetreg(&grf->gpio4c_iomux,
 			     GPIO4C3_MASK << GPIO4C3_SHIFT |
@@ -319,6 +326,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
 			     GPIO5B1_UART1BB_SOUT << GPIO5B1_SHIFT |
 			     GPIO5B0_UART1BB_SIN << GPIO5B0_SHIFT);
 		break;
+#endif
 	case PERIPH_ID_UART_DBG:
 		rk_clrsetreg(&grf->gpio7ch_iomux,
 			     GPIO7C7_MASK << GPIO7C7_SHIFT |
@@ -326,6 +334,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
 			     GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
 			     GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
 		break;
+#ifndef CONFIG_SPL_BUILD
 	case PERIPH_ID_UART_GPS:
 		rk_clrsetreg(&grf->gpio7b_iomux,
 			     GPIO7B2_MASK << GPIO7B2_SHIFT |
@@ -349,6 +358,7 @@ static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
 			     GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT |
 			     GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT);
 		break;
+#endif
 	default:
 		debug("uart id = %d iomux error!\n", uart_id);
 		break;
@@ -393,6 +403,7 @@ static void pinctrl_rk3288_sdmmc_config(struct rk3288_grf *grf, int mmc_id)
 	}
 }
 
+#ifndef CONFIG_SPL_BUILD
 static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
 {
 	switch (hdmi_id) {
@@ -407,6 +418,7 @@ static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
 		break;
 	}
 }
+#endif
 
 static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
 {
@@ -441,17 +453,19 @@ static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
 	case PERIPH_ID_UART4:
 		pinctrl_rk3288_uart_config(priv->grf, func);
 		break;
+#ifndef CONFIG_SPL_BUILD
 	case PERIPH_ID_LCDC0:
 	case PERIPH_ID_LCDC1:
 		pinctrl_rk3288_lcdc_config(priv->grf, func);
 		break;
+	case PERIPH_ID_HDMI:
+		pinctrl_rk3288_hdmi_config(priv->grf, func);
+		break;
+#endif
 	case PERIPH_ID_SDMMC0:
 	case PERIPH_ID_SDMMC1:
 		pinctrl_rk3288_sdmmc_config(priv->grf, func);
 		break;
-	case PERIPH_ID_HDMI:
-		pinctrl_rk3288_hdmi_config(priv->grf, func);
-		break;
 	default:
 		return -EINVAL;
 	}
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#86 lore raw

PATCH v9 42/49 rockchip: pinctrl: Reduce the size for SPL

Quoted 11 lines · Simon Glass

This file has many features that are not needed by SPL. Use #ifdef to remove the unused features and reduce the code size.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

Applied to u-boot-rockchip.

#87 lore raw

PATCH v9 43/49 rockchip: pinctrl: Implement the get_gpio_mux() method

In reply to Simon Glass

Implement this so that the GPIO command will be able to report whether a GPIO is used for input or output.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 68 +++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 16 deletions(-)
drivers/pinctrl/rockchip/pinctrl_rk3288.c +52 -16
index 53b8cf2..8356786 100644
@@ -520,18 +520,16 @@ static int rk3288_pinctrl_set_state_simple(struct udevice *dev,
 }
 
 #ifndef CONFIG_SPL_BUILD
-static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
-				   int muxval, int flags)
+int rk3288_pinctrl_get_pin_info(struct rk3288_pinctrl_priv *priv,
+				int banknum, int ind, u32 **addrp, uint *shiftp,
+				uint *maskp)
 {
-	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
 	struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum];
-	uint shift, muxnum, ind = index;
+	uint muxnum;
 	u32 *addr;
 
-	debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
 	for (muxnum = 0; muxnum < 4; muxnum++) {
 		struct rockchip_iomux *mux = &bank->iomux[muxnum];
-		uint mask;
 
 		if (ind >= 8) {
 			ind -= 8;
@@ -543,24 +541,61 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
 		else
 			addr = (u32 *)priv->grf - 4;
 		addr += mux->offset;
-		shift = ind & 7;
+		*shiftp = ind & 7;
 		if (mux->type & IOMUX_WIDTH_4BIT) {
-			mask = 0xf;
-			shift *= 4;
-			if (shift >= 16) {
-				shift -= 16;
+			*maskp = 0xf;
+			*shiftp *= 4;
+			if (*shiftp >= 16) {
+				*shiftp -= 16;
 				addr++;
 			}
 		} else {
-			mask = 3;
-			shift *= 2;
+			*maskp = 3;
+			*shiftp *= 2;
 		}
 
 		debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
-		      mask, shift);
-		rk_clrsetreg(addr, mask << shift, muxval << shift);
-		break;
+		      *maskp, *shiftp);
+		*addrp = addr;
+		return 0;
 	}
+
+	return -EINVAL;
+}
+
+static int rk3288_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
+				       int index)
+{
+	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+	uint shift;
+	uint mask;
+	u32 *addr;
+	int ret;
+
+	ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+					  &mask);
+	if (ret)
+		return ret;
+	return (readl(addr) & mask) >> shift;
+}
+
+static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
+				   int muxval, int flags)
+{
+	struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
+	uint shift, ind = index;
+	uint mask;
+	u32 *addr;
+	int ret;
+
+	debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
+	ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+					  &mask);
+	if (ret)
+		return ret;
+	rk_clrsetreg(addr, mask << shift, muxval << shift);
+
+	/* Handle pullup/pulldown */
 	if (flags) {
 		uint val = 0;
 
@@ -618,6 +653,7 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 static struct pinctrl_ops rk3288_pinctrl_ops = {
 #ifndef CONFIG_SPL_BUILD
 	.set_state	= rk3288_pinctrl_set_state,
+	.get_gpio_mux	= rk3288_pinctrl_get_gpio_mux,
 #endif
 	.set_state_simple	= rk3288_pinctrl_set_state_simple,
 	.request	= rk3288_pinctrl_request,
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#88 lore raw

PATCH v9 43/49 rockchip: pinctrl: Implement the get_gpio_mux() method

Quoted 11 lines · Simon Glass

Implement this so that the GPIO command will be able to report whether a GPIO is used for input or output.

---

Changes in v9: None
Changes in v2: None

 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 68 +++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 16 deletions(-)

Applied to u-boot-rockchip.

#89 lore raw

PATCH v9 44/49 rockchip: gpio: Read the GPIO value correctly

In reply to Simon Glass

This function should return 0 or 1, not a mask. Fix it.

---

Changes in v9: None
Changes in v2: None

 drivers/gpio/rk_gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/rk_gpio.c +1 -1
index fbdf9f3..a22e219 100644
@@ -53,7 +53,7 @@ static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset)
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	struct rockchip_gpio_regs *regs = priv->regs;
 
-	return readl(&regs->ext_port) & OFFSET_TO_BIT(offset);
+	return readl(&regs->ext_port) & OFFSET_TO_BIT(offset) ? 1 : 0;
 }
 
 static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset,
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#90 lore raw

PATCH v9 44/49 rockchip: gpio: Read the GPIO value correctly

Quoted 10 lines · Simon Glass

This function should return 0 or 1, not a mask. Fix it.

---

Changes in v9: None
Changes in v2: None

 drivers/gpio/rk_gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Applied to u-boot-rockchip.

#91 lore raw

PATCH v9 45/49 rockchip: gpio: Implement the get_function() method

In reply to Simon Glass

Provide this method so that 'gpio status' works fully. It now shows whether a pin is used for input, output or some other function.

---

Changes in v9: None
Changes in v2: None

 drivers/gpio/rk_gpio.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)
drivers/gpio/rk_gpio.c +36 -4
index a22e219..c62f025 100644
@@ -8,11 +8,16 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
+#include <syscon.h>
 #include <asm/errno.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <dm/pinctrl.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/rk3288-cru.h>
 
 enum {
 	ROCKCHIP_GPIOS_PER_BANK		= 32,
@@ -22,6 +27,8 @@ enum {
 
 struct rockchip_gpio_priv {
 	struct rockchip_gpio_regs *regs;
+	struct udevice *pinctrl;
+	int bank;
 	char name[2];
 };
 
@@ -70,7 +77,25 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset,
 
 static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
 {
-	return -ENOSYS;
+#ifdef CONFIG_SPL_BUILD
+	return -ENODATA;
+#else
+	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
+	struct rockchip_gpio_regs *regs = priv->regs;
+	bool is_output;
+	int ret;
+
+	ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset);
+	if (ret)
+		return ret;
+
+	/* If it's not 0, then it is not a GPIO */
+	if (ret)
+		return GPIOF_FUNC;
+	is_output = readl(&regs->swport_ddr) & OFFSET_TO_BIT(offset);
+
+	return is_output ? GPIOF_OUTPUT : GPIOF_INPUT;
+#endif
 }
 
 static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
@@ -87,13 +112,20 @@ static int rockchip_gpio_probe(struct udevice *dev)
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	char *end;
-	int bank;
+	int ret;
 
+	/* This only supports RK3288 at present */
 	priv->regs = (struct rockchip_gpio_regs *)dev_get_addr(dev);
+	ret = uclass_first_device(UCLASS_PINCTRL, &priv->pinctrl);
+	if (ret)
+		return ret;
+	if (!priv->pinctrl)
+		return -ENODEV;
+
 	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
 	end = strrchr(dev->name, '@');
-	bank = trailing_strtoln(dev->name, end);
-	priv->name[0] = 'A' + bank;
+	priv->bank = trailing_strtoln(dev->name, end);
+	priv->name[0] = 'A' + priv->bank;
 	uc_priv->bank_name = priv->name;
 
 	return 0;
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#92 lore raw

PATCH v9 45/49 rockchip: gpio: Implement the get_function() method

Quoted 11 lines · Simon Glass

Provide this method so that 'gpio status' works fully. It now shows whether a pin is used for input, output or some other function.

---

Changes in v9: None
Changes in v2: None

 drivers/gpio/rk_gpio.c | 40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

Applied to u-boot-rockchip.

#93 lore raw

PATCH v9 46/49 rockchip: spi: Implement the delays

In reply to Simon Glass

Some devices need delays before and after activiation. Implement these features in the SPI driver so that we will be able to enable the Chrome OS EC.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)
drivers/spi/rk_spi.c +23 -4
index 3418f9b..35b528f 100644
@@ -32,6 +32,7 @@ struct rockchip_spi_platdata {
 	s32 frequency;		/* Default clock frequency, -1 for none */
 	fdt_addr_t base;
 	uint deactivate_delay_us;	/* Delay to wait after deactivate */
+	uint activate_delay_us;		/* Delay to wait after activate */
 };
 
 struct rockchip_spi_priv {
@@ -101,16 +102,32 @@ static int rkspi_wait_till_not_busy(struct rockchip_spi *regs)
 	return 0;
 }
 
-static void spi_cs_activate(struct rockchip_spi *regs, uint cs)
+static void spi_cs_activate(struct udevice *dev, uint cs)
 {
+	struct udevice *bus = dev->parent;
+	struct rockchip_spi_platdata *plat = bus->platdata;
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+	struct rockchip_spi *regs = priv->regs;
+
 	debug("activate cs%u\n", cs);
 	writel(1 << cs, &regs->ser);
+	if (plat->activate_delay_us)
+		udelay(plat->activate_delay_us);
 }
 
-static void spi_cs_deactivate(struct rockchip_spi *regs, uint cs)
+static void spi_cs_deactivate(struct udevice *dev, uint cs)
 {
+	struct udevice *bus = dev->parent;
+	struct rockchip_spi_platdata *plat = bus->platdata;
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+	struct rockchip_spi *regs = priv->regs;
+
 	debug("deactivate cs%u\n", cs);
 	writel(0, &regs->ser);
+
+	/* Remember time of this transaction so we can honour the bus delay */
+	if (plat->deactivate_delay_us)
+		priv->last_transaction_us = timer_get_us();
 }
 
 static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
@@ -145,6 +162,8 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
 					 50000000);
 	plat->deactivate_delay_us = fdtdec_get_int(blob, node,
 					"spi-deactivate-delay", 0);
+	plat->activate_delay_us = fdtdec_get_int(blob, node,
+						 "spi-activate-delay", 0);
 	debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
 	      __func__, (uint)plat->base, plat->periph_id, plat->frequency,
 	      plat->deactivate_delay_us);
@@ -290,7 +309,7 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
 	/* Assert CS before transfer */
 	if (flags & SPI_XFER_BEGIN)
-		spi_cs_activate(regs, slave_plat->cs);
+		spi_cs_activate(dev, slave_plat->cs);
 
 	while (len > 0) {
 		int todo = min(len, 0xffff);
@@ -324,7 +343,7 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
 
 	/* Deassert CS after transfer */
 	if (flags & SPI_XFER_END)
-		spi_cs_deactivate(regs, slave_plat->cs);
+		spi_cs_deactivate(dev, slave_plat->cs);
 
 	rkspi_enable_chip(regs, false);
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#94 lore raw

PATCH v9 46/49 rockchip: spi: Implement the delays

Quoted 4 lines · Simon Glass

Some devices need delays before and after activiation. Implement these features in the SPI driver so that we will be able to enable the Chrome OS EC.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

Applied to u-boot-rockchip.

#95 lore raw

PATCH v9 47/49 rockchip: spi: Correct chip-enable code

In reply to Simon Glass

At present there is an incorrect call to rkspi_enable_chip(). It should be disabling the chip, not enabling it. Correct this and ensure that the chip is disabled when releasing the bus.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/spi/rk_spi.c +6 -1
index 35b528f..412fa8b 100644
@@ -286,6 +286,11 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 
 static int rockchip_spi_release_bus(struct udevice *dev)
 {
+	struct udevice *bus = dev->parent;
+	struct rockchip_spi_priv *priv = dev_get_priv(bus);
+
+	rkspi_enable_chip(priv->regs, false);
+
 	return 0;
 }
 
@@ -314,7 +319,7 @@ static int rockchip_spi_xfer(struct udevice *dev, unsigned int bitlen,
 	while (len > 0) {
 		int todo = min(len, 0xffff);
 
-		rkspi_enable_chip(regs, true);
+		rkspi_enable_chip(regs, false);
 		writel(todo - 1, &regs->ctrlr1);
 		rkspi_enable_chip(regs, true);
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#96 lore raw

PATCH v9 47/49 rockchip: spi: Correct chip-enable code

Quoted 4 lines · Simon Glass

At present there is an incorrect call to rkspi_enable_chip(). It should be disabling the chip, not enabling it. Correct this and ensure that the chip is disabled when releasing the bus.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Applied to u-boot-rockchip.

#97 lore raw

PATCH v9 48/49 rockchip: spi: Remove the explicit pinctrl setting

In reply to Simon Glass

The correct pinctrl is handled automatically so we don't need to do it in the driver. The exception is when we want to use a different chip select (other than 0). But this isn't used at present.

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)
drivers/spi/rk_spi.c +2 -26
index 412fa8b..9eff423 100644
@@ -27,8 +27,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define DEBUG_RK_SPI	0
 
 struct rockchip_spi_platdata {
-	int periph_id;
-	struct udevice *pinctrl;
 	s32 frequency;		/* Default clock frequency, -1 for none */
 	fdt_addr_t base;
 	uint deactivate_delay_us;	/* Delay to wait after deactivate */
@@ -139,17 +137,7 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
 	int ret;
 
 	plat->base = dev_get_addr(bus);
-	ret = uclass_get_device(UCLASS_PINCTRL, 0, &plat->pinctrl);
-	if (ret)
-		return ret;
-	ret = pinctrl_get_periph_id(plat->pinctrl, bus);
 
-	if (ret < 0) {
-		debug("%s: Could not get peripheral ID for %s: %d\n", __func__,
-		      bus->name, ret);
-		return ret;
-	}
-	plat->periph_id = ret;
 	ret = clk_get_by_index(bus, 0, &priv->clk);
 	if (ret < 0) {
 		debug("%s: Could not get clock for %s: %d\n", __func__,
@@ -164,8 +152,8 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
 					"spi-deactivate-delay", 0);
 	plat->activate_delay_us = fdtdec_get_int(blob, node,
 						 "spi-activate-delay", 0);
-	debug("%s: base=%x, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
-	      __func__, (uint)plat->base, plat->periph_id, plat->frequency,
+	debug("%s: base=%x, max-frequency=%d, deactivate_delay=%d\n",
+	      __func__, (uint)plat->base, plat->frequency,
 	      plat->deactivate_delay_us);
 
 	return 0;
@@ -207,11 +195,6 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 	struct rockchip_spi *regs = priv->regs;
 	u8 spi_dfs, spi_tf;
 	uint ctrlr0;
-#if !CONFIG_IS_ENABLED(PINCTRL_FULL)
-	struct rockchip_spi_platdata *plat = dev_get_platdata(bus);
-	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
-	int ret;
-#endif
 
 	/* Disable the SPI hardware */
 	rkspi_enable_chip(regs, 0);
@@ -273,13 +256,6 @@ static int rockchip_spi_claim_bus(struct udevice *dev)
 	ctrlr0 |= (priv->tmode & TMOD_MASK) << TMOD_SHIFT;
 
 	writel(ctrlr0, &regs->ctrlr0);
-#if !CONFIG_IS_ENABLED(PINCTRL_FULL)
-	ret = pinctrl_request(plat->pinctrl, plat->periph_id, slave_plat->cs);
-	if (ret) {
-		debug("%s: Cannot request pinctrl: %d\n", __func__, ret);
-		return ret;
-	}
-#endif
 
 	return 0;
 }
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#98 lore raw

PATCH v9 48/49 rockchip: spi: Remove the explicit pinctrl setting

Quoted 4 lines · Simon Glass

The correct pinctrl is handled automatically so we don't need to do it in the driver. The exception is when we want to use a different chip select (other than 0). But this isn't used at present.

Quoted 8 lines

---

Changes in v9: None
Changes in v2: None

 drivers/spi/rk_spi.c | 28 ++--------------------------
 1 file changed, 2 insertions(+), 26 deletions(-)

Applied to u-boot-rockchip.

#99 lore raw

PATCH v9 49/49 rockchip: jerry: Enable the Chrome OS EC

In reply to Simon Glass

Turn on the EC and enable the keyboard.

---

Changes in v9:
- Rebase to upstream/master

Changes in v2: None

 arch/arm/dts/rk3288-veyron-chromebook.dtsi | 4 ++++
 configs/chromebook_jerry_defconfig         | 8 ++++++++
 include/configs/chromebook_jerry.h         | 7 +++++++
 include/configs/firefly-rk3288.h           | 2 ++
 include/configs/rk3288_common.h            | 7 +++++++
 5 files changed, 28 insertions(+)
arch/arm/dts/rk3288-veyron-chromebook.dtsi +4 -0
index 6d619c9..bbbc2f4 100644
@@ -91,12 +91,16 @@
 
 &spi0 {
 	status = "okay";
+	spi-activate-delay = <100>;
+	spi-max-frequency = <3000000>;
+	spi-deactivate-delay = <200>;
 
 	cros_ec: ec at 0 {
 		compatible = "google,cros-ec-spi";
 		spi-max-frequency = <3000000>;
 		interrupt-parent = <&gpio7>;
 		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		ec-interrupt = <&gpio7 7 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&ec_int>;
 		reg = <0>;
configs/chromebook_jerry_defconfig +8 -0
index ceec6f5..b2672b8 100644
@@ -4,6 +4,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_CHROMEBOOK_JERRY=y
 CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_DM_KEYBOARD=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3288-jerry"
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
@@ -21,7 +22,13 @@ CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
+CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_I2C_MUX=y
+CONFIG_CROS_EC_KEYB=y
+CONFIG_CMD_CROS_EC=y
+CONFIG_CROS_EC=y
+CONFIG_CROS_EC_SPI=y
 CONFIG_PWRSEQ=y
 CONFIG_RESET=y
 CONFIG_DM_MMC=y
@@ -31,6 +38,7 @@ CONFIG_SPL_PINCTRL=y
 # CONFIG_SPL_PINCTRL_FULL is not set
 CONFIG_ROCKCHIP_PINCTRL=y
 CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
 CONFIG_PMIC_RK808=y
 CONFIG_DM_REGULATOR=y
 CONFIG_REGULATOR_RK808=y
include/configs/chromebook_jerry.h +7 -0
index 78c06af..6e32f2c 100644
@@ -7,6 +7,11 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdin=serial,cros-ec-keyb\0" \
+		"stdout=serial\0" \
+		"stderr=serial\0"
+
 #include <configs/rk3288_common.h>
 
 #define CONFIG_ENV_IS_NOWHERE
@@ -17,4 +22,6 @@
 
 #undef CONFIG_SPL_GPIO_SUPPORT
 
+#define CONFIG_KEYBOARD
+
 #endif
include/configs/firefly-rk3288.h +2 -0
index 4c5c4dd..8ac6521 100644
@@ -7,6 +7,8 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define ROCKCHIP_DEVICE_SETTINGS
+
 #include <configs/rk3288_common.h>
 
 #define CONFIG_SPL_MMC_SUPPORT
include/configs/rk3288_common.h +7 -0
index f47573b..ebddfb0 100644
@@ -42,6 +42,12 @@
 #define CONFIG_ROCKCHIP_COMMON
 #define CONFIG_SPL_ROCKCHIP_COMMON
 
+#define CONFIG_SILENT_CONSOLE
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_SYS_CONSOLE_IS_IN_ENV
+# define CONFIG_CONSOLE_MUX
+#endif
+
 /* MMC/SD IP block */
 #define CONFIG_MMC
 #define CONFIG_GENERIC_MMC
@@ -110,6 +116,7 @@
 	"fdt_high=0x1fffffff\0" \
 	"initrd_high=0x1fffffff\0" \
 	ENV_MEM_LAYOUT_SETTINGS \
+	ROCKCHIP_DEVICE_SETTINGS \
 	BOOTENV
 #endif
 
Signature · 1 line
2.7.0.rc3.207.g0ac5344
#100 lore raw

PATCH v9 49/49 rockchip: jerry: Enable the Chrome OS EC

Quoted 8 lines · Simon Glass

Turn on the EC and enable the keyboard.

---

Changes in v9:
- Rebase to upstream/master

Quoted 8 lines

Changes in v2: None

 arch/arm/dts/rk3288-veyron-chromebook.dtsi | 4 ++++
 configs/chromebook_jerry_defconfig         | 8 ++++++++
 include/configs/chromebook_jerry.h         | 7 +++++++
 include/configs/firefly-rk3288.h           | 2 ++
 include/configs/rk3288_common.h            | 7 +++++++
 5 files changed, 28 insertions(+)

Applied to u-boot-rockchip.