From 437b2296ced574eada632b11346e22f6b0103e17 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 20 Aug 2015 14:54:21 +1000 Subject: drm/nouveau/volt: convert to new-style nvkm_subdev Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c | 117 ++++++++++------------- drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c | 55 +++++------ drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c | 31 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h | 20 ++++ 5 files changed, 110 insertions(+), 117 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index cdb87e2900f1..dc8682c91cc7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -99,7 +99,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei) } if (volt) { - ret = volt->set_id(volt, cstate->voltage, +1); + ret = nvkm_volt_set_id(volt, cstate->voltage, +1); if (ret && ret != -ENODEV) { nvkm_error(subdev, "failed to raise voltage: %d\n", ret); return ret; @@ -113,7 +113,7 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei) } if (volt) { - ret = volt->set_id(volt, cstate->voltage, -1); + ret = nvkm_volt_set_id(volt, cstate->voltage, -1); if (ret && ret != -ENODEV) nvkm_error(subdev, "failed to lower voltage: %d\n", ret); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c index c1668c86f521..4752dbd33923 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c @@ -21,44 +21,39 @@ * * Authors: Ben Skeggs */ -#include +#include "priv.h" + #include #include #include -static int +int nvkm_volt_get(struct nvkm_volt *volt) { - if (volt->vid_get) { - int ret = volt->vid_get(volt), i; - if (ret >= 0) { - for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].vid == ret) - return volt->vid[i].uv; - } - ret = -EINVAL; + int ret = volt->func->vid_get(volt), i; + if (ret >= 0) { + for (i = 0; i < volt->vid_nr; i++) { + if (volt->vid[i].vid == ret) + return volt->vid[i].uv; } - return ret; + ret = -EINVAL; } - return -ENODEV; + return ret; } static int nvkm_volt_set(struct nvkm_volt *volt, u32 uv) { struct nvkm_subdev *subdev = &volt->subdev; - if (volt->vid_set) { - int i, ret = -EINVAL; - for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].uv == uv) { - ret = volt->vid_set(volt, volt->vid[i].vid); - nvkm_debug(subdev, "set %duv: %d\n", uv, ret); - break; - } + int i, ret = -EINVAL; + for (i = 0; i < volt->vid_nr; i++) { + if (volt->vid[i].uv == uv) { + ret = volt->func->vid_set(volt, volt->vid[i].vid); + nvkm_debug(subdev, "set %duv: %d\n", uv, ret); + break; } - return ret; } - return -ENODEV; + return ret; } static int @@ -83,10 +78,15 @@ nvkm_volt_map(struct nvkm_volt *volt, u8 id) return id ? id * 10000 : -ENODEV; } -static int +int nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition) { - int ret = nvkm_volt_map(volt, id); + int ret; + + if (volt->func->set_id) + return volt->func->set_id(volt, id, condition); + + ret = nvkm_volt_map(volt, id); if (ret >= 0) { int prev = nvkm_volt_get(volt); if (!condition || prev < 0 || @@ -135,53 +135,41 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) } } -int -_nvkm_volt_init(struct nvkm_object *object) +static int +nvkm_volt_init(struct nvkm_subdev *subdev) { - struct nvkm_volt *volt = (void *)object; - struct nvkm_subdev *subdev = &volt->subdev; - int ret; - - ret = nvkm_subdev_init_old(&volt->subdev); - if (ret) - return ret; - - ret = volt->get(volt); + struct nvkm_volt *volt = nvkm_volt(subdev); + int ret = nvkm_volt_get(volt); if (ret < 0) { if (ret != -ENODEV) nvkm_debug(subdev, "current voltage unknown\n"); return 0; } - nvkm_debug(subdev, "current voltage: %duv\n", ret); return 0; } -void -_nvkm_volt_dtor(struct nvkm_object *object) +static void * +nvkm_volt_dtor(struct nvkm_subdev *subdev) { - struct nvkm_volt *volt = (void *)object; - nvkm_subdev_destroy(&volt->subdev); + return nvkm_volt(subdev); } -int -nvkm_volt_create_(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, int length, void **pobject) +static const struct nvkm_subdev_func +nvkm_volt = { + .dtor = nvkm_volt_dtor, + .init = nvkm_volt_init, +}; + +void +nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device, + int index, struct nvkm_volt *volt) { - struct nvkm_device *device = (void *)parent; struct nvkm_bios *bios = device->bios; - struct nvkm_volt *volt; - int ret, i; - - ret = nvkm_subdev_create_(parent, engine, oclass, 0, "VOLT", - "voltage", length, pobject); - volt = *pobject; - if (ret) - return ret; + int i; - volt->get = nvkm_volt_get; - volt->set = nvkm_volt_set; - volt->set_id = nvkm_volt_set_id; + nvkm_subdev_ctor(&nvkm_volt, device, index, 0, &volt->subdev); + volt->func = func; /* Assuming the non-bios device should build the voltage table later */ if (bios) @@ -192,16 +180,15 @@ nvkm_volt_create_(struct nvkm_object *parent, struct nvkm_object *engine, nvkm_debug(&volt->subdev, "VID %02x: %duv\n", volt->vid[i].vid, volt->vid[i].uv); } - - /*XXX: this is an assumption.. there probably exists boards - * out there with i2c-connected voltage controllers too.. - */ - ret = nvkm_voltgpio_init(volt); - if (ret == 0) { - volt->vid_get = nvkm_voltgpio_get; - volt->vid_set = nvkm_voltgpio_set; - } } +} - return ret; +int +nvkm_volt_new_(const struct nvkm_volt_func *func, struct nvkm_device *device, + int index, struct nvkm_volt **pvolt) +{ + if (!(*pvolt = kzalloc(sizeof(**pvolt), GFP_KERNEL))) + return -ENOMEM; + nvkm_volt_ctor(func, device, index, *pvolt); + return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c index 59fa2cf898d2..01394a05e9d8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c @@ -19,7 +19,9 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#include +#define gk20a_volt(p) container_of((p), struct gk20a_volt, base) +#include "priv.h" + #ifdef __KERNEL__ #include #endif @@ -101,9 +103,9 @@ gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo) } static int -gk20a_volt_vid_get(struct nvkm_volt *obj) +gk20a_volt_vid_get(struct nvkm_volt *base) { - struct gk20a_volt *volt = container_of(obj, typeof(*volt), base); + struct gk20a_volt *volt = gk20a_volt(base); int i, uv; uv = regulator_get_voltage(volt->vdd); @@ -116,9 +118,9 @@ gk20a_volt_vid_get(struct nvkm_volt *obj) } static int -gk20a_volt_vid_set(struct nvkm_volt *obj, u8 vid) +gk20a_volt_vid_set(struct nvkm_volt *base, u8 vid) { - struct gk20a_volt *volt = container_of(obj, typeof(*volt), base); + struct gk20a_volt *volt = gk20a_volt(base); struct nvkm_subdev *subdev = &volt->base.subdev; nvkm_debug(subdev, "set voltage as %duv\n", volt->base.vid[vid].uv); @@ -126,9 +128,9 @@ gk20a_volt_vid_set(struct nvkm_volt *obj, u8 vid) } static int -gk20a_volt_set_id(struct nvkm_volt *obj, u8 id, int condition) +gk20a_volt_set_id(struct nvkm_volt *base, u8 id, int condition) { - struct gk20a_volt *volt = container_of(obj, typeof(*volt), base); + struct gk20a_volt *volt = gk20a_volt(base); struct nvkm_subdev *subdev = &volt->base.subdev; int prev_uv = regulator_get_voltage(volt->vdd); int target_uv = volt->base.vid[id].uv; @@ -147,27 +149,29 @@ gk20a_volt_set_id(struct nvkm_volt *obj, u8 id, int condition) return ret; } -static int -gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +static const struct nvkm_volt_func +gk20a_volt = { + .vid_get = gk20a_volt_vid_get, + .vid_set = gk20a_volt_vid_set, + .set_id = gk20a_volt_set_id, +}; + +int +gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) { - struct nvkm_device *device = (void *)parent; struct gk20a_volt *volt; - int i, ret, uv; + int i, uv; + + if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL))) + return -ENOMEM; - ret = nvkm_volt_create(parent, engine, oclass, &volt); - *pobject = nv_object(volt); - if (ret) - return ret; + nvkm_volt_ctor(&gk20a_volt, device, index, &volt->base); + *pvolt = &volt->base; uv = regulator_get_voltage(device->gpu->vdd); nvkm_info(&volt->base.subdev, "The default voltage is %duV\n", uv); volt->vdd = device->gpu->vdd; - volt->base.vid_get = gk20a_volt_vid_get; - volt->base.vid_set = gk20a_volt_vid_set; - volt->base.set_id = gk20a_volt_set_id; volt->base.vid_nr = ARRAY_SIZE(gk20a_cvb_coef); nvkm_debug(&volt->base.subdev, "%s - vid_nr = %d\n", __func__, @@ -183,14 +187,3 @@ gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine, return 0; } - -struct nvkm_oclass -gk20a_volt_oclass = { - .handle = NV_SUBDEV(VOLT, 0xea), - .ofuncs = &(struct nvkm_ofuncs) { - .ctor = gk20a_volt_ctor, - .dtor = _nvkm_volt_dtor, - .init = _nvkm_volt_init, - .fini = _nvkm_volt_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c index 16e8965c72f9..23409387abb5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/nv40.c @@ -21,31 +21,24 @@ * * Authors: Ben Skeggs */ -#include +#include "priv.h" -static int -nv40_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine, - struct nvkm_oclass *oclass, void *data, u32 size, - struct nvkm_object **pobject) +static const struct nvkm_volt_func +nv40_volt = { + .vid_get = nvkm_voltgpio_get, + .vid_set = nvkm_voltgpio_set, +}; + +int +nv40_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) { struct nvkm_volt *volt; int ret; - ret = nvkm_volt_create(parent, engine, oclass, &volt); - *pobject = nv_object(volt); + ret = nvkm_volt_new_(&nv40_volt, device, index, &volt); + *pvolt = volt; if (ret) return ret; - return 0; + return nvkm_voltgpio_init(volt); } - -struct nvkm_oclass -nv40_volt_oclass = { - .handle = NV_SUBDEV(VOLT, 0x40), - .ofuncs = &(struct nvkm_ofuncs) { - .ctor = nv40_volt_ctor, - .dtor = _nvkm_volt_dtor, - .init = _nvkm_volt_init, - .fini = _nvkm_volt_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h new file mode 100644 index 000000000000..394f37c723af --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h @@ -0,0 +1,20 @@ +#ifndef __NVKM_VOLT_PRIV_H__ +#define __NVKM_VOLT_PRIV_H__ +#define nvkm_volt(p) container_of((p), struct nvkm_volt, subdev) +#include + +void nvkm_volt_ctor(const struct nvkm_volt_func *, struct nvkm_device *, + int index, struct nvkm_volt *); +int nvkm_volt_new_(const struct nvkm_volt_func *, struct nvkm_device *, + int index, struct nvkm_volt **); + +struct nvkm_volt_func { + int (*vid_get)(struct nvkm_volt *); + int (*vid_set)(struct nvkm_volt *, u8 vid); + int (*set_id)(struct nvkm_volt *, u8 id, int condition); +}; + +int nvkm_voltgpio_init(struct nvkm_volt *); +int nvkm_voltgpio_get(struct nvkm_volt *); +int nvkm_voltgpio_set(struct nvkm_volt *, u8); +#endif -- cgit v1.2.3