diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index fb15b3dab..5464b88a6 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -582,6 +582,8 @@ static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, false); g->ops.clock_gating.slcg_perf_load_gating_prod(g, false); + g->ops.clock_gating.slcg_ltc_load_gating_prod(g, + false); gr_gk20a_init_blcg_mode(g, BLCG_RUN, ENGINE_GR_GK20A); g->elcg_enabled = false; diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index e6b3fd5fe..230e17222 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c @@ -385,6 +385,16 @@ int gk20a_init_fifo_reset_enable_hw(struct gk20a *g) gk20a_reset(g, mc_enable_pfifo_enabled_f() | mc_enable_ce2_enabled_f()); + if (g->ops.clock_gating.slcg_ce2_load_gating_prod) + g->ops.clock_gating.slcg_ce2_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.slcg_fifo_load_gating_prod) + g->ops.clock_gating.slcg_fifo_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.blcg_fifo_load_gating_prod) + g->ops.clock_gating.blcg_fifo_load_gating_prod(g, + g->blcg_enabled); + /* enable pbdma */ mask = 0; for (i = 0; i < proj_host_num_pbdma_v(); ++i) diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index a6a51de5c..0caef9671 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -907,6 +907,13 @@ static int gk20a_pm_finalize_poweron(struct device *dev) gk20a_writel(g, mc_intr_en_0_r(), mc_intr_en_0_inta_hardware_f()); + if (g->ops.clock_gating.slcg_bus_load_gating_prod) + g->ops.clock_gating.slcg_bus_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.blcg_bus_load_gating_prod) + g->ops.clock_gating.blcg_bus_load_gating_prod(g, + g->blcg_enabled); + if (!tegra_platform_is_silicon()) gk20a_writel(g, bus_intr_en_0_r(), 0x0); else @@ -914,6 +921,7 @@ static int gk20a_pm_finalize_poweron(struct device *dev) bus_intr_en_0_pri_squash_m() | bus_intr_en_0_pri_fecserr_m() | bus_intr_en_0_pri_timeout_m()); + gk20a_reset_priv_ring(g); gk20a_detect_chip(g); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index fc97fcb9d..b6d73343e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -150,11 +150,28 @@ struct gpu_ops { void (*init_kind_attr)(struct gk20a *g); } fb; struct { + void (*slcg_bus_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ce2_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_chiplet_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ctxsw_firmware_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_fb_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_fifo_load_gating_prod)(struct gk20a *g, bool prod); void (*slcg_gr_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ltc_load_gating_prod)(struct gk20a *g, bool prod); void (*slcg_perf_load_gating_prod)(struct gk20a *g, bool prod); - void (*blcg_gr_load_gating_prod)(struct gk20a *g, bool prod); - void (*pg_gr_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_priring_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_pmu_load_gating_prod)(struct gk20a *g, bool prod); void (*slcg_therm_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_xbar_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_bus_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_ctxsw_firmware_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_fb_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_fifo_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_gr_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_ltc_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_pwr_csb_load_gating_prod)(struct gk20a *g, bool prod); + void (*blcg_pmu_load_gating_prod)(struct gk20a *g, bool prod); + void (*pg_gr_load_gating_prod)(struct gk20a *g, bool prod); } clock_gating; struct { void (*bind_channel)(struct channel_gk20a *ch_gk20a); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.c b/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.c index c6478a5e1..0e3b0cb32 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.c @@ -311,6 +311,11 @@ void gr_gk20a_slcg_gr_load_gating_prod(struct gk20a *g, } } +void ltc_gk20a_slcg_ltc_load_gating_prod(struct gk20a *g, + bool prod) +{ +} + void gr_gk20a_slcg_perf_load_gating_prod(struct gk20a *g, bool prod) { diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.h b/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.h index 40a6c545c..b2a029842 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a_gating_reglist.h @@ -1,7 +1,7 @@ /* * drivers/video/tegra/host/gk20a/gk20a_gating_reglist.h * - * Copyright (c) 2012, NVIDIA Corporation. + * Copyright (c) 2012-2014, NVIDIA Corporation. 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 as published by @@ -27,6 +27,9 @@ void gr_gk20a_slcg_gr_load_gating_prod(struct gk20a *g, void gr_gk20a_slcg_perf_load_gating_prod(struct gk20a *g, bool prod); +void ltc_gk20a_slcg_ltc_load_gating_prod(struct gk20a *g, + bool prod); + void gr_gk20a_blcg_gr_load_gating_prod(struct gk20a *g, bool prod); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index fceed5e93..687147ed3 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c @@ -94,7 +94,19 @@ static ssize_t blcg_enable_store(struct device *device, g->blcg_enabled = false; gk20a_busy(g->dev); + if (g->ops.clock_gating.blcg_bus_load_gating_prod) + g->ops.clock_gating.blcg_bus_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod) + g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_fb_load_gating_prod) + g->ops.clock_gating.blcg_fb_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_fifo_load_gating_prod) + g->ops.clock_gating.blcg_fifo_load_gating_prod(g, g->blcg_enabled); g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_ltc_load_gating_prod) + g->ops.clock_gating.blcg_ltc_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_pmu_load_gating_prod) + g->ops.clock_gating.blcg_pmu_load_gating_prod(g, g->blcg_enabled); gk20a_idle(g->dev); dev_info(device, "BLCG is %s.\n", g->blcg_enabled ? "enabled" : @@ -136,8 +148,28 @@ static ssize_t slcg_enable_store(struct device *device, * it is added to init, we should add it here too. */ gk20a_busy(g->dev); + if (g->ops.clock_gating.slcg_bus_load_gating_prod) + g->ops.clock_gating.slcg_bus_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_ce2_load_gating_prod) + g->ops.clock_gating.slcg_ce2_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_chiplet_load_gating_prod) + g->ops.clock_gating.slcg_chiplet_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod) + g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_fb_load_gating_prod) + g->ops.clock_gating.slcg_fb_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_fifo_load_gating_prod) + g->ops.clock_gating.slcg_fifo_load_gating_prod(g, g->slcg_enabled); g->ops.clock_gating.slcg_gr_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_ltc_load_gating_prod) + g->ops.clock_gating.slcg_ltc_load_gating_prod(g, g->slcg_enabled); g->ops.clock_gating.slcg_perf_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_priring_load_gating_prod) + g->ops.clock_gating.slcg_priring_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_pmu_load_gating_prod) + g->ops.clock_gating.slcg_pmu_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_xbar_load_gating_prod) + g->ops.clock_gating.slcg_xbar_load_gating_prod(g, g->slcg_enabled); gk20a_idle(g->dev); dev_info(device, "SLCG is %s.\n", g->slcg_enabled ? "enabled" : diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index cbad12923..661a2ca30 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -4246,10 +4246,6 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) if (g->ops.gr.init_gpc_mmu) g->ops.gr.init_gpc_mmu(g); - /* slcg prod values */ - g->ops.clock_gating.slcg_gr_load_gating_prod(g, g->slcg_enabled); - g->ops.clock_gating.slcg_perf_load_gating_prod(g, g->slcg_enabled); - /* init mmu debug buffer */ addr = NV_MC_SMMU_VADDR_TRANSLATE(gr->mmu_wr_mem.iova); addr_lo = u64_lo32(addr); @@ -4281,9 +4277,6 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) gr_gk20a_zcull_init_hw(g, gr); - g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); - g->ops.clock_gating.pg_gr_load_gating_prod(g, true); - if (g->elcg_enabled) { gr_gk20a_init_elcg_mode(g, ELCG_AUTO, ENGINE_GR_GK20A); gr_gk20a_init_elcg_mode(g, ELCG_AUTO, ENGINE_CE2_GK20A); @@ -4426,6 +4419,19 @@ static int gk20a_init_gr_prepare(struct gk20a *g) | mc_enable_blg_enabled_f() | mc_enable_perfmon_enabled_f()); + /* slcg prod values */ + g->ops.clock_gating.slcg_gr_load_gating_prod(g, g->slcg_enabled); + if (g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod) + g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod(g, + g->slcg_enabled); + g->ops.clock_gating.slcg_perf_load_gating_prod(g, g->slcg_enabled); + + g->ops.clock_gating.blcg_gr_load_gating_prod(g, g->blcg_enabled); + if (g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod) + g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod(g, + g->blcg_enabled); + g->ops.clock_gating.pg_gr_load_gating_prod(g, true); + /* enable fifo access */ gk20a_writel(g, gr_gpfifo_ctl_r(), gr_gpfifo_ctl_access_enabled_f() | diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index 218491ea4..578b77bfb 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c @@ -33,6 +33,8 @@ struct gpu_ops gk20a_ops = { gr_gk20a_slcg_gr_load_gating_prod, .slcg_perf_load_gating_prod = gr_gk20a_slcg_perf_load_gating_prod, + .slcg_ltc_load_gating_prod = + ltc_gk20a_slcg_ltc_load_gating_prod, .blcg_gr_load_gating_prod = gr_gk20a_blcg_gr_load_gating_prod, .pg_gr_load_gating_prod = diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 3feb675b8..173776ffc 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -251,6 +251,19 @@ static int gk20a_init_mm_reset_enable_hw(struct gk20a *g) if (g->ops.fb.reset) g->ops.fb.reset(g); + if (g->ops.clock_gating.slcg_fb_load_gating_prod) + g->ops.clock_gating.slcg_fb_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.slcg_ltc_load_gating_prod) + g->ops.clock_gating.slcg_ltc_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.blcg_fb_load_gating_prod) + g->ops.clock_gating.blcg_fb_load_gating_prod(g, + g->blcg_enabled); + if (g->ops.clock_gating.blcg_ltc_load_gating_prod) + g->ops.clock_gating.blcg_ltc_load_gating_prod(g, + g->blcg_enabled); + if (g->ops.fb.init_fs_state) g->ops.fb.init_fs_state(g); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index eb62caafa..f77ad10b6 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -1124,6 +1124,13 @@ static int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable) int retries = GR_IDLE_CHECK_MAX / GR_IDLE_CHECK_DEFAULT; gk20a_enable(g, mc_enable_pwr_enabled_f()); + if (g->ops.clock_gating.slcg_pmu_load_gating_prod) + g->ops.clock_gating.slcg_pmu_load_gating_prod(g, + g->slcg_enabled); + if (g->ops.clock_gating.blcg_pmu_load_gating_prod) + g->ops.clock_gating.blcg_pmu_load_gating_prod(g, + g->blcg_enabled); + do { u32 w = gk20a_readl(g, pwr_falcon_dmactl_r()) & (pwr_falcon_dmactl_dmem_scrubbing_m() | diff --git a/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c b/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c index aea1a80bb..9d82a986d 100644 --- a/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c @@ -39,6 +39,10 @@ void gk20a_reset_priv_ring(struct gk20a *g) gk20a_reset(g, mc_enable_priv_ring_enabled_f()); + if (g->ops.clock_gating.slcg_priring_load_gating_prod) + g->ops.clock_gating.slcg_priring_load_gating_prod(g, + g->slcg_enabled); + gk20a_writel(g,pri_ringmaster_command_r(), 0x4); diff --git a/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.c b/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.c index 6b8648d33..fc4a94b9e 100644 --- a/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.c +++ b/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.c @@ -1,6 +1,4 @@ /* - * drivers/video/tegra/host/gm20b/gm20b_gating_reglist.c - * * Copyright (c) 2014, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -31,6 +29,40 @@ struct gating_desc { u32 prod; u32 disable; }; +/* slcg bus */ +const struct gating_desc gm20b_slcg_bus[] = { + {.addr = 0x00001c04, .prod = 0x00000000, .disable = 0x000003fe}, +}; + +/* slcg ce2 */ +const struct gating_desc gm20b_slcg_ce2[] = { + {.addr = 0x00106f28, .prod = 0x00000000, .disable = 0x000007fe}, +}; + +/* slcg chiplet */ +const struct gating_desc gm20b_slcg_chiplet[] = { + {.addr = 0x0010c07c, .prod = 0x00000000, .disable = 0x00000007}, + {.addr = 0x0010e07c, .prod = 0x00000000, .disable = 0x00000007}, + {.addr = 0x0010d07c, .prod = 0x00000000, .disable = 0x00000007}, + {.addr = 0x0010e17c, .prod = 0x00000000, .disable = 0x00000007}, +}; + +/* slcg ctxsw firmware */ +const struct gating_desc gm20b_slcg_ctxsw_firmware[] = { + {.addr = 0x00005f00, .prod = 0x00020008, .disable = 0x0003fffe}, +}; + +/* slcg fb */ +const struct gating_desc gm20b_slcg_fb[] = { + {.addr = 0x00100d14, .prod = 0x00000000, .disable = 0xfffffffe}, + {.addr = 0x00100c9c, .prod = 0x00000000, .disable = 0x000001fe}, +}; + +/* slcg fifo */ +const struct gating_desc gm20b_slcg_fifo[] = { + {.addr = 0x000026ac, .prod = 0x00000100, .disable = 0x0001fffe}, +}; + /* slcg gr */ const struct gating_desc gm20b_slcg_gr[] = { {.addr = 0x004041f4, .prod = 0x00000000, .disable = 0x03fffffe}, @@ -74,8 +106,8 @@ const struct gating_desc gm20b_slcg_gr[] = { {.addr = 0x00419ce0, .prod = 0x00000000, .disable = 0x001ffffe}, {.addr = 0x00419c74, .prod = 0x0000001e, .disable = 0x0000001e}, {.addr = 0x00419fd4, .prod = 0x00000000, .disable = 0x0003fffe}, - {.addr = 0x00419fdc, .prod = 0xfffffffe, .disable = 0xfffffffe}, - {.addr = 0x00419fe4, .prod = 0x00000000, .disable = 0x00001ffe}, + {.addr = 0x00419fdc, .prod = 0xffedff00, .disable = 0xfffffffe}, + {.addr = 0x00419fe4, .prod = 0x00001b00, .disable = 0x00001ffe}, {.addr = 0x00419ff4, .prod = 0x00000000, .disable = 0x00003ffe}, {.addr = 0x00419ffc, .prod = 0x00000000, .disable = 0x0001fffe}, {.addr = 0x0041be2c, .prod = 0x04115fc0, .disable = 0xfffffffe}, @@ -93,6 +125,12 @@ const struct gating_desc gm20b_slcg_gr[] = { {.addr = 0x00408a24, .prod = 0x00000000, .disable = 0x000001ff}, }; +/* slcg ltc */ +const struct gating_desc gm20b_slcg_ltc[] = { + {.addr = 0x0017e050, .prod = 0x00000000, .disable = 0xfffffffe}, + {.addr = 0x0017e35c, .prod = 0x00000000, .disable = 0xfffffffe}, +}; + /* slcg perf */ const struct gating_desc gm20b_slcg_perf[] = { {.addr = 0x001be018, .prod = 0x000001ff, .disable = 0x00000000}, @@ -101,6 +139,62 @@ const struct gating_desc gm20b_slcg_perf[] = { {.addr = 0x001b4124, .prod = 0x00000001, .disable = 0x00000000}, }; +/* slcg PriRing */ +const struct gating_desc gm20b_slcg_priring[] = { + {.addr = 0x001200a8, .prod = 0x00000000, .disable = 0x00000001}, +}; + +/* slcg pwr_csb */ +const struct gating_desc gm20b_slcg_pwr_csb[] = { + {.addr = 0x0000017c, .prod = 0x00020008, .disable = 0x0003fffe}, + {.addr = 0x00000e74, .prod = 0x00000000, .disable = 0x0000000f}, + {.addr = 0x00000a74, .prod = 0x00000000, .disable = 0x00007ffe}, + {.addr = 0x000016b8, .prod = 0x00000000, .disable = 0x0000000f}, +}; + +/* slcg pmu */ +const struct gating_desc gm20b_slcg_pmu[] = { + {.addr = 0x0010a17c, .prod = 0x00020008, .disable = 0x0003fffe}, + {.addr = 0x0010aa74, .prod = 0x00000000, .disable = 0x00007ffe}, + {.addr = 0x0010ae74, .prod = 0x00000000, .disable = 0x0000000f}, +}; + +/* therm gr */ +const struct gating_desc gm20b_slcg_therm[] = { + {.addr = 0x000206b8, .prod = 0x00000000, .disable = 0x0000000f}, +}; + +/* slcg Xbar */ +const struct gating_desc gm20b_slcg_xbar[] = { + {.addr = 0x0013cbe4, .prod = 0x00000000, .disable = 0x1ffffffe}, + {.addr = 0x0013cc04, .prod = 0x00000000, .disable = 0x1ffffffe}, +}; + +/* blcg bus */ +const struct gating_desc gm20b_blcg_bus[] = { + {.addr = 0x00001c00, .prod = 0x00000042, .disable = 0x00000000}, +}; + +/* blcg ctxsw firmware */ +const struct gating_desc gm20b_blcg_ctxsw_firmware[] = { + {.addr = 0x00022400, .prod = 0x00000000, .disable = 0x00000000}, +}; + +/* blcg fb */ +const struct gating_desc gm20b_blcg_fb[] = { + {.addr = 0x00100d10, .prod = 0x0000c242, .disable = 0x00000000}, + {.addr = 0x00100d30, .prod = 0x0000c242, .disable = 0x00000000}, + {.addr = 0x00100d3c, .prod = 0x00000242, .disable = 0x00000000}, + {.addr = 0x00100d48, .prod = 0x0000c242, .disable = 0x00000000}, + {.addr = 0x00100d1c, .prod = 0x00000042, .disable = 0x00000000}, + {.addr = 0x00100c98, .prod = 0x00000242, .disable = 0x00000000}, +}; + +/* blcg fifo */ +const struct gating_desc gm20b_blcg_fifo[] = { + {.addr = 0x000026a4, .prod = 0x0000c242, .disable = 0x00000000}, +}; + /* blcg gr */ const struct gating_desc gm20b_blcg_gr[] = { {.addr = 0x004041f0, .prod = 0x00004046, .disable = 0x00000000}, @@ -143,11 +237,11 @@ const struct gating_desc gm20b_blcg_gr[] = { {.addr = 0x00419cd4, .prod = 0x00000002, .disable = 0x00000000}, {.addr = 0x00419cdc, .prod = 0x00000002, .disable = 0x00000000}, {.addr = 0x00419c70, .prod = 0x00004044, .disable = 0x00000000}, - {.addr = 0x00419fd0, .prod = 0x00000044, .disable = 0x00000000}, - {.addr = 0x00419fd8, .prod = 0x00000045, .disable = 0x00000000}, - {.addr = 0x00419fe0, .prod = 0x00000044, .disable = 0x00000000}, + {.addr = 0x00419fd0, .prod = 0x00004044, .disable = 0x00000000}, + {.addr = 0x00419fd8, .prod = 0x00004046, .disable = 0x00000000}, + {.addr = 0x00419fe0, .prod = 0x00004044, .disable = 0x00000000}, {.addr = 0x00419fe8, .prod = 0x00000042, .disable = 0x00000000}, - {.addr = 0x00419ff0, .prod = 0x00000045, .disable = 0x00000000}, + {.addr = 0x00419ff0, .prod = 0x00004045, .disable = 0x00000000}, {.addr = 0x00419ff8, .prod = 0x00000002, .disable = 0x00000000}, {.addr = 0x00419f90, .prod = 0x00000002, .disable = 0x00000000}, {.addr = 0x0041be28, .prod = 0x00000042, .disable = 0x00000000}, @@ -166,16 +260,126 @@ const struct gating_desc gm20b_blcg_gr[] = { {.addr = 0x004089b8, .prod = 0x00004042, .disable = 0x00000000}, }; +/* blcg ltc */ +const struct gating_desc gm20b_blcg_ltc[] = { + {.addr = 0x0017e030, .prod = 0x00000044, .disable = 0x00000000}, + {.addr = 0x0017e040, .prod = 0x00000044, .disable = 0x00000000}, + {.addr = 0x0017e3e0, .prod = 0x00000044, .disable = 0x00000000}, + {.addr = 0x0017e3c8, .prod = 0x00000044, .disable = 0x00000000}, +}; + +/* blcg pwr_csb */ +const struct gating_desc gm20b_blcg_pwr_csb[] = { + {.addr = 0x00000a70, .prod = 0x00000045, .disable = 0x00000000}, +}; + +/* blcg pmu */ +const struct gating_desc gm20b_blcg_pmu[] = { + {.addr = 0x0010aa70, .prod = 0x00000045, .disable = 0x00000000}, +}; + +/* blcg Xbar */ +const struct gating_desc gm20b_blcg_xbar[] = { + {.addr = 0x0013cbe0, .prod = 0x00000042, .disable = 0x00000000}, + {.addr = 0x0013cc00, .prod = 0x00000042, .disable = 0x00000000}, +}; + /* pg gr */ const struct gating_desc gm20b_pg_gr[] = { }; -/* therm gr */ -const struct gating_desc gm20b_slcg_therm[] = { - {.addr = 0x000206b8, .prod = 0x00000000, .disable = 0x0000000f}, -}; +/* static inline functions */ +void gm20b_slcg_bus_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_bus) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_bus[i].addr, + gm20b_slcg_bus[i].prod); + else + gk20a_writel(g, gm20b_slcg_bus[i].addr, + gm20b_slcg_bus[i].disable); + } +} /* static inline functions */ +void gm20b_slcg_ce2_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_ce2) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_ce2[i].addr, + gm20b_slcg_ce2[i].prod); + else + gk20a_writel(g, gm20b_slcg_ce2[i].addr, + gm20b_slcg_ce2[i].disable); + } +} + +void gm20b_slcg_chiplet_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_chiplet) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_chiplet[i].addr, + gm20b_slcg_chiplet[i].prod); + else + gk20a_writel(g, gm20b_slcg_chiplet[i].addr, + gm20b_slcg_chiplet[i].disable); + } +} + +void gm20b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_ctxsw_firmware) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_ctxsw_firmware[i].addr, + gm20b_slcg_ctxsw_firmware[i].prod); + else + gk20a_writel(g, gm20b_slcg_ctxsw_firmware[i].addr, + gm20b_slcg_ctxsw_firmware[i].disable); + } +} + +void gm20b_slcg_fb_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_fb) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_fb[i].addr, + gm20b_slcg_fb[i].prod); + else + gk20a_writel(g, gm20b_slcg_fb[i].addr, + gm20b_slcg_fb[i].disable); + } +} + +void gm20b_slcg_fifo_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_fifo) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_fifo[i].addr, + gm20b_slcg_fifo[i].prod); + else + gk20a_writel(g, gm20b_slcg_fifo[i].addr, + gm20b_slcg_fifo[i].disable); + } +} + void gr_gm20b_slcg_gr_load_gating_prod(struct gk20a *g, bool prod) { @@ -191,7 +395,22 @@ void gr_gm20b_slcg_gr_load_gating_prod(struct gk20a *g, } } -void gr_gm20b_slcg_perf_load_gating_prod(struct gk20a *g, +void ltc_gm20b_slcg_ltc_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_ltc) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_ltc[i].addr, + gm20b_slcg_ltc[i].prod); + else + gk20a_writel(g, gm20b_slcg_ltc[i].addr, + gm20b_slcg_ltc[i].disable); + } +} + +void gm20b_slcg_perf_load_gating_prod(struct gk20a *g, bool prod) { u32 i; @@ -206,7 +425,142 @@ void gr_gm20b_slcg_perf_load_gating_prod(struct gk20a *g, } } -void gr_gm20b_blcg_gr_load_gating_prod(struct gk20a *g, +void gm20b_slcg_priring_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_priring) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_priring[i].addr, + gm20b_slcg_priring[i].prod); + else + gk20a_writel(g, gm20b_slcg_priring[i].addr, + gm20b_slcg_priring[i].disable); + } +} + +void gm20b_slcg_pwr_csb_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_pwr_csb) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_pwr_csb[i].addr, + gm20b_slcg_pwr_csb[i].prod); + else + gk20a_writel(g, gm20b_slcg_pwr_csb[i].addr, + gm20b_slcg_pwr_csb[i].disable); + } +} + +void gm20b_slcg_pmu_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_pmu) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_pmu[i].addr, + gm20b_slcg_pmu[i].prod); + else + gk20a_writel(g, gm20b_slcg_pmu[i].addr, + gm20b_slcg_pmu[i].disable); + } +} + +void gm20b_slcg_therm_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_therm) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_therm[i].addr, + gm20b_slcg_therm[i].prod); + else + gk20a_writel(g, gm20b_slcg_therm[i].addr, + gm20b_slcg_therm[i].disable); + } +} + +void gm20b_slcg_xbar_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_slcg_xbar) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_slcg_xbar[i].addr, + gm20b_slcg_xbar[i].prod); + else + gk20a_writel(g, gm20b_slcg_xbar[i].addr, + gm20b_slcg_xbar[i].disable); + } +} + +void gm20b_blcg_bus_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_bus) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_bus[i].addr, + gm20b_blcg_bus[i].prod); + else + gk20a_writel(g, gm20b_blcg_bus[i].addr, + gm20b_blcg_bus[i].disable); + } +} + +void gm20b_blcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_ctxsw_firmware) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_ctxsw_firmware[i].addr, + gm20b_blcg_ctxsw_firmware[i].prod); + else + gk20a_writel(g, gm20b_blcg_ctxsw_firmware[i].addr, + gm20b_blcg_ctxsw_firmware[i].disable); + } +} + +void gm20b_blcg_fb_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_fb) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_fb[i].addr, + gm20b_blcg_fb[i].prod); + else + gk20a_writel(g, gm20b_blcg_fb[i].addr, + gm20b_blcg_fb[i].disable); + } +} + +void gm20b_blcg_fifo_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_fifo) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_fifo[i].addr, + gm20b_blcg_fifo[i].prod); + else + gk20a_writel(g, gm20b_blcg_fifo[i].addr, + gm20b_blcg_fifo[i].disable); + } +} + +void gm20b_blcg_gr_load_gating_prod(struct gk20a *g, bool prod) { u32 i; @@ -221,6 +575,66 @@ void gr_gm20b_blcg_gr_load_gating_prod(struct gk20a *g, } } +void gm20b_blcg_ltc_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_ltc) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_ltc[i].addr, + gm20b_blcg_ltc[i].prod); + else + gk20a_writel(g, gm20b_blcg_ltc[i].addr, + gm20b_blcg_ltc[i].disable); + } +} + +void gm20b_blcg_pwr_csb_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_pwr_csb) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_pwr_csb[i].addr, + gm20b_blcg_pwr_csb[i].prod); + else + gk20a_writel(g, gm20b_blcg_pwr_csb[i].addr, + gm20b_blcg_pwr_csb[i].disable); + } +} + +void gm20b_blcg_pmu_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_pmu) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_pmu[i].addr, + gm20b_blcg_pmu[i].prod); + else + gk20a_writel(g, gm20b_blcg_pmu[i].addr, + gm20b_blcg_pmu[i].disable); + } +} + +void gm20b_blcg_xbar_load_gating_prod(struct gk20a *g, + bool prod) +{ + u32 i; + u32 size = sizeof(gm20b_blcg_xbar) / sizeof(struct gating_desc); + for (i = 0; i < size; i++) { + if (prod) + gk20a_writel(g, gm20b_blcg_xbar[i].addr, + gm20b_blcg_xbar[i].prod); + else + gk20a_writel(g, gm20b_blcg_xbar[i].addr, + gm20b_blcg_xbar[i].disable); + } +} + void gr_gm20b_pg_gr_load_gating_prod(struct gk20a *g, bool prod) { @@ -236,19 +650,4 @@ void gr_gm20b_pg_gr_load_gating_prod(struct gk20a *g, } } -void gr_gm20b_slcg_therm_load_gating_prod(struct gk20a *g, - bool prod) -{ - u32 i; - u32 size = sizeof(gm20b_slcg_therm) / sizeof(struct gating_desc); - for (i = 0; i < size; i++) { - if (prod) - gk20a_writel(g, gm20b_slcg_therm[i].addr, - gm20b_slcg_therm[i].prod); - else - gk20a_writel(g, gm20b_slcg_therm[i].addr, - gm20b_slcg_therm[i].disable); - } -} - #endif /* __gm20b_gating_reglist_h__ */ diff --git a/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.h b/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.h index 4097fad23..6f51e50db 100644 --- a/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.h +++ b/drivers/gpu/nvgpu/gm20b/gm20b_gating_reglist.h @@ -21,17 +21,69 @@ #include "gk20a/gk20a.h" +void gm20b_slcg_bus_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_ce2_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_chiplet_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_fb_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_fifo_load_gating_prod(struct gk20a *g, + bool prod); + void gr_gm20b_slcg_gr_load_gating_prod(struct gk20a *g, bool prod); -void gr_gm20b_slcg_perf_load_gating_prod(struct gk20a *g, +void ltc_gm20b_slcg_ltc_load_gating_prod(struct gk20a *g, bool prod); -void gr_gm20b_blcg_gr_load_gating_prod(struct gk20a *g, +void gm20b_slcg_perf_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_priring_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_pmu_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_therm_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_slcg_xbar_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_bus_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_fb_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_fifo_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_gr_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_ltc_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_pwr_csb_load_gating_prod(struct gk20a *g, + bool prod); + +void gm20b_blcg_pmu_load_gating_prod(struct gk20a *g, bool prod); void gr_gm20b_pg_gr_load_gating_prod(struct gk20a *g, bool prod); -void gr_gm20b_slcg_therm_load_gating_prod(struct gk20a *g, - bool prod); diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index 6ded69256..ec786a44c 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -35,16 +35,50 @@ struct gpu_ops gm20b_ops = { .clock_gating = { + .slcg_bus_load_gating_prod = + gm20b_slcg_bus_load_gating_prod, + .slcg_ce2_load_gating_prod = + gm20b_slcg_ce2_load_gating_prod, + .slcg_chiplet_load_gating_prod = + gm20b_slcg_chiplet_load_gating_prod, + .slcg_ctxsw_firmware_load_gating_prod = + gm20b_slcg_ctxsw_firmware_load_gating_prod, + .slcg_fb_load_gating_prod = + gm20b_slcg_fb_load_gating_prod, + .slcg_fifo_load_gating_prod = + gm20b_slcg_fifo_load_gating_prod, .slcg_gr_load_gating_prod = gr_gm20b_slcg_gr_load_gating_prod, + .slcg_ltc_load_gating_prod = + ltc_gm20b_slcg_ltc_load_gating_prod, .slcg_perf_load_gating_prod = - gr_gm20b_slcg_perf_load_gating_prod, + gm20b_slcg_perf_load_gating_prod, + .slcg_priring_load_gating_prod = + gm20b_slcg_priring_load_gating_prod, + .slcg_pmu_load_gating_prod = + gm20b_slcg_pmu_load_gating_prod, + .slcg_therm_load_gating_prod = + gm20b_slcg_therm_load_gating_prod, + .slcg_xbar_load_gating_prod = + gm20b_slcg_xbar_load_gating_prod, + .blcg_bus_load_gating_prod = + gm20b_blcg_bus_load_gating_prod, + .blcg_ctxsw_firmware_load_gating_prod = + gm20b_blcg_ctxsw_firmware_load_gating_prod, + .blcg_fb_load_gating_prod = + gm20b_blcg_fb_load_gating_prod, + .blcg_fifo_load_gating_prod = + gm20b_blcg_fifo_load_gating_prod, .blcg_gr_load_gating_prod = - gr_gm20b_blcg_gr_load_gating_prod, + gm20b_blcg_gr_load_gating_prod, + .blcg_ltc_load_gating_prod = + gm20b_blcg_ltc_load_gating_prod, + .blcg_pwr_csb_load_gating_prod = + gm20b_blcg_pwr_csb_load_gating_prod, + .blcg_pmu_load_gating_prod = + gm20b_blcg_pmu_load_gating_prod, .pg_gr_load_gating_prod = gr_gm20b_pg_gr_load_gating_prod, - .slcg_therm_load_gating_prod = - gr_gm20b_slcg_therm_load_gating_prod, } };