* [PATCH v3 2/2] dt-bindings:i2c:mux:ltc4306: Add dt-bindings for I2C multiplexer/switch
From: michael.hennerich @ 2017-04-03 13:31 UTC (permalink / raw)
To: wsa, peda, robh+dt, mark.rutland, linus.walleij
Cc: linux-i2c, devicetree, linux-gpio, linux-kernel,
Michael Hennerich
In-Reply-To: <1491226297-4970-1-git-send-email-michael.hennerich@analog.com>
From: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/i2c/i2c-mux-ltc4306.txt | 61 ++++++++++++++++++++++
1 file changed, 61 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
new file mode 100644
index 0000000..1e98c6b
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
@@ -0,0 +1,61 @@
+* Linear Technology / Analog Devices I2C bus switch
+
+Required Properties:
+
+ - compatible: Must contain one of the following.
+ "lltc,ltc4305", "lltc,ltc4306"
+ - reg: The I2C address of the device.
+
+ The following required properties are defined externally:
+
+ - Standard I2C mux properties. See i2c-mux.txt in this directory.
+ - I2C child bus nodes. See i2c-mux.txt in this directory.
+
+Optional Properties:
+
+ - enable-gpios: Reference to the GPIO connected to the enable input.
+ - i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
+ children in idle state. This is necessary for example, if there are several
+ multiplexers on the bus and the devices behind them use same I2C addresses.
+ - gpio-controller: Marks the device node as a GPIO Controller.
+ - #gpio-cells: Should be two. The first cell is the pin number and
+ the second cell is used to specify flags.
+ See ../gpio/gpio.txt for more information.
+ - ltc,downstream-accelerators-enable: Enables the rise time accelerators
+ on the downstream port.
+ - ltc,upstream-accelerators-enable: Enables the rise time accelerators
+ on the upstream port.
+
+Example:
+
+ ltc4306: i2c-mux@4a {
+ compatible = "lltc,ltc4306";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4a>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@50 {
+ compatible = "at,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ eeprom@50 {
+ compatible = "at,24c02";
+ reg = <0x50>;
+ };
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v3 1/2] i2c:mux:ltc4306: LTC4306 and LTC4305 I2C multiplexer/switch
From: michael.hennerich @ 2017-04-03 13:31 UTC (permalink / raw)
To: wsa, peda, robh+dt, mark.rutland, linus.walleij
Cc: linux-i2c, devicetree, linux-gpio, linux-kernel,
Michael Hennerich
From: Michael Hennerich <michael.hennerich@analog.com>
This patch adds support for the Analog Devices / Linear Technology
LTC4306 and LTC4305 4/2 Channel I2C Bus Multiplexer/Switches.
The LTC4306 optionally provides two general purpose input/output pins
(GPIOs) that can be configured as logic inputs, opendrain outputs or
push-pull outputs via the generic GPIOLIB framework.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
---
Changes since v1:
- Sort makefile entries
- Sort driver includes
- Use proper defines
- Miscellaneous coding style fixups
- Rename mux select callback
- Revise i2c-mux-idle-disconnect handling
- Add ENABLE GPIO handling on error and device removal.
- Remove surplus of_match_device call.
Changes since v2:
- Stop double error reporting (i2c_mux_add_adapter)
- Change subject
- Split dt bindings to separate patch
---
MAINTAINERS | 8 +
drivers/i2c/muxes/Kconfig | 10 +
drivers/i2c/muxes/Makefile | 1 +
drivers/i2c/muxes/i2c-mux-ltc4306.c | 363 ++++++++++++++++++++++++++++++++++++
4 files changed, 382 insertions(+)
create mode 100644 drivers/i2c/muxes/i2c-mux-ltc4306.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c776906..9a27a19 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7698,6 +7698,14 @@ S: Maintained
F: Documentation/hwmon/ltc4261
F: drivers/hwmon/ltc4261.c
+LTC4306 I2C MULTIPLEXER DRIVER
+M: Michael Hennerich <michael.hennerich@analog.com>
+W: http://ez.analog.com/community/linux-device-drivers
+L: linux-i2c@vger.kernel.org
+S: Supported
+F: drivers/i2c/muxes/i2c-mux-ltc4306.c
+F: Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
+
LTP (Linux Test Project)
M: Mike Frysinger <vapier@gentoo.org>
M: Cyril Hrubis <chrubis@suse.cz>
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 10b3d17..f501b3b 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -30,6 +30,16 @@ config I2C_MUX_GPIO
This driver can also be built as a module. If so, the module
will be called i2c-mux-gpio.
+config I2C_MUX_LTC4306
+ tristate "LTC LTC4306/5 I2C multiplexer"
+ select GPIOLIB
+ help
+ If you say yes here you get support for the LTC LTC4306 or LTC4305
+ I2C mux/switch devices.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-mux-ltc4306.
+
config I2C_MUX_PCA9541
tristate "NXP PCA9541 I2C Master Selector"
help
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile
index 9948fa4..ff7618c 100644
--- a/drivers/i2c/muxes/Makefile
+++ b/drivers/i2c/muxes/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE) += i2c-arb-gpio-challenge.o
obj-$(CONFIG_I2C_DEMUX_PINCTRL) += i2c-demux-pinctrl.o
obj-$(CONFIG_I2C_MUX_GPIO) += i2c-mux-gpio.o
+obj-$(CONFIG_I2C_MUX_LTC4306) += i2c-mux-ltc4306.o
obj-$(CONFIG_I2C_MUX_MLXCPLD) += i2c-mux-mlxcpld.o
obj-$(CONFIG_I2C_MUX_PCA9541) += i2c-mux-pca9541.o
obj-$(CONFIG_I2C_MUX_PCA954x) += i2c-mux-pca954x.o
diff --git a/drivers/i2c/muxes/i2c-mux-ltc4306.c b/drivers/i2c/muxes/i2c-mux-ltc4306.c
new file mode 100644
index 0000000..34ac47d
--- /dev/null
+++ b/drivers/i2c/muxes/i2c-mux-ltc4306.c
@@ -0,0 +1,363 @@
+/*
+ * Linear Technology LTC4306 and LTC4305 I2C multiplexer/switch
+ *
+ * Copyright (C) 2017 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ *
+ * Based on: i2c-mux-pca954x.c
+ *
+ * Datasheet: http://cds.linear.com/docs/en/datasheet/4306.pdf
+ */
+
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/i2c-mux.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#define LTC4305_MAX_NCHANS 2
+#define LTC4306_MAX_NCHANS 4
+
+#define LTC_REG_STATUS 0x0
+#define LTC_REG_CONFIG 0x1
+#define LTC_REG_MODE 0x2
+#define LTC_REG_SWITCH 0x3
+
+#define LTC_DOWNSTREAM_ACCL_EN BIT(6)
+#define LTC_UPSTREAM_ACCL_EN BIT(7)
+
+#define LTC_GPIO_ALL_INPUT 0xC0
+
+enum ltc_type {
+ ltc_4305,
+ ltc_4306,
+};
+
+struct chip_desc {
+ u8 nchans;
+ u8 num_gpios;
+};
+
+struct ltc4306 {
+ struct i2c_client *client;
+ struct gpio_desc *en_gpio;
+ struct gpio_chip gpiochip;
+ const struct chip_desc *chip;
+ u8 regs[LTC_REG_SWITCH + 1];
+};
+
+/* Provide specs for the PCA954x types we know about */
+static const struct chip_desc chips[] = {
+ [ltc_4305] = {
+ .nchans = LTC4305_MAX_NCHANS,
+ },
+ [ltc_4306] = {
+ .nchans = LTC4306_MAX_NCHANS,
+ .num_gpios = 2,
+ },
+};
+
+static int ltc4306_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct ltc4306 *data = gpiochip_get_data(chip);
+ int ret = 0;
+
+ if (gpiochip_line_is_open_drain(chip, offset) ||
+ (data->regs[LTC_REG_MODE] & BIT(7 - offset))) {
+ /* Open Drain or Input */
+ ret = i2c_smbus_read_byte_data(data->client, LTC_REG_CONFIG);
+ if (ret < 0)
+ return ret;
+
+ return !!(ret & BIT(1 - offset));
+ } else {
+ return !!(data->regs[LTC_REG_CONFIG] & BIT(5 - offset));
+ }
+}
+
+static void ltc4306_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct ltc4306 *data = gpiochip_get_data(chip);
+
+ if (value)
+ data->regs[LTC_REG_CONFIG] |= BIT(5 - offset);
+ else
+ data->regs[LTC_REG_CONFIG] &= ~BIT(5 - offset);
+
+ i2c_smbus_write_byte_data(data->client, LTC_REG_CONFIG,
+ data->regs[LTC_REG_CONFIG]);
+}
+
+static int ltc4306_gpio_direction_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct ltc4306 *data = gpiochip_get_data(chip);
+
+ data->regs[LTC_REG_MODE] |= BIT(7 - offset);
+
+ return i2c_smbus_write_byte_data(data->client, LTC_REG_MODE,
+ data->regs[LTC_REG_MODE]);
+}
+
+static int ltc4306_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct ltc4306 *data = gpiochip_get_data(chip);
+
+ ltc4306_gpio_set(chip, offset, value);
+ data->regs[LTC_REG_MODE] &= ~BIT(7 - offset);
+
+ return i2c_smbus_write_byte_data(data->client, LTC_REG_MODE,
+ data->regs[LTC_REG_MODE]);
+}
+
+static int ltc4306_gpio_set_config(struct gpio_chip *chip,
+ unsigned int offset, unsigned long config)
+{
+ struct ltc4306 *data = gpiochip_get_data(chip);
+
+ switch (pinconf_to_config_param(config)) {
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ data->regs[LTC_REG_MODE] &= ~BIT(4 - offset);
+ break;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ data->regs[LTC_REG_MODE] |= BIT(4 - offset);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ return i2c_smbus_write_byte_data(data->client, LTC_REG_MODE,
+ data->regs[LTC_REG_MODE]);
+}
+
+static int ltc4306_gpio_init(struct ltc4306 *data)
+{
+ if (!data->chip->num_gpios)
+ return 0;
+
+ data->gpiochip.label = dev_name(&data->client->dev);
+ data->gpiochip.base = -1;
+ data->gpiochip.ngpio = data->chip->num_gpios;
+ data->gpiochip.parent = &data->client->dev;
+ data->gpiochip.can_sleep = true;
+ data->gpiochip.direction_input = ltc4306_gpio_direction_input;
+ data->gpiochip.direction_output = ltc4306_gpio_direction_output;
+ data->gpiochip.get = ltc4306_gpio_get;
+ data->gpiochip.set = ltc4306_gpio_set;
+ data->gpiochip.set_config = ltc4306_gpio_set_config;
+ data->gpiochip.owner = THIS_MODULE;
+
+ /* gpiolib assumes all GPIOs default input */
+ data->regs[LTC_REG_MODE] |= LTC_GPIO_ALL_INPUT;
+ i2c_smbus_write_byte_data(data->client, LTC_REG_MODE,
+ data->regs[LTC_REG_MODE]);
+
+ return devm_gpiochip_add_data(&data->client->dev,
+ &data->gpiochip, data);
+}
+
+/*
+ * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
+ * as they will try to lock the adapter a second time.
+ */
+static int ltc4306_reg_write(struct i2c_adapter *adap,
+ struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret;
+
+ if (adap->algo->master_xfer) {
+ struct i2c_msg msg;
+ char buf[2];
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = 2;
+ buf[0] = reg;
+ buf[1] = val;
+ msg.buf = buf;
+ ret = __i2c_transfer(adap, &msg, 1);
+ } else {
+ union i2c_smbus_data data;
+
+ data.byte = val;
+ ret = adap->algo->smbus_xfer(adap, client->addr,
+ client->flags,
+ I2C_SMBUS_WRITE,
+ reg,
+ I2C_SMBUS_BYTE_DATA, &data);
+ }
+
+ return ret;
+}
+
+static int ltc4306_select_mux(struct i2c_mux_core *muxc, u32 chan)
+{
+ struct ltc4306 *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ u8 regval;
+ int ret = 0;
+
+ regval = BIT(7 - chan);
+
+ /* Only select the channel if its different from the last channel */
+ if (data->regs[LTC_REG_SWITCH] != regval) {
+ ret = ltc4306_reg_write(muxc->parent, client,
+ LTC_REG_SWITCH, regval);
+ data->regs[LTC_REG_SWITCH] = ret < 0 ? 0 : regval;
+ }
+
+ return ret;
+}
+
+static int ltc4306_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
+{
+ struct ltc4306 *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+
+ /* Deselect all channels */
+ data->regs[LTC_REG_SWITCH] = 0;
+
+ return ltc4306_reg_write(muxc->parent, client,
+ LTC_REG_SWITCH, data->regs[LTC_REG_SWITCH]);
+}
+
+static const struct i2c_device_id ltc4306_id[] = {
+ { "ltc4305", ltc_4305 },
+ { "ltc4306", ltc_4306 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ltc4306_id);
+
+static const struct of_device_id ltc4306_of_match[] = {
+ { .compatible = "lltc,ltc4305", .data = &chips[ltc_4305] },
+ { .compatible = "lltc,ltc4306", .data = &chips[ltc_4306] },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ltc4306_of_match);
+
+static int ltc4306_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+ struct device_node *of_node = client->dev.of_node;
+ bool idle_disconnect_dt = false;
+ struct i2c_mux_core *muxc;
+ struct ltc4306 *data;
+ int num, ret;
+
+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ if (of_node) {
+ idle_disconnect_dt =
+ of_property_read_bool(of_node,
+ "i2c-mux-idle-disconnect");
+ }
+
+ muxc = i2c_mux_alloc(adap, &client->dev,
+ LTC4306_MAX_NCHANS, sizeof(*data), 0,
+ ltc4306_select_mux, idle_disconnect_dt ?
+ ltc4306_deselect_mux : NULL);
+ if (!muxc)
+ return -ENOMEM;
+ data = i2c_mux_priv(muxc);
+
+ i2c_set_clientdata(client, muxc);
+ data->client = client;
+
+ /* Enable the mux if an enable GPIO is specified. */
+ data->en_gpio = devm_gpiod_get_optional(&client->dev, "enable",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(data->en_gpio))
+ return PTR_ERR(data->en_gpio);
+
+ /*
+ * Write the mux register at addr to verify
+ * that the mux is in fact present. This also
+ * initializes the mux to disconnected state.
+ */
+ if (i2c_smbus_write_byte_data(client, LTC_REG_SWITCH, 0) < 0) {
+ dev_warn(&client->dev, "probe failed\n");
+ ret = -ENODEV;
+ goto gpio_default;
+ }
+
+ if (of_node) {
+ data->chip = of_device_get_match_data(&client->dev);
+
+ if (of_property_read_bool(of_node,
+ "ltc,downstream-accelerators-enable"))
+ data->regs[LTC_REG_CONFIG] |= LTC_DOWNSTREAM_ACCL_EN;
+
+ if (of_property_read_bool(of_node,
+ "ltc,upstream-accelerators-enable"))
+ data->regs[LTC_REG_CONFIG] |= LTC_UPSTREAM_ACCL_EN;
+
+ if (i2c_smbus_write_byte_data(client, LTC_REG_CONFIG,
+ data->regs[LTC_REG_CONFIG]) < 0) {
+ dev_warn(&client->dev, "probe failed\n");
+ ret = -ENODEV;
+ goto gpio_default;
+ }
+ } else {
+ data->chip = &chips[id->driver_data];
+ }
+
+ ret = ltc4306_gpio_init(data);
+ if (ret < 0)
+ goto gpio_default;
+
+ /* Now create an adapter for each channel */
+ for (num = 0; num < data->chip->nchans; num++) {
+ ret = i2c_mux_add_adapter(muxc, 0, num, 0);
+ if (ret)
+ goto add_adapter_failed;
+ }
+
+ dev_info(&client->dev,
+ "registered %d multiplexed busses for I2C switch %s\n",
+ num, client->name);
+
+ return 0;
+
+add_adapter_failed:
+ i2c_mux_del_adapters(muxc);
+gpio_default:
+ gpiod_direction_input(data->en_gpio);
+ return ret;
+}
+
+static int ltc4306_remove(struct i2c_client *client)
+{
+ struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+ struct ltc4306 *data = i2c_mux_priv(muxc);
+
+ i2c_mux_del_adapters(muxc);
+ gpiod_direction_input(data->en_gpio);
+
+ return 0;
+}
+
+static struct i2c_driver ltc4306_driver = {
+ .driver = {
+ .name = "ltc4306",
+ .of_match_table = of_match_ptr(ltc4306_of_match),
+ },
+ .probe = ltc4306_probe,
+ .remove = ltc4306_remove,
+ .id_table = ltc4306_id,
+};
+
+module_i2c_driver(ltc4306_driver);
+
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
+MODULE_DESCRIPTION("Linear Technology LTC4306, LTC4305 I2C mux/switch driver");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
* Re: [RFC PATCH 1/2] dt-bindings: mtd: Add Cavium SOCs NAND bindings
From: Rob Herring @ 2017-04-03 13:29 UTC (permalink / raw)
To: Jan Glauber
Cc: Boris Brezillon, Richard Weinberger, David Woodhouse,
Brian Norris, Marek Vasut, Cyrille Pitchen,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170327160524.29019-2-jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
On Mon, Mar 27, 2017 at 06:05:23PM +0200, Jan Glauber wrote:
> Add device tree binding description for Cavium SOC nand flash controller.
>
> CC: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> CC: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>
> Signed-off-by: Jan Glauber <jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> ---
> .../devicetree/bindings/mtd/cavium_nand.txt | 32 ++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/cavium_nand.txt
>
> diff --git a/Documentation/devicetree/bindings/mtd/cavium_nand.txt b/Documentation/devicetree/bindings/mtd/cavium_nand.txt
> new file mode 100644
> index 0000000..4698d1f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/cavium_nand.txt
> @@ -0,0 +1,32 @@
> +* Cavium NAND controller
> +
> +Required properties:
> +
> +- compatible: should be "cavium,cn8xxx-nand"
Don't use wildcards in compatible strings. For PCI devices, this should
be based on the PCI vendor and device IDs.
> +- reg: PCI devfn
> +- clocks: must contain system clock
> +- #address-cells: <1>
> +- #size-cells: <0>
> +
> +The nand flash controller may contain up to 8 subnodes representing
> +NAND flash chips. Their properties are as follows.
> +
> +Required properties:
> +- compatible: should be "cavium,nandcs"
> +- reg: a single integer representing the chip-select number
> +- nand-ecc-mode: see nand.txt
> +
> +Example:
> +
> +nfc: nand@b,0 {
> + compatible = "cavium,cn8xxx-nand";
> + reg = <0x5800 0 0 0 0>;
> + clocks = <&sclk>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + nand@1 {
> + compatible = "cavium,nandcs";
> + reg = <1>;
> + nand-ecc-mode = "on-die";
> +};
> --
> 2.9.0.rc0.21.g7777322
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 1/4] Documentation: dt-bindings: iio: Add max9611 ADC
From: Rob Herring @ 2017-04-03 13:26 UTC (permalink / raw)
To: Jacopo Mondi
Cc: geert, wsa+renesas, magnus.damm, laurent.pinchart, jic23,
knaack.h, lars, pmeerw, mark.rutland, linux-iio,
linux-renesas-soc, devicetree
In-Reply-To: <1490627578-15938-2-git-send-email-jacopo+renesas@jmondi.org>
On Mon, Mar 27, 2017 at 05:12:55PM +0200, Jacopo Mondi wrote:
> Add device tree bindings documentation for Maxim max9611/max9612 current
> sense amplifier.
"dt-bindings: iio: adc: ..." for the subject.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> .../devicetree/bindings/iio/adc/max9611.txt | 26 ++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/max9611.txt
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/max9611.txt b/Documentation/devicetree/bindings/iio/adc/max9611.txt
> new file mode 100644
> index 0000000..8430d3b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/max9611.txt
> @@ -0,0 +1,26 @@
> +* Maxim max9611/max9612 current sense amplifier with 12-bits ADC interface
> +
> +Maxim max9611/max9612 is an high-side current sense amplifier with integrated
> +12-bits ADC communicating over I2c bus.
> +The device node for this driver shall be a child of a I2c controller.
> +
> +Required properties
> + - compatible: Should be "maxim,max9611" or "maxim,max9612"
> + - reg: The 7-bits long I2c address of the device
> + - shunt-resistor-uohm: Value, in uOhm, of the current sense shunt resistor
As Jonathan said.
> +
> +Example:
> +
> +&i2c4 {
> + csa: adc@7c {
> + compatible = "maxim,max9611";
> + reg = <0x7c>;
> +
> + shunt-resistor-uohm = <5000>;
> + };
> +};
> +
> +This device node describes a current sense amplifier sitting on I2c4 bus
> +with address 0x7c (read address is 0xf9, write address is 0xf8).
> +A sense resistor of 0,005 Ohm is installed between RS+ and RS- current-sensing
> +inputs.
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH 1/2] drm/sun4i: Add display backend interrupt to device tree binding
From: Rob Herring @ 2017-04-03 13:24 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Maxime Ripard, David Airlie, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170327143847.16259-2-wens-jdAy2FN1RRM@public.gmane.org>
On Mon, Mar 27, 2017 at 10:38:46PM +0800, Chen-Yu Tsai wrote:
> The display backend has an interrupt line. Add it to the device tree
> binding.
>
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 2 ++
> 1 file changed, 2 insertions(+)
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
^ permalink raw reply
* Re: [PATCH RFC v4 07/10] dt-bindings: net: add binding for QCA7000 UART
From: Rob Herring @ 2017-04-03 13:23 UTC (permalink / raw)
To: Stefan Wahren
Cc: Mark Rutland, David S. Miller, Greg Kroah-Hartman, Jiri Slaby,
Marcel Holtmann, Sebastian Reichel, netdev,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <9a094176-ebe7-d906-ca9c-967285e53b07-eS4NqCHxEME@public.gmane.org>
On Tue, Mar 28, 2017 at 06:18:03PM +0200, Stefan Wahren wrote:
> Am 27.03.2017 um 22:30 schrieb Rob Herring:
> > On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org> wrote:
> >> This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
> >>
> >> Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
> >> ---
> >>
> >> According to this binding are still some questions:
> >>
> >> Where should be the optional hardware flow control defined (at master or slave side)?
> > Probably should be in the slave side. We already have uart-has-rtscts
> > and rts/cts-gpios for the UART. Those mean we have RTS/CTS, but not
> > necessarily that we want to enable them.
> >
> > In many cases, the driver may know what it needs.
>
> Like all the other UART settings the hardware flow control can be
> configured in the QCA7000 firmware and the driver can't detect it.
>
> Property suggestion for the slave side:
>
> use-rtscts
Okay.
> >> Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
> > Are they mutually-exclusive or both are used at the same time?
>
> They are mutually-exclusive because they use the same pins.
>
> > What
> > are the dependencies between the interfaces?
>
> Except they uses the same pins of the QCA7000, i can't see any dependency.
I think they should be a single doc.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH V7 6/7] thermal: da9062/61: Thermal junction temperature monitoring driver
From: Steve Twiss @ 2017-04-03 13:21 UTC (permalink / raw)
To: Eduardo Valentin, Lee Jones
Cc: LINUX-KERNEL, LINUX-PM, Zhang Rui, DEVICETREE, Dmitry Torokhov,
Guenter Roeck, LINUX-INPUT, LINUX-WATCHDOG, Liam Girdwood,
Lukasz Luba, Mark Brown, Mark Rutland, Rob Herring,
Support Opensource, Wim Van Sebroeck
In-Reply-To: <20170401195916.GF28514@localhost.localdomain>
On 01 April 2017 @20:59, Eduardo Valentin wrote:
> Subject: Re: [PATCH V7 6/7] thermal: da9062/61: Thermal junction temperature monitoring driver
>
> On Tue, Mar 28, 2017 at 03:43:33PM +0100, Steve Twiss wrote:
> > From: Steve Twiss <stwiss.opensource@diasemi.com>
> >
> > Add junction temperature monitoring supervisor device driver, compatible
> > with the DA9062 and DA9061 PMICs. A MODULE_DEVICE_TABLE() macro is added.
> >
> > If the PMIC's internal junction temperature rises above T_WARN (125 degC)
> > an interrupt is issued. This T_WARN level is defined as the
> > THERMAL_TRIP_HOT trip-wire inside the device driver.
> >
> > The thermal triggering mechanism is interrupt based and happens when the
> > temperature rises above a given threshold level. The component cannot
> > return an exact temperature, it only has knowledge if the temperature is
> > above or below a given threshold value. A status bit must be polled to
> > detect when the temperature falls below that threshold level again. A
> > kernel work queue is configured to repeatedly poll and detect when the
> > temperature falls below this trip-wire, between 1 and 10 second intervals
> > (defaulting at 3 seconds).
> >
> > This scheme is provided as an example. It would be expected that any
> > final implementation will also include a notify() function and any of these
> > settings could be altered to match the application where appropriate.
> >
> > When over-temperature is reached, the interrupt from the DA9061/2 will be
> > repeatedly triggered. The IRQ is therefore disabled when the first
> > over-temperature event happens and the status bit is polled using a
> > work-queue until it becomes false.
> >
> > This strategy is designed to allow the periodic transmission of uevents
> > (HOT trip point) as the first level of temperature supervision method. It
> > is intended for non-invasive temperature control, where the necessary
> > measures for cooling the system down are left to the host software. Once
> > the temperature falls again, the IRQ is re-enabled so a new critical
> > over-temperature event can be detected.
> >
> > Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
> > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
>
> I have had a look on the history of this driver on its previous
> versions, and I do not think I have any other point to request on it.
Thank you.
> Obviously, I still need to state that I do not like its oddness as it is
> not really benefiting much of the thermal control implemented on the
> thermal subsystem.
Agreed.
But, it should be useful in the case of an over-temperature in the system PMIC
when the OS needs to be notified to bring core temperature under control.
> What is the plan for this series? Am I expected to get this driver
> through thermal tree ? Or is this series going into a one shot?
>
> If option 1 is the expected, would the driver need to get its
> mfd parent merged first?
Other components such as the ONKEY and Watchdog have not required the MFD
to be merged first. I don't see any strong dependency for the MFD to exist with this
thermal component.
I'm not sure how much Lee is waiting for Acks to exist before proceeding with the MFD.
I have TO:'d Lee Jones, for this case.
Regards,
Steve
^ permalink raw reply
* Re: [PATCH 2/2] nvmem: imx-ocotp: add write support
From: Rob Herring @ 2017-04-03 13:18 UTC (permalink / raw)
To: Richard Leitner
Cc: linux-kernel, srinivas.kandagatla, maxime.ripard, mark.rutland,
devicetree, dev
In-Reply-To: <1490621491-28247-2-git-send-email-richard.leitner@skidata.com>
On Mon, Mar 27, 2017 at 03:31:31PM +0200, Richard Leitner wrote:
> Implement write routine for OCOTP controller found in i.MX6 SoC's.
> Furthermore add locking to the read function to prevent race conditions.
> The write routine code is based on the fsl_otp driver from Freescale.
>
> Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
> ---
> .../devicetree/bindings/nvmem/imx-ocotp.txt | 4 +
Acked-by: Rob Herring <robh@kernel.org>
> drivers/nvmem/imx-ocotp.c | 210 ++++++++++++++++++++-
> 2 files changed, 212 insertions(+), 2 deletions(-)
^ permalink raw reply
* [PATCH net-next] macb: Add hardware PTP support.
From: Rafal Ozieblo @ 2017-04-03 13:10 UTC (permalink / raw)
To: David Miller, nicolas.ferre, netdev, linux-kernel, devicetree,
linux-arm-kernel, harinikatakamlinux, harini.katakam,
richardcochran, Andrei.Pistirica
Cc: Rafal Ozieblo
In-Reply-To: <20170329.093914.152103359543418375.davem@davemloft.net>
This patch is based on original Harini's patch and Andrei's patch,
implemented in aseparate file to ease the review/maintanance
and integration with other platforms.
In case that macb is compiled as a module, it has been renamed to
cadence-macb.ko to avoid naming confusion in Makefile.
This driver does support GEM-GXL:
- Enable HW time stamp
- Register ptp clock framework
- Initialize PTP related registers
- Updated dma buffer descriptor read/write mechanism
- HW time stamp on the PTP Ethernet packets are received using the
SO_TIMESTAMPING API. Where timers are obtained from the dma buffer
descriptors
- Added tsu_clk to device tree
Note: Patch on net-next, on April 3rd.
Signed-off-by: Rafal Ozieblo <rafalo@cadence.com>
---
Documentation/devicetree/bindings/net/macb.txt | 1 +
drivers/net/ethernet/cadence/Kconfig | 10 +-
drivers/net/ethernet/cadence/Makefile | 7 +-
drivers/net/ethernet/cadence/macb.c | 237 ++++++--
drivers/net/ethernet/cadence/macb.h | 176 +++++-
drivers/net/ethernet/cadence/macb_ptp.c | 724 +++++++++++++++++++++++++
6 files changed, 1109 insertions(+), 46 deletions(-)
create mode 100755 drivers/net/ethernet/cadence/macb_ptp.c
diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt
index 1506e94..27966ae 100644
--- a/Documentation/devicetree/bindings/net/macb.txt
+++ b/Documentation/devicetree/bindings/net/macb.txt
@@ -22,6 +22,7 @@ Required properties:
Required elements: 'pclk', 'hclk'
Optional elements: 'tx_clk'
Optional elements: 'rx_clk' applies to cdns,zynqmp-gem
+ Optional elements: 'tsu_clk'
- clocks: Phandles to input clocks.
Optional properties for PHY child node:
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
index 608bea1..427d65a 100644
--- a/drivers/net/ethernet/cadence/Kconfig
+++ b/drivers/net/ethernet/cadence/Kconfig
@@ -29,7 +29,15 @@ config MACB
support for the MACB/GEM chip.
To compile this driver as a module, choose M here: the module
- will be called macb.
+ will be macb.
+
+config MACB_USE_HWSTAMP
+ bool "Use IEEE 1588 hwstamp"
+ depends on MACB
+ default y
+ imply PTP_1588_CLOCK
+ ---help---
+ Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB.
config MACB_PCI
tristate "Cadence PCI MACB/GEM support"
diff --git a/drivers/net/ethernet/cadence/Makefile b/drivers/net/ethernet/cadence/Makefile
index 4ba7559..a7f6e04 100644
--- a/drivers/net/ethernet/cadence/Makefile
+++ b/drivers/net/ethernet/cadence/Makefile
@@ -1,6 +1,11 @@
#
# Makefile for the Atmel network device drivers.
#
+cadence-macb-y := macb.o
-obj-$(CONFIG_MACB) += macb.o
+ifeq ($(CONFIG_MACB_USE_HWSTAMP),y)
+cadence-macb-y += macb_ptp.o
+endif
+
+obj-$(CONFIG_MACB) += cadence-macb.o
obj-$(CONFIG_MACB_PCI) += macb_pci.o
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 30606b1..32af94e 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -79,33 +79,84 @@
#define MACB_HALT_TIMEOUT 1230
/* DMA buffer descriptor might be different size
- * depends on hardware configuration.
+ * depends on hardware configuration:
+ *
+ * 1. dma address width 32 bits:
+ * word 1: 32 bit address of Data Buffer
+ * word 2: control
+ *
+ * 2. dma address width 64 bits:
+ * word 1: 32 bit address of Data Buffer
+ * word 2: control
+ * word 3: upper 32 bit address of Data Buffer
+ * word 4: unused
+ *
+ * 3. dma address width 32 bits with hardware timestamping:
+ * word 1: 32 bit address of Data Buffer
+ * word 2: control
+ * word 3: timestamp word 1
+ * word 4: timestamp word 2
+ *
+ * 4. dma address width 64 bits with hardware timestamping:
+ * word 1: 32 bit address of Data Buffer
+ * word 2: control
+ * word 3: upper 32 bit address of Data Buffer
+ * word 4: unused
+ * word 5: timestamp word 1
+ * word 6: timestamp word 2
*/
static unsigned int macb_dma_desc_get_size(struct macb *bp)
{
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
- return sizeof(struct macb_dma_desc) + sizeof(struct macb_dma_desc_64);
+#ifdef MACB_EXT_DESC
+ unsigned int desc_size;
+
+ switch (bp->hw_dma_cap) {
+ case HW_DMA_CAP_64B:
+ desc_size = sizeof(struct macb_dma_desc)
+ + sizeof(struct macb_dma_desc_64);
+ break;
+ case HW_DMA_CAP_PTP:
+ desc_size = sizeof(struct macb_dma_desc)
+ + sizeof(struct macb_dma_desc_ptp);
+ break;
+ case HW_DMA_CAP_64B_PTP:
+ desc_size = sizeof(struct macb_dma_desc)
+ + sizeof(struct macb_dma_desc_64)
+ + sizeof(struct macb_dma_desc_ptp);
+ break;
+ default:
+ desc_size = sizeof(struct macb_dma_desc);
+ }
+ return desc_size;
#endif
return sizeof(struct macb_dma_desc);
}
-static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int idx)
+static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx)
{
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- /* Dma buffer descriptor is 4 words length (instead of 2 words)
- * for 64b GEM.
- */
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
- idx <<= 1;
+#ifdef MACB_EXT_DESC
+ switch (bp->hw_dma_cap) {
+ case HW_DMA_CAP_64B:
+ case HW_DMA_CAP_PTP:
+ desc_idx <<= 1;
+ break;
+ case HW_DMA_CAP_64B_PTP:
+ desc_idx *= 3;
+ break;
+ default:
+ break;
+ }
+ return desc_idx;
#endif
- return idx;
+ return desc_idx;
}
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc)
{
- return (struct macb_dma_desc_64 *)((void *)desc + sizeof(struct macb_dma_desc));
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
+ return (struct macb_dma_desc_64 *)((void *)desc + sizeof(struct macb_dma_desc));
+ return NULL;
}
#endif
@@ -600,7 +651,7 @@ static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
struct macb_dma_desc_64 *desc_64;
- if (bp->hw_dma_cap == HW_DMA_CAP_64B) {
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B) {
desc_64 = macb_64b_desc(bp, desc);
desc_64->addrh = upper_32_bits(addr);
}
@@ -614,7 +665,7 @@ static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc)
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
struct macb_dma_desc_64 *desc_64;
- if (bp->hw_dma_cap == HW_DMA_CAP_64B) {
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B) {
desc_64 = macb_64b_desc(bp, desc);
addr = ((u64)(desc_64->addrh) << 32);
}
@@ -713,7 +764,7 @@ static void macb_tx_error_task(struct work_struct *work)
/* Reinitialize the TX desc queue */
queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma));
#endif
/* Make TX ring reflect state of hardware */
@@ -775,6 +826,16 @@ static void macb_tx_interrupt(struct macb_queue *queue)
/* First, update TX stats if needed */
if (skb) {
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (gem_ptp_do_txstamp(queue, skb, desc) == 0) {
+ /* skb now belongs to timestamp buffer
+ * and will be removed later
+ */
+ tx_skb->skb = NULL;
+ schedule_work(&queue->tx_ts_task);
+
+ }
+#endif
netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
macb_tx_ring_wrap(bp, tail),
skb->data);
@@ -941,6 +1002,10 @@ static int gem_rx(struct macb *bp, int budget)
bp->stats.rx_packets++;
bp->stats.rx_bytes += skb->len;
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ gem_ptp_do_rxstamp(bp, skb, desc);
+#endif
+
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
@@ -1263,6 +1328,11 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
queue_writel(queue, ISR, MACB_BIT(HRESP));
}
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (status & MACB_PTP_INT_MASK)
+ macb_ptp_int(queue, status);
+#endif
+
status = queue_readl(queue, ISR);
}
@@ -1592,8 +1662,10 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Make newly initialized descriptor visible to hardware */
wmb();
-
- skb_tx_timestamp(skb);
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (!bp->ptp_hw_support)
+#endif
+ skb_tx_timestamp(skb);
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
@@ -1921,9 +1993,13 @@ static void macb_configure_dma(struct macb *bp)
dmacfg &= ~GEM_BIT(TXCOEN);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
dmacfg |= GEM_BIT(ADDR64);
#endif
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (bp->hw_dma_cap & HW_DMA_CAP_PTP)
+ dmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT);
+#endif
netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
dmacfg);
gem_writel(bp, DMACFG, dmacfg);
@@ -1971,21 +2047,22 @@ static void macb_init_hw(struct macb *bp)
/* Initialize TX and RX buffers */
macb_writel(bp, RBQP, lower_32_bits(bp->rx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
macb_writel(bp, RBQPH, upper_32_bits(bp->rx_ring_dma));
#endif
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
- queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma));
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
+ queue_writel(queue, TBQPH,
+ upper_32_bits(queue->tx_ring_dma));
#endif
/* Enable interrupts */
queue_writel(queue, IER,
- MACB_RX_INT_FLAGS |
- MACB_TX_INT_FLAGS |
- MACB_BIT(HRESP));
+ MACB_RX_INT_FLAGS |
+ MACB_TX_INT_FLAGS |
+ MACB_BIT(HRESP));
}
/* Enable TX and RX */
@@ -2446,6 +2523,71 @@ static int macb_set_ringparam(struct net_device *netdev,
return 0;
}
+#ifdef CONFIG_MACB_USE_HWSTAMP
+static unsigned int gem_get_tsu_rate(struct macb *bp)
+{
+ struct clk *tsu_clk;
+ unsigned int tsu_rate;
+
+ tsu_clk = devm_clk_get(&bp->pdev->dev, "tsu_clk");
+ if (!IS_ERR(tsu_clk))
+ tsu_rate = clk_get_rate(tsu_clk);
+ /* try pclk instead */
+ else if (!IS_ERR(bp->pclk)) {
+ tsu_clk = bp->pclk;
+ tsu_rate = clk_get_rate(tsu_clk);
+ } else
+ return -ENOTSUPP;
+ return tsu_rate;
+}
+
+static s32 gem_get_ptp_max_adj(void)
+{
+ return 64E6;
+}
+
+static int gem_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct macb *bp = netdev_priv(dev);
+
+ ethtool_op_get_ts_info(dev, info);
+ if (!bp->ptp_hw_support)
+ return 0;
+
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_ONESTEP_SYNC) |
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_ALL);
+ info->phc_index = -1;
+
+ if (bp->ptp_clock)
+ info->phc_index = ptp_clock_index(bp->ptp_clock);
+
+ return 0;
+}
+
+static struct macb_ptp_info gem_ptp_info = {
+ .ptp_init = gem_ptp_init,
+ .ptp_remove = gem_ptp_remove,
+ .get_ptp_max_adj = gem_get_ptp_max_adj,
+ .get_tsu_rate = gem_get_tsu_rate,
+ .get_ts_info = gem_get_ts_info,
+ .get_hwtst = gem_get_hwtst,
+ .set_hwtst = gem_set_hwtst,
+};
+#endif
+
static int macb_get_ts_info(struct net_device *netdev,
struct ethtool_ts_info *info)
{
@@ -2579,6 +2721,18 @@ static void macb_configure_caps(struct macb *bp,
dcfg = gem_readl(bp, DCFG2);
if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
bp->caps |= MACB_CAPS_FIFO_MODE;
+ /* if HWSTAMP is configure and gem has the capability */
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ bp->ptp_hw_support = false;
+ if (gem_has_ptp(bp)) {
+ if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5)))
+ pr_err("GEM doesn't support hardware ptp.\n");
+ else {
+ bp->ptp_hw_support = true;
+ bp->ptp_info = &gem_ptp_info;
+ }
+ }
+#endif
}
dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
@@ -2716,7 +2870,7 @@ static int macb_init(struct platform_device *pdev)
queue->IMR = GEM_IMR(hw_q - 1);
queue->TBQP = GEM_TBQP(hw_q - 1);
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
queue->TBQPH = GEM_TBQPH(hw_q - 1);
#endif
} else {
@@ -2727,7 +2881,7 @@ static int macb_init(struct platform_device *pdev)
queue->IMR = MACB_IMR;
queue->TBQP = MACB_TBQP;
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (bp->hw_dma_cap == HW_DMA_CAP_64B)
+ if (bp->hw_dma_cap & HW_DMA_CAP_64B)
queue->TBQPH = MACB_TBQPH;
#endif
}
@@ -3184,7 +3338,9 @@ static const struct macb_config np4_config = {
};
static const struct macb_config zynqmp_config = {
- .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO,
+ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+ MACB_CAPS_JUMBO |
+ MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@@ -3218,7 +3374,9 @@ MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */
static const struct macb_config default_gem_config = {
- .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO,
+ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+ MACB_CAPS_JUMBO |
+ MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@@ -3307,19 +3465,24 @@ static int macb_probe(struct platform_device *pdev)
bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) {
- dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
- bp->hw_dma_cap = HW_DMA_CAP_64B;
- } else
- bp->hw_dma_cap = HW_DMA_CAP_32B;
-#endif
-
spin_lock_init(&bp->lock);
/* setup capabilities */
macb_configure_caps(bp, macb_config);
+#ifdef MACB_EXT_DESC
+ bp->hw_dma_cap = HW_DMA_CAP_32B;
+#endif
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) {
+ dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
+ bp->hw_dma_cap |= HW_DMA_CAP_64B;
+ }
+#endif
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (bp->ptp_hw_support)
+ bp->hw_dma_cap |= HW_DMA_CAP_PTP;
+#endif
platform_set_drvdata(pdev, dev);
dev->irq = platform_get_irq(pdev, 0);
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 234a49e..07a1e8e 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -11,6 +11,13 @@
#define _MACB_H
#include <linux/phy.h>
+#include <linux/ptp_clock.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/net_tstamp.h>
+
+#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) || defined(CONFIG_MACB_USE_HWSTAMP)
+#define MACB_EXT_DESC
+#endif
#define MACB_GREGS_NBR 16
#define MACB_GREGS_VERSION 2
@@ -86,6 +93,10 @@
#define GEM_SA3T 0x009C /* Specific3 Top */
#define GEM_SA4B 0x00A0 /* Specific4 Bottom */
#define GEM_SA4T 0x00A4 /* Specific4 Top */
+#define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */
+#define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */
+#define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */
+#define GEM_PEFRSH 0x00f4 /* PTP Peer Event Frame Received Seconds Register 47:32 */
#define GEM_OTX 0x0100 /* Octets transmitted */
#define GEM_OCTTXL 0x0100 /* Octets transmitted [31:0] */
#define GEM_OCTTXH 0x0104 /* Octets transmitted [47:32] */
@@ -155,6 +166,9 @@
#define GEM_DCFG6 0x0294 /* Design Config 6 */
#define GEM_DCFG7 0x0298 /* Design Config 7 */
+#define GEM_TXBDCTRL 0x04cc /* TX Buffer Descriptor control register */
+#define GEM_RXBDCTRL 0x04d0 /* RX Buffer Descriptor control register */
+
#define GEM_ISR(hw_q) (0x0400 + ((hw_q) << 2))
#define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2))
#define GEM_TBQPH(hw_q) (0x04C8)
@@ -191,6 +205,8 @@
#define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */
#define MACB_TZQ_SIZE 1
#define MACB_SRTSM_OFFSET 15
+#define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */
+#define MACB_OSSMODE_SIZE 1
/* Bitfields in NCFGR */
#define MACB_SPD_OFFSET 0 /* Speed */
@@ -269,6 +285,10 @@
#define GEM_RXBS_SIZE 8
#define GEM_DDRP_OFFSET 24 /* disc_when_no_ahb */
#define GEM_DDRP_SIZE 1
+#define GEM_RXEXT_OFFSET 28 /* RX extended Buffer Descriptor mode */
+#define GEM_RXEXT_SIZE 1
+#define GEM_TXEXT_OFFSET 29 /* TX extended Buffer Descriptor mode */
+#define GEM_TXEXT_SIZE 1
#define GEM_ADDR64_OFFSET 30 /* Address bus width - 64b or 32b */
#define GEM_ADDR64_SIZE 1
@@ -354,6 +374,16 @@
#define MACB_PDRSFT_SIZE 1
#define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */
#define MACB_SRI_SIZE 1
+#define MACB_TCI_OFFSET 29 /* TSU timer comparison interrupt */
+#define MACB_TCI_SIZE 1
+#define MACB_PTP_INT_MASK (MACB_BIT(DRQFR) \
+ | MACB_BIT(SFR) \
+ | MACB_BIT(DRQFT) \
+ | MACB_BIT(SFT) \
+ | MACB_BIT(PDRQFR) \
+ | MACB_BIT(PDRSFR) \
+ | MACB_BIT(PDRQFT) \
+ | MACB_BIT(PDRSFT))
/* Timer increment fields */
#define MACB_TI_CNS_OFFSET 0
@@ -425,6 +455,11 @@
#define GEM_TX_PKT_BUFF_OFFSET 21
#define GEM_TX_PKT_BUFF_SIZE 1
+
+/* Bitfields in DCFG5. */
+#define GEM_TSU_OFFSET 8
+#define GEM_TSU_SIZE 1
+
/* Bitfields in DCFG6. */
#define GEM_PBUF_LSO_OFFSET 27
#define GEM_PBUF_LSO_SIZE 1
@@ -439,6 +474,52 @@
#define GEM_NSINCR_OFFSET 0
#define GEM_NSINCR_SIZE 8
+/* Bitfields in TSH */
+#define GEM_TSH_OFFSET 0 /* TSU timer value (s). MSB [47:32] of seconds timer count */
+#define GEM_TSH_SIZE 16
+
+/* Bitfields in TSL */
+#define GEM_TSL_OFFSET 0 /* TSU timer value (s). LSB [31:0] of seconds timer count */
+#define GEM_TSL_SIZE 32
+
+/* Bitfields in TN */
+#define GEM_TN_OFFSET 0 /* TSU timer value (ns) */
+#define GEM_TN_SIZE 30
+
+/* Bitfields in TXBDCTRL */
+#define GEM_TXTSMODE_OFFSET 4 /* TX Descriptor Timestamp Insertion mode */
+#define GEM_TXTSMODE_SIZE 2
+
+/* Bitfields in RXBDCTRL */
+#define GEM_RXTSMODE_OFFSET 4 /* RX Descriptor Timestamp Insertion mode */
+#define GEM_RXTSMODE_SIZE 2
+
+/* Transmit DMA buffer descriptor Word 1 */
+#define GEM_DMA_TXVALID_OFFSET 23 /* timestamp has been captured in the Buffer Descriptor */
+#define GEM_DMA_TXVALID_SIZE 1
+
+/* Receive DMA buffer descriptor Word 0 */
+#define GEM_DMA_RXVALID_OFFSET 2 /* indicates a valid timestamp in the Buffer Descriptor */
+#define GEM_DMA_RXVALID_SIZE 1
+
+/* DMA buffer descriptor Word 2 (32 bit addressing) or Word 4 (64 bit addressing) */
+#define GEM_DMA_SECL_OFFSET 30 /* Timestamp seconds[1:0] */
+#define GEM_DMA_SECL_SIZE 2
+#define GEM_DMA_NSEC_OFFSET 0 /* Timestamp nanosecs [29:0] */
+#define GEM_DMA_NSEC_SIZE 30
+
+/* DMA buffer descriptor Word 3 (32 bit addressing) or Word 5 (64 bit addressing) */
+
+/* New hardware supports 12 bit precision of timestamp in DMA buffer descriptor.
+ * Old hardware supports only 6 bit precision but it is enough for PTP.
+ * Less accuracy is used always instead of checking hardware version.
+ */
+#define GEM_DMA_SECH_OFFSET 0 /* Timestamp seconds[5:2] */
+#define GEM_DMA_SECH_SIZE 4
+#define GEM_DMA_SEC_WIDTH (GEM_DMA_SECH_SIZE + GEM_DMA_SECL_SIZE)
+#define GEM_DMA_SEC_TOP (1 << GEM_DMA_SEC_WIDTH)
+#define GEM_DMA_SEC_MASK (GEM_DMA_SEC_TOP - 1)
+
/* Bitfields in ADJ */
#define GEM_ADDSUB_OFFSET 31
#define GEM_ADDSUB_SIZE 1
@@ -514,6 +595,8 @@
#define queue_readl(queue, reg) (queue)->bp->macb_reg_readl((queue)->bp, (queue)->reg)
#define queue_writel(queue, reg, value) (queue)->bp->macb_reg_writel((queue)->bp, (queue)->reg, (value))
+#define PTP_TS_BUFFER_SIZE 128 /* must be power of 2 */
+
/* Conditional GEM/MACB macros. These perform the operation to the correct
* register dependent on whether the device is a GEM or a MACB. For registers
* and bitfields that are common across both devices, use macb_{read,write}l
@@ -546,16 +629,21 @@ struct macb_dma_desc {
u32 ctrl;
};
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
-enum macb_hw_dma_cap {
- HW_DMA_CAP_32B,
- HW_DMA_CAP_64B,
-};
+#ifdef MACB_EXT_DESC
+#define HW_DMA_CAP_32B 0
+#define HW_DMA_CAP_64B (1 << 0)
+#define HW_DMA_CAP_PTP (1 << 1)
+#define HW_DMA_CAP_64B_PTP (HW_DMA_CAP_64B | HW_DMA_CAP_PTP)
struct macb_dma_desc_64 {
u32 addrh;
u32 resvd;
};
+
+struct macb_dma_desc_ptp {
+ u32 ts_1;
+ u32 ts_2;
+};
#endif
/* DMA descriptor bitfields */
@@ -871,6 +959,18 @@ struct macb_config {
int jumbo_max_len;
};
+#ifdef CONFIG_MACB_USE_HWSTAMP
+struct tsu_incr {
+ u32 sub_ns;
+ u32 ns;
+};
+
+struct gem_tx_ts {
+ struct sk_buff *skb;
+ struct macb_dma_desc_ptp desc_ptp;
+};
+#endif
+
struct macb_queue {
struct macb *bp;
int irq;
@@ -887,6 +987,12 @@ struct macb_queue {
struct macb_tx_skb *tx_skb;
dma_addr_t tx_ring_dma;
struct work_struct tx_error_task;
+
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ struct work_struct tx_ts_task;
+ unsigned int tx_ts_head, tx_ts_tail;
+ struct gem_tx_ts tx_timestamps[PTP_TS_BUFFER_SIZE];
+#endif
};
struct macb {
@@ -955,11 +1061,67 @@ struct macb {
u32 wol;
struct macb_ptp_info *ptp_info; /* macb-ptp interface */
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
- enum macb_hw_dma_cap hw_dma_cap;
+#ifdef MACB_EXT_DESC
+ uint8_t hw_dma_cap;
+#endif
+
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ bool ptp_hw_support;
+ spinlock_t tsu_clk_lock; /* gem tsu clock locking */
+ unsigned int tsu_rate;
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_clock_info;
+ struct tsu_incr tsu_incr;
+ struct hwtstamp_config tstamp_config;
#endif
};
+#ifdef CONFIG_MACB_USE_HWSTAMP
+#define GEM_TSEC_SIZE (GEM_TSH_SIZE + GEM_TSL_SIZE)
+#define TSU_SEC_MAX_VAL (((u64)1 << GEM_TSEC_SIZE) - 1)
+#define TSU_NSEC_MAX_VAL ((1 << GEM_TN_SIZE) - 1)
+
+enum macb_bd_control {
+ TSTAMP_DISABLED,
+ TSTAMP_FRAME_PTP_EVENT_ONLY,
+ TSTAMP_ALL_PTP_FRAMES,
+ TSTAMP_ALL_FRAMES,
+};
+
+void gem_ptp_init(struct net_device *ndev);
+void gem_ptp_remove(struct net_device *ndev);
+int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *des);
+void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
+void macb_ptp_int(struct macb_queue *queue, u32 status);
+static inline int gem_ptp_do_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *desc)
+{
+ if (queue->bp->tstamp_config.tx_type == TSTAMP_DISABLED)
+ return -ENOTSUPP;
+
+ return gem_ptp_txstamp(queue, skb, desc);
+}
+
+static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc)
+{
+ if (bp->tstamp_config.rx_filter == TSTAMP_DISABLED)
+ return;
+
+ gem_ptp_rxstamp(bp, skb, desc);
+}
+int gem_get_hwtst(struct net_device *dev, struct ifreq *rq);
+int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd);
+#else
+static inline void gem_ptp_init(struct net_device *ndev) { }
+static inline void gem_ptp_remove(struct net_device *ndev) { }
+
+static inline int gem_ptp_do_txstamp(struct macb_queue *queue, struct sk_buff *skb, struct macb_dma_desc *desc)
+{
+ return 0;
+}
+
+static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
+#endif
+
static inline bool macb_is_gem(struct macb *bp)
{
return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
new file mode 100755
index 0000000..72a79c4
--- /dev/null
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -0,0 +1,724 @@
+/**
+ * 1588 PTP support for Cadence GEM device.
+ *
+ * Copyright (C) 2017 Cadence Design Systems - http://www.cadence.com
+ *
+ * Authors: Rafal Ozieblo <rafalo@cadence.com>
+ * Bartosz Folta <bfolta@cadence.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/time64.h>
+#include <linux/ptp_classify.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/net_tstamp.h>
+#include <linux/circ_buf.h>
+#include <linux/spinlock.h>
+
+#include "macb.h"
+
+#define GEM_PTP_TIMER_NAME "gem-ptp-timer"
+
+static struct macb_dma_desc_ptp *macb_ptp_desc(struct macb *bp,
+ struct macb_dma_desc *desc)
+{
+ if (bp->hw_dma_cap == HW_DMA_CAP_PTP)
+ return (struct macb_dma_desc_ptp *)
+ ((u8 *)desc + sizeof(struct macb_dma_desc));
+ if (bp->hw_dma_cap == HW_DMA_CAP_64B_PTP)
+ return (struct macb_dma_desc_ptp *)
+ ((u8 *)desc + sizeof(struct macb_dma_desc)
+ + sizeof(struct macb_dma_desc_64));
+ return NULL;
+}
+
+static int gem_tsu_get_time(struct macb *bp, struct timespec64 *ts)
+{
+ long first, second;
+ u32 secl, sech;
+ unsigned long flags;
+
+ if (!bp || !ts)
+ return -EINVAL;
+
+ spin_lock_irqsave(&bp->tsu_clk_lock, flags);
+ first = gem_readl(bp, TN);
+ secl = gem_readl(bp, TSL);
+ sech = gem_readl(bp, TSH);
+ second = gem_readl(bp, TN);
+
+ /* test for nsec rollover */
+ if (first > second) {
+ /* if so, use later read & re-read seconds
+ * (assume all done within 1s)
+ */
+ ts->tv_nsec = gem_readl(bp, TN);
+ secl = gem_readl(bp, TSL);
+ sech = gem_readl(bp, TSH);
+ } else
+ ts->tv_nsec = first;
+
+ ts->tv_sec = (((u64)sech << GEM_TSL_SIZE) | secl)
+ & TSU_SEC_MAX_VAL;
+
+ spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);
+ return 0;
+}
+
+static int gem_tsu_set_time(struct macb *bp, const struct timespec64 *ts)
+{
+ u32 ns, sech, secl;
+ unsigned long flags;
+
+ if (!bp || !ts)
+ return -EINVAL;
+
+ secl = (u32)ts->tv_sec;
+ sech = (ts->tv_sec >> GEM_TSL_SIZE) & ((1 << GEM_TSH_SIZE) - 1);
+ ns = ts->tv_nsec;
+
+ spin_lock_irqsave(&bp->tsu_clk_lock, flags);
+
+ /* TSH doesn't latch the time and no atomicity! */
+ gem_writel(bp, TN, 0); /* clear to avoid overflow */
+ gem_writel(bp, TSH, sech);
+ /* write lower bits 2nd, for synchronized secs update */
+ gem_writel(bp, TSL, secl);
+ gem_writel(bp, TN, ns);
+
+ spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);
+
+ return 0;
+}
+
+static int gem_tsu_incr_set(struct macb *bp, struct tsu_incr *incr_spec)
+{
+ unsigned long flags;
+
+ if (!bp || !incr_spec)
+ return -EINVAL;
+
+ /* tsu_timer_incr register must be written after
+ * the tsu_timer_incr_sub_ns register and the write operation
+ * will cause the value written to the tsu_timer_incr_sub_ns register
+ * to take effect.
+ */
+ spin_lock_irqsave(&bp->tsu_clk_lock, flags);
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, incr_spec->sub_ns));
+ gem_writel(bp, TI, GEM_BF(NSINCR, incr_spec->ns));
+ spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);
+
+ return 0;
+}
+
+static int gem_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+ struct tsu_incr incr_spec;
+ struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
+ u64 adj;
+ u32 word;
+ bool neg_adj = false;
+
+ if (!ptp)
+ return -EINVAL;
+
+ if (scaled_ppm < 0) {
+ neg_adj = true;
+ scaled_ppm = -scaled_ppm;
+ }
+
+ /* Adjustment is relative to base frequency */
+ incr_spec.sub_ns = bp->tsu_incr.sub_ns;
+ incr_spec.ns = bp->tsu_incr.ns;
+
+ /* scaling: unused(8bit) | ns(8bit) | fractions(16bit) */
+ word = ((u64)incr_spec.ns << GEM_SUBNSINCR_SIZE) + incr_spec.sub_ns;
+ adj = (u64)scaled_ppm * word;
+ /* Divide with rounding, equivalent to floating dividing:
+ * (temp / USEC_PER_SEC) + 0.5
+ */
+ adj += (USEC_PER_SEC >> 1);
+ adj >>= GEM_SUBNSINCR_SIZE; /* remove fractions */
+ adj = div_u64(adj, USEC_PER_SEC);
+ adj = neg_adj ? (word - adj) : (word + adj);
+
+ incr_spec.ns = (adj >> GEM_SUBNSINCR_SIZE)
+ & ((1 << GEM_NSINCR_SIZE) - 1);
+ incr_spec.sub_ns = adj & ((1 << GEM_SUBNSINCR_SIZE) - 1);
+ gem_tsu_incr_set(bp, &incr_spec);
+ return 0;
+}
+
+static int gem_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct timespec64 now, then = ns_to_timespec64(delta);
+ struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
+ u32 adj, sign = 0;
+
+ if (!ptp)
+ return -EINVAL;
+
+ if (delta < 0) {
+ sign = 1;
+ delta = -delta;
+ }
+
+ if (delta > TSU_NSEC_MAX_VAL) {
+ gem_tsu_get_time(bp, &now);
+ if (sign)
+ now = timespec64_sub(now, then);
+ else
+ now = timespec64_add(now, then);
+
+ gem_tsu_set_time(bp, (const struct timespec64 *)&now);
+ } else {
+ adj = (sign << GEM_ADDSUB_OFFSET) | delta;
+
+ gem_writel(bp, TA, adj);
+ }
+
+ return 0;
+}
+
+static int gem_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
+
+ if (!ptp || !ts)
+ return -EINVAL;
+
+ gem_tsu_get_time(bp, ts);
+ return 0;
+}
+
+static int gem_ptp_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
+
+ if (!ptp || !ts)
+ return -EINVAL;
+
+ gem_tsu_set_time(bp, ts);
+ return 0;
+}
+
+static int gem_ptp_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
+
+ if (!ptp || !rq)
+ return -EINVAL;
+
+ switch (rq->type) {
+ case PTP_CLK_REQ_EXTTS: /* Toggle TSU match interrupt */
+ if (on)
+ macb_writel(bp, IER, MACB_BIT(TCI));
+ else
+ macb_writel(bp, IDR, MACB_BIT(TCI));
+ break;
+ case PTP_CLK_REQ_PEROUT: /* Toggle Periodic output */
+ return -EOPNOTSUPP;
+ /* break; */
+ case PTP_CLK_REQ_PPS: /* Toggle TSU periodic (second) interrupt */
+ if (on)
+ macb_writel(bp, IER, MACB_BIT(SRI));
+ else
+ macb_writel(bp, IDR, MACB_BIT(SRI));
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct ptp_clock_info gem_ptp_caps_template = {
+ .owner = THIS_MODULE,
+ .name = GEM_PTP_TIMER_NAME,
+ .max_adj = 0,
+ .n_alarm = 1,
+ .n_ext_ts = 1,
+ .n_per_out = 0,
+ .n_pins = 0,
+ .pps = 1,
+ .adjfine = gem_ptp_adjfine,
+ .adjtime = gem_ptp_adjtime,
+ .gettime64 = gem_ptp_gettime,
+ .settime64 = gem_ptp_settime,
+ .enable = gem_ptp_enable,
+};
+
+static void gem_ptp_init_timer(struct macb *bp)
+{
+ u32 rem = 0;
+
+ bp->tsu_incr.ns = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem);
+ if (rem) {
+ u64 adj = rem;
+
+ adj <<= GEM_SUBNSINCR_SIZE;
+ bp->tsu_incr.sub_ns = div_u64(adj, bp->tsu_rate);
+ } else {
+ bp->tsu_incr.sub_ns = 0;
+ }
+}
+
+static void gem_ptp_init_tsu(struct macb *bp)
+{
+ struct timespec64 ts;
+
+ /* 1. get current system time */
+ ts = ns_to_timespec64(ktime_to_ns(ktime_get_real()));
+
+ /* 2. set ptp timer */
+ gem_tsu_set_time(bp, &ts);
+
+ /* 3. set PTP timer increment value to BASE_INCREMENT */
+ gem_tsu_incr_set(bp, &bp->tsu_incr);
+
+ gem_writel(bp, TA, 0);
+}
+
+static void gem_ptp_clear_timer(struct macb *bp)
+{
+ bp->tsu_incr.ns = 0;
+ bp->tsu_incr.sub_ns = 0;
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, 0));
+ gem_writel(bp, TI, GEM_BF(NSINCR, 0));
+ gem_writel(bp, TA, 0);
+}
+
+static int gem_hw_timestamp(struct macb *bp,
+ u32 dma_desc_ts_1, u32 dma_desc_ts_2, struct timespec64 *ts)
+{
+ struct timespec64 tsu;
+
+ ts->tv_sec = (GEM_BFEXT(DMA_SECH, dma_desc_ts_2) << GEM_DMA_SECL_SIZE) |
+ GEM_BFEXT(DMA_SECL, dma_desc_ts_1);
+ ts->tv_nsec = GEM_BFEXT(DMA_NSEC, dma_desc_ts_1);
+
+ /* TSU overlaping workaround
+ * The timestamp only contains lower few bits of seconds,
+ * so add value from 1588 timer
+ */
+ gem_tsu_get_time(bp, &tsu);
+
+ /* If the top bit is set in the timestamp,
+ * but not in 1588 timer, it has rolled over,
+ * so subtract max size
+ */
+ if ((ts->tv_sec & (GEM_DMA_SEC_TOP >> 1)) &&
+ !(tsu.tv_sec & (GEM_DMA_SEC_TOP >> 1)))
+ ts->tv_sec -= GEM_DMA_SEC_TOP;
+
+ ts->tv_sec += ((~GEM_DMA_SEC_MASK) & (tsu.tv_sec));
+
+ return 0;
+}
+
+void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb,
+ struct macb_dma_desc *desc)
+{
+ struct timespec64 ts;
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct macb_dma_desc_ptp *desc_ptp;
+
+ if (GEM_BFEXT(DMA_RXVALID, desc->addr)) {
+ desc_ptp = macb_ptp_desc(bp, desc);
+ gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
+ }
+}
+
+static void gem_tstamp_tx(struct macb *bp, struct sk_buff *skb,
+ struct macb_dma_desc_ptp *desc_ptp)
+{
+ struct skb_shared_hwtstamps shhwtstamps;
+ struct timespec64 ts;
+
+ gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts);
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
+ skb_tstamp_tx(skb, &shhwtstamps);
+}
+
+int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb,
+ struct macb_dma_desc *desc)
+{
+ struct gem_tx_ts *tx_timestamp;
+ struct macb_dma_desc_ptp *desc_ptp;
+ unsigned long head = queue->tx_ts_head;
+ unsigned long tail = READ_ONCE(queue->tx_ts_tail);
+
+ if (!GEM_BFEXT(DMA_TXVALID, desc->ctrl))
+ return -EINVAL;
+
+ if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0)
+ return -ENOMEM;
+
+ desc_ptp = macb_ptp_desc(queue->bp, desc);
+ tx_timestamp = &queue->tx_timestamps[head];
+ tx_timestamp->skb = skb;
+ tx_timestamp->desc_ptp.ts_1 = desc_ptp->ts_1;
+ tx_timestamp->desc_ptp.ts_2 = desc_ptp->ts_2;
+ /* move head */
+ smp_store_release(&queue->tx_ts_head,
+ (head + 1) & (PTP_TS_BUFFER_SIZE - 1));
+ return 0;
+}
+
+static void gem_tx_timestamp_flush(struct work_struct *work)
+{
+ struct macb_queue *queue =
+ container_of(work, struct macb_queue, tx_ts_task);
+ struct gem_tx_ts *tx_ts;
+ unsigned long head, tail;
+
+ /* take current head */
+ head = smp_load_acquire(&queue->tx_ts_head);
+ tail = queue->tx_ts_tail;
+
+ while (CIRC_CNT(head, tail, PTP_TS_BUFFER_SIZE)) {
+ tx_ts = &queue->tx_timestamps[tail];
+ gem_tstamp_tx(queue->bp, tx_ts->skb, &tx_ts->desc_ptp);
+ /* cleanup */
+ dev_kfree_skb_any(tx_ts->skb);
+ /* remove old tail */
+ smp_store_release(&queue->tx_ts_tail,
+ (tail + 1) & (PTP_TS_BUFFER_SIZE - 1));
+ tail = queue->tx_ts_tail;
+ }
+}
+
+void gem_ptp_init(struct net_device *dev)
+{
+ struct macb *bp = netdev_priv(dev);
+ unsigned int q;
+ struct macb_queue *queue;
+
+ bp->ptp_clock_info = gem_ptp_caps_template;
+
+ /* nominal frequency and maximum adjustment in ppb */
+ bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
+ bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
+ gem_ptp_init_timer(bp);
+ bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev);
+ if (IS_ERR(&bp->ptp_clock)) {
+ bp->ptp_clock = NULL;
+ pr_err("ptp clock register failed\n");
+ return;
+ }
+
+ spin_lock_init(&bp->tsu_clk_lock);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ queue->tx_ts_head = 0;
+ queue->tx_ts_tail = 0;
+ INIT_WORK(&queue->tx_ts_task, gem_tx_timestamp_flush);
+ queue_writel(queue, IER, MACB_PTP_INT_MASK);
+ }
+
+ gem_ptp_init_tsu(bp);
+
+ dev_info(&bp->pdev->dev, "%s ptp clock registered.\n",
+ GEM_PTP_TIMER_NAME);
+}
+
+void gem_ptp_remove(struct net_device *ndev)
+{
+ struct macb *bp = netdev_priv(ndev);
+
+ if (bp->ptp_clock)
+ ptp_clock_unregister(bp->ptp_clock);
+
+ gem_ptp_clear_timer(bp);
+
+ dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n",
+ GEM_PTP_TIMER_NAME);
+}
+
+static int gem_ptp_set_ts_mode(struct macb *bp,
+ enum macb_bd_control tx_bd_control,
+ enum macb_bd_control rx_bd_control)
+{
+ if (!bp)
+ return -EINVAL;
+
+ gem_writel(bp, TXBDCTRL, GEM_BF(TXTSMODE, tx_bd_control));
+ gem_writel(bp, RXBDCTRL, GEM_BF(RXTSMODE, rx_bd_control));
+
+ return 0;
+}
+
+int gem_get_hwtst(struct net_device *dev, struct ifreq *rq)
+{
+ struct macb *bp = netdev_priv(dev);
+ struct hwtstamp_config *tstamp_config = &bp->tstamp_config;
+
+ if (!bp->ptp_hw_support)
+ return -EFAULT;
+
+ if (copy_to_user(rq->ifr_data, tstamp_config, sizeof(*tstamp_config)))
+ return -EFAULT;
+ else
+ return 0;
+}
+
+static int gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
+{
+ u32 reg_val;
+
+ if (!bp || enable > 1)
+ return -EINVAL;
+
+ reg_val = macb_readl(bp, NCR);
+
+ if (enable)
+ macb_writel(bp, NCR, reg_val | MACB_BIT(OSSMODE));
+ else
+ macb_writel(bp, NCR, reg_val & ~MACB_BIT(OSSMODE));
+
+ return 0;
+}
+
+int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct macb *bp = netdev_priv(dev);
+ struct hwtstamp_config *tstamp_config = &bp->tstamp_config;
+ enum macb_bd_control tx_bd_control = TSTAMP_DISABLED;
+ enum macb_bd_control rx_bd_control = TSTAMP_DISABLED;
+ u32 regval;
+
+ if (!bp->ptp_hw_support)
+ return -EFAULT;
+
+ if (copy_from_user(tstamp_config, ifr->ifr_data,
+ sizeof(*tstamp_config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (tstamp_config->flags)
+ return -EINVAL;
+
+ switch (tstamp_config->tx_type) {
+ case HWTSTAMP_TX_OFF:
+ break;
+ case HWTSTAMP_TX_ONESTEP_SYNC:
+ if (gem_ptp_set_one_step_sync(bp, 1) != 0)
+ return -ERANGE;
+ case HWTSTAMP_TX_ON:
+ tx_bd_control = TSTAMP_ALL_FRAMES;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (tstamp_config->rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ rx_bd_control = TSTAMP_ALL_PTP_FRAMES;
+ tstamp_config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ regval = macb_readl(bp, NCR);
+ macb_writel(bp, NCR, (regval | MACB_BIT(SRTSM)));
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ rx_bd_control = TSTAMP_ALL_FRAMES;
+ tstamp_config->rx_filter = HWTSTAMP_FILTER_ALL;
+ break;
+ default:
+ tstamp_config->rx_filter = HWTSTAMP_FILTER_NONE;
+ return -ERANGE;
+ }
+
+ if (gem_ptp_set_ts_mode(bp, tx_bd_control, rx_bd_control) != 0)
+ return -ERANGE;
+
+ if (copy_to_user(ifr->ifr_data, tstamp_config, sizeof(*tstamp_config)))
+ return -EFAULT;
+ else
+ return 0;
+}
+
+static int gem_ptp_time_peer_frame_tx_get(struct macb *bp,
+ struct timespec64 *ts)
+{
+ if (!bp || !ts)
+ return -EINVAL;
+
+ ts->tv_sec = (((u64)gem_readl(bp, PEFTSH) << 32) |
+ gem_readl(bp, PEFTSL)) & TSU_SEC_MAX_VAL;
+ ts->tv_nsec = gem_readl(bp, PEFTN);
+
+ return 0;
+}
+
+static int gem_ptp_time_peer_frame_rx_get(struct macb *bp,
+ struct timespec64 *ts)
+{
+ if (!bp || !ts)
+ return -EINVAL;
+
+ ts->tv_sec = (((u64)gem_readl(bp, PEFRSH) << 32) |
+ gem_readl(bp, PEFRSL)) & TSU_SEC_MAX_VAL;
+ ts->tv_nsec = gem_readl(bp, PEFRN);
+
+ return 0;
+}
+
+static int gem_ptp_time_frame_tx_get(struct macb *bp, struct timespec64 *ts)
+{
+ if (!bp || !ts)
+ return -EINVAL;
+
+ ts->tv_sec = (((u64)gem_readl(bp, EFTSH) << 32) |
+ gem_readl(bp, EFTSL)) & TSU_SEC_MAX_VAL;
+ ts->tv_nsec = gem_readl(bp, EFTN);
+
+ return 0;
+}
+
+static int gem_ptp_time_frame_rx_get(struct macb *bp, struct timespec64 *ts)
+{
+ if (!bp || !ts)
+ return -EINVAL;
+
+ ts->tv_sec = (((u64)gem_readl(bp, EFRSH) << 32) |
+ gem_readl(bp, EFRSL)) & TSU_SEC_MAX_VAL;
+ ts->tv_nsec = gem_readl(bp, EFRN);
+
+ return 0;
+}
+
+static int gem_ptp_event(struct macb *bp, struct timespec64 *ts)
+{
+ struct ptp_clock_event event;
+
+ event.type = PTP_CLOCK_EXTTS;
+ event.index = 0;
+ event.timestamp = ts->tv_sec * NSEC_PER_SEC + ts->tv_nsec;
+
+ ptp_clock_event(bp->ptp_clock, &event);
+
+ return 0;
+}
+
+void macb_ptp_int(struct macb_queue *queue, u32 status)
+{
+ struct macb *bp = queue->bp;
+ struct timespec64 ts;
+
+ if (status & MACB_BIT(DRQFR)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(DRQFR));
+ if (gem_ptp_time_frame_rx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(SFR)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(SFR));
+ if (gem_ptp_time_frame_rx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(DRQFT)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(DRQFT));
+ if (gem_ptp_time_frame_tx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(SFT)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(SFT));
+ if (gem_ptp_time_frame_tx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(PDRQFR)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(PDRQFR));
+ if (gem_ptp_time_peer_frame_rx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(PDRSFR)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR, MACB_BIT(PDRSFR));
+ if (gem_ptp_time_peer_frame_rx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(PDRQFT)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR,
+ MACB_BIT(PDRQFT));
+ if (gem_ptp_time_peer_frame_tx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+
+ if (status & MACB_BIT(PDRSFT)) {
+ if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+ queue_writel(queue, ISR,
+ MACB_BIT(PDRSFT));
+ if (gem_ptp_time_peer_frame_tx_get(bp, &ts) != 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ gem_ptp_event(bp, &ts);
+ }
+}
--
2.4.5
^ permalink raw reply related
* Re: [PATCH v3 01/20] net: stmmac: export stmmac_set_mac_addr/stmmac_get_mac_addr
From: Giuseppe CAVALLARO @ 2017-04-03 12:39 UTC (permalink / raw)
To: Corentin Labbe, robh+dt, mark.rutland, maxime.ripard, wens, linux,
catalin.marinas, will.deacon, alexandre.torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, netdev
In-Reply-To: <20170403091444.29876-2-clabbe.montjoie@gmail.com>
Hello Alex
do you can check if this has to be done for ST platforms?
I do not remember that it was necessary when build as module so
I cannot expect this should be only for dwmac-sun8i.
Regards
peppe
On 4/3/2017 11:14 AM, Corentin Labbe wrote:
> Thoses symbol will be needed for the dwmac-sun8i ethernet driver.
> For letting it to be build as module, they need to be exported.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> index 38f9430..67af0bd 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
> @@ -248,6 +248,7 @@ void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
> data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
> writel(data, ioaddr + low);
> }
> +EXPORT_SYMBOL_GPL(stmmac_set_mac_addr);
>
> /* Enable disable MAC RX/TX */
> void stmmac_set_mac(void __iomem *ioaddr, bool enable)
> @@ -279,4 +280,4 @@ void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
> addr[4] = hi_addr & 0xff;
> addr[5] = (hi_addr >> 8) & 0xff;
> }
> -
> +EXPORT_SYMBOL_GPL(stmmac_get_mac_addr);
^ permalink raw reply
* Re: [PATCH v3 02/20] net: stmmac: add optional setup function
From: Giuseppe CAVALLARO @ 2017-04-03 12:32 UTC (permalink / raw)
To: Corentin Labbe, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
linux-I+IVW8TIWO2tmTQ+vhA3Yw, catalin.marinas-5wv7dgnIgG8,
will.deacon-5wv7dgnIgG8, alexandre.torgue-qxv4g6HH51o
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170403091444.29876-3-clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hello Corentin
On 4/3/2017 11:14 AM, Corentin Labbe wrote:
> Instead of adding more ifthen logic for adding a new mac_device_info
> setup function, it is easier to add a function pointer to the function
> needed.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +++-
> include/linux/stmmac.h | 3 +++
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 43361f3..3beca41 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3508,7 +3508,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
> struct mac_device_info *mac;
>
> /* Identify the MAC HW device */
> - if (priv->plat->has_gmac) {
> + if (priv->plat->setup) {
> + mac = priv->plat->setup(priv);
> + } else if (priv->plat->has_gmac) {
> priv->dev->priv_flags |= IFF_UNICAST_FLT;
> mac = dwmac1000_setup(priv->ioaddr,
> priv->plat->multicast_filter_bins,
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index 3921cb9..dadd74b 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -144,6 +144,8 @@ struct stmmac_txq_cfg {
> u32 prio;
> };
>
> +struct stmmac_priv;
> +
> struct plat_stmmacenet_data {
> int bus_id;
> int phy_addr;
> @@ -177,6 +179,7 @@ struct plat_stmmacenet_data {
> void (*fix_mac_speed)(void *priv, unsigned int speed);
> int (*init)(struct platform_device *pdev, void *priv);
> void (*exit)(struct platform_device *pdev, void *priv);
> + struct mac_device_info *(*setup)(struct stmmac_priv *priv);
In that case I prefer to have void *priv as done for the other callbacks.
I mean, keep the priv struct inside the driver part.
peppe
> void *bsp_priv;
> struct clk *stmmac_clk;
> struct clk *pclk;
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] i2c/muxes/i2c-mux-ltc4306: LTC4306 and LTC4305 I2C multiplexer/switch
From: Peter Rosin @ 2017-04-03 12:03 UTC (permalink / raw)
To: michael.hennerich, wsa, robh+dt, mark.rutland, linus.walleij
Cc: linux-i2c, devicetree, linux-gpio, linux-kernel
In-Reply-To: <0d4c068f-d909-64be-421d-4500da7ebd4c@axentia.se>
On 2017-03-31 17:29, Peter Rosin wrote:
> Hi!
>
> Sorry for my incremental reviewing...
>
Another incremental...
> On 2017-03-29 12:15, michael.hennerich@analog.com wrote:
>> +
>> + /* Now create an adapter for each channel */
>> + for (num = 0; num < data->chip->nchans; num++) {
>> + ret = i2c_mux_add_adapter(muxc, 0, num, 0);
>> + if (ret) {
>> + dev_err(&client->dev,
>> + "failed to register multiplexed adapter %d\n",
>> + num);
Just a heads up, I submitted a series to remove a bunch of dev_err calls
when i2c_mux_add_adapter fails. See https://lkml.org/lkml/2017/4/3/115
You can remove this one as well.
And please use a subject of the form:
i2c: mux: ltc4306: <message>
Cheers,
peda
>> + goto add_adapter_failed;
>> + }
^ permalink raw reply
* Re: [PATCH] ARM: sun7i: Cubietruck: enable ACIN und USB power supply subnode
From: Maxime Ripard @ 2017-04-03 11:48 UTC (permalink / raw)
To: Alexander Syring
Cc: Rob Herring, Mark Rutland, Russell King, Chen-Yu Tsai,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20170403091245.9766-1-alex-a4LgQbPKaXiELgA04lAiVw@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1459 bytes --]
Hi,
On Mon, Apr 03, 2017 at 11:12:45AM +0200, Alexander Syring wrote:
> The Cubietruck has an AXP209 PMIC and can be power-supplied by ACIN via
> the CHG-IN pin or by USB.
>
> This enables the ACIN and the USB power supply subnode in the DT.
>
> Signed-off-by: Alexander Syring <alex-a4LgQbPKaXiELgA04lAiVw@public.gmane.org>
> ---
>
> Send again to all relevant people
>
> ---
> arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> index feb995d29799..98431ef15bc9 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> @@ -267,6 +267,10 @@
>
> #include "axp209.dtsi"
>
> +&ac_power_supply {
> + status = "okay";
> +};
> +
> ®_dcdc2 {
> regulator-always-on;
> regulator-min-microvolt = <1000000>;
> @@ -323,6 +327,10 @@
> status = "okay";
> };
>
> +&usb_power_supply {
> + status = "okay";
> +};
> +
> &usbphy {
> pinctrl-names = "default";
> pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
> @@ -333,3 +341,4 @@
> usb2_vbus-supply = <®_usb2_vbus>;
> status = "okay";
> };
> +
You had a whitespace error here. I fixed it, and applied.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 20/20] ARM: sunxi: Enable dwmac-sun8i driver on multi_v7_defconfig
From: Maxime Ripard @ 2017-04-03 11:39 UTC (permalink / raw)
To: Corentin Labbe
Cc: robh+dt, mark.rutland, wens, linux, catalin.marinas, will.deacon,
peppe.cavallaro, alexandre.torgue, devicetree, linux-kernel,
netdev, linux-arm-kernel
In-Reply-To: <20170403091444.29876-21-clabbe.montjoie@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 290 bytes --]
On Mon, Apr 03, 2017 at 11:14:44AM +0200, Corentin Labbe wrote:
> Enable the dwmac-sun8i driver in the multi_v7 default configuration
Your prefix should be arm: multi_v7:
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 16/20] ARM: dts: sun50i-a64: enable dwmac-sun8i on pine64
From: Maxime Ripard @ 2017-04-03 11:38 UTC (permalink / raw)
To: Corentin Labbe
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
wens-jdAy2FN1RRM, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170403091444.29876-17-clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 555 bytes --]
On Mon, Apr 03, 2017 at 11:14:40AM +0200, Corentin Labbe wrote:
> The dwmac-sun8i hardware is present on the pine64
> It uses an external PHY via RMII.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Looks fine, but please use "arm64: allwinner: pine64: " as your title
prefix. It applies to all your other patches (and the arm ones should
be "arm: <family>: <soc-or-board>:".
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 12/20] ARM: dts: sun8i: Enable dwmac-sun8i on the Orange Pi plus
From: Maxime Ripard @ 2017-04-03 11:37 UTC (permalink / raw)
To: Corentin Labbe
Cc: mark.rutland, devicetree, alexandre.torgue, catalin.marinas,
will.deacon, linux, linux-kernel, wens, robh+dt, netdev,
peppe.cavallaro, linux-arm-kernel
In-Reply-To: <20170403091444.29876-13-clabbe.montjoie@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 1693 bytes --]
On Mon, Apr 03, 2017 at 11:14:36AM +0200, Corentin Labbe wrote:
> The dwmac-sun8i hardware is present on the Orange PI plus.
> It uses an external PHY rtl8211e via RGMII.
>
> This patch create the needed regulator, emac and phy nodes.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
> arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 36 ++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
> index 8c40ab7..6852006 100644
> --- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
> +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
> @@ -58,6 +58,18 @@
> enable-active-high;
> gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>;
> };
> +
> + reg_gmac_3v3: gmac-3v3 {
> + compatible = "regulator-fixed";
> + pinctrl-names = "default";
> + pinctrl-0 = <&gmac_power_pin_orangepi>;
> + regulator-name = "gmac-3v3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + startup-delay-us = <100000>;
> + enable-active-high;
> + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
> + };
> };
>
> &ehci3 {
> @@ -86,8 +98,32 @@
> pins = "PG11";
> function = "gpio_out";
> };
> +
> + gmac_power_pin_orangepi: gmac_power_pin@0 {
> + pins = "PD6";
> + function = "gpio_out";
> + drive-strength = <10>;
> + };
This is not needed, and will even harm the fixing of a bug that will
require to remove all the GPIO nodes. It works fine without it, please
remove it.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* RE: [PATCH 4/5] mtd: nand: add support for Micron on-die ECC
From: Bean Huo (beanhuo) @ 2017-04-03 11:31 UTC (permalink / raw)
To: Boris Brezillon
Cc: Thomas Petazzoni, richard-/L3Ra7n9ekc@public.gmane.org,
marek.vasut-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
Cyrille Pitchen,
computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Campbell, pawel.moll-5wv7dgnIgG8@public.gmane.org, Mark Rutland,
galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
In-Reply-To: <20170322155216.319efc3e@bbrezillon>
Hi, Boris and Thomas
>>
>> Ok, but I recommend that 70s should be the first choice on this single
>> solution, it doesn't need to read twice to detect its bitflips count.
>
>That's exactly why we need to differentiate the 2 chips.
Sorry for later this response.
Below is the pseudo codes about how to differentiate these 2 series parallel
NAND with on-die ECC:
if (NAND == SLC ) { // on-die ECC only exists in SLC
//check device ID byte 4
if ((ID.byte4 & 0x02) == 0x02) {// internal ECC level ==10b
if (ID.byte4 & 0x80) {//on-Die ECC enabled
if (ONFI.byte112 == 4)
60s SLC NAND with on-die ECC
else if (ONFI.byte112 == 8)
70s SLC NAND with on-die ECC
else
Doesn't support on-die ECC
}
else
On-die ECC not enabled
}
else
Doesn't support on-die ECC
}
else
Doesn't support on-die ECC.
//beanhuo
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 04/20] ARM: sun8i: dt: Add DT bindings documentation for Allwinner syscon
From: Maxime Ripard @ 2017-04-03 11:19 UTC (permalink / raw)
To: Corentin Labbe
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
wens-jdAy2FN1RRM, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170403091444.29876-5-clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]
On Mon, Apr 03, 2017 at 11:14:28AM +0200, Corentin Labbe wrote:
> Signed-off-by: Corentin Labbe <clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> .../devicetree/bindings/misc/allwinner,syscon.txt | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/misc/allwinner,syscon.txt
>
> diff --git a/Documentation/devicetree/bindings/misc/allwinner,syscon.txt b/Documentation/devicetree/bindings/misc/allwinner,syscon.txt
> new file mode 100644
> index 0000000..9f5f1f5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/allwinner,syscon.txt
> @@ -0,0 +1,19 @@
> +* Allwinner sun8i system controller
> +
> +This file describes the bindings for the system controller present in
> +Allwinner SoC H3, A83T and A64.
> +The principal function of this syscon is to control EMAC PHY choice and
> +config.
> +
> +Required properties for the system controller:
> +- reg: address and length of the register for the device.
> +- compatible: should be "syscon" and one of the following string:
> + "allwinner,sun8i-h3-system-controller"
> + "allwinner,sun8i-a64-system-controller"
> + "allwinner,sun8i-a83t-system-controller"
> +
> +Example:
> +syscon: syscon@01c00000 {
> + compatible = "syscon", "allwinner,sun8i-h3-system-controller";
The syntax is the more specific first, so your compatibles should be
the other way around.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 03/20] dt-bindings: net: Add DT bindings documentation for Allwinner dwmac-sun8i
From: Maxime Ripard @ 2017-04-03 11:19 UTC (permalink / raw)
To: Corentin Labbe
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
wens-jdAy2FN1RRM, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
peppe.cavallaro-qxv4g6HH51o, alexandre.torgue-qxv4g6HH51o,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170403091444.29876-4-clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2434 bytes --]
On Mon, Apr 03, 2017 at 11:14:27AM +0200, Corentin Labbe wrote:
> This patch adds documentation for Device-Tree bindings for the
> Allwinner dwmac-sun8i driver.
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> .../devicetree/bindings/net/dwmac-sun8i.txt | 77 ++++++++++++++++++++++
> 1 file changed, 77 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/dwmac-sun8i.txt
>
> diff --git a/Documentation/devicetree/bindings/net/dwmac-sun8i.txt b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt
> new file mode 100644
> index 0000000..f01ef17
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dwmac-sun8i.txt
> @@ -0,0 +1,77 @@
> +* Allwinner sun8i GMAC ethernet controller
> +
> +This device is a platform glue layer for stmmac.
> +Please see stmmac.txt for the other unchanged properties.
> +
> +Required properties:
> +- compatible: should be one of the following string:
> + "allwinner,sun8i-a83t-emac"
> + "allwinner,sun8i-h3-emac"
> + "allwinner,sun50i-a64-emac"
> +- reg: address and length of the register for the device.
> +- interrupts: interrupt for the device
> +- interrupt-names: should be "macirq"
> +- clocks: A phandle to the reference clock for this device
> +- clock-names: should be "stmmaceth"
> +- resets: A phandle to the reset control for this device
> +- reset-names: should be "stmmaceth"
> +- phy-mode: See ethernet.txt
> +- phy-handle: See ethernet.txt
> +- #address-cells: shall be 1
> +- #size-cells: shall be 0
> +- syscon: A phandle to the syscon of the SoC with one of the following
> + compatible string:
> + - allwinner,sun8i-h3-system-controller
> + - allwinner,sun8i-a64-system-controller
> + - allwinner,sun8i-a83t-system-controller
I'm not sure you need to document those compatibles here.
> +Optional properties:
> +- allwinner,tx-delay: TX clock delay chain value. Range value is 0-0x07. Default is 0)
> +- allwinner,rx-delay: RX clock delay chain value. Range value is 0-0x1F. Default is 0)
> +Both delay properties are in 0.1ns step.
allwinner,tx-delay-ps and allwinner,rx-delay-ps, with the value in
picoseconds?
Looks good otherwise, thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v3 5/7] mfd: Add Device Tree bindings document for TI tps6105x chip
From: Lee Jones @ 2017-04-03 11:15 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland
In-Reply-To: <20170401071854.23198-6-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
On Sat, 01 Apr 2017, Javier Martinez Canillas wrote:
> There are Device Tree source files defining a device node for the
> tps61050/61052 I2C chip but there isn't a binding document for it.
>
> Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> Documentation/devicetree/bindings/mfd/tps6105x.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/tps6105x.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/tps6105x.txt b/Documentation/devicetree/bindings/mfd/tps6105x.txt
> new file mode 100644
> index 000000000000..c076f28575fc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/tps6105x.txt
> @@ -0,0 +1,17 @@
> +* Device tree bindings for TI TPS61050/61052 Boost Converters
> +
> +The TP61050/TPS61052 is a high-power "white LED driver". This boost converter
> +is also used for other things than white LEDs, and also contains a GPIO pin.
What functions does it offer?
> +Required properties:
> +- compatible: "ti,tps61050" or "ti,tps61052"
> +- reg: Specifies the I2C slave address
> +
> +Example:
> +
> +i2c0 {
> + tps61052@33 {
> + compatible = "ti,tps61052";
> + reg = <0x33>;
> + };
> +};
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 2/7] mfd: retu: Add OF device ID table
From: Lee Jones @ 2017-04-03 11:15 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring
In-Reply-To: <20170401071854.23198-3-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
On Sat, 01 Apr 2017, Javier Martinez Canillas wrote:
> The driver doesn't have a struct of_device_id table but supported devices
> are registered via Device Trees. This is working on the assumption that a
> I2C device registered via OF will always match a legacy I2C device ID and
> that the MODALIAS reported will always be of the form i2c:<device>.
>
> But this could change in the future so the correct approach is to have a
> OF device ID table if the devices are registered via OF.
>
> Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>
> ---
>
> Changes in v3:
> - Add a vendor prefix to the compatible string (Rob Herring).
>
> Changes in v2:
> - Don't use of_match_ptr() to avoid build warning when CONFIG_OF is disabled.
>
> drivers/mfd/retu-mfd.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
> index d4c114abeb75..937a1c21eec4 100644
> --- a/drivers/mfd/retu-mfd.c
> +++ b/drivers/mfd/retu-mfd.c
> @@ -308,9 +308,17 @@ static const struct i2c_device_id retu_id[] = {
> };
> MODULE_DEVICE_TABLE(i2c, retu_id);
>
> +static const struct of_device_id retu_of_match[] = {
> + { .compatible = "nokia,retu-mfd" },
> + { .compatible = "nokia,tahvo-mfd" },
Please drop the "-mfd".
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, retu_of_match);
> +
> static struct i2c_driver retu_driver = {
> .driver = {
> .name = "retu-mfd",
> + .of_match_table = retu_of_match,
> },
> .probe = retu_probe,
> .remove = retu_remove,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 1/7] mfd: Add Device Tree bindings document for retu/tahvo ASIC chips
From: Lee Jones @ 2017-04-03 11:13 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland
In-Reply-To: <20170401071854.23198-2-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
On Sat, 01 Apr 2017, Javier Martinez Canillas wrote:
> There are Device Tree source files defining a device node for the
> retu/tahvo I2C chip, but there isn't a DT binding document for it.
>
> Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> Documentation/devicetree/bindings/mfd/retu.txt | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/retu.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/retu.txt b/Documentation/devicetree/bindings/mfd/retu.txt
> new file mode 100644
> index 000000000000..2309e599a731
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/retu.txt
> @@ -0,0 +1,19 @@
> +* Device tree bindings for Nokia Retu and Tahvo multi-function device
> +
> +Retu and Tahvo are a multi-function devices found on Nokia Internet
> +Tablets (770, N800 and N810).
More information please. What functions to they serve?
> +Required properties:
> +- compatible: "nokia,retu-mfd" or "nokia,tahvo-mfd"
> +- reg: Specifies the I2C slave address of the ASIC chip
> +
> +Example:
> +
> +i2c0 {
> + retu_mfd: retu@1 {
Please avoid the term MFD at all times when using Device Tree. DT is
meant to be OS agnostic and MFD is a Linuxisum.
> + compatible = "nokia,retu-mfd";
> + interrupt-parent = <&gpio4>;
> + interrupts = <12 IRQ_TYPE_EDGE_RISING>;
> + reg = <0x1>;
> + };
> +};
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH RESEND v5 7/7] mfd: dt-bindings: Add RK805 device tree bindings document
From: Lee Jones @ 2017-04-03 11:06 UTC (permalink / raw)
To: Elaine Zhang
Cc: lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
huangtao-TNX95d0MmH7DzftRWevZcw, xxx-TNX95d0MmH7DzftRWevZcw,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
chenjh-TNX95d0MmH7DzftRWevZcw, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
w.egorov-guT5V/WYfQezQB+pC5nmwQ
In-Reply-To: <1490597615-852-1-git-send-email-zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
On Mon, 27 Mar 2017, Elaine Zhang wrote:
> Add device tree bindings documentation for Rockchip's RK805 PMIC.
>
> Signed-off-by: Elaine Zhang <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
> ---
> Documentation/devicetree/bindings/mfd/rk808.txt | 22 +++++++++++++++++++++-
> 1 file changed, 21 insertions(+), 1 deletion(-)
For my own reference:
Acked-for-MFD-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
> index 9636ae8d8d41..91b65227afeb 100644
> --- a/Documentation/devicetree/bindings/mfd/rk808.txt
> +++ b/Documentation/devicetree/bindings/mfd/rk808.txt
> @@ -1,11 +1,14 @@
> RK8XX Power Management Integrated Circuit
>
> The rk8xx family current members:
> +rk805
> rk808
> rk818
>
> Required properties:
> -- compatible: "rockchip,rk808", "rockchip,rk818"
> +- compatible: "rockchip,rk805"
> +- compatible: "rockchip,rk808"
> +- compatible: "rockchip,rk818"
> - reg: I2C slave address
> - interrupt-parent: The parent interrupt controller.
> - interrupts: the interrupt outputs of the controller.
> @@ -18,6 +21,14 @@ Optional properties:
> - rockchip,system-power-controller: Telling whether or not this pmic is controlling
> the system power.
>
> +Optional RK805 properties:
> +- vcc1-supply: The input supply for DCDC_REG1
> +- vcc2-supply: The input supply for DCDC_REG2
> +- vcc3-supply: The input supply for DCDC_REG3
> +- vcc4-supply: The input supply for DCDC_REG4
> +- vcc5-supply: The input supply for LDO_REG1 and LDO_REG2
> +- vcc6-supply: The input supply for LDO_REG3
> +
> Optional RK808 properties:
> - vcc1-supply: The input supply for DCDC_REG1
> - vcc2-supply: The input supply for DCDC_REG2
> @@ -56,6 +67,15 @@ by a child node of the 'regulators' node.
> /* standard regulator bindings here */
> };
>
> +Following regulators of the RK805 PMIC regulators are supported. Note that
> +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> +number as described in RK805 datasheet.
> +
> + - DCDC_REGn
> + - valid values for n are 1 to 4.
> + - LDO_REGn
> + - valid values for n are 1 to 3
> +
> Following regulators of the RK808 PMIC block are supported. Note that
> the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> number as described in RK808 datasheet.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v5 4/7] mfd: rk808: Add RK805 support
From: Lee Jones @ 2017-04-03 11:05 UTC (permalink / raw)
To: Elaine Zhang
Cc: lgirdwood, broonie, huangtao, xxx, linux-rockchip, linux-kernel,
chenjh, robh+dt, mark.rutland, devicetree, w.egorov
In-Reply-To: <1490595705-28844-5-git-send-email-zhangqing@rock-chips.com>
On Mon, 27 Mar 2017, Elaine Zhang wrote:
> The RK805 chip is a Power Management IC (PMIC) for multimedia and handheld
> devices. It contains the following components:
>
> - Regulators
> - RTC
> - Clocking
>
> Both RK808 and RK805 chips are using a similar register map,
> so we can reuse the RTC and Clocking functionality.
>
> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
> ---
> drivers/mfd/Kconfig | 4 +-
> drivers/mfd/rk808.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 110 insertions(+), 2 deletions(-)
For my own reference:
Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 55ecdfb74d31..b410a348b756 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -892,13 +892,13 @@ config MFD_RC5T583
> different functionality of the device.
>
> config MFD_RK808
> - tristate "Rockchip RK808/RK818 Power Management Chip"
> + tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
> depends on I2C && OF
> select MFD_CORE
> select REGMAP_I2C
> select REGMAP_IRQ
> help
> - If you say yes here you get support for the RK808 and RK818
> + If you say yes here you get support for the RK805, RK808 and RK818
> Power Management chips.
> This driver provides common support for accessing the device
> through I2C interface. The device supports multiple sub-devices
> diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
> index 3334a2a7f3fb..7276555f0630 100644
> --- a/drivers/mfd/rk808.c
> +++ b/drivers/mfd/rk808.c
> @@ -70,6 +70,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> .volatile_reg = rk808_is_volatile_reg,
> };
>
> +static const struct regmap_config rk805_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> + .max_register = RK805_OFF_SOURCE_REG,
> + .cache_type = REGCACHE_RBTREE,
> + .volatile_reg = rk808_is_volatile_reg,
> +};
> +
> static const struct regmap_config rk808_regmap_config = {
> .reg_bits = 8,
> .val_bits = 8,
> @@ -86,6 +94,16 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> }
> };
>
> +static const struct mfd_cell rk805s[] = {
> + { .name = "rk808-clkout", },
> + { .name = "rk808-regulator", },
> + {
> + .name = "rk808-rtc",
> + .num_resources = ARRAY_SIZE(rtc_resources),
> + .resources = &rtc_resources[0],
> + },
> +};
> +
> static const struct mfd_cell rk808s[] = {
> { .name = "rk808-clkout", },
> { .name = "rk808-regulator", },
> @@ -106,6 +124,20 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> },
> };
>
> +static const struct rk808_reg_data rk805_pre_init_reg[] = {
> + {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
> + RK805_BUCK1_2_ILMAX_4000MA},
> + {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
> + RK805_BUCK1_2_ILMAX_4000MA},
> + {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
> + RK805_BUCK3_ILMAX_3000MA},
> + {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
> + RK805_BUCK4_ILMAX_3500MA},
> + {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
> + {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
> + {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
> +};
> +
> static const struct rk808_reg_data rk808_pre_init_reg[] = {
> { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
> { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
> @@ -135,6 +167,41 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> VB_LO_SEL_3500MV },
> };
>
> +static const struct regmap_irq rk805_irqs[] = {
> + [RK805_IRQ_PWRON_RISE] = {
> + .mask = RK805_IRQ_PWRON_RISE_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_VB_LOW] = {
> + .mask = RK805_IRQ_VB_LOW_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_PWRON] = {
> + .mask = RK805_IRQ_PWRON_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_PWRON_LP] = {
> + .mask = RK805_IRQ_PWRON_LP_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_HOTDIE] = {
> + .mask = RK805_IRQ_HOTDIE_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_RTC_ALARM] = {
> + .mask = RK805_IRQ_RTC_ALARM_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_RTC_PERIOD] = {
> + .mask = RK805_IRQ_RTC_PERIOD_MSK,
> + .reg_offset = 0,
> + },
> + [RK805_IRQ_PWRON_FALL] = {
> + .mask = RK805_IRQ_PWRON_FALL_MSK,
> + .reg_offset = 0,
> + },
> +};
> +
> static const struct regmap_irq rk808_irqs[] = {
> /* INT_STS */
> [RK808_IRQ_VOUT_LO] = {
> @@ -247,6 +314,17 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> },
> };
>
> +static struct regmap_irq_chip rk805_irq_chip = {
> + .name = "rk805",
> + .irqs = rk805_irqs,
> + .num_irqs = ARRAY_SIZE(rk805_irqs),
> + .num_regs = 1,
> + .status_base = RK805_INT_STS_REG,
> + .mask_base = RK805_INT_STS_MSK_REG,
> + .ack_base = RK805_INT_STS_REG,
> + .init_ack_masked = true,
> +};
> +
> static const struct regmap_irq_chip rk808_irq_chip = {
> .name = "rk808",
> .irqs = rk808_irqs,
> @@ -272,6 +350,25 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
> };
>
> static struct i2c_client *rk808_i2c_client;
> +
> +static void rk805_device_shutdown(void)
> +{
> + int ret;
> + struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
> +
> + if (!rk808) {
> + dev_warn(&rk808_i2c_client->dev,
> + "have no rk805, so do nothing here\n");
> + return;
> + }
> +
> + ret = regmap_update_bits(rk808->regmap,
> + RK805_DEV_CTRL_REG,
> + DEV_OFF, DEV_OFF);
> + if (ret)
> + dev_err(&rk808_i2c_client->dev, "power off error!\n");
> +}
> +
> static void rk808_device_shutdown(void)
> {
> int ret;
> @@ -309,6 +406,7 @@ static void rk818_device_shutdown(void)
> }
>
> static const struct of_device_id rk808_of_match[] = {
> + { .compatible = "rockchip,rk805" },
> { .compatible = "rockchip,rk808" },
> { .compatible = "rockchip,rk818" },
> { },
> @@ -352,6 +450,15 @@ static int rk808_probe(struct i2c_client *client,
> dev_info(&client->dev, "Chip id: 0x%x\n", (unsigned int)rk808->variant);
>
> switch (rk808->variant) {
> + case RK805_ID:
> + rk808->regmap_cfg = &rk805_regmap_config;
> + rk808->regmap_irq_chip = &rk805_irq_chip;
> + pre_init_reg = rk805_pre_init_reg;
> + nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
> + cells = rk805s;
> + nr_cells = ARRAY_SIZE(rk805s);
> + pm_pwroff_fn = rk805_device_shutdown;
> + break;
> case RK808_ID:
> rk808->regmap_cfg = &rk808_regmap_config;
> rk808->regmap_irq_chip = &rk808_irq_chip;
> @@ -444,6 +551,7 @@ static int rk808_remove(struct i2c_client *client)
> }
>
> static const struct i2c_device_id rk808_ids[] = {
> + { "rk805" },
> { "rk808" },
> { "rk818" },
> { },
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v5 2/7] mfd: rk808: add rk805 regs addr and ID
From: Lee Jones @ 2017-04-03 11:04 UTC (permalink / raw)
To: Elaine Zhang
Cc: lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
huangtao-TNX95d0MmH7DzftRWevZcw, xxx-TNX95d0MmH7DzftRWevZcw,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
chenjh-TNX95d0MmH7DzftRWevZcw, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
w.egorov-guT5V/WYfQezQB+pC5nmwQ
In-Reply-To: <1490595705-28844-3-git-send-email-zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
On Mon, 27 Mar 2017, Elaine Zhang wrote:
> Signed-off-by: Elaine Zhang <zhangqing-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
> ---
> include/linux/mfd/rk808.h | 120 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 120 insertions(+)
For my own reference:
Acked-for-MFD-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index 54feb140c210..d3156594674c 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -206,6 +206,97 @@ enum rk818_reg {
> #define RK818_USB_ILMIN_2000MA 0x7
> #define RK818_USB_CHG_SD_VSEL_MASK 0x70
>
> +/* RK805 */
> +enum rk805_reg {
> + RK805_ID_DCDC1,
> + RK805_ID_DCDC2,
> + RK805_ID_DCDC3,
> + RK805_ID_DCDC4,
> + RK805_ID_LDO1,
> + RK805_ID_LDO2,
> + RK805_ID_LDO3,
> +};
> +
> +/* CONFIG REGISTER */
> +#define RK805_VB_MON_REG 0x21
> +#define RK805_THERMAL_REG 0x22
> +
> +/* POWER CHANNELS ENABLE REGISTER */
> +#define RK805_DCDC_EN_REG 0x23
> +#define RK805_SLP_DCDC_EN_REG 0x25
> +#define RK805_SLP_LDO_EN_REG 0x26
> +#define RK805_LDO_EN_REG 0x27
> +
> +/* BUCK AND LDO CONFIG REGISTER */
> +#define RK805_BUCK_LDO_SLP_LP_EN_REG 0x2A
> +#define RK805_BUCK1_CONFIG_REG 0x2E
> +#define RK805_BUCK1_ON_VSEL_REG 0x2F
> +#define RK805_BUCK1_SLP_VSEL_REG 0x30
> +#define RK805_BUCK2_CONFIG_REG 0x32
> +#define RK805_BUCK2_ON_VSEL_REG 0x33
> +#define RK805_BUCK2_SLP_VSEL_REG 0x34
> +#define RK805_BUCK3_CONFIG_REG 0x36
> +#define RK805_BUCK4_CONFIG_REG 0x37
> +#define RK805_BUCK4_ON_VSEL_REG 0x38
> +#define RK805_BUCK4_SLP_VSEL_REG 0x39
> +#define RK805_LDO1_ON_VSEL_REG 0x3B
> +#define RK805_LDO1_SLP_VSEL_REG 0x3C
> +#define RK805_LDO2_ON_VSEL_REG 0x3D
> +#define RK805_LDO2_SLP_VSEL_REG 0x3E
> +#define RK805_LDO3_ON_VSEL_REG 0x3F
> +#define RK805_LDO3_SLP_VSEL_REG 0x40
> +
> +/* INTERRUPT REGISTER */
> +#define RK805_PWRON_LP_INT_TIME_REG 0x47
> +#define RK805_PWRON_DB_REG 0x48
> +#define RK805_DEV_CTRL_REG 0x4B
> +#define RK805_INT_STS_REG 0x4C
> +#define RK805_INT_STS_MSK_REG 0x4D
> +#define RK805_GPIO_IO_POL_REG 0x50
> +#define RK805_OUT_REG 0x52
> +#define RK805_ON_SOURCE_REG 0xAE
> +#define RK805_OFF_SOURCE_REG 0xAF
> +
> +#define RK805_NUM_REGULATORS 7
> +
> +#define RK805_PWRON_FALL_RISE_INT_EN 0x0
> +#define RK805_PWRON_FALL_RISE_INT_MSK 0x81
> +
> +/* RK805 IRQ Definitions */
> +#define RK805_IRQ_PWRON_RISE 0
> +#define RK805_IRQ_VB_LOW 1
> +#define RK805_IRQ_PWRON 2
> +#define RK805_IRQ_PWRON_LP 3
> +#define RK805_IRQ_HOTDIE 4
> +#define RK805_IRQ_RTC_ALARM 5
> +#define RK805_IRQ_RTC_PERIOD 6
> +#define RK805_IRQ_PWRON_FALL 7
> +
> +#define RK805_IRQ_PWRON_RISE_MSK BIT(0)
> +#define RK805_IRQ_VB_LOW_MSK BIT(1)
> +#define RK805_IRQ_PWRON_MSK BIT(2)
> +#define RK805_IRQ_PWRON_LP_MSK BIT(3)
> +#define RK805_IRQ_HOTDIE_MSK BIT(4)
> +#define RK805_IRQ_RTC_ALARM_MSK BIT(5)
> +#define RK805_IRQ_RTC_PERIOD_MSK BIT(6)
> +#define RK805_IRQ_PWRON_FALL_MSK BIT(7)
> +
> +#define RK805_PWR_RISE_INT_STATUS BIT(0)
> +#define RK805_VB_LOW_INT_STATUS BIT(1)
> +#define RK805_PWRON_INT_STATUS BIT(2)
> +#define RK805_PWRON_LP_INT_STATUS BIT(3)
> +#define RK805_HOTDIE_INT_STATUS BIT(4)
> +#define RK805_ALARM_INT_STATUS BIT(5)
> +#define RK805_PERIOD_INT_STATUS BIT(6)
> +#define RK805_PWR_FALL_INT_STATUS BIT(7)
> +
> +#define RK805_BUCK1_2_ILMAX_MASK (3 << 6)
> +#define RK805_BUCK3_4_ILMAX_MASK (3 << 3)
> +#define RK805_RTC_PERIOD_INT_MASK (1 << 6)
> +#define RK805_RTC_ALARM_INT_MASK (1 << 5)
> +#define RK805_INT_ALARM_EN (1 << 3)
> +#define RK805_INT_TIMER_EN (1 << 2)
> +
> /* RK808 IRQ Definitions */
> #define RK808_IRQ_VOUT_LO 0
> #define RK808_IRQ_VB_LO 1
> @@ -298,7 +389,14 @@ enum rk818_reg {
> #define VOUT_LO_INT BIT(0)
> #define CLK32KOUT2_EN BIT(0)
>
> +#define TEMP115C 0x0c
> +#define TEMP_HOTDIE_MSK 0x0c
> +#define SLP_SD_MSK (0x3 << 2)
> +#define SHUTDOWN_FUN (0x2 << 2)
> +#define SLEEP_FUN (0x1 << 2)
> #define RK8XX_ID_MSK 0xfff0
> +#define FPWM_MODE BIT(7)
> +
> enum {
> BUCK_ILMIN_50MA,
> BUCK_ILMIN_100MA,
> @@ -322,6 +420,28 @@ enum {
> };
>
> enum {
> + RK805_BUCK1_2_ILMAX_2500MA,
> + RK805_BUCK1_2_ILMAX_3000MA,
> + RK805_BUCK1_2_ILMAX_3500MA,
> + RK805_BUCK1_2_ILMAX_4000MA,
> +};
> +
> +enum {
> + RK805_BUCK3_ILMAX_1500MA,
> + RK805_BUCK3_ILMAX_2000MA,
> + RK805_BUCK3_ILMAX_2500MA,
> + RK805_BUCK3_ILMAX_3000MA,
> +};
> +
> +enum {
> + RK805_BUCK4_ILMAX_2000MA,
> + RK805_BUCK4_ILMAX_2500MA,
> + RK805_BUCK4_ILMAX_3000MA,
> + RK805_BUCK4_ILMAX_3500MA,
> +};
> +
> +enum {
> + RK805_ID = 0x8050,
> RK808_ID = 0x0000,
> RK818_ID = 0x8181,
> };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox