drm/nouveau/clk/gk20a: split gk20a_clk_new()
authorAlexandre Courbot <acourbot@nvidia.com>
Fri, 12 Feb 2016 05:22:17 +0000 (14:22 +0900)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 14 Mar 2016 00:13:55 +0000 (10:13 +1000)
This allows to instanciate drivers that use the same logic as gk20a with
different parameters.

Add a constructor function to allow other chips that inherit from this
clock to easily initialize its members

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c

index 311cf49..4e92186 100644 (file)
@@ -671,29 +671,48 @@ gk20a_clk = {
 };
 
 int
-gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
+_gk20a_clk_ctor(struct nvkm_device *device, int index,
+               const struct nvkm_clk_func *func,
+               const struct gk20a_clk_pllg_params *params,
+               struct gk20a_clk *clk)
 {
        struct nvkm_device_tegra *tdev = device->func->tegra(device);
-       struct gk20a_clk *clk;
-       int ret, i;
-
-       if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL)))
-               return -ENOMEM;
-       *pclk = &clk->base;
+       int ret;
+       int i;
 
        /* Finish initializing the pstates */
-       for (i = 0; i < ARRAY_SIZE(gk20a_pstates); i++) {
-               INIT_LIST_HEAD(&gk20a_pstates[i].list);
-               gk20a_pstates[i].pstate = i + 1;
+       for (i = 0; i < func->nr_pstates; i++) {
+               INIT_LIST_HEAD(&func->pstates[i].list);
+               func->pstates[i].pstate = i + 1;
        }
 
-       clk->params = &gk20a_pllg_params;
+       clk->params = params;
        clk->parent_rate = clk_get_rate(tdev->clk);
 
-       ret = nvkm_clk_ctor(&gk20a_clk, device, index, true, &clk->base);
+       ret = nvkm_clk_ctor(func, device, index, true, &clk->base);
+       if (ret)
+               return ret;
+
        nvkm_debug(&clk->base.subdev, "parent clock rate: %d Khz\n",
                   clk->parent_rate / KHZ);
 
+       return 0;
+}
+
+int
+gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
+{
+       struct gk20a_clk *clk;
+       int ret;
+
+       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       if (!clk)
+               return -ENOMEM;
+       *pclk = &clk->base;
+
+       ret = _gk20a_clk_ctor(device, index, &gk20a_clk, &gk20a_pllg_params,
+                             clk);
+
        clk->pl_to_div = pl_to_div;
        clk->div_to_pl = div_to_pl;