All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Configure Power Sensors
@ 2016-03-25 11:19 Karol Herbst
       [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Karol Herbst @ 2016-03-25 11:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The power sensors can be configured to sample the readout values over time.
Nvidia does this too, so nouveau should probably do that too.

Karol Herbst (4):
  iccsense: remove read function
  iccsense: convert to linked list
  iccsense: split sensor into own struct
  iccsense: configure sensors like nvidia does

 drm/nouveau/include/nvkm/subdev/iccsense.h |   6 +-
 drm/nouveau/nouveau_hwmon.c                |   2 +-
 drm/nouveau/nvkm/subdev/iccsense/base.c    | 246 +++++++++++++++++++++--------
 drm/nouveau/nvkm/subdev/iccsense/priv.h    |  16 +-
 4 files changed, 198 insertions(+), 72 deletions(-)

-- 
2.7.4

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* [PATCH 1/4] iccsense: remove read function
       [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2016-03-25 11:19   ` Karol Herbst
  2016-03-25 11:19   ` [PATCH 2/4] iccsense: convert to linked list Karol Herbst
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Karol Herbst @ 2016-03-25 11:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/iccsense.h |  1 -
 drm/nouveau/nvkm/subdev/iccsense/base.c    | 23 ++++++++++-------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
index 530c621..c3defcd 100644
--- a/drm/nouveau/include/nvkm/subdev/iccsense.h
+++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
@@ -12,6 +12,5 @@ struct nvkm_iccsense {
 };
 
 int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **);
-int nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx);
 int nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense);
 #endif
diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
index c44a852..bf1b94e 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -96,26 +96,23 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
 }
 
 int
-nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx)
+nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
 {
-	struct nvkm_iccsense_rail *rail;
+	int result = 0, i;
 
-	if (!iccsense || idx >= iccsense->rail_count)
+	if (!iccsense)
 		return -EINVAL;
 
-	rail = &iccsense->rails[idx];
-	if (!rail->read)
+	if (iccsense->rail_count == 0)
 		return -ENODEV;
 
-	return rail->read(iccsense, rail);
-}
-
-int
-nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
-{
-	int result = 0, i;
 	for (i = 0; i < iccsense->rail_count; ++i) {
-		int res = nvkm_iccsense_read(iccsense, i);
+		int res;
+		struct nvkm_iccsense_rail *rail = &iccsense->rails[i];
+		if (!rail->read)
+			return -ENODEV;
+
+		res = rail->read(iccsense, rail);
 		if (res >= 0)
 			result += res;
 		else
-- 
2.7.4

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* [PATCH 2/4] iccsense: convert to linked list
       [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-03-25 11:19   ` [PATCH 1/4] iccsense: remove read function Karol Herbst
@ 2016-03-25 11:19   ` Karol Herbst
       [not found]     ` <1458904780-1553-3-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-03-25 11:19   ` [PATCH 3/4] iccsense: split sensor into own struct Karol Herbst
  2016-03-25 11:19   ` [PATCH 4/4] iccsense: configure sensors like nvidia does Karol Herbst
  3 siblings, 1 reply; 8+ messages in thread
From: Karol Herbst @ 2016-03-25 11:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/iccsense.h |  4 +---
 drm/nouveau/nouveau_hwmon.c                |  2 +-
 drm/nouveau/nvkm/subdev/iccsense/base.c    | 32 +++++++++++++-----------------
 drm/nouveau/nvkm/subdev/iccsense/priv.h    |  1 +
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
index c3defcd..a4c0da0 100644
--- a/drm/nouveau/include/nvkm/subdev/iccsense.h
+++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
@@ -3,12 +3,10 @@
 
 #include <core/subdev.h>
 
-struct nkvm_iccsense_rail;
 struct nvkm_iccsense {
 	struct nvkm_subdev subdev;
-	u8 rail_count;
 	bool data_valid;
-	struct nvkm_iccsense_rail *rails;
+	struct list_head rails;
 };
 
 int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **);
diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
index 67edd2f..74f237b 100644
--- a/drm/nouveau/nouveau_hwmon.c
+++ b/drm/nouveau/nouveau_hwmon.c
@@ -689,7 +689,7 @@ nouveau_hwmon_init(struct drm_device *dev)
 			goto error;
 	}
 
-	if (iccsense && iccsense->data_valid && iccsense->rail_count) {
+	if (iccsense && iccsense->data_valid && !list_empty(&iccsense->rails)) {
 		ret = sysfs_create_group(&hwmon_dev->kobj,
 					 &hwmon_power_attrgroup);
 		if (ret)
diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
index bf1b94e..6fde68d 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -98,25 +98,21 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
 int
 nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
 {
-	int result = 0, i;
+	int result = 0;
+	struct nvkm_iccsense_rail *rail;
 
 	if (!iccsense)
 		return -EINVAL;
 
-	if (iccsense->rail_count == 0)
-		return -ENODEV;
-
-	for (i = 0; i < iccsense->rail_count; ++i) {
+	list_for_each_entry(rail, &iccsense->rails, head) {
 		int res;
-		struct nvkm_iccsense_rail *rail = &iccsense->rails[i];
 		if (!rail->read)
 			return -ENODEV;
 
 		res = rail->read(iccsense, rail);
-		if (res >= 0)
-			result += res;
-		else
+		if (res < 0)
 			return res;
+		result += res;
 	}
 	return result;
 }
@@ -125,9 +121,10 @@ static void *
 nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
 {
 	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
+	struct nvkm_iccsense_rail *rail, *tmp;
 
-	if (iccsense->rails)
-		kfree(iccsense->rails);
+	list_for_each_entry_safe(rail, tmp, &iccsense->rails, head)
+		kfree(rail);
 
 	return iccsense;
 }
@@ -145,11 +142,6 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
 	    || !stbl.nr_entry)
 		return 0;
 
-	iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry,
-	                          GFP_KERNEL);
-	if (!iccsense->rails)
-		return -ENOMEM;
-
 	iccsense->data_valid = true;
 	for (i = 0; i < stbl.nr_entry; ++i) {
 		struct pwr_rail_t *r = &stbl.rail[i];
@@ -184,7 +176,10 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
 			continue;
 		}
 
-		rail = &iccsense->rails[iccsense->rail_count];
+		rail = kmalloc(sizeof(*rail), GFP_KERNEL);
+		if (!rail)
+			return -ENOMEM;
+
 		switch (extdev.type) {
 		case NVBIOS_EXTDEV_INA209:
 			rail->read = nvkm_iccsense_ina209_read;
@@ -201,7 +196,7 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
 		rail->rail = r->rail;
 		rail->mohm = r->resistor_mohm;
 		rail->i2c = &i2c_bus->i2c;
-		++iccsense->rail_count;
+		list_add_tail(&rail->head, &iccsense->rails);
 	}
 	return 0;
 }
@@ -224,6 +219,7 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
 {
 	if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
 		return -ENOMEM;
+	INIT_LIST_HEAD(&(*iccsense)->rails);
 	nvkm_iccsense_ctor(device, index, *iccsense);
 	return 0;
 }
diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h
index ed398b8..e479128 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/priv.h
+++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h
@@ -4,6 +4,7 @@
 #include <subdev/iccsense.h>
 
 struct nvkm_iccsense_rail {
+	struct list_head head;
 	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
 	struct i2c_adapter *i2c;
 	u8 addr;
-- 
2.7.4

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* [PATCH 3/4] iccsense: split sensor into own struct
       [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-03-25 11:19   ` [PATCH 1/4] iccsense: remove read function Karol Herbst
  2016-03-25 11:19   ` [PATCH 2/4] iccsense: convert to linked list Karol Herbst
@ 2016-03-25 11:19   ` Karol Herbst
       [not found]     ` <1458904780-1553-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  2016-03-25 11:19   ` [PATCH 4/4] iccsense: configure sensors like nvidia does Karol Herbst
  3 siblings, 1 reply; 8+ messages in thread
From: Karol Herbst @ 2016-03-25 11:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/include/nvkm/subdev/iccsense.h |   1 +
 drm/nouveau/nvkm/subdev/iccsense/base.c    | 141 ++++++++++++++++++++---------
 drm/nouveau/nvkm/subdev/iccsense/priv.h    |  15 ++-
 3 files changed, 112 insertions(+), 45 deletions(-)

diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
index a4c0da0..3c2ddd9 100644
--- a/drm/nouveau/include/nvkm/subdev/iccsense.h
+++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
@@ -6,6 +6,7 @@
 struct nvkm_iccsense {
 	struct nvkm_subdev subdev;
 	bool data_valid;
+	struct list_head sensors;
 	struct list_head rails;
 };
 
diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
index 6fde68d..b6f6222 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -30,15 +30,14 @@
 
 static bool
 nvkm_iccsense_validate_device(struct i2c_adapter *i2c, u8 addr,
-			      enum nvbios_extdev_type type, u8 rail)
+			      enum nvbios_extdev_type type)
 {
 	switch (type) {
 	case NVBIOS_EXTDEV_INA209:
 	case NVBIOS_EXTDEV_INA219:
-		return rail == 0 && nv_rd16i2cr(i2c, addr, 0x0) >= 0;
+		return nv_rd16i2cr(i2c, addr, 0x0) >= 0;
 	case NVBIOS_EXTDEV_INA3221:
-		return rail <= 3 &&
-		       nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
+		return nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
 		       nv_rd16i2cr(i2c, addr, 0xfe) == 0x5449;
 	default:
 		return false;
@@ -67,8 +66,9 @@ nvkm_iccsense_ina2x9_read(struct nvkm_iccsense *iccsense,
                           struct nvkm_iccsense_rail *rail,
 			  u8 shunt_reg, u8 bus_reg)
 {
-	return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, shunt_reg, 0,
-				       bus_reg, 3, rail->mohm, 10 * 4);
+	return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
+				       shunt_reg, 0, bus_reg, 3, rail->mohm,
+				       10 * 4);
 }
 
 static int
@@ -89,9 +89,9 @@ static int
 nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
 			   struct nvkm_iccsense_rail *rail)
 {
-	return nvkm_iccsense_poll_lane(rail->i2c, rail->addr,
-				       1 + (rail->rail * 2), 3,
-				       2 + (rail->rail * 2), 3, rail->mohm,
+	return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
+				       1 + (rail->idx * 2), 3,
+				       2 + (rail->idx * 2), 3, rail->mohm,
 				       40 * 8);
 }
 
@@ -121,81 +121,137 @@ static void *
 nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
 {
 	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
-	struct nvkm_iccsense_rail *rail, *tmp;
+	struct nvkm_iccsense_sensor *sensor, *tmps;
+	struct nvkm_iccsense_rail *rail, *tmpr;
 
-	list_for_each_entry_safe(rail, tmp, &iccsense->rails, head)
+	list_for_each_entry_safe(sensor, tmps, &iccsense->sensors, head)
+		kfree(sensor);
+	list_for_each_entry_safe(rail, tmpr, &iccsense->rails, head)
 		kfree(rail);
 
 	return iccsense;
 }
 
+static struct nvkm_iccsense_sensor*
+nvkm_iccsense_create_sensor(struct nvkm_iccsense *iccsense, u8 id)
+{
+
+	struct nvkm_subdev *subdev = &iccsense->subdev;
+	struct nvkm_bios *bios = subdev->device->bios;
+	struct nvkm_i2c *i2c = subdev->device->i2c;
+	struct nvbios_extdev_func extdev;
+	struct nvkm_i2c_bus *i2c_bus;
+	struct nvkm_iccsense_sensor *sensor;
+	u8 addr;
+
+	if (!i2c || !bios || nvbios_extdev_parse(bios, id, &extdev))
+		return NULL;
+
+	if (extdev.type == 0xff)
+		return NULL;
+
+	if (extdev.type != NVBIOS_EXTDEV_INA209 &&
+	    extdev.type != NVBIOS_EXTDEV_INA219 &&
+	    extdev.type != NVBIOS_EXTDEV_INA3221) {
+		iccsense->data_valid = false;
+		nvkm_error(subdev, "found unknown sensor type %x, "
+			   "power reading might be invalid\n",
+			   extdev.type);
+		return NULL;
+	}
+
+	if (extdev.bus)
+		i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
+	else
+		i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
+	if (!i2c_bus)
+		return NULL;
+
+	addr = extdev.addr >> 1;
+	if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
+					   extdev.type)) {
+		iccsense->data_valid = false;
+		nvkm_warn(subdev, "found invalid sensor id: %i, power reading"
+			  "might be invalid\n", id);
+		return NULL;
+	}
+
+	sensor = kmalloc(sizeof(*sensor), GFP_KERNEL);
+	if (!sensor)
+		return NULL;
+
+	list_add_tail(&sensor->head, &iccsense->sensors);
+	sensor->id = id;
+	sensor->type = extdev.type;
+	sensor->i2c = &i2c_bus->i2c;
+	sensor->addr = addr;
+	sensor->rail_mask = 0x0;
+	return sensor;
+}
+
+static struct nvkm_iccsense_sensor*
+nvkm_iccsense_get_sensor(struct nvkm_iccsense *iccsense, u8 id)
+{
+	struct nvkm_iccsense_sensor *sensor;
+	list_for_each_entry(sensor, &iccsense->sensors, head) {
+		if (sensor->id == id)
+			return sensor;
+	}
+	return nvkm_iccsense_create_sensor(iccsense, id);
+}
+
 static int
 nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
 {
 	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
 	struct nvkm_bios *bios = subdev->device->bios;
-	struct nvkm_i2c *i2c = subdev->device->i2c;
 	struct nvbios_iccsense stbl;
 	int i;
 
-	if (!i2c || !bios || nvbios_iccsense_parse(bios, &stbl)
-	    || !stbl.nr_entry)
+	if (!bios || nvbios_iccsense_parse(bios, &stbl) || !stbl.nr_entry)
 		return 0;
 
 	iccsense->data_valid = true;
 	for (i = 0; i < stbl.nr_entry; ++i) {
 		struct pwr_rail_t *r = &stbl.rail[i];
-		struct nvbios_extdev_func extdev;
 		struct nvkm_iccsense_rail *rail;
-		struct nvkm_i2c_bus *i2c_bus;
-		u8 addr;
+		struct nvkm_iccsense_sensor *sensor;
 
 		if (!r->mode || r->resistor_mohm == 0)
 			continue;
 
-		if (nvbios_extdev_parse(bios, r->extdev_id, &extdev))
-			continue;
-
-		if (extdev.type == 0xff)
-			continue;
-
-		if (extdev.bus)
-			i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
-		else
-			i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
-		if (!i2c_bus)
+		sensor = nvkm_iccsense_get_sensor(iccsense, r->extdev_id);
+		if (!sensor)
 			continue;
 
-		addr = extdev.addr >> 1;
-		if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
-						   extdev.type, r->rail)) {
-			iccsense->data_valid = false;
-			nvkm_warn(subdev, "found unknown or invalid rail entry"
-				  " type 0x%x rail %i, power reading might be"
-				  " invalid\n", extdev.type, r->rail);
-			continue;
-		}
-
 		rail = kmalloc(sizeof(*rail), GFP_KERNEL);
 		if (!rail)
 			return -ENOMEM;
 
-		switch (extdev.type) {
+		switch (sensor->type) {
 		case NVBIOS_EXTDEV_INA209:
+			if (r->rail != 0)
+				continue;
 			rail->read = nvkm_iccsense_ina209_read;
 			break;
 		case NVBIOS_EXTDEV_INA219:
+			if (r->rail != 0)
+				continue;
 			rail->read = nvkm_iccsense_ina219_read;
 			break;
 		case NVBIOS_EXTDEV_INA3221:
+			if (r->rail >= 3)
+				continue;
 			rail->read = nvkm_iccsense_ina3221_read;
 			break;
+		default:
+			continue;
 		}
 
-		rail->addr = addr;
-		rail->rail = r->rail;
+		sensor->rail_mask |= 1 << r->rail;
+		rail->sensor = sensor;
+		rail->idx = r->rail;
 		rail->mohm = r->resistor_mohm;
-		rail->i2c = &i2c_bus->i2c;
 		list_add_tail(&rail->head, &iccsense->rails);
 	}
 	return 0;
@@ -219,6 +275,7 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
 {
 	if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
 		return -ENOMEM;
+	INIT_LIST_HEAD(&(*iccsense)->sensors);
 	INIT_LIST_HEAD(&(*iccsense)->rails);
 	nvkm_iccsense_ctor(device, index, *iccsense);
 	return 0;
diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h
index e479128..b72c31d 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/priv.h
+++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h
@@ -2,13 +2,22 @@
 #define __NVKM_ICCSENSE_PRIV_H__
 #define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev)
 #include <subdev/iccsense.h>
+#include <subdev/bios/extdev.h>
 
-struct nvkm_iccsense_rail {
+struct nvkm_iccsense_sensor {
 	struct list_head head;
-	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
+	int id;
+	enum nvbios_extdev_type type;
 	struct i2c_adapter *i2c;
 	u8 addr;
-	u8 rail;
+	u8 rail_mask;
+};
+
+struct nvkm_iccsense_rail {
+	struct list_head head;
+	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
+	struct nvkm_iccsense_sensor *sensor;
+	u8 idx;
 	u8 mohm;
 };
 
-- 
2.7.4

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* [PATCH 4/4] iccsense: configure sensors like nvidia does
       [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
                     ` (2 preceding siblings ...)
  2016-03-25 11:19   ` [PATCH 3/4] iccsense: split sensor into own struct Karol Herbst
@ 2016-03-25 11:19   ` Karol Herbst
       [not found]     ` <1458904780-1553-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
  3 siblings, 1 reply; 8+ messages in thread
From: Karol Herbst @ 2016-03-25 11:19 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
---
 drm/nouveau/nvkm/subdev/iccsense/base.c | 68 +++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
index b6f6222..6f3709e 100644
--- a/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -95,6 +95,63 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
 				       40 * 8);
 }
 
+static void
+nvkm_iccsense_ina2x9_config(struct nvkm_iccsense *iccsense,
+			    struct nvkm_iccsense_sensor *sensor)
+{
+	struct nvkm_subdev *subdev = &iccsense->subdev;
+	/* configuration:
+	 * 0x0007: 0x0007 shunt and bus continous
+	 * 0x0078: 0x0078 128 samples shunt
+	 * 0x0780: 0x0780 128 samples bus
+	 * 0x1800: 0x0000 +-40 mV shunt range
+	 * 0x2000: 0x0000 16V FSR
+         */
+	u16 value = 0x07ff;
+	nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
+	nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
+}
+
+static void
+nvkm_iccsense_ina3221_config(struct nvkm_iccsense *iccsense,
+			     struct nvkm_iccsense_sensor *sensor)
+{
+	struct nvkm_subdev *subdev = &iccsense->subdev;
+	/* configuration:
+	 * 0x0007: 0x0007 shunt and bus continous
+	 * 0x0031: 0x0000 140 us conversion time shunt
+	 * 0x01c0: 0x0000 140 us conversion time bus
+	 * 0x0f00: 0x0f00 1024 samples
+	 * 0x7000: 0x?000 channels
+         */
+	u16 value = 0x0e07;
+	if (sensor->rail_mask & 0x1)
+		value |= 0x1 << 14;
+	if (sensor->rail_mask & 0x2)
+		value |= 0x1 << 13;
+	if (sensor->rail_mask & 0x4)
+		value |= 0x1 << 12;
+	nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
+	nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
+}
+
+static void
+nvkm_iccsense_sensor_config(struct nvkm_iccsense *iccsense,
+		            struct nvkm_iccsense_sensor *sensor)
+{
+	switch (sensor->type) {
+	case NVBIOS_EXTDEV_INA209:
+	case NVBIOS_EXTDEV_INA219:
+		nvkm_iccsense_ina2x9_config(iccsense, sensor);
+		break;
+	case NVBIOS_EXTDEV_INA3221:
+		nvkm_iccsense_ina3221_config(iccsense, sensor);
+		break;
+	default:
+		break;
+	}
+}
+
 int
 nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
 {
@@ -257,8 +314,19 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
 	return 0;
 }
 
+static int
+nvkm_iccsense_init(struct nvkm_subdev *subdev)
+{
+	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
+	struct nvkm_iccsense_sensor *sensor;
+	list_for_each_entry(sensor, &iccsense->sensors, head)
+		nvkm_iccsense_sensor_config(iccsense, sensor);
+	return 0;
+}
+
 struct nvkm_subdev_func iccsense_func = {
 	.oneinit = nvkm_iccsense_oneinit,
+	.init = nvkm_iccsense_init,
 	.dtor = nvkm_iccsense_dtor,
 };
 
-- 
2.7.4

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 2/4] iccsense: convert to linked list
       [not found]     ` <1458904780-1553-3-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2016-03-28 10:18       ` Martin Peres
  0 siblings, 0 replies; 8+ messages in thread
From: Martin Peres @ 2016-03-28 10:18 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 25/03/16 13:19, Karol Herbst wrote:
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
> ---
>   drm/nouveau/include/nvkm/subdev/iccsense.h |  4 +---
>   drm/nouveau/nouveau_hwmon.c                |  2 +-
>   drm/nouveau/nvkm/subdev/iccsense/base.c    | 32 +++++++++++++-----------------
>   drm/nouveau/nvkm/subdev/iccsense/priv.h    |  1 +
>   4 files changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
> index c3defcd..a4c0da0 100644
> --- a/drm/nouveau/include/nvkm/subdev/iccsense.h
> +++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
> @@ -3,12 +3,10 @@
>   
>   #include <core/subdev.h>
>   
> -struct nkvm_iccsense_rail;
>   struct nvkm_iccsense {
>   	struct nvkm_subdev subdev;
> -	u8 rail_count;
>   	bool data_valid;
> -	struct nvkm_iccsense_rail *rails;
> +	struct list_head rails;
>   };
>   
>   int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **);
> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
> index 67edd2f..74f237b 100644
> --- a/drm/nouveau/nouveau_hwmon.c
> +++ b/drm/nouveau/nouveau_hwmon.c
> @@ -689,7 +689,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>   			goto error;
>   	}
>   
> -	if (iccsense && iccsense->data_valid && iccsense->rail_count) {
> +	if (iccsense && iccsense->data_valid && !list_empty(&iccsense->rails)) {
>   		ret = sysfs_create_group(&hwmon_dev->kobj,
>   					 &hwmon_power_attrgroup);
>   		if (ret)
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
> index bf1b94e..6fde68d 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/base.c
> +++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
> @@ -98,25 +98,21 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
>   int
>   nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
>   {
> -	int result = 0, i;
> +	int result = 0;
> +	struct nvkm_iccsense_rail *rail;
>   
>   	if (!iccsense)
>   		return -EINVAL;
>   
> -	if (iccsense->rail_count == 0)
> -		return -ENODEV;
> -
> -	for (i = 0; i < iccsense->rail_count; ++i) {
> +	list_for_each_entry(rail, &iccsense->rails, head) {
>   		int res;
> -		struct nvkm_iccsense_rail *rail = &iccsense->rails[i];
>   		if (!rail->read)
>   			return -ENODEV;
>   
>   		res = rail->read(iccsense, rail);
> -		if (res >= 0)
> -			result += res;
> -		else
> +		if (res < 0)
>   			return res;
> +		result += res;
>   	}
>   	return result;
>   }
> @@ -125,9 +121,10 @@ static void *
>   nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
>   {
>   	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
> +	struct nvkm_iccsense_rail *rail, *tmp;
>   
> -	if (iccsense->rails)
> -		kfree(iccsense->rails);
> +	list_for_each_entry_safe(rail, tmp, &iccsense->rails, head)
> +		kfree(rail);
The rails list is filled with invalid pointers at this point. Please add 
list_del(rail); before kfree(rail);

It has the added benefit of adding poisonous pointers that will show any 
access after freeing.
>   
>   	return iccsense;
>   }
> @@ -145,11 +142,6 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   	    || !stbl.nr_entry)
>   		return 0;
>   
> -	iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry,
> -	                          GFP_KERNEL);
> -	if (!iccsense->rails)
> -		return -ENOMEM;
> -
>   	iccsense->data_valid = true;
>   	for (i = 0; i < stbl.nr_entry; ++i) {
>   		struct pwr_rail_t *r = &stbl.rail[i];
> @@ -184,7 +176,10 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   			continue;
>   		}
>   
> -		rail = &iccsense->rails[iccsense->rail_count];
> +		rail = kmalloc(sizeof(*rail), GFP_KERNEL);
> +		if (!rail)
> +			return -ENOMEM;
> +
>   		switch (extdev.type) {
>   		case NVBIOS_EXTDEV_INA209:
>   			rail->read = nvkm_iccsense_ina209_read;
> @@ -201,7 +196,7 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   		rail->rail = r->rail;
>   		rail->mohm = r->resistor_mohm;
>   		rail->i2c = &i2c_bus->i2c;
> -		++iccsense->rail_count;
> +		list_add_tail(&rail->head, &iccsense->rails);
>   	}
>   	return 0;
>   }
> @@ -224,6 +219,7 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
>   {
>   	if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
>   		return -ENOMEM;
> +	INIT_LIST_HEAD(&(*iccsense)->rails);
>   	nvkm_iccsense_ctor(device, index, *iccsense);
>   	return 0;
>   }
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> index ed398b8..e479128 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/priv.h
> +++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> @@ -4,6 +4,7 @@
>   #include <subdev/iccsense.h>
>   
>   struct nvkm_iccsense_rail {
> +	struct list_head head;
>   	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
>   	struct i2c_adapter *i2c;
>   	u8 addr;

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 3/4] iccsense: split sensor into own struct
       [not found]     ` <1458904780-1553-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2016-03-28 10:36       ` Martin Peres
  0 siblings, 0 replies; 8+ messages in thread
From: Martin Peres @ 2016-03-28 10:36 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 25/03/16 13:19, Karol Herbst wrote:
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
> ---
>   drm/nouveau/include/nvkm/subdev/iccsense.h |   1 +
>   drm/nouveau/nvkm/subdev/iccsense/base.c    | 141 ++++++++++++++++++++---------
>   drm/nouveau/nvkm/subdev/iccsense/priv.h    |  15 ++-
>   3 files changed, 112 insertions(+), 45 deletions(-)
>
> diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
> index a4c0da0..3c2ddd9 100644
> --- a/drm/nouveau/include/nvkm/subdev/iccsense.h
> +++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
> @@ -6,6 +6,7 @@
>   struct nvkm_iccsense {
>   	struct nvkm_subdev subdev;
>   	bool data_valid;
> +	struct list_head sensors;
>   	struct list_head rails;
>   };
>   
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
> index 6fde68d..b6f6222 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/base.c
> +++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
> @@ -30,15 +30,14 @@
>   
>   static bool
>   nvkm_iccsense_validate_device(struct i2c_adapter *i2c, u8 addr,
> -			      enum nvbios_extdev_type type, u8 rail)
> +			      enum nvbios_extdev_type type)
>   {
>   	switch (type) {
>   	case NVBIOS_EXTDEV_INA209:
>   	case NVBIOS_EXTDEV_INA219:
> -		return rail == 0 && nv_rd16i2cr(i2c, addr, 0x0) >= 0;
> +		return nv_rd16i2cr(i2c, addr, 0x0) >= 0;
>   	case NVBIOS_EXTDEV_INA3221:
> -		return rail <= 3 &&
> -		       nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
> +		return nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
>   		       nv_rd16i2cr(i2c, addr, 0xfe) == 0x5449;
>   	default:
>   		return false;
> @@ -67,8 +66,9 @@ nvkm_iccsense_ina2x9_read(struct nvkm_iccsense *iccsense,
>                             struct nvkm_iccsense_rail *rail,
>   			  u8 shunt_reg, u8 bus_reg)
>   {
> -	return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, shunt_reg, 0,
> -				       bus_reg, 3, rail->mohm, 10 * 4);
> +	return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
> +				       shunt_reg, 0, bus_reg, 3, rail->mohm,
> +				       10 * 4);
>   }
>   
>   static int
> @@ -89,9 +89,9 @@ static int
>   nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
>   			   struct nvkm_iccsense_rail *rail)
>   {
> -	return nvkm_iccsense_poll_lane(rail->i2c, rail->addr,
> -				       1 + (rail->rail * 2), 3,
> -				       2 + (rail->rail * 2), 3, rail->mohm,
> +	return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
> +				       1 + (rail->idx * 2), 3,
> +				       2 + (rail->idx * 2), 3, rail->mohm,
>   				       40 * 8);
>   }
>   
> @@ -121,81 +121,137 @@ static void *
>   nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
>   {
>   	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
> -	struct nvkm_iccsense_rail *rail, *tmp;
> +	struct nvkm_iccsense_sensor *sensor, *tmps;
> +	struct nvkm_iccsense_rail *rail, *tmpr;
>   
> -	list_for_each_entry_safe(rail, tmp, &iccsense->rails, head)
> +	list_for_each_entry_safe(sensor, tmps, &iccsense->sensors, head)
> +		kfree(sensor);
> +	list_for_each_entry_safe(rail, tmpr, &iccsense->rails, head)
>   		kfree(rail);

Same problem as the last patch.

>   
>   	return iccsense;
>   }
>   
> +static struct nvkm_iccsense_sensor*
> +nvkm_iccsense_create_sensor(struct nvkm_iccsense *iccsense, u8 id)
> +{
> +
> +	struct nvkm_subdev *subdev = &iccsense->subdev;
> +	struct nvkm_bios *bios = subdev->device->bios;
> +	struct nvkm_i2c *i2c = subdev->device->i2c;
> +	struct nvbios_extdev_func extdev;
> +	struct nvkm_i2c_bus *i2c_bus;
> +	struct nvkm_iccsense_sensor *sensor;
> +	u8 addr;
> +
> +	if (!i2c || !bios || nvbios_extdev_parse(bios, id, &extdev))
> +		return NULL;
> +
> +	if (extdev.type == 0xff)
> +		return NULL;
> +
> +	if (extdev.type != NVBIOS_EXTDEV_INA209 &&
> +	    extdev.type != NVBIOS_EXTDEV_INA219 &&
> +	    extdev.type != NVBIOS_EXTDEV_INA3221) {
> +		iccsense->data_valid = false;
> +		nvkm_error(subdev, "found unknown sensor type %x, "
> +			   "power reading might be invalid\n",
> +			   extdev.type);

You do not create the sensor if it is unknown, so why do you say the 
report might be invalid?

Please change it to "Unknown sensor type %x".

> +		return NULL;
> +	}
> +
> +	if (extdev.bus)
> +		i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
> +	else
> +		i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
> +	if (!i2c_bus)
> +		return NULL;
> +
> +	addr = extdev.addr >> 1;
> +	if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
> +					   extdev.type)) {
> +		iccsense->data_valid = false;
> +		nvkm_warn(subdev, "found invalid sensor id: %i, power reading"
> +			  "might be invalid\n", id);
> +		return NULL;
> +	}
> +
> +	sensor = kmalloc(sizeof(*sensor), GFP_KERNEL);
> +	if (!sensor)
> +		return NULL;
> +
> +	list_add_tail(&sensor->head, &iccsense->sensors);
> +	sensor->id = id;
> +	sensor->type = extdev.type;
> +	sensor->i2c = &i2c_bus->i2c;
> +	sensor->addr = addr;
> +	sensor->rail_mask = 0x0;
> +	return sensor;
> +}
> +
> +static struct nvkm_iccsense_sensor*
> +nvkm_iccsense_get_sensor(struct nvkm_iccsense *iccsense, u8 id)
> +{
> +	struct nvkm_iccsense_sensor *sensor;
> +	list_for_each_entry(sensor, &iccsense->sensors, head) {
> +		if (sensor->id == id)
> +			return sensor;
> +	}
> +	return nvkm_iccsense_create_sensor(iccsense, id);
> +}
> +
>   static int
>   nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   {
>   	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
>   	struct nvkm_bios *bios = subdev->device->bios;
> -	struct nvkm_i2c *i2c = subdev->device->i2c;
>   	struct nvbios_iccsense stbl;
>   	int i;
>   
> -	if (!i2c || !bios || nvbios_iccsense_parse(bios, &stbl)
> -	    || !stbl.nr_entry)
> +	if (!bios || nvbios_iccsense_parse(bios, &stbl) || !stbl.nr_entry)
>   		return 0;
>   
>   	iccsense->data_valid = true;
>   	for (i = 0; i < stbl.nr_entry; ++i) {
>   		struct pwr_rail_t *r = &stbl.rail[i];
> -		struct nvbios_extdev_func extdev;
>   		struct nvkm_iccsense_rail *rail;
> -		struct nvkm_i2c_bus *i2c_bus;
> -		u8 addr;
> +		struct nvkm_iccsense_sensor *sensor;
>   
>   		if (!r->mode || r->resistor_mohm == 0)
>   			continue;
>   
> -		if (nvbios_extdev_parse(bios, r->extdev_id, &extdev))
> -			continue;
> -
> -		if (extdev.type == 0xff)
> -			continue;
> -
> -		if (extdev.bus)
> -			i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
> -		else
> -			i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
> -		if (!i2c_bus)
> +		sensor = nvkm_iccsense_get_sensor(iccsense, r->extdev_id);
> +		if (!sensor)
>   			continue;
>   
> -		addr = extdev.addr >> 1;
> -		if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
> -						   extdev.type, r->rail)) {
> -			iccsense->data_valid = false;
> -			nvkm_warn(subdev, "found unknown or invalid rail entry"
> -				  " type 0x%x rail %i, power reading might be"
> -				  " invalid\n", extdev.type, r->rail);
> -			continue;
> -		}
> -
>   		rail = kmalloc(sizeof(*rail), GFP_KERNEL);
>   		if (!rail)
>   			return -ENOMEM;
>   
> -		switch (extdev.type) {
> +		switch (sensor->type) {
>   		case NVBIOS_EXTDEV_INA209:
> +			if (r->rail != 0)
> +				continue;
>   			rail->read = nvkm_iccsense_ina209_read;
>   			break;
>   		case NVBIOS_EXTDEV_INA219:
> +			if (r->rail != 0)
> +				continue;
>   			rail->read = nvkm_iccsense_ina219_read;
>   			break;
>   		case NVBIOS_EXTDEV_INA3221:
> +			if (r->rail >= 3)
> +				continue;
>   			rail->read = nvkm_iccsense_ina3221_read;
>   			break;
> +		default:
> +			continue;
>   		}
>   
> -		rail->addr = addr;
> -		rail->rail = r->rail;
> +		sensor->rail_mask |= 1 << r->rail;
> +		rail->sensor = sensor;
> +		rail->idx = r->rail;
>   		rail->mohm = r->resistor_mohm;
> -		rail->i2c = &i2c_bus->i2c;
>   		list_add_tail(&rail->head, &iccsense->rails);
>   	}
>   	return 0;
> @@ -219,6 +275,7 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
>   {
>   	if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
>   		return -ENOMEM;
> +	INIT_LIST_HEAD(&(*iccsense)->sensors);
>   	INIT_LIST_HEAD(&(*iccsense)->rails);
>   	nvkm_iccsense_ctor(device, index, *iccsense);
>   	return 0;
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> index e479128..b72c31d 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/priv.h
> +++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> @@ -2,13 +2,22 @@
>   #define __NVKM_ICCSENSE_PRIV_H__
>   #define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev)
>   #include <subdev/iccsense.h>
> +#include <subdev/bios/extdev.h>
>   
> -struct nvkm_iccsense_rail {
> +struct nvkm_iccsense_sensor {
>   	struct list_head head;
> -	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
> +	int id;
> +	enum nvbios_extdev_type type;
>   	struct i2c_adapter *i2c;
>   	u8 addr;
> -	u8 rail;
> +	u8 rail_mask;
> +};
> +
> +struct nvkm_iccsense_rail {
> +	struct list_head head;
> +	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
> +	struct nvkm_iccsense_sensor *sensor;
> +	u8 idx;
>   	u8 mohm;
>   };
>   

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

* Re: [PATCH 4/4] iccsense: configure sensors like nvidia does
       [not found]     ` <1458904780-1553-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
@ 2016-03-28 10:40       ` Martin Peres
  0 siblings, 0 replies; 8+ messages in thread
From: Martin Peres @ 2016-03-28 10:40 UTC (permalink / raw)
  To: Karol Herbst, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 25/03/16 13:19, Karol Herbst wrote:
> Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
> ---
>   drm/nouveau/nvkm/subdev/iccsense/base.c | 68 +++++++++++++++++++++++++++++++++
>   1 file changed, 68 insertions(+)
>
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
> index b6f6222..6f3709e 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/base.c
> +++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
> @@ -95,6 +95,63 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
>   				       40 * 8);
>   }
>   
> +static void
> +nvkm_iccsense_ina2x9_config(struct nvkm_iccsense *iccsense,
> +			    struct nvkm_iccsense_sensor *sensor)

Maybe calling the sensor ina209 and using it also for 219 would be less 
confusing, especially if a 229 is later released by TI.
> +{
> +	struct nvkm_subdev *subdev = &iccsense->subdev;
> +	/* configuration:
> +	 * 0x0007: 0x0007 shunt and bus continous
> +	 * 0x0078: 0x0078 128 samples shunt
> +	 * 0x0780: 0x0780 128 samples bus
> +	 * 0x1800: 0x0000 +-40 mV shunt range
> +	 * 0x2000: 0x0000 16V FSR
> +         */
> +	u16 value = 0x07ff;
> +	nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
> +	nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
> +}
> +
> +static void
> +nvkm_iccsense_ina3221_config(struct nvkm_iccsense *iccsense,
> +			     struct nvkm_iccsense_sensor *sensor)
> +{
> +	struct nvkm_subdev *subdev = &iccsense->subdev;
> +	/* configuration:
> +	 * 0x0007: 0x0007 shunt and bus continous
> +	 * 0x0031: 0x0000 140 us conversion time shunt
> +	 * 0x01c0: 0x0000 140 us conversion time bus
> +	 * 0x0f00: 0x0f00 1024 samples
> +	 * 0x7000: 0x?000 channels
> +         */
> +	u16 value = 0x0e07;
> +	if (sensor->rail_mask & 0x1)
> +		value |= 0x1 << 14;
> +	if (sensor->rail_mask & 0x2)
> +		value |= 0x1 << 13;
> +	if (sensor->rail_mask & 0x4)
> +		value |= 0x1 << 12;
> +	nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
> +	nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
> +}
> +
> +static void
> +nvkm_iccsense_sensor_config(struct nvkm_iccsense *iccsense,
> +		            struct nvkm_iccsense_sensor *sensor)
> +{
> +	switch (sensor->type) {
> +	case NVBIOS_EXTDEV_INA209:
> +	case NVBIOS_EXTDEV_INA219:
> +		nvkm_iccsense_ina2x9_config(iccsense, sensor);
> +		break;
> +	case NVBIOS_EXTDEV_INA3221:
> +		nvkm_iccsense_ina3221_config(iccsense, sensor);
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
>   int
>   nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
>   {
> @@ -257,8 +314,19 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   	return 0;
>   }
>   
> +static int
> +nvkm_iccsense_init(struct nvkm_subdev *subdev)
> +{
> +	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
> +	struct nvkm_iccsense_sensor *sensor;
> +	list_for_each_entry(sensor, &iccsense->sensors, head)
> +		nvkm_iccsense_sensor_config(iccsense, sensor);
> +	return 0;
> +}
> +
>   struct nvkm_subdev_func iccsense_func = {
>   	.oneinit = nvkm_iccsense_oneinit,
> +	.init = nvkm_iccsense_init,
>   	.dtor = nvkm_iccsense_dtor,
>   };
>   

Looks like a good cleanup and improvement to me!

With the free-ing the lists fixed and maybe the change in name for the 
ina2x9, this is:
Martin Peres <martin.peres@free.fr>
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

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

end of thread, other threads:[~2016-03-28 10:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-25 11:19 [PATCH 0/4] Configure Power Sensors Karol Herbst
     [not found] ` <1458904780-1553-1-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2016-03-25 11:19   ` [PATCH 1/4] iccsense: remove read function Karol Herbst
2016-03-25 11:19   ` [PATCH 2/4] iccsense: convert to linked list Karol Herbst
     [not found]     ` <1458904780-1553-3-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2016-03-28 10:18       ` Martin Peres
2016-03-25 11:19   ` [PATCH 3/4] iccsense: split sensor into own struct Karol Herbst
     [not found]     ` <1458904780-1553-4-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2016-03-28 10:36       ` Martin Peres
2016-03-25 11:19   ` [PATCH 4/4] iccsense: configure sensors like nvidia does Karol Herbst
     [not found]     ` <1458904780-1553-5-git-send-email-nouveau-lIBOoy2+GI7scQ4cX5LuPg@public.gmane.org>
2016-03-28 10:40       ` Martin Peres

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