Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/3] hwmon: ltc2990: refactor value conversion
From: Guenter Roeck @ 2016-11-17 16:36 UTC (permalink / raw)
  To: Tom Levens
  Cc: jdelvare, robh+dt, mark.rutland, linux-kernel, linux-hwmon,
	devicetree
In-Reply-To: <alpine.LRH.2.20.1611171613250.12237@pcbe13573-vm.dyndns.cern.ch>

On 11/17/2016 08:23 AM, Tom Levens wrote:
> Hi Guenter,
>
> Thanks for taking the time to review the patch.
>
> On Thu, 17 Nov 2016, Guenter Roeck wrote:
>
>> Hi Tom,
>>
>> On 11/17/2016 04:10 AM, Tom Levens wrote:
>>>  Conversion from raw values to signed integers has been refactored using
>>>  the macros in bitops.h.
>>>
>> Please also mention that this fixes a bug in negative temperature conversions.
>
> Yes, of course, I will include the information in v3.
>
>>
>>>  Signed-off-by: Tom Levens <tom.levens@cern.ch>
>>>  ---
>>>   drivers/hwmon/ltc2990.c |   27 ++++++++++-----------------
>>>   1 files changed, 10 insertions(+), 17 deletions(-)
>>>
>>>  diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>>>  index 8f8fe05..0ec4102 100644
>>>  --- a/drivers/hwmon/ltc2990.c
>>>  +++ b/drivers/hwmon/ltc2990.c
>>>  @@ -9,8 +9,12 @@
>>>    * This driver assumes the chip is wired as a dual current monitor, and
>>>    * reports the voltage drop across two series resistors. It also reports
>>>    * the chip's internal temperature and Vcc power supply voltage.
>>>  + *
>>>  + * Value conversion refactored
>>>  + * by Tom Levens <tom.levens@cern.ch>
>>
>> Kind of unusual to do that for minor changes like this. Imagine if everyone would do that.
>> The commit log is what gives you credit.
>
> Good point, thanks for the hint. I will remove it from v3.
>
>>>    */
>>>
>>>  +#include <linux/bitops.h>
>>>   #include <linux/err.h>
>>>   #include <linux/hwmon.h>
>>>   #include <linux/hwmon-sysfs.h>
>>>  @@ -34,19 +38,10 @@
>>>   #define LTC2990_CONTROL_MODE_CURRENT    0x06
>>>   #define LTC2990_CONTROL_MODE_VOLTAGE    0x07
>>>
>>>  -/* convert raw register value to sign-extended integer in 16-bit range */
>>>  -static int ltc2990_voltage_to_int(int raw)
>>>  -{
>>>  -    if (raw & BIT(14))
>>>  -        return -(0x4000 - (raw & 0x3FFF)) << 2;
>>>  -    else
>>>  -        return (raw & 0x3FFF) << 2;
>>>  -}
>>>  -
>>>  /* Return the converted value from the given register in uV or mC */
>>>  -static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, int *result)
>>>  +static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, s32 *result)
>>>  {
>>>  -    int val;
>>>  +    s32 val;
>>
>> Please just leave the variable type alone. it is also used for the return value
>> from i2c_smbus_read_word_swapped(), which is an int, and changing it to s32 doesn't really make the code better.
>
> According to i2c.h the return type for i2c_smbus_read_word_swapped() is s32, which is why I modified it here. But it could be changed back if you think it is better to leave it as an int.
>
Ah, ok. Good to know. Please leave it anyway, reason being that there is no real
reason to change it. Effectively those are just whitespace changes (unlike the rest,
which is part bug fix, part cleanup).

>> Can you send me a register map for the chip ? I would like to write a module test.
>
> Here is an example register dump:

I meant the output of i2cdump (something like "i2cdump -y -f <bus> <i2c-address> w").

Thanks,
Guenter

>
> 00 00 00 00
> 01 90 07 d0
> 2c cd 7d 80
> 7c 29 20 00
>
> The expected values in this case are:
>
> in0_input     5000
> in1_input    610
> in2_input    3500
> in3_input    -195
> in4_input    -299
> temp1_input     25000
> temp2_input     125000
> temp3_input    -40000
> curr1_input    38840
> curr2_input    -12428
>
> Testing with lltc,mode set to <5>, <6> and <7> should give you all measurements.
>
>> Thanks,
>> Guenter
>
> Cheers,
>

^ permalink raw reply

* Re: [PATCH v2 3/3] hwmon: ltc2990: support all measurement modes
From: Guenter Roeck @ 2016-11-17 16:56 UTC (permalink / raw)
  To: Tom Levens
  Cc: jdelvare-IBi9RG/b67k, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-hwmon-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Mike Looijmans
In-Reply-To: <1479384616-12479-3-git-send-email-tom.levens-vJEk5272eHo@public.gmane.org>

On 11/17/2016 04:10 AM, Tom Levens wrote:
> Updated version of the ltc2990 driver which supports all measurement
> modes available in the chip. The mode can be set through a devicetree
> attribute.

property

>
> Signed-off-by: Tom Levens <tom.levens-vJEk5272eHo@public.gmane.org>
> ---
>
> Changes since v1:
>   * Refactored value conversion (patch 1/3)
>   * Split the devicetree binding into separate patch (patch 2/3)
>   * Specifying an invalid mode now returns -EINVAL, previously this
>     only issued a warning and used the default value
>   * Removed the "mode" sysfs attribute, as the mode of the chip is
>     hardware specific and should not be user configurable. This allows much
>     simpler code as a result.
>
>  Documentation/hwmon/ltc2990 |   24 ++++---
>  drivers/hwmon/Kconfig       |    7 +--
>  drivers/hwmon/ltc2990.c     |  167 ++++++++++++++++++++++++++++++++++++-------
>  3 files changed, 159 insertions(+), 39 deletions(-)
>
> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
> index c25211e..3ed68f6 100644
> --- a/Documentation/hwmon/ltc2990
> +++ b/Documentation/hwmon/ltc2990
> @@ -8,6 +8,7 @@ Supported chips:
>      Datasheet: http://www.linear.com/product/ltc2990
>
>  Author: Mike Looijmans <mike.looijmans-Oq418RWZeHk@public.gmane.org>
> +        Tom Levens <tom.levens-vJEk5272eHo@public.gmane.org>
>
>
>  Description
> @@ -16,10 +17,8 @@ Description
>  LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
>  The chip's inputs can measure 4 voltages, or two inputs together (1+2 and 3+4)
>  can be combined to measure a differential voltage, which is typically used to
> -measure current through a series resistor, or a temperature.
> -
> -This driver currently uses the 2x differential mode only. In order to support
> -other modes, the driver will need to be expanded.
> +measure current through a series resistor, or a temperature with an external
> +diode.
>
>
>  Usage Notes
> @@ -32,12 +31,19 @@ devices explicitly.
>  Sysfs attributes
>  ----------------
>
> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
> +temp1_input   Internal chip temperature in millidegrees Celcius
> +
> +A subset of the following attributes are visible, depending on the measurement
> +mode of the chip.
> +
> +in[1-4]_input Voltage at V[1-4] pin in millivolt
> +temp2_input   External temperature sensor TR1 in millidegrees Celcius
> +temp3_input   External temperature sensor TR2 in millidegrees Celcius
> +curr1_input   Current in mA across V1-V2 assuming a 1mOhm sense resistor
> +curr2_input   Current in mA across V3-V4 assuming a 1mOhm sense resistor
> +
>  The "curr*_input" measurements actually report the voltage drop across the
>  input pins in microvolts. This is equivalent to the current through a 1mOhm
>  sense resistor. Divide the reported value by the actual sense resistor value
>  in mOhm to get the actual value.
> -
> -in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
> -temp1_input   Internal chip temperature in millidegrees Celcius
> -curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense resistor.
> -curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense resistor.
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 45cef3d..f7096ca 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -699,15 +699,12 @@ config SENSORS_LTC2945
>  	  be called ltc2945.
>
>  config SENSORS_LTC2990
> -	tristate "Linear Technology LTC2990 (current monitoring mode only)"
> +	tristate "Linear Technology LTC2990"
>  	depends on I2C
>  	help
>  	  If you say yes here you get support for Linear Technology LTC2990
>  	  I2C System Monitor. The LTC2990 supports a combination of voltage,
> -	  current and temperature monitoring, but in addition to the Vcc supply
> -	  voltage and chip temperature, this driver currently only supports
> -	  reading two currents by measuring two differential voltages across
> -	  series resistors.
> +	  current and temperature monitoring.
>
>  	  This driver can also be built as a module. If so, the module will
>  	  be called ltc2990.
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> index 0ec4102..e8d36f5 100644
> --- a/drivers/hwmon/ltc2990.c
> +++ b/drivers/hwmon/ltc2990.c
> @@ -6,11 +6,7 @@
>   *
>   * License: GPLv2
>   *
> - * This driver assumes the chip is wired as a dual current monitor, and
> - * reports the voltage drop across two series resistors. It also reports
> - * the chip's internal temperature and Vcc power supply voltage.
> - *
> - * Value conversion refactored
> + * Value conversion refactored and support for all measurement modes added
>   * by Tom Levens <tom.levens-vJEk5272eHo@public.gmane.org>
>   */
>
> @@ -21,6 +17,7 @@
>  #include <linux/i2c.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/of.h>
>
>  #define LTC2990_STATUS	0x00
>  #define LTC2990_CONTROL	0x01
> @@ -35,32 +32,96 @@
>  #define LTC2990_CONTROL_KELVIN		BIT(7)
>  #define LTC2990_CONTROL_SINGLE		BIT(6)
>  #define LTC2990_CONTROL_MEASURE_ALL	(0x3 << 3)
> -#define LTC2990_CONTROL_MODE_CURRENT	0x06
> -#define LTC2990_CONTROL_MODE_VOLTAGE	0x07
> +#define LTC2990_CONTROL_MODE_DEFAULT	0x06

I think LTC2990_CONTROL_MODE_CURRENT was better - it describes the actual mode.
Changing the define to _DEFAULT does not really improve code readability.

> +#define LTC2990_CONTROL_MODE_MAX	0x07
> +
> +#define LTC2990_IN0	BIT(0)
> +#define LTC2990_IN1	BIT(1)
> +#define LTC2990_IN2	BIT(2)
> +#define LTC2990_IN3	BIT(3)
> +#define LTC2990_IN4	BIT(4)
> +#define LTC2990_CURR1	BIT(5)
> +#define LTC2990_CURR2	BIT(6)
> +#define LTC2990_TEMP1	BIT(7)
> +#define LTC2990_TEMP2	BIT(8)
> +#define LTC2990_TEMP3	BIT(9)
> +
> +static const int ltc2990_attrs_ena[] = {
> +	LTC2990_IN1 | LTC2990_IN2 | LTC2990_TEMP3,
> +	LTC2990_CURR1 | LTC2990_TEMP3,
> +	LTC2990_CURR1 | LTC2990_IN3 | LTC2990_IN4,
> +	LTC2990_TEMP2 | LTC2990_IN3 | LTC2990_IN4,
> +	LTC2990_TEMP2 | LTC2990_CURR2,
> +	LTC2990_TEMP2 | LTC2990_TEMP3,
> +	LTC2990_CURR1 | LTC2990_CURR2,
> +	LTC2990_IN1 | LTC2990_IN2 | LTC2990_IN3 | LTC2990_IN4
> +};
> +
> +struct ltc2990_data {
> +	struct i2c_client *i2c;
> +	u32 mode;
> +};
>
>  /* Return the converted value from the given register in uV or mC */
> -static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, s32 *result)
> +static int ltc2990_get_value(struct i2c_client *i2c, int index, s32 *result)
>  {
>  	s32 val;
> +	u8 reg;
> +
> +	switch (index) {
> +	case LTC2990_IN0:
> +		reg = LTC2990_VCC_MSB;
> +		break;
> +	case LTC2990_IN1:
> +	case LTC2990_CURR1:
> +	case LTC2990_TEMP2:
> +		reg = LTC2990_V1_MSB;
> +		break;
> +	case LTC2990_IN2:
> +		reg = LTC2990_V2_MSB;
> +		break;
> +	case LTC2990_IN3:
> +	case LTC2990_CURR2:
> +	case LTC2990_TEMP3:
> +		reg = LTC2990_V3_MSB;
> +		break;
> +	case LTC2990_IN4:
> +		reg = LTC2990_V4_MSB;
> +		break;
> +	case LTC2990_TEMP1:
> +		reg = LTC2990_TINT_MSB;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
>
>  	val = i2c_smbus_read_word_swapped(i2c, reg);
>  	if (unlikely(val < 0))
>  		return val;
>
> -	switch (reg) {
> -	case LTC2990_TINT_MSB:
> -		/* internal temp, 0.0625 degrees/LSB, 13-bit  */
> +	switch (index) {
> +	case LTC2990_TEMP1:
> +	case LTC2990_TEMP2:
> +	case LTC2990_TEMP3:
> +		/* temp, 0.0625 degrees/LSB, 13-bit  */
>  		*result = sign_extend32(val, 12) * 1000 / 16;
>  		break;
> -	case LTC2990_V1_MSB:
> -	case LTC2990_V3_MSB:
> -		 /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
> +	case LTC2990_CURR1:
> +	case LTC2990_CURR2:
> +		 /* Vx-Vy, 19.42uV/LSB */
>  		*result = sign_extend32(val, 14) * 1942 / 100;
>  		break;
> -	case LTC2990_VCC_MSB:
> -		/* Vcc, 305.18μV/LSB, 2.5V offset */
> +	case LTC2990_IN0:
> +		/* Vcc, 305.18uV/LSB, 2.5V offset */
>  		*result = sign_extend32(val, 14) * 30518 / (100 * 1000) + 2500;
>  		break;
> +	case LTC2990_IN1:
> +	case LTC2990_IN2:
> +	case LTC2990_IN3:
> +	case LTC2990_IN4:
> +		/* Vx: 305.18uV/LSB */
> +		*result = sign_extend32(val, 14) * 30518 / (100 * 1000);
> +		break;
>  	default:
>  		return -EINVAL; /* won't happen, keep compiler happy */
>  	}
> @@ -72,48 +133,104 @@ static ssize_t ltc2990_show_value(struct device *dev,
>  				  struct device_attribute *da, char *buf)
>  {
>  	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +	struct ltc2990_data *data = dev_get_drvdata(dev);
>  	s32 value;
>  	int ret;
>
> -	ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);
> +	ret = ltc2990_get_value(data->i2c, attr->index, &value);
>  	if (unlikely(ret < 0))
>  		return ret;
>
>  	return snprintf(buf, PAGE_SIZE, "%d\n", value);
>  }
>
> +static umode_t ltc2990_attrs_visible(struct kobject *kobj,
> +				     struct attribute *a, int n)
> +{
> +	struct device *dev = container_of(kobj, struct device, kobj);
> +	struct ltc2990_data *data = dev_get_drvdata(dev);
> +	struct device_attribute *da =
> +			container_of(a, struct device_attribute, attr);
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> +
> +	if (attr->index == LTC2990_TEMP1 ||
> +	    attr->index == LTC2990_IN0 ||
> +	    attr->index & ltc2990_attrs_ena[data->mode])
> +		return a->mode;
> +	else

Unnecessary else

> +		return 0;
> +}
> +
>  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value, NULL,
> -			  LTC2990_TINT_MSB);
> +			  LTC2990_TEMP1);
> +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_TEMP2);
> +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_TEMP3);
>  static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value, NULL,
> -			  LTC2990_V1_MSB);
> +			  LTC2990_CURR1);
>  static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value, NULL,
> -			  LTC2990_V3_MSB);
> +			  LTC2990_CURR2);
>  static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
> -			  LTC2990_VCC_MSB);
> +			  LTC2990_IN0);
> +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_IN1);
> +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_IN2);
> +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_IN3);
> +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc2990_show_value, NULL,
> +			  LTC2990_IN4);
>
>  static struct attribute *ltc2990_attrs[] = {
>  	&sensor_dev_attr_temp1_input.dev_attr.attr,
> +	&sensor_dev_attr_temp2_input.dev_attr.attr,
> +	&sensor_dev_attr_temp3_input.dev_attr.attr,
>  	&sensor_dev_attr_curr1_input.dev_attr.attr,
>  	&sensor_dev_attr_curr2_input.dev_attr.attr,
>  	&sensor_dev_attr_in0_input.dev_attr.attr,
> +	&sensor_dev_attr_in1_input.dev_attr.attr,
> +	&sensor_dev_attr_in2_input.dev_attr.attr,
> +	&sensor_dev_attr_in3_input.dev_attr.attr,
> +	&sensor_dev_attr_in4_input.dev_attr.attr,
>  	NULL,
>  };
> -ATTRIBUTE_GROUPS(ltc2990);
> +
> +static const struct attribute_group ltc2990_group = {
> +	.attrs = ltc2990_attrs,
> +	.is_visible = ltc2990_attrs_visible,
> +};
> +__ATTRIBUTE_GROUPS(ltc2990);
>
>  static int ltc2990_i2c_probe(struct i2c_client *i2c,
>  			     const struct i2c_device_id *id)
>  {
>  	int ret;
>  	struct device *hwmon_dev;
> +	struct ltc2990_data *data;
> +	struct device_node *of_node = i2c->dev.of_node;
>
>  	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
>  				     I2C_FUNC_SMBUS_WORD_DATA))
>  		return -ENODEV;
>
> -	/* Setup continuous mode, current monitor */
> +	data = devm_kzalloc(&i2c->dev, sizeof(struct ltc2990_data), GFP_KERNEL);
> +	if (unlikely(!data))
> +		return -ENOMEM;
> +	data->i2c = i2c;
> +
> +	if (!of_node || of_property_read_u32(of_node, "lltc,mode", &data->mode))
> +		data->mode = LTC2990_CONTROL_MODE_DEFAULT;

Iam arguing with myself if we should still do this or if we should read the mode
from the chip instead if it isn't provided (after all, it may have been initialized
by the BIOS/ROMMON).

Mike, would that break your application, or can you specify the mode in devicetree ?

Thanks,
Guenter

> +
> +	if (data->mode > LTC2990_CONTROL_MODE_MAX) {
> +		dev_err(&i2c->dev, "Error: Invalid mode %d.\n", data->mode);
> +		return -EINVAL;
> +	}
> +
> +	/* Setup continuous mode */
>  	ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
>  					LTC2990_CONTROL_MEASURE_ALL |
> -					LTC2990_CONTROL_MODE_CURRENT);
> +					data->mode);
>  	if (ret < 0) {
>  		dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
>  		return ret;
> @@ -127,7 +244,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>
>  	hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
>  							   i2c->name,
> -							   i2c,
> +							   data,
>  							   ltc2990_groups);
>
>  	return PTR_ERR_OR_ZERO(hwmon_dev);
>

--
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

* [PATCH] soc/tegra: Implement Tegra186 PMC support
From: Thierry Reding @ 2016-11-17 17:16 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Rob Herring, Mark Rutland, Stephen Warren, Alexandre Courbot,
	Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

The power management controller on Tegra186 has changed in backwards-
incompatible ways with respect to earlier generations. This implements a
new driver that supports inversion of the PMU interrupt as well as the
"recovery", "bootloader" and "forced-recovery" reboot commands.

Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 .../bindings/arm/tegra/nvidia,tegra186-pmc.txt     |  34 +++++
 drivers/soc/tegra/Makefile                         |   2 +-
 drivers/soc/tegra/pmc-tegra186.c                   | 169 +++++++++++++++++++++
 3 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
 create mode 100644 drivers/soc/tegra/pmc-tegra186.c

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
new file mode 100644
index 000000000000..078a58b0302f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
@@ -0,0 +1,34 @@
+NVIDIA Tegra Power Management Controller (PMC)
+
+Required properties:
+- compatible: Should contain one of the following:
+  - "nvidia,tegra186-pmc": for Tegra186
+- reg: Must contain an (offset, length) pair of the register set for each
+  entry in reg-names.
+- reg-names: Must include the following entries:
+  - "pmc"
+  - "wake"
+  - "aotag"
+  - "scratch"
+
+Optional properties:
+- nvidia,invert-interrupt: If present, inverts the PMU interrupt signal.
+
+Example:
+
+SoC DTSI:
+
+	pmc@c3600000 {
+		compatible = "nvidia,tegra186-pmc";
+		reg = <0 0x0c360000 0 0x10000>,
+		      <0 0x0c370000 0 0x10000>,
+		      <0 0x0c380000 0 0x10000>,
+		      <0 0x0c390000 0 0x10000>;
+		reg-names = "pmc", "wake", "aotag", "scratch";
+	};
+
+Board DTS:
+
+	pmc@c360000 {
+		nvidia,invert-interrupt;
+	};
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
index ae857ff7d53d..9976a0de1927 100644
--- a/drivers/soc/tegra/Makefile
+++ b/drivers/soc/tegra/Makefile
@@ -1,4 +1,4 @@
 obj-y += fuse/
 
 obj-y += common.o
-obj-y += pmc.o
+obj-y += pmc.o pmc-tegra186.o
diff --git a/drivers/soc/tegra/pmc-tegra186.c b/drivers/soc/tegra/pmc-tegra186.c
new file mode 100644
index 000000000000..ee28eddd8e3c
--- /dev/null
+++ b/drivers/soc/tegra/pmc-tegra186.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+
+#include <asm/system_misc.h>
+
+#define PMC_CNTRL 0x000
+#define  PMC_CNTRL_MAIN_RST BIT(4)
+
+#define PMC_RST_STATUS 0x070
+
+#define WAKE_AOWAKE_CTRL 0x4f4
+#define  WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
+
+#define SCRATCH_SCRATCH0 0x2000
+#define  SCRATCH_SCRATCH0_MODE_RECOVERY BIT(31)
+#define  SCRATCH_SCRATCH0_MODE_BOOTLOADER BIT(30)
+#define  SCRATCH_SCRATCH0_MODE_RCM BIT(1)
+#define  SCRATCH_SCRATCH0_MODE_MASK (SCRATCH_SCRATCH0_MODE_RECOVERY | \
+				     SCRATCH_SCRATCH0_MODE_BOOTLOADER | \
+				     SCRATCH_SCRATCH0_MODE_RCM)
+
+struct tegra_pmc {
+	struct device *dev;
+	void __iomem *regs;
+	void __iomem *wake;
+	void __iomem *aotag;
+	void __iomem *scratch;
+
+	void (*system_restart)(enum reboot_mode mode, const char *cmd);
+	struct notifier_block restart;
+};
+
+static int tegra186_pmc_restart_notify(struct notifier_block *nb,
+				       unsigned long action,
+				       void *data)
+{
+	struct tegra_pmc *pmc = container_of(nb, struct tegra_pmc, restart);
+	const char *cmd = data;
+	u32 value;
+
+	value = readl(pmc->scratch + SCRATCH_SCRATCH0);
+	value &= ~SCRATCH_SCRATCH0_MODE_MASK;
+
+	if (cmd) {
+		if (strcmp(cmd, "recovery") == 0)
+			value |= SCRATCH_SCRATCH0_MODE_RECOVERY;
+
+		if (strcmp(cmd, "bootloader") == 0)
+			value |= SCRATCH_SCRATCH0_MODE_BOOTLOADER;
+
+		if (strcmp(cmd, "forced-recovery") == 0)
+			value |= SCRATCH_SCRATCH0_MODE_RCM;
+	}
+
+	writel(value, pmc->scratch + SCRATCH_SCRATCH0);
+
+	/*
+	 * If available, call the system restart implementation that was
+	 * registered earlier (typically PSCI).
+	 */
+	if (pmc->system_restart) {
+		pmc->system_restart(reboot_mode, cmd);
+		return NOTIFY_DONE;
+	}
+
+	/* reset everything but SCRATCH0_SCRATCH0 and PMC_RST_STATUS */
+	value = readl(pmc->regs + PMC_CNTRL);
+	value |= PMC_CNTRL_MAIN_RST;
+	writel(value, pmc->regs + PMC_CNTRL);
+
+	return NOTIFY_DONE;
+}
+
+static int tegra186_pmc_setup(struct tegra_pmc *pmc)
+{
+	struct device_node *np = pmc->dev->of_node;
+	bool invert;
+	u32 value;
+
+	invert = of_property_read_bool(np, "nvidia,invert-interrupt");
+
+	value = readl(pmc->wake + WAKE_AOWAKE_CTRL);
+
+	if (invert)
+		value |= WAKE_AOWAKE_CTRL_INTR_POLARITY;
+	else
+		value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY;
+
+	writel(value, pmc->wake + WAKE_AOWAKE_CTRL);
+
+	/*
+	 * We need to hook any system restart implementation registered
+	 * previously so we can write SCRATCH_SCRATCH0 before reset.
+	 */
+	pmc->system_restart = arm_pm_restart;
+	arm_pm_restart = NULL;
+
+	pmc->restart.notifier_call = tegra186_pmc_restart_notify;
+	pmc->restart.priority = 128;
+
+	return register_restart_handler(&pmc->restart);
+}
+
+static int tegra186_pmc_probe(struct platform_device *pdev)
+{
+	struct tegra_pmc *pmc;
+	struct resource *res;
+
+	pmc = devm_kzalloc(&pdev->dev, sizeof(*pmc), GFP_KERNEL);
+	if (!pmc)
+		return -ENOMEM;
+
+	pmc->dev = &pdev->dev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmc");
+	pmc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pmc->regs))
+		return PTR_ERR(pmc->regs);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wake");
+	pmc->wake = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pmc->wake))
+		return PTR_ERR(pmc->wake);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aotag");
+	pmc->aotag = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pmc->aotag))
+		return PTR_ERR(pmc->aotag);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "scratch");
+	pmc->scratch = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pmc->scratch))
+		return PTR_ERR(pmc->scratch);
+
+	tegra186_pmc_setup(pmc);
+
+	return 0;
+}
+
+static const struct of_device_id tegra186_pmc_of_match[] = {
+	{ .compatible = "nvidia,tegra186-pmc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tegra186_pmc_of_match);
+
+static struct platform_driver tegra186_pmc_driver = {
+	.driver = {
+		.name = "tegra186-pmc",
+		.of_match_table = tegra186_pmc_of_match,
+	},
+	.probe = tegra186_pmc_probe,
+};
+builtin_platform_driver(tegra186_pmc_driver);
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH v3 2/3] drm/bridge: Add ti-tfp410 DVI transmitter driver
From: Laurent Pinchart @ 2016-11-17 17:20 UTC (permalink / raw)
  To: Jyri Sarha
  Cc: devicetree, bcousson, khilman, dri-devel, bgolaszewski,
	tomi.valkeinen
In-Reply-To: <5969991d-c4cd-4ac5-9025-dfcd2b6b914d@ti.com>

Hi Jyri,

On Thursday 17 Nov 2016 15:39:26 Jyri Sarha wrote:
> On 11/17/16 15:28, Jyri Sarha wrote:
> > Add very basic ti-ftp410 DVI transmitter driver. The only feature
> > separating this from a completely dummy bridge is the EDID read
> > support trough DDC I2C. Even that functionality should be in a
> > separate generic connector driver. However, because of missing DRM
> > infrastructure support the connector is implemented within the bridge
> > driver. Some tfp410 HW specific features may be added later if needed,
> > because there is a set of registers behind i2c if it is connected.
> > 
> > This implementation is tested against my new tilcdc bridge support
> > and it works with BeagleBone DVI-D Cape Rev A3. A DT binding document
> > is also added.
> > 
> > Signed-off-by: Jyri Sarha <jsarha@ti.com>
> > ---
> > 
> >  .../bindings/display/bridge/ti,tfp410.txt          |  40 +++
> >  drivers/gpu/drm/bridge/Kconfig                     |   7 +
> >  drivers/gpu/drm/bridge/Makefile                    |   1 +
> >  drivers/gpu/drm/bridge/ti-tfp410.c                 | 287 ++++++++++++++++
> >  4 files changed, 335 insertions(+)
> >  create mode 100644
> >  Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt create
> >  mode 100644 drivers/gpu/drm/bridge/ti-tfp410.c
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
> > b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt new file
> > mode 100644
> > index 0000000..6174b18
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
> > @@ -0,0 +1,40 @@
> > +TFP410 DVI bridge bindings
> > +
> > +Required properties:
> > +	- compatible: "ti,tfp410"
> > +
> > +Optional properties
> > +	- reg: I2C address. If and only if present the device node
> > +	  should be placed into the i2c controller node where the
> > +	  tfp410 i2c is connected to.
> > +
> > +Required subnodes:
> > +	- port@0: Video input port node to connect the bridge to a
> > +	  display controller output [1].
> > +	- port@1: Video output port node to connect the bridge to a
> > +	  connector input [1].
> > +
> > +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> > +
> > +Example:
> > +	hdmi-bridge {
> > +		compatible = "ti,tfp410";
> > +		ports {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			port@0 {
> > +				reg = <0>;
> > +				bridge_in: endpoint {
> > +					remote-endpoint = <&dc_out>;
> > +				};
> > +			};
> > +
> > +			port@1 {
> > +				reg = <1>;
> > +				bridge_out: endpoint {
> > +					remote-endpoint = <&hdmi_in>;
> > +				};
> > +			};
> > +		};
> > +	};
> > diff --git a/drivers/gpu/drm/bridge/Kconfig
> > b/drivers/gpu/drm/bridge/Kconfig index bd6acc8..a424e03 100644
> > --- a/drivers/gpu/drm/bridge/Kconfig
> > +++ b/drivers/gpu/drm/bridge/Kconfig
> > @@ -81,6 +81,13 @@ config DRM_TOSHIBA_TC358767
> > 
> >  	---help---
> >  	
> >  	  Toshiba TC358767 eDP bridge chip driver.
> > 
> > +config DRM_TI_TFP410
> > +	tristate "TI TFP410 DVI/HDMI bridge"
> > +	depends on OF
> > +	select DRM_KMS_HELPER
> > +	---help---
> > +	  Texas Instruments TFP410 DVI/HDMI Transmitter driver
> > +
> > 
> >  source "drivers/gpu/drm/bridge/analogix/Kconfig"
> >  
> >  source "drivers/gpu/drm/bridge/adv7511/Kconfig"
> > 
> > diff --git a/drivers/gpu/drm/bridge/Makefile
> > b/drivers/gpu/drm/bridge/Makefile index 97ed1a5..8b065d9 100644
> > --- a/drivers/gpu/drm/bridge/Makefile
> > +++ b/drivers/gpu/drm/bridge/Makefile
> > @@ -11,3 +11,4 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o
> > 
> >  obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
> >  obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> >  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
> > 
> > +obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
> > diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c
> > b/drivers/gpu/drm/bridge/ti-tfp410.c new file mode 100644
> > index 0000000..64f54e4
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/ti-tfp410.c
> > @@ -0,0 +1,287 @@
> > +/*
> > + * Copyright (C) 2016 Texas Instruments
> > + * Author: Jyri Sarha <jsarha@ti.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 as
> > published by + * the Free Software Foundation.
> > + *
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/of_graph.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/i2c.h>
> > +
> > +#include <drm/drmP.h>
> > +#include <drm/drm_atomic_helper.h>
> > +#include <drm/drm_crtc.h>
> > +#include <drm/drm_crtc_helper.h>
> > +
> > +struct tfp410 {
> > +	struct drm_bridge	bridge;
> > +	struct drm_connector	connector;
> > +
> > +	struct i2c_adapter	*ddc;
> > +
> > +	struct device *dev;
> > +};
> > +
> > +static inline struct tfp410 *
> > +drm_bridge_to_tfp410(struct drm_bridge *bridge)
> > +{
> > +	return container_of(bridge, struct tfp410, bridge);
> > +}
> > +
> > +static inline struct tfp410 *
> > +drm_connector_to_tfp410(struct drm_connector *connector)
> > +{
> > +	return container_of(connector, struct tfp410, connector);
> > +}
> > +
> > +static int tfp410_get_modes(struct drm_connector *connector)
> > +{
> > +	struct tfp410 *dvi = drm_connector_to_tfp410(connector);
> > +	struct edid *edid;
> > +	int ret;
> > +
> > +	if (!dvi->ddc)
> > +		goto fallback;
> > +
> > +	edid = drm_get_edid(connector, dvi->ddc);
> > +	if (!edid) {
> > +		DRM_INFO("EDID read failed. Fallback to standard modes\n");
> > +		goto fallback;
> > +	}
> > +
> > +	drm_mode_connector_update_edid_property(connector, edid);
> > +
> > +	return drm_add_edid_modes(connector, edid);
> > +fallback:
> > +	/* No EDID, fallback on the XGA standard modes */
> > +	ret = drm_add_modes_noedid(connector, 1920, 1200);
> > +
> > +	/* And prefer a mode pretty much anything can handle */
> > +	drm_set_preferred_mode(connector, 1024, 768);
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct drm_connector_helper_funcs tfp410_con_helper_funcs =
> > {
> > +	.get_modes	= tfp410_get_modes,
> > +};
> > +
> > +static enum drm_connector_status
> > +tfp410_connector_detect(struct drm_connector *connector, bool force)
> > +{
> > +	struct tfp410 *dvi = drm_connector_to_tfp410(connector);
> > +
> > +	if (dvi->ddc) {
> > +		if (drm_probe_ddc(dvi->ddc))
> > +			return connector_status_connected;
> > +		else
> > +			return connector_status_disconnected;
> > +	}
> > +
> > +	return connector_status_unknown;
> > +}
> > +
> > +static const struct drm_connector_funcs tfp410_con_funcs = {
> > +	.dpms			= drm_atomic_helper_connector_dpms,
> > +	.detect			= tfp410_connector_detect,
> > +	.fill_modes		= drm_helper_probe_single_connector_modes,
> > +	.destroy		= drm_connector_cleanup,
> > +	.reset			= drm_atomic_helper_connector_reset,
> > +	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
> > +	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
> > +};
> > +
> > +static int tfp410_attach(struct drm_bridge *bridge)
> > +{
> > +	struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
> > +	int ret;
> > +
> > +	if (!bridge->encoder) {
> > +		dev_err(dvi->dev, "Missing encoder\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	drm_connector_helper_add(&dvi->connector,
> > +				 &tfp410_con_helper_funcs);
> > +	ret = drm_connector_init(bridge->dev, &dvi->connector,
> > +				 &tfp410_con_funcs, DRM_MODE_CONNECTOR_HDMIA);
> > +	if (ret) {
> > +		dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	drm_mode_connector_attach_encoder(&dvi->connector,
> > +					  bridge->encoder);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct drm_bridge_funcs tfp410_bridge_funcs = {
> > +	.attach		= tfp410_attach,
> > +};
> > +
> > +static int tfp410_get_connector_ddc(struct tfp410 *dvi)
> > +{
> > +	struct device_node *ep = NULL, *connector_node = NULL;
> > +	struct device_node *ddc_phandle = NULL;
> > +	int ret = 0;
> > +
> > +	/* port@1 is the connector node */
> > +	ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 1, -1);
> > +	if (!ep)
> > +		goto fail;
> > +
> > +	connector_node = of_graph_get_remote_port_parent(ep);
> > +	if (!connector_node)
> > +		goto fail;
> > +
> > +	ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0);
> > +	if (!ddc_phandle)
> > +		goto fail;
> > +
> > +	dvi->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
> > +	if (dvi->ddc)
> > +		dev_info(dvi->dev, "Connector's ddc i2c bus found\n");
> > +	else
> > +		ret = -EPROBE_DEFER;
> > +
> > +fail:
> > +	of_node_put(ep);
> > +	of_node_put(connector_node);
> > +	of_node_put(ddc_phandle);
> > +	return ret;
> > +}
> > +
> > +static int tfp410_init(struct device *dev)
> > +{
> > +	struct tfp410 *dvi;
> > +	int ret;
> > +
> > +	if (!dev->of_node) {
> > +		dev_err(dev, "device-tree data is missing\n");
> > +		return -ENXIO;
> > +	}
> > +
> > +	dvi = devm_kzalloc(dev, sizeof(*dvi), GFP_KERNEL);
> > +	if (!dvi)
> > +		return -ENOMEM;
> > +	dev_set_drvdata(dev, dvi);
> > +
> > +	dvi->bridge.funcs = &tfp410_bridge_funcs;
> > +	dvi->bridge.of_node = dev->of_node;
> > +	dvi->dev = dev;
> > +
> > +	ret = tfp410_get_connector_ddc(dvi);
> > +	if (ret)
> > +		goto fail;
> > +
> > +	ret = drm_bridge_add(&dvi->bridge);
> > +	if (ret) {
> > +		dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
> > +		goto fail;
> > +	}
> > +
> > +	return 0;
> > +fail:
> > +	i2c_put_adapter(dvi->ddc);
> > +	return ret;
> > +}
> > +
> > +static int tfp410_fini(struct device *dev)
> > +{
> > +	struct tfp410 *dvi = dev_get_drvdata(dev);
> > +
> > +	drm_bridge_remove(&dvi->bridge);
> > +
> > +	if (dvi->ddc)
> > +		i2c_put_adapter(dvi->ddc);
> > +
> > +	return 0;
> > +}
> > +
> > +static int tfp410_probe(struct platform_device *pdev)
> > +{
> > +	return tfp410_init(&pdev->dev);
> > +}
> > +
> > +static int tfp410_remove(struct platform_device *pdev)
> > +{
> > +	return tfp410_fini(&pdev->dev);
> > +}
> > +
> > +/* There is currently no i2c functionality. */
> > +static int tfp410_i2c_probe(struct i2c_client *client,
> > +			    const struct i2c_device_id *id)
> > +{
> > +	int reg;
> > +
> > +	if (!client->dev.of_node ||
> > +	    of_property_read_u32(client->dev.of_node, "reg", &reg)) {
> > +		dev_err(&client->dev,
> > +			"Can't get i2c reg property from device-tree\n");
> > +		return -ENXIO;
> > +	}
> > +
> > +	return tfp410_init(&client->dev);
> > +}
> > +
> > +static int tfp410_i2c_remove(struct i2c_client *client)
> > +{
> > +	return tfp410_fini(&client->dev);
> > +}
> > +
> > +static const struct of_device_id tfp410_match[] = {
> > +	{ .compatible = "ti,tfp410" },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, tfp410_match);
> > +
> > +struct platform_driver tfp410_platform_driver = {
> > +	.probe	= tfp410_probe,
> > +	.remove	= tfp410_remove,
> > +	.driver	= {
> > +		.name		= "tfp410-bridge",
> > +		.of_match_table	= tfp410_match,
> > +	},
> > +};
> > +
> > +static const struct i2c_device_id tfp410_i2c_ids[] = {
> > +	{ "tfp410", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(i2c, tfp410_i2c_ids);
> > +
> > +static struct i2c_driver tfp410_i2c_driver = {
> > +	.driver = {
> > +		.name	= "tfp410",
> > +		.of_match_table = of_match_ptr(tfp410_match),
> > +	},
> > +	.id_table	= tfp410_i2c_ids,
> > +	.probe		= tfp410_i2c_probe,
> > +	.remove		= tfp410_i2c_remove,
> > +};
> > +
> > +static int __init tfp410_module_init(void)
> > +{
> > +	i2c_add_driver(&tfp410_i2c_driver);
> > +	platform_driver_register(&tfp410_platform_driver);
> 
> Oops, forgot to handle the return values. This is how I fixed it:
> static int __init tfp410_module_init(void)
> {
> 	int ret;
> 
> 	ret = i2c_add_driver(&tfp410_i2c_driver);
> 	if (ret)
> 		return ret;
> 
> 	ret = platform_driver_register(&tfp410_platform_driver);
> 	if (ret)
> 		i2c_del_driver(&tfp410_i2c_driver);
> 
> 	return ret;
> }

If registration of one of the two drivers fail, wouldn't it make sense to 
still continue (probably with an error message) to avoid breaking the other 
one ?

> > +
> > +	return 0;
> > +}
> > +module_init(tfp410_module_init);
> > +
> > +static void __exit tfp410_module_exit(void)
> > +{
> > +	i2c_del_driver(&tfp410_i2c_driver);
> > +	platform_driver_unregister(&tfp410_platform_driver);
> > +}
> > +module_exit(tfp410_module_exit);
> > +
> > +MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
> > +MODULE_DESCRIPTION("TI TFP410 DVI bridge driver");
> > +MODULE_LICENSE("GPL");

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH] soc/tegra: Implement Tegra186 PMC support
From: Sudeep Holla @ 2016-11-17 17:28 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sudeep Holla, Rob Herring, Mark Rutland, Stephen Warren,
	Alexandre Courbot, Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161117171636.20580-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>



On 17/11/16 17:16, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> The power management controller on Tegra186 has changed in backwards-
> incompatible ways with respect to earlier generations. This implements a
> new driver that supports inversion of the PMU interrupt as well as the
> "recovery", "bootloader" and "forced-recovery" reboot commands.
>
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  .../bindings/arm/tegra/nvidia,tegra186-pmc.txt     |  34 +++++
>  drivers/soc/tegra/Makefile                         |   2 +-
>  drivers/soc/tegra/pmc-tegra186.c                   | 169 +++++++++++++++++++++
>  3 files changed, 204 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
>  create mode 100644 drivers/soc/tegra/pmc-tegra186.c
>

[...]

> diff --git a/drivers/soc/tegra/pmc-tegra186.c b/drivers/soc/tegra/pmc-tegra186.c
> new file mode 100644
> index 000000000000..ee28eddd8e3c
> --- /dev/null
> +++ b/drivers/soc/tegra/pmc-tegra186.c

[...]

> +
> +	/*
> +	 * If available, call the system restart implementation that was
> +	 * registered earlier (typically PSCI).
> +	 */
> +	if (pmc->system_restart) {
> +		pmc->system_restart(reboot_mode, cmd);
> +		return NOTIFY_DONE;
> +	}
> +

IIUC, Tegra186 implements PSCI v1.0 and it always takes above path.
So what other platforms does this driver support ? The name is
pmc-tegra186.c, hence the confusion.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH] soc/tegra: Implement Tegra186 PMC support
From: Thierry Reding @ 2016-11-17 17:31 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Rob Herring, Mark Rutland, Stephen Warren, Alexandre Courbot,
	Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <0068ebe4-09f3-4434-fc38-071cf2d553bc-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1949 bytes --]

On Thu, Nov 17, 2016 at 05:28:53PM +0000, Sudeep Holla wrote:
> 
> 
> On 17/11/16 17:16, Thierry Reding wrote:
> > From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > 
> > The power management controller on Tegra186 has changed in backwards-
> > incompatible ways with respect to earlier generations. This implements a
> > new driver that supports inversion of the PMU interrupt as well as the
> > "recovery", "bootloader" and "forced-recovery" reboot commands.
> > 
> > Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > ---
> >  .../bindings/arm/tegra/nvidia,tegra186-pmc.txt     |  34 +++++
> >  drivers/soc/tegra/Makefile                         |   2 +-
> >  drivers/soc/tegra/pmc-tegra186.c                   | 169 +++++++++++++++++++++
> >  3 files changed, 204 insertions(+), 1 deletion(-)
> >  create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
> >  create mode 100644 drivers/soc/tegra/pmc-tegra186.c
> > 
> 
> [...]
> 
> > diff --git a/drivers/soc/tegra/pmc-tegra186.c b/drivers/soc/tegra/pmc-tegra186.c
> > new file mode 100644
> > index 000000000000..ee28eddd8e3c
> > --- /dev/null
> > +++ b/drivers/soc/tegra/pmc-tegra186.c
> 
> [...]
> 
> > +
> > +	/*
> > +	 * If available, call the system restart implementation that was
> > +	 * registered earlier (typically PSCI).
> > +	 */
> > +	if (pmc->system_restart) {
> > +		pmc->system_restart(reboot_mode, cmd);
> > +		return NOTIFY_DONE;
> > +	}
> > +
> 
> IIUC, Tegra186 implements PSCI v1.0 and it always takes above path.
> So what other platforms does this driver support ? The name is
> pmc-tegra186.c, hence the confusion.

It's technically possible to run Tegra186 without PSCI enabled, or even
boot it with firmware that doesn't implement PSCI. In such cases it
would be nice to still be able to reboot via the PMC code above.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [PATCH v2 3/3] hwmon: ltc2990: support all measurement modes
From: Mike Looijmans @ 2016-11-17 17:40 UTC (permalink / raw)
  To: Guenter Roeck, Tom Levens
  Cc: jdelvare, robh+dt, mark.rutland, linux-kernel, linux-hwmon,
	devicetree
In-Reply-To: <410de6c9-a13e-51f7-4d66-6f4e2537c574@roeck-us.net>

On 17-11-16 17:56, Guenter Roeck wrote:
> On 11/17/2016 04:10 AM, Tom Levens wrote:
>> Updated version of the ltc2990 driver which supports all measurement
>> modes available in the chip. The mode can be set through a devicetree
>> attribute.
>
> property
>
>>
>> Signed-off-by: Tom Levens <tom.levens@cern.ch>
>> ---
>>
>> Changes since v1:
>>   * Refactored value conversion (patch 1/3)
>>   * Split the devicetree binding into separate patch (patch 2/3)
>>   * Specifying an invalid mode now returns -EINVAL, previously this
>>     only issued a warning and used the default value
>>   * Removed the "mode" sysfs attribute, as the mode of the chip is
>>     hardware specific and should not be user configurable. This allows
>> much
>>     simpler code as a result.
>>
>>  Documentation/hwmon/ltc2990 |   24 ++++---
>>  drivers/hwmon/Kconfig       |    7 +--
>>  drivers/hwmon/ltc2990.c     |  167
>> ++++++++++++++++++++++++++++++++++++-------
>>  3 files changed, 159 insertions(+), 39 deletions(-)
>>
>> diff --git a/Documentation/hwmon/ltc2990 b/Documentation/hwmon/ltc2990
>> index c25211e..3ed68f6 100644
>> --- a/Documentation/hwmon/ltc2990
>> +++ b/Documentation/hwmon/ltc2990
>> @@ -8,6 +8,7 @@ Supported chips:
>>      Datasheet: http://www.linear.com/product/ltc2990
>>
>>  Author: Mike Looijmans <mike.looijmans@topic.nl>
>> +        Tom Levens <tom.levens@cern.ch>
>>
>>
>>  Description
>> @@ -16,10 +17,8 @@ Description
>>  LTC2990 is a Quad I2C Voltage, Current and Temperature Monitor.
>>  The chip's inputs can measure 4 voltages, or two inputs together (1+2
>> and 3+4)
>>  can be combined to measure a differential voltage, which is typically
>> used to
>> -measure current through a series resistor, or a temperature.
>> -
>> -This driver currently uses the 2x differential mode only. In order to
>> support
>> -other modes, the driver will need to be expanded.
>> +measure current through a series resistor, or a temperature with an
>> external
>> +diode.
>>
>>
>>  Usage Notes
>> @@ -32,12 +31,19 @@ devices explicitly.
>>  Sysfs attributes
>>  ----------------
>>
>> +in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
>> +temp1_input   Internal chip temperature in millidegrees Celcius
>> +
>> +A subset of the following attributes are visible, depending on the
>> measurement
>> +mode of the chip.
>> +
>> +in[1-4]_input Voltage at V[1-4] pin in millivolt
>> +temp2_input   External temperature sensor TR1 in millidegrees Celcius
>> +temp3_input   External temperature sensor TR2 in millidegrees Celcius
>> +curr1_input   Current in mA across V1-V2 assuming a 1mOhm sense resistor
>> +curr2_input   Current in mA across V3-V4 assuming a 1mOhm sense resistor
>> +
>>  The "curr*_input" measurements actually report the voltage drop
>> across the
>>  input pins in microvolts. This is equivalent to the current through a
>> 1mOhm
>>  sense resistor. Divide the reported value by the actual sense
>> resistor value
>>  in mOhm to get the actual value.
>> -
>> -in0_input     Voltage at Vcc pin in millivolt (range 2.5V to 5V)
>> -temp1_input   Internal chip temperature in millidegrees Celcius
>> -curr1_input   Current in mA across v1-v2 assuming a 1mOhm sense
>> resistor.
>> -curr2_input   Current in mA across v3-v4 assuming a 1mOhm sense
>> resistor.
>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
>> index 45cef3d..f7096ca 100644
>> --- a/drivers/hwmon/Kconfig
>> +++ b/drivers/hwmon/Kconfig
>> @@ -699,15 +699,12 @@ config SENSORS_LTC2945
>>        be called ltc2945.
>>
>>  config SENSORS_LTC2990
>> -    tristate "Linear Technology LTC2990 (current monitoring mode only)"
>> +    tristate "Linear Technology LTC2990"
>>      depends on I2C
>>      help
>>        If you say yes here you get support for Linear Technology LTC2990
>>        I2C System Monitor. The LTC2990 supports a combination of voltage,
>> -      current and temperature monitoring, but in addition to the Vcc
>> supply
>> -      voltage and chip temperature, this driver currently only supports
>> -      reading two currents by measuring two differential voltages across
>> -      series resistors.
>> +      current and temperature monitoring.
>>
>>        This driver can also be built as a module. If so, the module will
>>        be called ltc2990.
>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>> index 0ec4102..e8d36f5 100644
>> --- a/drivers/hwmon/ltc2990.c
>> +++ b/drivers/hwmon/ltc2990.c
>> @@ -6,11 +6,7 @@
>>   *
>>   * License: GPLv2
>>   *
>> - * This driver assumes the chip is wired as a dual current monitor, and
>> - * reports the voltage drop across two series resistors. It also reports
>> - * the chip's internal temperature and Vcc power supply voltage.
>> - *
>> - * Value conversion refactored
>> + * Value conversion refactored and support for all measurement modes
>> added
>>   * by Tom Levens <tom.levens@cern.ch>
>>   */
>>
>> @@ -21,6 +17,7 @@
>>  #include <linux/i2c.h>
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>> +#include <linux/of.h>
>>
>>  #define LTC2990_STATUS    0x00
>>  #define LTC2990_CONTROL    0x01
>> @@ -35,32 +32,96 @@
>>  #define LTC2990_CONTROL_KELVIN        BIT(7)
>>  #define LTC2990_CONTROL_SINGLE        BIT(6)
>>  #define LTC2990_CONTROL_MEASURE_ALL    (0x3 << 3)
>> -#define LTC2990_CONTROL_MODE_CURRENT    0x06
>> -#define LTC2990_CONTROL_MODE_VOLTAGE    0x07
>> +#define LTC2990_CONTROL_MODE_DEFAULT    0x06
>
> I think LTC2990_CONTROL_MODE_CURRENT was better - it describes the
> actual mode.
> Changing the define to _DEFAULT does not really improve code readability.

I think I understand what the author intended - the mode becomes an 
index into the array.

But I think the define can be dropped altogether, see below.

>
>> +#define LTC2990_CONTROL_MODE_MAX    0x07
>> +
>> +#define LTC2990_IN0    BIT(0)
>> +#define LTC2990_IN1    BIT(1)
>> +#define LTC2990_IN2    BIT(2)
>> +#define LTC2990_IN3    BIT(3)
>> +#define LTC2990_IN4    BIT(4)
>> +#define LTC2990_CURR1    BIT(5)
>> +#define LTC2990_CURR2    BIT(6)
>> +#define LTC2990_TEMP1    BIT(7)
>> +#define LTC2990_TEMP2    BIT(8)
>> +#define LTC2990_TEMP3    BIT(9)
>> +
>> +static const int ltc2990_attrs_ena[] = {
>> +    LTC2990_IN1 | LTC2990_IN2 | LTC2990_TEMP3,
>> +    LTC2990_CURR1 | LTC2990_TEMP3,
>> +    LTC2990_CURR1 | LTC2990_IN3 | LTC2990_IN4,
>> +    LTC2990_TEMP2 | LTC2990_IN3 | LTC2990_IN4,
>> +    LTC2990_TEMP2 | LTC2990_CURR2,
>> +    LTC2990_TEMP2 | LTC2990_TEMP3,
>> +    LTC2990_CURR1 | LTC2990_CURR2,
>> +    LTC2990_IN1 | LTC2990_IN2 | LTC2990_IN3 | LTC2990_IN4
>> +};
>> +
>> +struct ltc2990_data {
>> +    struct i2c_client *i2c;
>> +    u32 mode;
>> +};
>>
>>  /* Return the converted value from the given register in uV or mC */
>> -static int ltc2990_get_value(struct i2c_client *i2c, u8 reg, s32
>> *result)
>> +static int ltc2990_get_value(struct i2c_client *i2c, int index, s32
>> *result)
>>  {
>>      s32 val;
>> +    u8 reg;
>> +
>> +    switch (index) {
>> +    case LTC2990_IN0:
>> +        reg = LTC2990_VCC_MSB;
>> +        break;
>> +    case LTC2990_IN1:
>> +    case LTC2990_CURR1:
>> +    case LTC2990_TEMP2:
>> +        reg = LTC2990_V1_MSB;
>> +        break;
>> +    case LTC2990_IN2:
>> +        reg = LTC2990_V2_MSB;
>> +        break;
>> +    case LTC2990_IN3:
>> +    case LTC2990_CURR2:
>> +    case LTC2990_TEMP3:
>> +        reg = LTC2990_V3_MSB;
>> +        break;
>> +    case LTC2990_IN4:
>> +        reg = LTC2990_V4_MSB;
>> +        break;
>> +    case LTC2990_TEMP1:
>> +        reg = LTC2990_TINT_MSB;
>> +        break;
>> +    default:
>> +        return -EINVAL;
>> +    }
>>
>>      val = i2c_smbus_read_word_swapped(i2c, reg);
>>      if (unlikely(val < 0))
>>          return val;
>>
>> -    switch (reg) {
>> -    case LTC2990_TINT_MSB:
>> -        /* internal temp, 0.0625 degrees/LSB, 13-bit  */
>> +    switch (index) {
>> +    case LTC2990_TEMP1:
>> +    case LTC2990_TEMP2:
>> +    case LTC2990_TEMP3:
>> +        /* temp, 0.0625 degrees/LSB, 13-bit  */
>>          *result = sign_extend32(val, 12) * 1000 / 16;
>>          break;
>> -    case LTC2990_V1_MSB:
>> -    case LTC2990_V3_MSB:
>> -         /* Vx-Vy, 19.42uV/LSB. Depends on mode. */
>> +    case LTC2990_CURR1:
>> +    case LTC2990_CURR2:
>> +         /* Vx-Vy, 19.42uV/LSB */
>>          *result = sign_extend32(val, 14) * 1942 / 100;
>>          break;
>> -    case LTC2990_VCC_MSB:
>> -        /* Vcc, 305.18μV/LSB, 2.5V offset */
>> +    case LTC2990_IN0:
>> +        /* Vcc, 305.18uV/LSB, 2.5V offset */
>>          *result = sign_extend32(val, 14) * 30518 / (100 * 1000) + 2500;
>>          break;
>> +    case LTC2990_IN1:
>> +    case LTC2990_IN2:
>> +    case LTC2990_IN3:
>> +    case LTC2990_IN4:
>> +        /* Vx: 305.18uV/LSB */
>> +        *result = sign_extend32(val, 14) * 30518 / (100 * 1000);
>> +        break;
>>      default:
>>          return -EINVAL; /* won't happen, keep compiler happy */
>>      }
>> @@ -72,48 +133,104 @@ static ssize_t ltc2990_show_value(struct device
>> *dev,
>>                    struct device_attribute *da, char *buf)
>>  {
>>      struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>> +    struct ltc2990_data *data = dev_get_drvdata(dev);
>>      s32 value;
>>      int ret;
>>
>> -    ret = ltc2990_get_value(dev_get_drvdata(dev), attr->index, &value);
>> +    ret = ltc2990_get_value(data->i2c, attr->index, &value);
>>      if (unlikely(ret < 0))
>>          return ret;
>>
>>      return snprintf(buf, PAGE_SIZE, "%d\n", value);
>>  }
>>
>> +static umode_t ltc2990_attrs_visible(struct kobject *kobj,
>> +                     struct attribute *a, int n)
>> +{
>> +    struct device *dev = container_of(kobj, struct device, kobj);
>> +    struct ltc2990_data *data = dev_get_drvdata(dev);
>> +    struct device_attribute *da =
>> +            container_of(a, struct device_attribute, attr);
>> +    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
>> +
>> +    if (attr->index == LTC2990_TEMP1 ||
>> +        attr->index == LTC2990_IN0 ||
>> +        attr->index & ltc2990_attrs_ena[data->mode])
>> +        return a->mode;
>> +    else
>
> Unnecessary else
>
>> +        return 0;
>> +}
>> +
>>  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ltc2990_show_value,
>> NULL,
>> -              LTC2990_TINT_MSB);
>> +              LTC2990_TEMP1);
>> +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, ltc2990_show_value,
>> NULL,
>> +              LTC2990_TEMP2);
>> +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, ltc2990_show_value,
>> NULL,
>> +              LTC2990_TEMP3);
>>  static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2990_show_value,
>> NULL,
>> -              LTC2990_V1_MSB);
>> +              LTC2990_CURR1);
>>  static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc2990_show_value,
>> NULL,
>> -              LTC2990_V3_MSB);
>> +              LTC2990_CURR2);
>>  static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ltc2990_show_value, NULL,
>> -              LTC2990_VCC_MSB);
>> +              LTC2990_IN0);
>> +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc2990_show_value, NULL,
>> +              LTC2990_IN1);
>> +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc2990_show_value, NULL,
>> +              LTC2990_IN2);
>> +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc2990_show_value, NULL,
>> +              LTC2990_IN3);
>> +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc2990_show_value, NULL,
>> +              LTC2990_IN4);
>>
>>  static struct attribute *ltc2990_attrs[] = {
>>      &sensor_dev_attr_temp1_input.dev_attr.attr,
>> +    &sensor_dev_attr_temp2_input.dev_attr.attr,
>> +    &sensor_dev_attr_temp3_input.dev_attr.attr,
>>      &sensor_dev_attr_curr1_input.dev_attr.attr,
>>      &sensor_dev_attr_curr2_input.dev_attr.attr,
>>      &sensor_dev_attr_in0_input.dev_attr.attr,
>> +    &sensor_dev_attr_in1_input.dev_attr.attr,
>> +    &sensor_dev_attr_in2_input.dev_attr.attr,
>> +    &sensor_dev_attr_in3_input.dev_attr.attr,
>> +    &sensor_dev_attr_in4_input.dev_attr.attr,
>>      NULL,
>>  };
>> -ATTRIBUTE_GROUPS(ltc2990);
>> +
>> +static const struct attribute_group ltc2990_group = {
>> +    .attrs = ltc2990_attrs,
>> +    .is_visible = ltc2990_attrs_visible,
>> +};
>> +__ATTRIBUTE_GROUPS(ltc2990);
>>
>>  static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>                   const struct i2c_device_id *id)
>>  {
>>      int ret;
>>      struct device *hwmon_dev;
>> +    struct ltc2990_data *data;
>> +    struct device_node *of_node = i2c->dev.of_node;
>>
>>      if (!i2c_check_functionality(i2c->adapter,
>> I2C_FUNC_SMBUS_BYTE_DATA |
>>                       I2C_FUNC_SMBUS_WORD_DATA))
>>          return -ENODEV;
>>
>> -    /* Setup continuous mode, current monitor */
>> +    data = devm_kzalloc(&i2c->dev, sizeof(struct ltc2990_data),
>> GFP_KERNEL);
>> +    if (unlikely(!data))
>> +        return -ENOMEM;
>> +    data->i2c = i2c;
>> +
>> +    if (!of_node || of_property_read_u32(of_node, "lltc,mode",
>> &data->mode))
>> +        data->mode = LTC2990_CONTROL_MODE_DEFAULT;
>
> Iam arguing with myself if we should still do this or if we should read
> the mode
> from the chip instead if it isn't provided (after all, it may have been
> initialized
> by the BIOS/ROMMON).

I think the mode should be explicitly set, without default. There's no 
way to tell whether the BIOS or bootloader has really set it up or 
whether the chip is just reporting whatever it happened to default to. 
And given the chip's function, it's unlikely a bootloader would want to 
initialize it.

My advice would be to make it a required property. If not set, display 
an error and bail out.

> Mike, would that break your application, or can you specify the mode in
> devicetree ?

I'm fine with specifying this in the devicetree. It will break things 
for me, but I've been warned and willing to bow for the greater good :)

>
> Thanks,
> Guenter
>
>> +
>> +    if (data->mode > LTC2990_CONTROL_MODE_MAX) {
>> +        dev_err(&i2c->dev, "Error: Invalid mode %d.\n", data->mode);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Setup continuous mode */
>>      ret = i2c_smbus_write_byte_data(i2c, LTC2990_CONTROL,
>>                      LTC2990_CONTROL_MEASURE_ALL |
>> -                    LTC2990_CONTROL_MODE_CURRENT);
>> +                    data->mode);
>>      if (ret < 0) {
>>          dev_err(&i2c->dev, "Error: Failed to set control mode.\n");
>>          return ret;
>> @@ -127,7 +244,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>
>>      hwmon_dev = devm_hwmon_device_register_with_groups(&i2c->dev,
>>                                 i2c->name,
>> -                               i2c,
>> +                               data,
>>                                 ltc2990_groups);
>>
>>      return PTR_ERR_OR_ZERO(hwmon_dev);
>>
>


-- 
Mike Looijmans


Kind regards,

Mike Looijmans
System Expert

TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

^ permalink raw reply

* Re: [PATCH] soc/tegra: Implement Tegra186 PMC support
From: Sudeep Holla @ 2016-11-17 17:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sudeep Holla, Rob Herring, Mark Rutland, Stephen Warren,
	Alexandre Courbot, Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161117173110.GA7915-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>



On 17/11/16 17:31, Thierry Reding wrote:
> On Thu, Nov 17, 2016 at 05:28:53PM +0000, Sudeep Holla wrote:
>>
>>
>> On 17/11/16 17:16, Thierry Reding wrote:
>>> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>>
>>> The power management controller on Tegra186 has changed in backwards-
>>> incompatible ways with respect to earlier generations. This implements a
>>> new driver that supports inversion of the PMU interrupt as well as the
>>> "recovery", "bootloader" and "forced-recovery" reboot commands.
>>>
>>> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>> ---
>>>  .../bindings/arm/tegra/nvidia,tegra186-pmc.txt     |  34 +++++
>>>  drivers/soc/tegra/Makefile                         |   2 +-
>>>  drivers/soc/tegra/pmc-tegra186.c                   | 169 +++++++++++++++++++++
>>>  3 files changed, 204 insertions(+), 1 deletion(-)
>>>  create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
>>>  create mode 100644 drivers/soc/tegra/pmc-tegra186.c
>>>
>>
>> [...]
>>
>>> diff --git a/drivers/soc/tegra/pmc-tegra186.c b/drivers/soc/tegra/pmc-tegra186.c
>>> new file mode 100644
>>> index 000000000000..ee28eddd8e3c
>>> --- /dev/null
>>> +++ b/drivers/soc/tegra/pmc-tegra186.c
>>
>> [...]
>>
>>> +
>>> +	/*
>>> +	 * If available, call the system restart implementation that was
>>> +	 * registered earlier (typically PSCI).
>>> +	 */
>>> +	if (pmc->system_restart) {
>>> +		pmc->system_restart(reboot_mode, cmd);
>>> +		return NOTIFY_DONE;
>>> +	}
>>> +
>>
>> IIUC, Tegra186 implements PSCI v1.0 and it always takes above path.
>> So what other platforms does this driver support ? The name is
>> pmc-tegra186.c, hence the confusion.
>
> It's technically possible to run Tegra186 without PSCI enabled, or even
> boot it with firmware that doesn't implement PSCI. In such cases it

OK, with enable-method as "spin-table" I suppose ?

> would be nice to still be able to reboot via the PMC code above.

I assume it's only for development purposes as you won't have much CPU
power management support without PSCI.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [RESEND PATCH v7 0/3] Add clockevent for timer-nps driver to NPS400 SoC
From: Vineet Gupta @ 2016-11-17 17:50 UTC (permalink / raw)
  To: Noam Camus, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A
  Cc: tglx-hfZtesqFncYOwBW4kG4KsQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Alexey.Brodkin-HKixBCOQz3hWk0Htik3J/w
In-Reply-To: <1479277873-18994-1-git-send-email-noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

On 11/15/2016 10:31 PM, Noam Camus wrote:
> From: Noam Camus <noamca-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 
> Change log
> ---
> V6 --> V7
> Apply several comments made by Daniel Lezcano:
> 1) Remove CLOCK_EVT_FEAT_PERIODIC support. This way it is
>  pure oneshot driver. This simplifies driver so that:
>  nps_clkevent_add_thread()
>  nps_clkevent_rm_thread()
>  are more clearer without any vague logic if to change
>  TSI bit of current HW thread or not.
> 2) tick_resume is also calls nps_clkevent_rm_thread()
> 3) Few (hopefully last) typo fixes. 
> 
> V5 --> V6
> Apply several comments made by Daniel Lezcano:
> 1) nps_get_timer_clk() - use clk_put() on error scenario
> 2) nps_get_timer_clk() - return EINVAL and not plain 1
> 3) Fix typos in log (double checked with spell checker)
> 
> V4 --> V5
> Apply several comments made by Daniel Lezcano:
> 1) Add __init attribute to nps_get_timer_clk()
> 2) Fix return value of nps_get_timer_clk()
>  when failing to get clk rate
> 3) Change clocksource rate from 301 -> 300
> 
> V3 --> V4
> Main changes are [Thanks for the review]:
> Fix many typos at log [Daniel]
> Add handling for bad return values [Daniel and Thomas]
> Replace use of internal irqchip pointers with existing IRQ API [Thomas]
> Provide interrupt handler (percpu) with dev_id equal to evt [Thomas]
> Fix passing *clk by reference to nps_get_timer_clk() [Daniel]
> 
> V2 --> V3
> Apply Rob Herring comment about backword compatibility
> 
> V1 --> V2
> Apply Daniel Lezcano comments:
> 	CLOCKSOURCE_OF_DECLARE return value
> 	update hotplug callbacks usage
> 	squash of 2 first commits.
> In this version I created new commit to serve as preperation for adding clockevents.
> This way the last patch is more readable with clockevent content.
> ---
> 
> In first version of this driver we supported clocksource for the NPS400.
> The support for clockevent was taken from Synopsys ARC timer driver.
> This was good for working with our simulator of NPS400.
> However in NPS400 ASIC the timers behave differently than simulation.
> The timers in ASIC are shared between all threads whithin a core
> and hence need different driver to support this behaviour.
> 
> The idea of this design is that we got 16 HW threads per core
> each represented at bimask in a shared register in this core.
> So when thread wants that next clockevent expiration will produce
> timer interrupt to itself the correspondance bit in this register
> should be set.
> So theoretically if all 16 bits are set then all HW threads will get
> timer interrupt on next expiration of timer 0.
> 
> Note that we use Synopsys ARC design naming convention for the timers
> where:
> timer0 is used for clockevents
> timer1 is used for clocksource.
> 
> Noam Camus (3):
>   soc: Support for NPS HW scheduling
>   clocksource: update "fn" at CLOCKSOURCE_OF_DECLARE() of nps400 timer
>   clocksource: Add clockevent support to NPS400 driver
> 
>  .../bindings/timer/ezchip,nps400-timer.txt         |   15 --
>  .../bindings/timer/ezchip,nps400-timer0.txt        |   17 ++
>  .../bindings/timer/ezchip,nps400-timer1.txt        |   15 ++
>  arch/arc/plat-eznps/include/plat/ctop.h            |    2 -
>  drivers/clocksource/timer-nps.c                    |  223 ++++++++++++++++++--
>  include/soc/nps/mtm.h                              |   59 +++++
>  6 files changed, 294 insertions(+), 37 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer0.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer1.txt
>  create mode 100644 include/soc/nps/mtm.h

Added to ARC for-next !

Thx,
-Vineet
--
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] soc/tegra: Implement Tegra186 PMC support
From: Thierry Reding @ 2016-11-17 17:52 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Rob Herring, Mark Rutland, Stephen Warren, Alexandre Courbot,
	Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <efb274c8-d361-f4d1-95aa-547b9e941d68-5wv7dgnIgG8@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2729 bytes --]

On Thu, Nov 17, 2016 at 05:40:35PM +0000, Sudeep Holla wrote:
> 
> 
> On 17/11/16 17:31, Thierry Reding wrote:
> > On Thu, Nov 17, 2016 at 05:28:53PM +0000, Sudeep Holla wrote:
> > > 
> > > 
> > > On 17/11/16 17:16, Thierry Reding wrote:
> > > > From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > > > 
> > > > The power management controller on Tegra186 has changed in backwards-
> > > > incompatible ways with respect to earlier generations. This implements a
> > > > new driver that supports inversion of the PMU interrupt as well as the
> > > > "recovery", "bootloader" and "forced-recovery" reboot commands.
> > > > 
> > > > Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > > > ---
> > > >  .../bindings/arm/tegra/nvidia,tegra186-pmc.txt     |  34 +++++
> > > >  drivers/soc/tegra/Makefile                         |   2 +-
> > > >  drivers/soc/tegra/pmc-tegra186.c                   | 169 +++++++++++++++++++++
> > > >  3 files changed, 204 insertions(+), 1 deletion(-)
> > > >  create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
> > > >  create mode 100644 drivers/soc/tegra/pmc-tegra186.c
> > > > 
> > > 
> > > [...]
> > > 
> > > > diff --git a/drivers/soc/tegra/pmc-tegra186.c b/drivers/soc/tegra/pmc-tegra186.c
> > > > new file mode 100644
> > > > index 000000000000..ee28eddd8e3c
> > > > --- /dev/null
> > > > +++ b/drivers/soc/tegra/pmc-tegra186.c
> > > 
> > > [...]
> > > 
> > > > +
> > > > +	/*
> > > > +	 * If available, call the system restart implementation that was
> > > > +	 * registered earlier (typically PSCI).
> > > > +	 */
> > > > +	if (pmc->system_restart) {
> > > > +		pmc->system_restart(reboot_mode, cmd);
> > > > +		return NOTIFY_DONE;
> > > > +	}
> > > > +
> > > 
> > > IIUC, Tegra186 implements PSCI v1.0 and it always takes above path.
> > > So what other platforms does this driver support ? The name is
> > > pmc-tegra186.c, hence the confusion.
> > 
> > It's technically possible to run Tegra186 without PSCI enabled, or even
> > boot it with firmware that doesn't implement PSCI. In such cases it
> 
> OK, with enable-method as "spin-table" I suppose ?

Yes, that would probably be the other choice for SMP.

> > would be nice to still be able to reboot via the PMC code above.
> 
> I assume it's only for development purposes as you won't have much CPU
> power management support without PSCI.

This is what I had primarily in mind. Sometimes it might be useful to
boot without PSCI at all (as a poor man's way of disable SMP), in which
case this driver can still be used for reboot into the bootloader or
recovery mode.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* [PATCH v2 1/2] regulator: max77620: add support to configure MPOK
From: Venkat Reddy Talla @ 2016-11-17 17:54 UTC (permalink / raw)
  To: lee.jones, lgirdwood, broonie, robh+dt, mark.rutland, devicetree,
	linux-kernel
  Cc: ldewangan, svelpula, vreddytalla

Adding support to configure regulator POK mapping bit
to control nRST_IO and GPIO1 POK function.
In  tegra based platform which uses MAX20024 pmic, when
some of regulators are configured FPS_NONE(flexible power sequencer)
causes PMIC GPIO1 to go low which lead to various other rails turning off,
to avoid this MPOK bit of those regulators need to be set to 0
so that PMIC GPIO1 will not go low.

Signed-off-by: Venkat Reddy Talla <vreddytalla@nvidia.com>

---
changes in v2:
- updated commit message for the patch
- address review comments
---
 drivers/regulator/max77620-regulator.c | 46 ++++++++++++++++++++++++++++++++++
 include/linux/mfd/max77620.h           |  2 ++
 2 files changed, 48 insertions(+)

diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c
index a1b49a6..850b14c 100644
--- a/drivers/regulator/max77620-regulator.c
+++ b/drivers/regulator/max77620-regulator.c
@@ -81,6 +81,7 @@ struct max77620_regulator_pdata {
 	int suspend_fps_pd_slot;
 	int suspend_fps_pu_slot;
 	int current_mode;
+	int power_ok;
 	int ramp_rate_setting;
 };
 
@@ -351,11 +352,48 @@ static int max77620_set_slew_rate(struct max77620_regulator *pmic, int id,
 	return 0;
 }
 
+static int max77620_config_power_ok(struct max77620_regulator *pmic, int id)
+{
+	struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id];
+	struct max77620_regulator_info *rinfo = pmic->rinfo[id];
+	struct max77620_chip *chip = dev_get_drvdata(pmic->dev->parent);
+	u8 val, mask;
+	int ret;
+
+	switch (chip->chip_id) {
+	case MAX20024:
+		if (rpdata->power_ok >= 0) {
+			if (rinfo->type == MAX77620_REGULATOR_TYPE_SD)
+				mask = MAX20024_SD_CFG1_MPOK_MASK;
+			else
+				mask = MAX20024_LDO_CFG2_MPOK_MASK;
+
+			val = rpdata->power_ok ? mask : 0;
+
+			ret = regmap_update_bits(pmic->rmap, rinfo->cfg_addr,
+						 mask, val);
+			if (ret < 0) {
+				dev_err(pmic->dev, "Reg 0x%02x update failed %d\n",
+					rinfo->cfg_addr, ret);
+				return ret;
+			}
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int max77620_init_pmic(struct max77620_regulator *pmic, int id)
 {
 	struct max77620_regulator_pdata *rpdata = &pmic->reg_pdata[id];
 	int ret;
 
+	max77620_config_power_ok(pmic, id);
+
 	/* Update power mode */
 	ret = max77620_regulator_get_power_mode(pmic, id);
 	if (ret < 0)
@@ -595,6 +633,12 @@ static int max77620_of_parse_cb(struct device_node *np,
 			np, "maxim,suspend-fps-power-down-slot", &pval);
 	rpdata->suspend_fps_pd_slot = (!ret) ? pval : -1;
 
+	ret = of_property_read_u32(np, "maxim,power-ok-control", &pval);
+	if (!ret)
+		rpdata->power_ok = pval;
+	else
+		rpdata->power_ok = -1;
+
 	ret = of_property_read_u32(np, "maxim,ramp-rate-setting", &pval);
 	rpdata->ramp_rate_setting = (!ret) ? pval : 0;
 
@@ -807,6 +851,8 @@ static int max77620_regulator_resume(struct device *dev)
 	for (id = 0; id < MAX77620_NUM_REGS; id++) {
 		reg_pdata = &pmic->reg_pdata[id];
 
+		max77620_config_power_ok(pmic, id);
+
 		max77620_regulator_set_fps_slots(pmic, id, false);
 		if (reg_pdata->active_fps_src < 0)
 			continue;
diff --git a/include/linux/mfd/max77620.h b/include/linux/mfd/max77620.h
index 3ca0af07..ad2a9a8 100644
--- a/include/linux/mfd/max77620.h
+++ b/include/linux/mfd/max77620.h
@@ -180,6 +180,7 @@
 #define MAX77620_SD_CFG1_FPWM_SD_MASK		BIT(2)
 #define MAX77620_SD_CFG1_FPWM_SD_SKIP		0
 #define MAX77620_SD_CFG1_FPWM_SD_FPWM		BIT(2)
+#define MAX20024_SD_CFG1_MPOK_MASK		BIT(1)
 #define MAX77620_SD_CFG1_FSRADE_SD_MASK		BIT(0)
 #define MAX77620_SD_CFG1_FSRADE_SD_DISABLE	0
 #define MAX77620_SD_CFG1_FSRADE_SD_ENABLE	BIT(0)
@@ -187,6 +188,7 @@
 /* LDO_CNFG2 */
 #define MAX77620_LDO_POWER_MODE_MASK		0xC0
 #define MAX77620_LDO_POWER_MODE_SHIFT		6
+#define MAX20024_LDO_CFG2_MPOK_MASK		BIT(2)
 #define MAX77620_LDO_CFG2_ADE_MASK		BIT(1)
 #define MAX77620_LDO_CFG2_ADE_DISABLE		0
 #define MAX77620_LDO_CFG2_ADE_ENABLE		BIT(1)
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2 2/2] dt-bindings: max77620: add documentation for MPOK property
From: Venkat Reddy Talla @ 2016-11-17 17:54 UTC (permalink / raw)
  To: lee.jones, lgirdwood, broonie, robh+dt, mark.rutland, devicetree,
	linux-kernel
  Cc: ldewangan, svelpula, vreddytalla
In-Reply-To: <1479405276-26452-1-git-send-email-vreddytalla@nvidia.com>

Adding documentation for maxim,power-ok-control dts property

Signed-off-by: Venkat Reddy Talla <vreddytalla@nvidia.com>

---
Changes from V1:
 None
---
 Documentation/devicetree/bindings/mfd/max77620.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/max77620.txt b/Documentation/devicetree/bindings/mfd/max77620.txt
index 2ad44f7..9c16d51 100644
--- a/Documentation/devicetree/bindings/mfd/max77620.txt
+++ b/Documentation/devicetree/bindings/mfd/max77620.txt
@@ -106,6 +106,18 @@ Here supported time periods by device in microseconds are as follows:
 MAX77620 supports 40, 80, 160, 320, 640, 1280, 2560 and 5120 microseconds.
 MAX20024 supports 20, 40, 80, 160, 320, 640, 1280 and 2540 microseconds.
 
+-maxim,power-ok-control: configure map power ok bit
+			1: Enables POK(Power OK) to control nRST_IO and GPIO1
+			POK function.
+			0: Disables POK control.
+			if property missing, do not configure MPOK bit.
+			If POK mapping is enabled for GPIO1/nRST_IO then,
+			GPIO1/nRST_IO pins are HIGH only if all rails
+			that have POK control enabled are HIGH.
+			If any of the rails goes down(which are enabled for POK
+			control) then, GPIO1/nRST_IO goes LOW.
+			this property is valid for max20024 only.
+
 For DT binding details of different sub modules like GPIO, pincontrol,
 regulator, power, please refer respective device-tree binding document
 under their respective sub-system directories.
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH] soc/tegra: Implement Tegra186 PMC support
From: Sudeep Holla @ 2016-11-17 17:55 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sudeep Holla, Rob Herring, Mark Rutland, Stephen Warren,
	Alexandre Courbot, Jon Hunter, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161117175218.GA7751-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>



On 17/11/16 17:52, Thierry Reding wrote:
> On Thu, Nov 17, 2016 at 05:40:35PM +0000, Sudeep Holla wrote:
>>
>>
>> On 17/11/16 17:31, Thierry Reding wrote:

[...]

>>> would be nice to still be able to reboot via the PMC code above.
>>
>> I assume it's only for development purposes as you won't have much CPU
>> power management support without PSCI.
>
> This is what I had primarily in mind. Sometimes it might be useful to
> boot without PSCI at all (as a poor man's way of disable SMP), in which
> case this driver can still be used for reboot into the bootloader or
> recovery mode.
>

Thanks for clarification.

-- 
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH net 1/3] net: phy: realtek: add eee advertisement disable options
From: Anand Moon @ 2016-11-17 18:00 UTC (permalink / raw)
  To: Jerome Brunet
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree, Florian Fainelli,
	Alexandre TORGUE, Neil Armstrong, Martin Blumenstingl,
	Kevin Hilman, Linux Kernel, Andre Roth,
	linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Carlo Caione,
	Giuseppe Cavallaro, linux-arm-kernel
In-Reply-To: <1479378055.17538.57.camel-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Hi Jerone,

On 17 November 2016 at 15:50, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> On Wed, 2016-11-16 at 22:36 +0530, Anand Moon wrote:
>>  Hi Jerome.
>>
>> On 15 November 2016 at 19:59, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> wrote:
>> >
>> > On some platforms, energy efficient ethernet with rtl8211 devices
>> > is
>> > causing issue, like throughput drop or broken link.
>> >
>> > This was reported on the OdroidC2 (DWMAC + RTL8211F). While the
>> > issue root
>> > cause is not fully understood yet, disabling EEE advertisement
>> > prevent auto
>> > negotiation from enabling EEE.
>> >
>> > This patch provides options to disable 1000T and 100TX EEE
>> > advertisement
>> > individually for the realtek phys supporting this feature.
>> >
>> > Reported-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23myhRSP0FMvGiw@public.gmane.org
>> > m>
>> > Cc: Giuseppe Cavallaro <peppe.cavallaro-qxv4g6HH51o@public.gmane.org>
>> > Cc: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
>> > Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> > Signed-off-by: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> > Tested-by: Andre Roth <neolynx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> > ---
>> >  drivers/net/phy/realtek.c | 65
>> > ++++++++++++++++++++++++++++++++++++++++++++++-
>> >  1 file changed, 64 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
>> > index aadd6e9f54ad..77235fd5faaf 100644
>> > --- a/drivers/net/phy/realtek.c
>> > +++ b/drivers/net/phy/realtek.c
>> > @@ -15,6 +15,12 @@
>> >   */
>> >  #include <linux/phy.h>
>> >  #include <linux/module.h>
>> > +#include <linux/of.h>
>> > +
>> > +struct rtl8211x_phy_priv {
>> > +       bool eee_1000t_disable;
>> > +       bool eee_100tx_disable;
>> > +};
>> >
>> >  #define RTL821x_PHYSR          0x11
>> >  #define RTL821x_PHYSR_DUPLEX   0x2000
>> > @@ -93,12 +99,44 @@ static int rtl8211f_config_intr(struct
>> > phy_device *phydev)
>> >         return err;
>> >  }
>> >
>> > +static void rtl8211x_clear_eee_adv(struct phy_device *phydev)
>> > +{
>> > +       struct rtl8211x_phy_priv *priv = phydev->priv;
>> > +       u16 val;
>> > +
>> > +       if (priv->eee_1000t_disable || priv->eee_100tx_disable) {
>> > +               val = phy_read_mmd_indirect(phydev,
>> > MDIO_AN_EEE_ADV,
>> > +                                           MDIO_MMD_AN);
>> > +
>> > +               if (priv->eee_1000t_disable)
>> > +                       val &= ~MDIO_AN_EEE_ADV_1000T;
>> > +               if (priv->eee_100tx_disable)
>> > +                       val &= ~MDIO_AN_EEE_ADV_100TX;
>> > +
>> > +               phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
>> > +                                      MDIO_MMD_AN, val);
>> > +       }
>> > +}
>> > +
>> > +static int rtl8211x_config_init(struct phy_device *phydev)
>> > +{
>> > +       int ret;
>> > +
>> > +       ret = genphy_config_init(phydev);
>> > +       if (ret < 0)
>> > +               return ret;
>> > +
>> > +       rtl8211x_clear_eee_adv(phydev);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> >  static int rtl8211f_config_init(struct phy_device *phydev)
>> >  {
>> >         int ret;
>> >         u16 reg;
>> >
>> > -       ret = genphy_config_init(phydev);
>> > +       ret = rtl8211x_config_init(phydev);
>> >         if (ret < 0)
>> >                 return ret;
>> >
>> > @@ -115,6 +153,26 @@ static int rtl8211f_config_init(struct
>> > phy_device *phydev)
>> >         return 0;
>> >  }
>> >
>> > +static int rtl8211x_phy_probe(struct phy_device *phydev)
>> > +{
>> > +       struct device *dev = &phydev->mdio.dev;
>> > +       struct device_node *of_node = dev->of_node;
>> > +       struct rtl8211x_phy_priv *priv;
>> > +
>> > +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>> > +       if (!priv)
>> > +               return -ENOMEM;
>> > +
>> > +       priv->eee_1000t_disable =
>> > +               of_property_read_bool(of_node, "realtek,disable-
>> > eee-1000t");
>> > +       priv->eee_100tx_disable =
>> > +               of_property_read_bool(of_node, "realtek,disable-
>> > eee-100tx");
>> > +
>> > +       phydev->priv = priv;
>> > +
>> > +       return 0;
>> > +}
>> > +
>> >  static struct phy_driver realtek_drvs[] = {
>> >         {
>> >                 .phy_id         = 0x00008201,
>> > @@ -140,7 +198,9 @@ static struct phy_driver realtek_drvs[] = {
>> >                 .phy_id_mask    = 0x001fffff,
>> >                 .features       = PHY_GBIT_FEATURES,
>> >                 .flags          = PHY_HAS_INTERRUPT,
>> > +               .probe          = &rtl8211x_phy_probe,
>> >                 .config_aneg    = genphy_config_aneg,
>> > +               .config_init    = &rtl8211x_config_init,
>> >                 .read_status    = genphy_read_status,
>> >                 .ack_interrupt  = rtl821x_ack_interrupt,
>> >                 .config_intr    = rtl8211e_config_intr,
>> > @@ -152,7 +212,9 @@ static struct phy_driver realtek_drvs[] = {
>> >                 .phy_id_mask    = 0x001fffff,
>> >                 .features       = PHY_GBIT_FEATURES,
>> >                 .flags          = PHY_HAS_INTERRUPT,
>> > +               .probe          = &rtl8211x_phy_probe,
>> >                 .config_aneg    = &genphy_config_aneg,
>> > +               .config_init    = &rtl8211x_config_init,
>> >                 .read_status    = &genphy_read_status,
>> >                 .ack_interrupt  = &rtl821x_ack_interrupt,
>> >                 .config_intr    = &rtl8211e_config_intr,
>> > @@ -164,6 +226,7 @@ static struct phy_driver realtek_drvs[] = {
>> >                 .phy_id_mask    = 0x001fffff,
>> >                 .features       = PHY_GBIT_FEATURES,
>> >                 .flags          = PHY_HAS_INTERRUPT,
>> > +               .probe          = &rtl8211x_phy_probe,
>> >                 .config_aneg    = &genphy_config_aneg,
>> >                 .config_init    = &rtl8211f_config_init,
>> >                 .read_status    = &genphy_read_status,
>> > --
>> > 2.7.4
>> >
>>
>> How about adding callback functionality for .soft_reset to handle
>> BMCR
>> where we update the Auto-Negotiation for the phy,
>> as per the datasheet of the rtl8211f.
>
> I'm not sure I understand how this would help with our issue (and EEE).
> Am I missing something or is it something unrelated that you would like
> to see happening on this driver ?
>
[snip]

I was just tying other phy module to understand the feature.
But in order to improve  the throughput I tried to integrate blow u-boot commit.

commit 3d6af748ebd831524cb22a29433e9092af469ec7
Author: Shengzhou Liu <Shengzhou.Liu-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
Date:   Thu Mar 12 18:54:59 2015 +0800

    net/phy: Add support for realtek RTL8211F

    RTL8211F has different registers from RTL8211E.
    This patch adds support for RTL8211F PHY which
    can be found on Freescale's T1023 RDB board.

And added the similar functionality to  .config_aneg    = &rtl8211f_config_aneg,

And I seem to have better results in through put with periodic drop
but it recovers.
-----
odroid@odroid64:~$ iperf3 -c 10.0.0.102 -p 2006 -i 1 -t 100 -V
iperf 3.0.11
Linux odroid64 4.9.0-rc5-xc2ml #18 SMP PREEMPT Thu Nov 17 22:56:00 IST
2016 aarch64 aarch64 aarch64 GNU/Linux
Time: Thu, 17 Nov 2016 17:35:25 GMT
Connecting to host 10.0.0.102, port 2006
      Cookie: odroid64.1479404125.404729.3b45146e7
      TCP MSS: 1448 (default)
[  4] local 10.0.0.105 port 40238 connected to 10.0.0.102 port 2006
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks, omitting
0 seconds, 100 second test
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  4]   0.00-1.00   sec   114 MBytes   952 Mbits/sec    0    368 KBytes
[  4]   1.00-2.00   sec   112 MBytes   937 Mbits/sec    0    368 KBytes
[  4]   2.00-3.00   sec   111 MBytes   935 Mbits/sec    0    368 KBytes
[  4]   3.00-4.00   sec   112 MBytes   936 Mbits/sec    0    368 KBytes
[  4]   4.00-5.00   sec   112 MBytes   939 Mbits/sec    0    368 KBytes
[  4]   5.00-6.00   sec   112 MBytes   936 Mbits/sec    0    368 KBytes
[  4]   6.00-7.00   sec   111 MBytes   933 Mbits/sec    0    368 KBytes
[  4]   7.00-8.00   sec   112 MBytes   942 Mbits/sec    0    368 KBytes
[  4]   8.00-9.00   sec   111 MBytes   935 Mbits/sec    0    368 KBytes
[  4]   9.00-10.00  sec   111 MBytes   932 Mbits/sec    0    368 KBytes
[  4]  10.00-11.00  sec   112 MBytes   937 Mbits/sec    0    368 KBytes
[  4]  11.00-12.00  sec   111 MBytes   935 Mbits/sec    0    368 KBytes
[  4]  12.00-13.00  sec   112 MBytes   938 Mbits/sec    0    368 KBytes
[  4]  13.00-14.00  sec   112 MBytes   940 Mbits/sec    0    368 KBytes
[  4]  14.00-15.00  sec   111 MBytes   934 Mbits/sec    0    368 KBytes
[  4]  15.00-16.00  sec   111 MBytes   935 Mbits/sec    0    368 KBytes
[  4]  16.00-17.00  sec   112 MBytes   939 Mbits/sec    0    368 KBytes
[  4]  17.00-18.00  sec   112 MBytes   936 Mbits/sec    0    368 KBytes
[  4]  18.00-19.00  sec   111 MBytes   934 Mbits/sec    0    368 KBytes
[  4]  19.00-20.00  sec   112 MBytes   940 Mbits/sec    0    368 KBytes
[  4]  20.00-21.00  sec   111 MBytes   933 Mbits/sec    0    368 KBytes
[  4]  21.00-22.00  sec   112 MBytes   941 Mbits/sec    0    368 KBytes
[  4]  22.00-23.00  sec   111 MBytes   931 Mbits/sec    0    368 KBytes
[  4]  23.00-24.00  sec   112 MBytes   938 Mbits/sec    0    368 KBytes
[  4]  24.00-25.00  sec   112 MBytes   938 Mbits/sec    0    368 KBytes
[  4]  25.00-26.00  sec   111 MBytes   934 Mbits/sec    0    368 KBytes
[  4]  26.00-27.00  sec   112 MBytes   940 Mbits/sec    0    368 KBytes
[  4]  27.00-28.00  sec   112 MBytes   936 Mbits/sec    0    368 KBytes
[  4]  28.00-29.00  sec   111 MBytes   934 Mbits/sec    0    368 KBytes
[  4]  29.00-30.00  sec   112 MBytes   937 Mbits/sec    0    368 KBytes
[  4]  30.00-31.00  sec   111 MBytes   934 Mbits/sec    0    368 KBytes
[  4]  31.00-32.00  sec   112 MBytes   942 Mbits/sec    0    368 KBytes
[  4]  32.00-33.00  sec   111 MBytes   933 Mbits/sec    0    368 KBytes
[  4]  33.00-34.00  sec   111 MBytes   935 Mbits/sec    0    368 KBytes
[  4]  34.00-35.00  sec   112 MBytes   941 Mbits/sec    0    368 KBytes
[  4]  35.00-36.00  sec   107 MBytes   896 Mbits/sec    0    368 KBytes
[  4]  36.00-37.00  sec  0.00 Bytes  0.00 bits/sec    2   1.41 KBytes
[  4]  37.00-38.00  sec  0.00 Bytes  0.00 bits/sec    1   1.41 KBytes
[  4]  38.00-39.00  sec  0.00 Bytes  0.00 bits/sec    0   1.41 KBytes
[  4]  39.00-40.00  sec  38.0 MBytes   319 Mbits/sec    1    385 KBytes
[  4]  40.00-41.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  41.00-42.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  42.00-43.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  43.00-44.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  44.00-45.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  45.00-46.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  46.00-47.00  sec   111 MBytes   931 Mbits/sec    0    385 KBytes
[  4]  47.00-48.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  48.00-49.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  49.00-50.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  50.00-51.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  51.00-52.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  52.00-53.00  sec   112 MBytes   941 Mbits/sec    0    385 KBytes
[  4]  53.00-54.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  54.00-55.00  sec   111 MBytes   930 Mbits/sec    0    385 KBytes
[  4]  55.00-56.00  sec   112 MBytes   941 Mbits/sec    0    385 KBytes
[  4]  56.00-57.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  57.00-58.00  sec   111 MBytes   933 Mbits/sec    0    385 KBytes
[  4]  58.00-59.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  59.00-60.00  sec   112 MBytes   940 Mbits/sec    0    385 KBytes
[  4]  60.00-61.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  61.00-62.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  62.00-63.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  63.00-64.00  sec   112 MBytes   938 Mbits/sec    0    385 KBytes
[  4]  64.00-65.00  sec   111 MBytes   932 Mbits/sec    0    385 KBytes
[  4]  65.00-66.00  sec   112 MBytes   940 Mbits/sec    0    385 KBytes
[  4]  66.00-67.00  sec   112 MBytes   938 Mbits/sec    0    385 KBytes
[  4]  67.00-68.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  68.00-69.00  sec   111 MBytes   933 Mbits/sec    0    385 KBytes
[  4]  69.00-70.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  70.00-71.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  71.00-72.00  sec   112 MBytes   941 Mbits/sec    0    385 KBytes
[  4]  72.00-73.00  sec   111 MBytes   933 Mbits/sec    0    385 KBytes
[  4]  73.00-74.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  74.00-75.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  75.00-76.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  76.00-77.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  77.00-78.00  sec   112 MBytes   938 Mbits/sec    0    385 KBytes
[  4]  78.00-79.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  79.00-80.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  80.00-81.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  81.00-82.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  82.00-83.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  83.00-84.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  84.00-85.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  85.00-86.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  86.00-87.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  87.00-88.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  88.00-89.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  89.00-90.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  90.00-91.00  sec   112 MBytes   937 Mbits/sec    0    385 KBytes
[  4]  91.00-92.00  sec   111 MBytes   934 Mbits/sec    0    385 KBytes
[  4]  92.00-93.00  sec   112 MBytes   939 Mbits/sec    0    385 KBytes
[  4]  93.00-94.00  sec   111 MBytes   935 Mbits/sec    0    385 KBytes
[  4]  94.00-95.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  95.00-96.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  96.00-97.00  sec   112 MBytes   936 Mbits/sec    0    385 KBytes
[  4]  97.00-98.00  sec   113 MBytes   945 Mbits/sec    0    559 KBytes
[  4]  98.00-99.00  sec   112 MBytes   937 Mbits/sec    0    559 KBytes
[  4]  99.00-100.00 sec   111 MBytes   928 Mbits/sec    0    559 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-100.00 sec  10.5 GBytes   902 Mbits/sec    4             sender
[  4]   0.00-100.00 sec  10.5 GBytes   902 Mbits/sec                  receiver
CPU Utilization: local/sender 5.6% (0.2%u/5.4%s), remote/receiver
17.1% (1.2%u/15.9%s)

Can your confirm this at your end.
Once confirm I will try to send this as a fix for this issue.

-Best Regards
Anand Moon
--
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 1/2] ARM: dts: sun5i: Add touchscreen node to reference-design-tablet.dtsi
From: Maxime Ripard @ 2016-11-17 18:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Chen-Yu Tsai, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree
In-Reply-To: <0c3a9e9c-d310-c6c3-ae10-1ae9e520963e-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 6182 bytes --]

Hi Hans,

On Tue, Nov 15, 2016 at 11:12:35AM +0100, Hans de Goede wrote:
> Hi,
> 
> On 14-11-16 21:08, Maxime Ripard wrote:
> > Hi,
> > 
> > On Sun, Nov 13, 2016 at 08:22:02PM +0100, Hans de Goede wrote:
> > > Just like on sun8i all sun5i tablets use the same interrupt and power
> > > gpios for their touchscreens. I've checked all known a13 fex files and
> > > only the UTOO P66 uses a different gpio for the interrupt.
> > > 
> > > Add a touchscreen node to sun5i-reference-design-tablet.dtsi, which
> > > fills in the necessary gpios to avoid duplication in the tablet dts files,
> > > just like we do in sun8i-reference-design-tablet.dtsi.
> > > 
> > > This will make future patches adding touchscreen nodes to a13 tablets
> > > simpler.
> > > 
> > > Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > ---
> > >  arch/arm/boot/dts/sun5i-a13-utoo-p66.dts           | 38 ++++++++--------------
> > >  .../boot/dts/sun5i-reference-design-tablet.dtsi    | 25 ++++++++++++++
> > >  2 files changed, 39 insertions(+), 24 deletions(-)
> > > 
> > > diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
> > > index a8b0bcc..3d7ff10 100644
> > > --- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
> > > +++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
> > > @@ -83,22 +83,6 @@
> > >  	allwinner,pins = "PG3";
> > >  };
> > > 
> > > -&i2c1 {
> > > -	icn8318: touchscreen@40 {
> > > -		compatible = "chipone,icn8318";
> > > -		reg = <0x40>;
> > > -		interrupt-parent = <&pio>;
> > > -		interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
> > > -		pinctrl-names = "default";
> > > -		pinctrl-0 = <&ts_wake_pin_p66>;
> > > -		wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
> > > -		touchscreen-size-x = <800>;
> > > -		touchscreen-size-y = <480>;
> > > -		touchscreen-inverted-x;
> > > -		touchscreen-swapped-x-y;
> > > -	};
> > > -};
> > > -
> > >  &mmc2 {
> > >  	pinctrl-names = "default";
> > >  	pinctrl-0 = <&mmc2_pins_a>;
> > > @@ -121,20 +105,26 @@
> > >  		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> > >  		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> > >  	};
> > > -
> > > -	ts_wake_pin_p66: ts_wake_pin@0 {
> > > -		allwinner,pins = "PB3";
> > > -		allwinner,function = "gpio_out";
> > > -		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> > > -		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> > > -	};
> > > -
> > >  };
> > > 
> > >  &reg_usb0_vbus {
> > >  	gpio = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
> > >  };
> > > 
> > > +&touchscreen {
> > > +	compatible = "chipone,icn8318";
> > > +	reg = <0x40>;
> > > +	/* The P66 uses a different EINT then the reference design */
> > > +	interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
> > > +	/* The icn8318 binding expects wake-gpios instead of power-gpios */
> > > +	wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
> > > +	touchscreen-size-x = <800>;
> > > +	touchscreen-size-y = <480>;
> > > +	touchscreen-inverted-x;
> > > +	touchscreen-swapped-x-y;
> > > +	status = "okay";
> > > +};
> > > +
> > >  &uart1 {
> > >  	/* The P66 uses the uart pins as gpios */
> > >  	status = "disabled";
> > > diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
> > > index 20cc940..7af488a 100644
> > > --- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
> > > +++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
> > > @@ -41,6 +41,7 @@
> > >   */
> > >  #include "sunxi-reference-design-tablet.dtsi"
> > > 
> > > +#include <dt-bindings/interrupt-controller/irq.h>
> > >  #include <dt-bindings/pwm/pwm.h>
> > > 
> > >  / {
> > > @@ -84,6 +85,23 @@
> > >  };
> > > 
> > >  &i2c1 {
> > > +	/*
> > > +	 * The gsl1680 is rated at 400KHz and it will not work reliable at
> > > +	 * 100KHz, this has been confirmed on multiple different q8 tablets.
> > > +	 * All other devices on this bus are also rated for 400KHz.
> > > +	 */
> > > +	clock-frequency = <400000>;
> > > +
> > > +	touchscreen: touchscreen {
> > > +		interrupt-parent = <&pio>;
> > > +		interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; /* EINT11 (PG11) */
> > > +		pinctrl-names = "default";
> > > +		pinctrl-0 = <&ts_power_pin>;
> > > +		power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
> > > +		/* Tablet dts must provide reg and compatible */
> > > +		status = "disabled";
> > > +	};
> > > +
> > >  	pcf8563: rtc@51 {
> > >  		compatible = "nxp,pcf8563";
> > >  		reg = <0x51>;
> > > @@ -125,6 +143,13 @@
> > >  		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> > >  	};
> > > 
> > > +	ts_power_pin: ts_power_pin {
> > > +		allwinner,pins = "PB3";
> > > +		allwinner,function = "gpio_out";
> > > +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> > > +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> > > +	};
> > > +
> > 
> > For the next release, we'll switch to the generic pin mux properties
> > ("pins" and "function"), and we actually implemented the fact that the
> > drive and pull properties are optional, so you can drop them both.
> > 
> > You'll need next + http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/467123.html
> 
> Ok, before I send a v2 first a question about this, for the touchscreen
> case I actually need:
> 
> 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> 
> Because otherwise when the touchscreen controller is powered by a separate
> regulator and that regulator is off, then it may draw just enough current
> from its enable pin to be sort-of listening to the i2c bus and mess up
> that bus.
> 
> So is this the default, or do we get the power-on default when not
> specifying these? If it is the power-on default then we do need to
> specify these, because AFAICT the power-on drive strength typically
> is 20 mA.

Leaving them out will keep whatever state has been programmed. Putting
them in the DT will force them to whatever value has been set.

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 1/2] ARM: dts: sun5i: Add touchscreen node to reference-design-tablet.dtsi
From: Hans de Goede @ 2016-11-17 18:52 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Chen-Yu Tsai, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree
In-Reply-To: <20161117183520.vpyw72mchynpqx7d@lukather>

Hi,

On 17-11-16 19:35, Maxime Ripard wrote:
> Hi Hans,
>
> On Tue, Nov 15, 2016 at 11:12:35AM +0100, Hans de Goede wrote:
>> Hi,
>>
>> On 14-11-16 21:08, Maxime Ripard wrote:
>>> Hi,
>>>
>>> On Sun, Nov 13, 2016 at 08:22:02PM +0100, Hans de Goede wrote:
>>>> Just like on sun8i all sun5i tablets use the same interrupt and power
>>>> gpios for their touchscreens. I've checked all known a13 fex files and
>>>> only the UTOO P66 uses a different gpio for the interrupt.
>>>>
>>>> Add a touchscreen node to sun5i-reference-design-tablet.dtsi, which
>>>> fills in the necessary gpios to avoid duplication in the tablet dts files,
>>>> just like we do in sun8i-reference-design-tablet.dtsi.
>>>>
>>>> This will make future patches adding touchscreen nodes to a13 tablets
>>>> simpler.
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>> ---
>>>>  arch/arm/boot/dts/sun5i-a13-utoo-p66.dts           | 38 ++++++++--------------
>>>>  .../boot/dts/sun5i-reference-design-tablet.dtsi    | 25 ++++++++++++++
>>>>  2 files changed, 39 insertions(+), 24 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
>>>> index a8b0bcc..3d7ff10 100644
>>>> --- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
>>>> +++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
>>>> @@ -83,22 +83,6 @@
>>>>  	allwinner,pins = "PG3";
>>>>  };
>>>>
>>>> -&i2c1 {
>>>> -	icn8318: touchscreen@40 {
>>>> -		compatible = "chipone,icn8318";
>>>> -		reg = <0x40>;
>>>> -		interrupt-parent = <&pio>;
>>>> -		interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
>>>> -		pinctrl-names = "default";
>>>> -		pinctrl-0 = <&ts_wake_pin_p66>;
>>>> -		wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
>>>> -		touchscreen-size-x = <800>;
>>>> -		touchscreen-size-y = <480>;
>>>> -		touchscreen-inverted-x;
>>>> -		touchscreen-swapped-x-y;
>>>> -	};
>>>> -};
>>>> -
>>>>  &mmc2 {
>>>>  	pinctrl-names = "default";
>>>>  	pinctrl-0 = <&mmc2_pins_a>;
>>>> @@ -121,20 +105,26 @@
>>>>  		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>>>>  		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>>>>  	};
>>>> -
>>>> -	ts_wake_pin_p66: ts_wake_pin@0 {
>>>> -		allwinner,pins = "PB3";
>>>> -		allwinner,function = "gpio_out";
>>>> -		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>>>> -		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>>> -	};
>>>> -
>>>>  };
>>>>
>>>>  &reg_usb0_vbus {
>>>>  	gpio = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
>>>>  };
>>>>
>>>> +&touchscreen {
>>>> +	compatible = "chipone,icn8318";
>>>> +	reg = <0x40>;
>>>> +	/* The P66 uses a different EINT then the reference design */
>>>> +	interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */
>>>> +	/* The icn8318 binding expects wake-gpios instead of power-gpios */
>>>> +	wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
>>>> +	touchscreen-size-x = <800>;
>>>> +	touchscreen-size-y = <480>;
>>>> +	touchscreen-inverted-x;
>>>> +	touchscreen-swapped-x-y;
>>>> +	status = "okay";
>>>> +};
>>>> +
>>>>  &uart1 {
>>>>  	/* The P66 uses the uart pins as gpios */
>>>>  	status = "disabled";
>>>> diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
>>>> index 20cc940..7af488a 100644
>>>> --- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
>>>> +++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
>>>> @@ -41,6 +41,7 @@
>>>>   */
>>>>  #include "sunxi-reference-design-tablet.dtsi"
>>>>
>>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>>>  #include <dt-bindings/pwm/pwm.h>
>>>>
>>>>  / {
>>>> @@ -84,6 +85,23 @@
>>>>  };
>>>>
>>>>  &i2c1 {
>>>> +	/*
>>>> +	 * The gsl1680 is rated at 400KHz and it will not work reliable at
>>>> +	 * 100KHz, this has been confirmed on multiple different q8 tablets.
>>>> +	 * All other devices on this bus are also rated for 400KHz.
>>>> +	 */
>>>> +	clock-frequency = <400000>;
>>>> +
>>>> +	touchscreen: touchscreen {
>>>> +		interrupt-parent = <&pio>;
>>>> +		interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; /* EINT11 (PG11) */
>>>> +		pinctrl-names = "default";
>>>> +		pinctrl-0 = <&ts_power_pin>;
>>>> +		power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
>>>> +		/* Tablet dts must provide reg and compatible */
>>>> +		status = "disabled";
>>>> +	};
>>>> +
>>>>  	pcf8563: rtc@51 {
>>>>  		compatible = "nxp,pcf8563";
>>>>  		reg = <0x51>;
>>>> @@ -125,6 +143,13 @@
>>>>  		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>>>>  	};
>>>>
>>>> +	ts_power_pin: ts_power_pin {
>>>> +		allwinner,pins = "PB3";
>>>> +		allwinner,function = "gpio_out";
>>>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>>>> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>>> +	};
>>>> +
>>>
>>> For the next release, we'll switch to the generic pin mux properties
>>> ("pins" and "function"), and we actually implemented the fact that the
>>> drive and pull properties are optional, so you can drop them both.
>>>
>>> You'll need next + http://lists.infradead.org/pipermail/linux-arm-kernel/2016-November/467123.html
>>
>> Ok, before I send a v2 first a question about this, for the touchscreen
>> case I actually need:
>>
>> 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>
>> Because otherwise when the touchscreen controller is powered by a separate
>> regulator and that regulator is off, then it may draw just enough current
>> from its enable pin to be sort-of listening to the i2c bus and mess up
>> that bus.
>>
>> So is this the default, or do we get the power-on default when not
>> specifying these? If it is the power-on default then we do need to
>> specify these, because AFAICT the power-on drive strength typically
>> is 20 mA.
>
> Leaving them out will keep whatever state has been programmed. Putting
> them in the DT will force them to whatever value has been set.

Thanks for the answer, in the mean time I've send a v2 which leaves
them in using the new names (which according to your answer seems to
be the right thing to do).

Regards,

Hans
--
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 2/4] usb: dwc2: Add binding for AHB burst
From: John Youn @ 2016-11-17 18:54 UTC (permalink / raw)
  To: Felipe Balbi, John Youn, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland
  Cc: Christian Lamparter, Stefan Wahren
In-Reply-To: <874m36tkgz.fsf-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

On 11/17/2016 3:28 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> John Youn <johnyoun-HKixBCOQz3hWk0Htik3J/w@public.gmane.org> writes:
>> Add the "snps,ahb-burst" binding and read it in.
>>
>> This property controls which burst type to perform on the AHB bus as a
>> master in internal DMA mode. This overrides the legacy param value,
>> which we need to keep around for now since several platforms use it.
>>
>> Some platforms may see better or worse performance based on this
>> value. The HAPS platform is one example where all INCRx have worse
>> performance than INCR.
>>
>> Other platforms (such as the Canyonlands board) report that the default
>> value causes system hangs.
>>
>> Signed-off-by: John Youn <johnyoun-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
>> Cc: Christian Lamparter <chunkeey-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> 
> it's getting rather late for this merge window. I still need an ack by
> Rob or any of the devicetree folks.
> 

Sure, no problem if it doesn't make it.

Regards,
John

--
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 3/3] hwmon: ltc2990: support all measurement modes
From: Guenter Roeck @ 2016-11-17 18:56 UTC (permalink / raw)
  To: Mike Looijmans
  Cc: Tom Levens, jdelvare, robh+dt, mark.rutland, linux-kernel,
	linux-hwmon, devicetree
In-Reply-To: <582DEB81.6050806@topic.nl>

On Thu, Nov 17, 2016 at 06:40:17PM +0100, Mike Looijmans wrote:
> On 17-11-16 17:56, Guenter Roeck wrote:
> >On 11/17/2016 04:10 AM, Tom Levens wrote:
> >>Updated version of the ltc2990 driver which supports all measurement
> >>modes available in the chip. The mode can be set through a devicetree
> >>attribute.
> >
[ ... ] 

> >>
> >> static int ltc2990_i2c_probe(struct i2c_client *i2c,
> >>                  const struct i2c_device_id *id)
> >> {
> >>     int ret;
> >>     struct device *hwmon_dev;
> >>+    struct ltc2990_data *data;
> >>+    struct device_node *of_node = i2c->dev.of_node;
> >>
> >>     if (!i2c_check_functionality(i2c->adapter,
> >>I2C_FUNC_SMBUS_BYTE_DATA |
> >>                      I2C_FUNC_SMBUS_WORD_DATA))
> >>         return -ENODEV;
> >>
> >>-    /* Setup continuous mode, current monitor */
> >>+    data = devm_kzalloc(&i2c->dev, sizeof(struct ltc2990_data),
> >>GFP_KERNEL);
> >>+    if (unlikely(!data))
> >>+        return -ENOMEM;
> >>+    data->i2c = i2c;
> >>+
> >>+    if (!of_node || of_property_read_u32(of_node, "lltc,mode",
> >>&data->mode))
> >>+        data->mode = LTC2990_CONTROL_MODE_DEFAULT;
> >
> >Iam arguing with myself if we should still do this or if we should read
> >the mode
> >from the chip instead if it isn't provided (after all, it may have been
> >initialized
> >by the BIOS/ROMMON).
> 
> I think the mode should be explicitly set, without default. There's no way
> to tell whether the BIOS or bootloader has really set it up or whether the
> chip is just reporting whatever it happened to default to. And given the
> chip's function, it's unlikely a bootloader would want to initialize it.
> 
Unlikely but possible. Even if we all agree that the chip should be configured
by the driver, I don't like imposing that view on everyone else.

> My advice would be to make it a required property. If not set, display an
> error and bail out.
> 
It is not that easy, unfortunately. It also has to work on a non-devicetree
system. I would not object to making the property mandatory, but we would
still need to provide non-DT support.

My "use case" for taking the current mode from the chip if not specified
is that it would enable me to run a module test with all modes. I consider
this extremely valuable.

> >Mike, would that break your application, or can you specify the mode in
> >devicetree ?
> 
> I'm fine with specifying this in the devicetree. It will break things for
> me, but I've been warned and willing to bow for the greater good :)
> 
I should have asked if your system uses devicetree. If it does, the problem
should be easy to fix for you. If not, we'll need to find a solution
for your use case.

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v4] arm64: dts: qcom: Add msm8916 CoreSight components
From: Mathieu Poirier @ 2016-11-17 18:59 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
	iivanov.xz-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161117153522.11630-1-georgi.djakov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Thu, Nov 17, 2016 at 05:35:22PM +0200, Georgi Djakov wrote:
> From: "Ivan T. Ivanov" <ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> 
> Add initial set of CoreSight components found on Qualcomm's 8x16 chipset.

Hello Georgi,

Could you add a better desccription for the SoC?  To me "8x16" doesn't
say much.

With that change:
Acked-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

> 
> Signed-off-by: Ivan T. Ivanov <ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Georgi Djakov <georgi.djakov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> 
> This patch was on hold for some time, as it has a dependency on RPM clocks,
> which is now merged into clk-next.
> 
> Changes since v3: (https://lkml.org/lkml/2015/5/11/134)
>  * Include msm8916-coresight.dtsi into msm8916.dtsi
> 
> Changes since v2: (https://lkml.org/lkml/2015/4/29/242)
>  * Added "1x" to "qcom,coresight-replicator" compatible string, to match what
>    devicetree bindings documentations says.
> 
> 
>  arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi | 254 ++++++++++++++++++++++++
>  arch/arm64/boot/dts/qcom/msm8916.dtsi           |   2 +
>  2 files changed, 256 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
> 
> diff --git a/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
> new file mode 100644
> index 000000000000..900f1f484a0a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
> @@ -0,0 +1,254 @@
> +/*
> + * Copyright (c) 2013 - 2015, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 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.
> + */
> +
> +&soc {
> +
> +	tpiu@820000 {
> +		compatible = "arm,coresight-tpiu", "arm,primecell";
> +		reg = <0x820000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		port {
> +			tpiu_in: endpoint {
> +				slave-mode;
> +				remote-endpoint = <&replicator_out1>;
> +			};
> +		};
> +	};
> +
> +	funnel@821000 {
> +		compatible = "arm,coresight-funnel", "arm,primecell";
> +		reg = <0x821000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/*
> +			 * Not described input ports:
> +			 * 0 - connected to Resource and Power Manger CPU ETM
> +			 * 1 - not-connected
> +			 * 2 - connected to Modem CPU ETM
> +			 * 3 - not-connected
> +			 * 5 - not-connected
> +			 * 6 - connected trought funnel to Wireless CPU ETM
> +			 * 7 - connected to STM component
> +			 */
> +			port@4 {
> +				reg = <4>;
> +				funnel0_in4: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&funnel1_out>;
> +				};
> +			};
> +			port@8 {
> +				reg = <0>;
> +				funnel0_out: endpoint {
> +					remote-endpoint = <&etf_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	replicator@824000 {
> +		compatible = "qcom,coresight-replicator1x", "arm,primecell";
> +		reg = <0x824000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				replicator_out0: endpoint {
> +					remote-endpoint = <&etr_in>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				replicator_out1: endpoint {
> +					remote-endpoint = <&tpiu_in>;
> +				};
> +			};
> +			port@2 {
> +				reg = <0>;
> +				replicator_in: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etf_out>;
> +				};
> +			};
> +		};
> +	};
> +
> +	etf@825000 {
> +		compatible = "arm,coresight-tmc", "arm,primecell";
> +		reg = <0x825000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				etf_out: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&funnel0_out>;
> +				};
> +			};
> +			port@1 {
> +				reg = <0>;
> +				etf_in: endpoint {
> +					remote-endpoint = <&replicator_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	etr@826000 {
> +		compatible = "arm,coresight-tmc", "arm,primecell";
> +		reg = <0x826000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		port {
> +			etr_in: endpoint {
> +				slave-mode;
> +				remote-endpoint = <&replicator_out0>;
> +			};
> +		};
> +	};
> +
> +	funnel@841000 {	/* APSS funnel only 4 inputs are used */
> +		compatible = "arm,coresight-funnel", "arm,primecell";
> +		reg = <0x841000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				funnel1_in0: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm0_out>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				funnel1_in1: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm1_out>;
> +				};
> +			};
> +			port@2 {
> +				reg = <2>;
> +				funnel1_in2: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm2_out>;
> +				};
> +			};
> +			port@3 {
> +				reg = <3>;
> +				funnel1_in3: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm3_out>;
> +				};
> +			};
> +			port@4 {
> +				reg = <0>;
> +				funnel1_out: endpoint {
> +					remote-endpoint = <&funnel0_in4>;
> +				};
> +			};
> +		};
> +	};
> +
> +	etm@85c000 {
> +		compatible = "arm,coresight-etm4x", "arm,primecell";
> +		reg = <0x85c000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		cpu = <&CPU0>;
> +
> +		port {
> +			etm0_out: endpoint {
> +				remote-endpoint = <&funnel1_in0>;
> +			};
> +		};
> +	};
> +
> +	etm@85d000 {
> +		compatible = "arm,coresight-etm4x", "arm,primecell";
> +		reg = <0x85d000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		cpu = <&CPU1>;
> +
> +		port {
> +			etm1_out: endpoint {
> +				remote-endpoint = <&funnel1_in1>;
> +			};
> +		};
> +	};
> +
> +	etm@85e000 {
> +		compatible = "arm,coresight-etm4x", "arm,primecell";
> +		reg = <0x85e000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		cpu = <&CPU2>;
> +
> +		port {
> +			etm2_out: endpoint {
> +				remote-endpoint = <&funnel1_in2>;
> +			};
> +		};
> +	};
> +
> +	etm@85f000 {
> +		compatible = "arm,coresight-etm4x", "arm,primecell";
> +		reg = <0x85f000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
> +		clock-names = "apb_pclk", "atclk";
> +
> +		cpu = <&CPU3>;
> +
> +		port {
> +			etm3_out: endpoint {
> +				remote-endpoint = <&funnel1_in3>;
> +			};
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
> index 4221b7d2c0ce..bfaeb9364190 100644
> --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
> @@ -14,6 +14,7 @@
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/clock/qcom,gcc-msm8916.h>
>  #include <dt-bindings/reset/qcom,gcc-msm8916.h>
> +#include <dt-bindings/clock/qcom,rpmcc.h>
>  
>  / {
>  	model = "Qualcomm Technologies, Inc. MSM8916";
> @@ -993,4 +994,5 @@
>  	};
>  };
>  
> +#include "msm8916-coresight.dtsi"
>  #include "msm8916-pins.dtsi"
--
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] ARM: dts: qcom: Add apq8064 CoreSight components
From: Mathieu Poirier @ 2016-11-17 19:04 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: andy.gross-QSEj5FYQhm4dnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A,
	iivanov.xz-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161117153609.11705-1-georgi.djakov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On Thu, Nov 17, 2016 at 05:36:09PM +0200, Georgi Djakov wrote:
> From: "Ivan T. Ivanov" <ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> 
> Add initial set of CoreSight components found on Qualcomm's
> 8064 chipset.
> 
> Signed-off-by: Ivan T. Ivanov <ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Georgi Djakov <georgi.djakov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/boot/dts/qcom-apq8064-coresight.dtsi | 196 ++++++++++++++++++++++++++
>  arch/arm/boot/dts/qcom-apq8064.dtsi           |  11 +-
>  2 files changed, 203 insertions(+), 4 deletions(-)
>  create mode 100644 arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
> 
> diff --git a/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi b/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
> new file mode 100644
> index 000000000000..9395fddb1bf0
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright (c) 2015, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 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.
> + */
> +
> +&soc {
> +
> +	etb@1a01000 {
> +		compatible = "coresight-etb10", "arm,primecell";
> +		reg = <0x1a01000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		port {
> +			etb_in: endpoint {
> +				slave-mode;
> +				remote-endpoint = <&replicator_out0>;
> +			};
> +		};
> +	};
> +
> +	tpiu@1a03000 {
> +		compatible = "arm,coresight-tpiu", "arm,primecell";
> +		reg = <0x1a03000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		port {
> +			tpiu_in: endpoint {
> +				slave-mode;
> +				remote-endpoint = <&replicator_out1>;
> +			};
> +		};
> +	};
> +
> +	replicator {
> +		compatible = "arm,coresight-replicator";
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port@0 {
> +				reg = <0>;
> +				replicator_out0: endpoint {
> +					remote-endpoint = <&etb_in>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				replicator_out1: endpoint {
> +					remote-endpoint = <&tpiu_in>;
> +				};
> +			};
> +			port@2 {
> +				reg = <0>;
> +				replicator_in: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&funnel_out>;
> +				};
> +			};
> +		};
> +	};
> +
> +	funnel@1a04000 {
> +		compatible = "arm,coresight-funnel", "arm,primecell";
> +		reg = <0x1a04000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/*
> +			 * Not described input ports:
> +			 * 2 - connected to STM component
> +			 * 3 - not-connected
> +			 * 6 - not-connected
> +			 * 7 - not-connected
> +			 */
> +			port@0 {
> +				reg = <0>;
> +				funnel_in0: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm0_out>;
> +				};
> +			};
> +			port@1 {
> +				reg = <1>;
> +				funnel_in1: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm1_out>;
> +				};
> +			};
> +			port@4 {
> +				reg = <4>;
> +				funnel_in4: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm2_out>;
> +				};
> +			};
> +			port@5 {
> +				reg = <5>;
> +				funnel_in5: endpoint {
> +					slave-mode;
> +					remote-endpoint = <&etm3_out>;
> +				};
> +			};
> +			port@8 {
> +				reg = <0>;
> +				funnel_out: endpoint {
> +					remote-endpoint = <&replicator_in>;
> +				};
> +			};
> +		};
> +	};
> +
> +	etm@1a1c000 {
> +		compatible = "arm,coresight-etm3x", "arm,primecell";
> +		reg = <0x1a1c000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		cpu = <&CPU0>;
> +
> +		port {
> +			etm0_out: endpoint {
> +				remote-endpoint = <&funnel_in0>;
> +			};
> +		};
> +	};
> +
> +	etm@1a1d000 {
> +		compatible = "arm,coresight-etm3x", "arm,primecell";
> +		reg = <0x1a1d000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		cpu = <&CPU1>;
> +
> +		port {
> +			etm1_out: endpoint {
> +				remote-endpoint = <&funnel_in1>;
> +			};
> +		};
> +	};
> +
> +	etm@1a1e000 {
> +		compatible = "arm,coresight-etm3x", "arm,primecell";
> +		reg = <0x1a1e000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		cpu = <&CPU2>;
> +
> +		port {
> +			etm2_out: endpoint {
> +				remote-endpoint = <&funnel_in4>;
> +			};
> +		};
> +	};
> +
> +	etm@1a1f000 {
> +		compatible = "arm,coresight-etm3x", "arm,primecell";
> +		reg = <0x1a1f000 0x1000>;
> +
> +		clocks = <&rpmcc RPM_QDSS_CLK>;
> +		clock-names = "apb_pclk";
> +
> +		cpu = <&CPU3>;
> +
> +		port {
> +			etm3_out: endpoint {
> +				remote-endpoint = <&funnel_in5>;
> +			};
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
> index 268bd470c865..18469c632e2f 100644
> --- a/arch/arm/boot/dts/qcom-apq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
> @@ -4,6 +4,7 @@
>  #include <dt-bindings/clock/qcom,gcc-msm8960.h>
>  #include <dt-bindings/reset/qcom,gcc-msm8960.h>
>  #include <dt-bindings/clock/qcom,mmcc-msm8960.h>
> +#include <dt-bindings/clock/qcom,rpmcc.h>
>  #include <dt-bindings/soc/qcom,gsbi.h>
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> @@ -27,7 +28,7 @@
>  		#address-cells = <1>;
>  		#size-cells = <0>;
>  
> -		cpu@0 {
> +		CPU0: cpu@0 {
>  			compatible = "qcom,krait";
>  			enable-method = "qcom,kpss-acc-v1";
>  			device_type = "cpu";
> @@ -38,7 +39,7 @@
>  			cpu-idle-states = <&CPU_SPC>;
>  		};
>  
> -		cpu@1 {
> +		CPU1: cpu@1 {
>  			compatible = "qcom,krait";
>  			enable-method = "qcom,kpss-acc-v1";
>  			device_type = "cpu";
> @@ -49,7 +50,7 @@
>  			cpu-idle-states = <&CPU_SPC>;
>  		};
>  
> -		cpu@2 {
> +		CPU2: cpu@2 {
>  			compatible = "qcom,krait";
>  			enable-method = "qcom,kpss-acc-v1";
>  			device_type = "cpu";
> @@ -60,7 +61,7 @@
>  			cpu-idle-states = <&CPU_SPC>;
>  		};
>  
> -		cpu@3 {
> +		CPU3: cpu@3 {
>  			compatible = "qcom,krait";
>  			enable-method = "qcom,kpss-acc-v1";
>  			device_type = "cpu";
> @@ -1418,4 +1419,6 @@
>  		};
>  	};
>  };
> +
> +#include "qcom-apq8064-coresight.dtsi"
>  #include "qcom-apq8064-pins.dtsi"

Acked-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
--
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 3/3] hwmon: ltc2990: support all measurement modes
From: Mike Looijmans @ 2016-11-17 19:52 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Tom Levens, jdelvare, robh+dt, mark.rutland, linux-kernel,
	linux-hwmon, devicetree
In-Reply-To: <20161117185654.GA19338@roeck-us.net>

On 17-11-2016 19:56, Guenter Roeck wrote:
> On Thu, Nov 17, 2016 at 06:40:17PM +0100, Mike Looijmans wrote:
>> On 17-11-16 17:56, Guenter Roeck wrote:
>>> On 11/17/2016 04:10 AM, Tom Levens wrote:
>>>> Updated version of the ltc2990 driver which supports all measurement
>>>> modes available in the chip. The mode can be set through a devicetree
>>>> attribute.
>>>
> [ ... ]
>
>>>>
>>>> static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>>>                   const struct i2c_device_id *id)
>>>> {
>>>>      int ret;
>>>>      struct device *hwmon_dev;
>>>> +    struct ltc2990_data *data;
>>>> +    struct device_node *of_node = i2c->dev.of_node;
>>>>
>>>>      if (!i2c_check_functionality(i2c->adapter,
>>>> I2C_FUNC_SMBUS_BYTE_DATA |
>>>>                       I2C_FUNC_SMBUS_WORD_DATA))
>>>>          return -ENODEV;
>>>>
>>>> -    /* Setup continuous mode, current monitor */
>>>> +    data = devm_kzalloc(&i2c->dev, sizeof(struct ltc2990_data),
>>>> GFP_KERNEL);
>>>> +    if (unlikely(!data))
>>>> +        return -ENOMEM;
>>>> +    data->i2c = i2c;
>>>> +
>>>> +    if (!of_node || of_property_read_u32(of_node, "lltc,mode",
>>>> &data->mode))
>>>> +        data->mode = LTC2990_CONTROL_MODE_DEFAULT;
>>>
>>> Iam arguing with myself if we should still do this or if we should read
>>> the mode
>> >from the chip instead if it isn't provided (after all, it may have been
>>> initialized
>>> by the BIOS/ROMMON).
>>
>> I think the mode should be explicitly set, without default. There's no way
>> to tell whether the BIOS or bootloader has really set it up or whether the
>> chip is just reporting whatever it happened to default to. And given the
>> chip's function, it's unlikely a bootloader would want to initialize it.
>>
> Unlikely but possible. Even if we all agree that the chip should be configured
> by the driver, I don't like imposing that view on everyone else.
>
>> My advice would be to make it a required property. If not set, display an
>> error and bail out.
>>
> It is not that easy, unfortunately. It also has to work on a non-devicetree
> system. I would not object to making the property mandatory, but we would
> still need to provide non-DT support.
>
> My "use case" for taking the current mode from the chip if not specified
> is that it would enable me to run a module test with all modes. I consider
> this extremely valuable.

Good point.

The chip defaults to measuring internal temperature only, and the mode 
defaults to "0".

Choosing a mode that doesn't match the actual circuitry could be bad for 
the chip or the board (though unlikely, it'll probably just be useless) 
since it will actively drive some of the inputs in the temperature modes 
(which is default for V3/V4 pins).

Instead of failing, one could choose to set the default mode to "7", 
which just measures the 4 voltages, which would be a harmless mode in 
all cases.

As a way to let a bootloader set things up, I think it would be a good 
check to see if CONTROL register bits 4:3 are set. If "00", the chip is 
not acquiring data at all, and probably needs configuration still. In 
that case, the mode must be provided by the devicetree (or the default "7").
If bits 4:3 are "11", it has already been set up to measure its inputs, 
and it's okay to continue doing just that and use the current value of 
2:0 register as default mode (if the devicetree didn't specify any mode 
at all).

The reason I wanted the property to be mandatory is to trigger users 
like me (probably I'm the only other user so far) to update their 
devicetree. But I'd notice quickly enough if it defaults to something 
else. So that's not very compelling.

>>> Mike, would that break your application, or can you specify the mode in
>>> devicetree ?
>>
>> I'm fine with specifying this in the devicetree. It will break things for
>> me, but I've been warned and willing to bow for the greater good :)
>>
> I should have asked if your system uses devicetree. If it does, the problem
> should be easy to fix for you. If not, we'll need to find a solution
> for your use case.

I'm using devicetree. I planned to 'mainline' the boards some time this 
year...

>
> Thanks,
> Guenter
>


-- 
Mike Looijmans


Kind regards,

Mike Looijmans
System Expert

TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail






^ permalink raw reply

* [PATCH] ARM: dts: am335x-boneblack: Add blue-and-red-wiring -property to LCDC node
From: Jyri Sarha @ 2016-11-17 20:13 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	devicetree-u79uwXL29TY76Z2rM5mHXA, tony-4v6yS6AI5VpBDgjK7y7TUQ
  Cc: tomi.valkeinen-l0cyMroinI0, Jyri Sarha

Add blue-and-red-wiring -property to LCDC node. Also adds comments on
how to get support 24 bit RGB mode. After this patch am335x-boneblack
support RGB565, BGR888, and XBGR8888 color formats. See details in
Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt.

The BBB has straight color wiring from am335x to tda19988, however the
tda19988 can be configured to cross the blue and red wires. The
comments show how to do that with video-ports property of tda19988
node and how to tell LCDC that blue and red wires are crossed, with
blue-and-red-wiring LCDC node property. This changes supported color
formats from 16 bit RGB and 24 bit BGR to 16 bit BGR and 24 bit RGB.

Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
---
Hi Tony,
Could you pick this for 4.10. We left it out form 4.9 to avoid
conflict with beaglebone-back hdmi audio dts patches that slipped in
trough drm branch.

Cheers,
Jyri

 arch/arm/boot/dts/am335x-boneblack.dts | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index 6bbb1fe..db00d8e 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -79,6 +79,14 @@
 
 &lcdc {
 	status = "okay";
+
+	/* If you want to get 24 bit RGB and 16 BGR mode instead of
+	 * current 16 bit RGB and 24 BGR modes, set the propety
+	 * below to "crossed" and uncomment the video-ports -property
+	 * in tda19988 node.
+	 */
+	blue-and-red-wiring = "straight";
+
 	port {
 		lcdc_0: endpoint@0 {
 			remote-endpoint = <&hdmi_0>;
@@ -95,6 +103,9 @@
 		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
 		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
 
+		/* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+		/* video-ports = <0x234501>; */
+
 		#sound-dai-cells = <0>;
 		audio-ports = <	TDA998x_I2S	0x03>;
 
-- 
1.9.1

--
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 related

* Re: [PATCH v3 2/3] drm/bridge: Add ti-tfp410 DVI transmitter driver
From: Jyri Sarha @ 2016-11-17 20:16 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: devicetree, bcousson, khilman, dri-devel, bgolaszewski,
	tomi.valkeinen
In-Reply-To: <12647548.AgjiIO6s4p@avalon>

On 11/17/16 19:20, Laurent Pinchart wrote:
>> > Oops, forgot to handle the return values. This is how I fixed it:
>> > static int __init tfp410_module_init(void)
>> > {
>> > 	int ret;
>> > 
>> > 	ret = i2c_add_driver(&tfp410_i2c_driver);
>> > 	if (ret)
>> > 		return ret;
>> > 
>> > 	ret = platform_driver_register(&tfp410_platform_driver);
>> > 	if (ret)
>> > 		i2c_del_driver(&tfp410_i2c_driver);
>> > 
>> > 	return ret;
>> > }
> If registration of one of the two drivers fail, wouldn't it make sense to 
> still continue (probably with an error message) to avoid breaking the other 
> one ?
> 

Oh, good point. I fix that too. Anything else about this series? I'd
like to send a pull request for 4.10 soon.

>>> > > +
>>> > > +	return 0;
>>> > > +}

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v2] ARM: dts: sun5i: Add touchscreen node to reference-design-tablet.dtsi
From: Maxime Ripard @ 2016-11-17 20:24 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Chen-Yu Tsai, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree
In-Reply-To: <20161116131508.12541-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 792 bytes --]

On Wed, Nov 16, 2016 at 02:15:08PM +0100, Hans de Goede wrote:
> Just like on sun8i all sun5i tablets use the same interrupt and power
> gpios for their touchscreens. I've checked all known a13 fex files and
> only the UTOO P66 uses a different gpio for the interrupt.
> 
> Add a touchscreen node to sun5i-reference-design-tablet.dtsi, which
> fills in the necessary gpios to avoid duplication in the tablet dts files,
> just like we do in sun8i-reference-design-tablet.dtsi.
> 
> This will make future patches adding touchscreen nodes to a13 tablets
> simpler.
> 
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

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 v4 2/2] ARM: dts: sun6i: hummingbird-a31: Enable display output through VGA bridge
From: Maxime Ripard @ 2016-11-17 20:27 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: David Airlie, Archit Taneja,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20161116154232.872-3-wens-jdAy2FN1RRM@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]

On Wed, Nov 16, 2016 at 11:42:32PM +0800, Chen-Yu Tsai wrote:
> The Hummingbird A31 board has a VGA DAC which converts RGB output
> from the LCD interface to VGA analog signals.
> 
> Add nodes for the VGA DAC, its power supply, and enable this part
> of the display pipeline.
> 
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>

Applied, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox