diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index b2ecade52..a03d5765f 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -238,6 +238,7 @@ struct gpu_ops { struct { int (*prepare_ucode)(struct gk20a *g); int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); + int (*pmu_setup_elpg)(struct gk20a *g); } pmu; struct { int (*init_clk_support)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 068611e32..7c441f53b 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -2280,8 +2280,12 @@ static void pmu_setup_hw_enable_elpg(struct gk20a *g) /* Save zbc table after PMU is initialized. */ gr_gk20a_pmu_save_zbc(g, 0xf); - if (g->elpg_enabled) + if (g->elpg_enabled) { + /* Init reg with prod values*/ + if (g->ops.pmu.pmu_setup_elpg) + g->ops.pmu.pmu_setup_elpg(g); gk20a_pmu_enable_elpg(g); + } udelay(50); @@ -2296,6 +2300,7 @@ void gk20a_init_pmu_ops(struct gpu_ops *gops) { gops->pmu.prepare_ucode = gk20a_prepare_ucode; gops->pmu.pmu_setup_hw_and_bootstrap = gk20a_init_pmu_setup_hw1; + gops->pmu.pmu_setup_elpg = NULL; } int gk20a_init_pmu_support(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c index 4b42b8386..04f9e02a6 100644 --- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c @@ -15,6 +15,138 @@ #include "gk20a/gk20a.h" #include "acr_gm20b.h" +#include "pmu_gm20b.h" + +/*! + * Structure/object which single register write need to be done during PG init + * sequence to set PROD values. + */ +struct pg_init_sequence_list { + u32 regaddr; + u32 writeval; +}; + + +/* PROD settings for ELPG sequencing registers*/ +static struct pg_init_sequence_list _pginitseq_gm20b[] = { + { 0x0010ab10, 0x8180}, + { 0x0010e118, 0x81818080}, + { 0x0010e068, 0}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000083}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000080}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000081}, + { 0x0010e06c, 0x00000082}, + { 0x0010e06c, 0x00000083}, + { 0x0010ab14, 0x00000000}, + { 0x0010ab18, 0x00000000}, + { 0x0010e024, 0x00000000}, + { 0x0010e028, 0x00000000}, + { 0x0010e11c, 0x00000000}, + { 0x0010e120, 0x00000000}, + { 0x0010ab1c, 0x00010011}, + { 0x0010e020, 0x001C0011}, + { 0x0010e124, 0x00030011}, + { 0x0010ab20, 0xfedcba98}, + { 0x0010ab24, 0x00000000}, + { 0x0010e02c, 0xfedcba98}, + { 0x0010e030, 0x00000000}, + { 0x0010e128, 0xfedcba98}, + { 0x0010e12c, 0x00000000}, + { 0x0010ab28, 0x71111111}, + { 0x0010ab2c, 0x70000000}, + { 0x0010e034, 0x71111111}, + { 0x0010e038, 0x70000000}, + { 0x0010e130, 0x71111111}, + { 0x0010e134, 0x70000000}, + { 0x0010ab30, 0x00000000}, + { 0x0010ab34, 0x00000001}, + { 0x00020004, 0x00000000}, + { 0x0010e138, 0x00000000}, + { 0x0010e040, 0x00000000}, +}; + +int gm20b_pmu_setup_elpg(struct gk20a *g) +{ + int ret = 0; + u32 reg_writes; + u32 index; + + gk20a_dbg_fn(""); + + if (g->elpg_enabled) { + reg_writes = ((sizeof(_pginitseq_gm20b) / + sizeof((_pginitseq_gm20b)[0]))); + /* Initialize registers with production values*/ + for (index = 0; index < reg_writes; index++) { + gk20a_writel(g, _pginitseq_gm20b[index].regaddr, + _pginitseq_gm20b[index].writeval); + } + } + + gk20a_dbg_fn("done"); + return ret; +} void gm20b_init_pmu_ops(struct gpu_ops *gops) { @@ -23,4 +155,5 @@ void gm20b_init_pmu_ops(struct gpu_ops *gops) #else gk20a_init_pmu_ops(gops); #endif + gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg; } diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.h b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.h index d36d38036..fc2f7d60b 100644 --- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.h @@ -15,5 +15,7 @@ #ifndef __PMU_GM20B_H_ #define __PMU_GM20B_H_ + void gm20b_init_pmu_ops(struct gpu_ops *gops); + #endif /*__PMU_GM20B_H_*/