From 905f1c0392bf244b321f56f82661eeb2fe00ee05 Mon Sep 17 00:00:00 2001 From: David Nieto Date: Fri, 19 Aug 2016 17:09:35 -0700 Subject: gpu: nvgpu: parse and execute mclk shadow script * Parsing of shadow registers from VBIOS * Partial devinit engine interpreter implementation JIRA DNVGPU-117 Change-Id: I42179748889f17d674ad0a986e81c418b3b8df11 Signed-off-by: David Nieto Reviewed-on: http://git-master/r/1214956 Reviewed-on: http://git-master/r/1237293 Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/Makefile.nvgpu-t18x | 1 + drivers/gpu/nvgpu/clk/clk_mclk.c | 278 +++++++++++++++++++++++---------- drivers/gpu/nvgpu/clk/clk_mclk.h | 3 +- drivers/gpu/nvgpu/gp106/bios_gp106.c | 121 ++++++++++++++ drivers/gpu/nvgpu/gp106/bios_gp106.h | 31 ++++ drivers/gpu/nvgpu/gp106/hal_gp106.c | 4 +- drivers/gpu/nvgpu/gp106/hw_fb_gp106.h | 72 +++++++++ drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h | 56 +++++++ drivers/gpu/nvgpu/include/bios.h | 94 +++++++++++ 9 files changed, 572 insertions(+), 88 deletions(-) create mode 100644 drivers/gpu/nvgpu/gp106/bios_gp106.c create mode 100644 drivers/gpu/nvgpu/gp106/bios_gp106.h create mode 100644 drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu-t18x b/drivers/gpu/nvgpu/Makefile.nvgpu-t18x index 17b33959..ceae6006 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu-t18x +++ b/drivers/gpu/nvgpu/Makefile.nvgpu-t18x @@ -29,6 +29,7 @@ nvgpu-y += \ $(nvgpu-t18x)/gp106/fifo_gp106.o \ $(nvgpu-t18x)/gp106/ltc_gp106.o \ $(nvgpu-t18x)/gp106/fb_gp106.o \ + $(nvgpu-t18x)/gp106/bios_gp106.o \ $(nvgpu-t18x)/clk/clk_mclk.o \ $(nvgpu-t18x)/pstate/pstate.o \ $(nvgpu-t18x)/clk/clk_vin.o \ diff --git a/drivers/gpu/nvgpu/clk/clk_mclk.c b/drivers/gpu/nvgpu/clk/clk_mclk.c index df010221..b63fab1e 100644 --- a/drivers/gpu/nvgpu/clk/clk_mclk.c +++ b/drivers/gpu/nvgpu/clk/clk_mclk.c @@ -17,6 +17,9 @@ #include "gm206/bios_gm206.h" #include "gk20a/pmu_gk20a.h" #include "gk20a/hw_pwr_gk20a.h" +#include "gp106/hw_fb_gp106.h" + +#include "include/bios.h" #define VREG_COUNT 24 @@ -29,63 +32,6 @@ struct memory_link_training_pattern { u32 writeval; }; -static struct memory_link_training_pattern memory_shadow_p0_reglist[] = { - {0x9a065c, 0x20}, - {0x98467c, 0xffff0000}, - {0x984708, 0x30550}, - {0x98470c, 0x4C4C}, - {0x9006a0, 0x03030303}, - {0x9006a4, 0x03030303}, - {0x9046a0, 0x03030303}, - {0x9046a4, 0x03030303}, - {0x9086a0, 0x03030303}, - {0x9086a4, 0x03030303}, - {0x9846a8, 0x03030303}, - {0x9846ac, 0x03030303}, - {0x9a065c, 0x00}, -}; - -static struct memory_link_training_pattern memory_shadow_p5_reglist[] = { - {0x9a065c, 0x10}, - {0x98467c, 0xfff10000}, - {0x984708, 0x30002}, - {0x98470c, 0x1414}, - {0x9006a0, 0x12121212}, - {0x9006a4, 0x12121212}, - {0x9046a0, 0x12121212}, - {0x9046a4, 0x12121212}, - {0x9086a0, 0x12121212}, - {0x9086a4, 0x12121212}, - {0x90c6a0, 0x12121212}, - {0x90c6a4, 0x12121212}, - {0x9106a0, 0x12121212}, - {0x9106a4, 0x12121212}, - {0x9146a0, 0x12121212}, - {0x9146a4, 0x12121212}, - {0x9a065c, 0x0}, - {0x9a08e0, 0x10}, - {0x9846a8, 0x0f0f0f0f}, - {0x9846ac, 0x0f0f0f0f}, - {0x984d98, 0x22222222}, - {0x984d9c, 0x22222222}, - {0x984da0, 0x22222222}, - {0x984da4, 0x22222222}, - {0x984da8, 0x22222222}, - {0x984dac, 0x22222222}, - {0x984dac, 0x22222222}, - {0x984d70, 0x0}, - {0x984d74, 0x0}, - {0x984d78, 0x0}, - {0x984d7c, 0x0}, - {0x984d80, 0x0}, - {0x984d84, 0x0}, - {0x984d88, 0x0}, - {0x984d8c, 0x0}, - {0x984d90, 0x0}, - {0x984d94, 0x0}, - {0x9a08e0, 0x0}, -}; - static struct memory_link_training_pattern memory_pattern_reglist[] = { {0x9a0968, 0x0}, {0x9a0920, 0x0}, @@ -2026,31 +1972,6 @@ static void mclk_memory_load_training_pattern(struct gk20a *g) gk20a_dbg_fn("done"); } -static void mclk_memory_load_shadow_regs(struct gk20a *g) -{ - u32 reg_writes; - u32 index; - - gk20a_dbg_info(""); - - reg_writes = ((sizeof(memory_shadow_p0_reglist) / - sizeof((memory_shadow_p0_reglist)[0]))); - for (index = 0; index < reg_writes; index++) { - gk20a_writel(g, memory_shadow_p0_reglist[index].regaddr, - memory_shadow_p0_reglist[index].writeval); - } - - reg_writes = ((sizeof(memory_shadow_p5_reglist) / - sizeof((memory_shadow_p5_reglist)[0]))); - for (index = 0; index < reg_writes; index++) { - gk20a_writel(g, memory_shadow_p5_reglist[index].regaddr, - memory_shadow_p5_reglist[index].writeval); - } - - gk20a_dbg_fn("done"); - -} - static void mclk_seq_pmucmdhandler(struct gk20a *g, struct pmu_msg *_msg, void *param, u32 handle, u32 status) { @@ -2082,9 +2003,189 @@ status_update: *((u32 *)param) = msg_status; } +static int mclk_get_memclk_table(struct gk20a *g) +{ + int status = 0; + u8 *mem_table_ptr = NULL; + u32 idx_to_ptr_tbl[8]; + u32 idx_to_cmd_ptr_tbl[8]; + + u32 old_fbio_delay; + u32 old_fbio_cmd_delay; + + u32 cmd_idx; + u32 shadow_idx; + + struct vbios_memory_clock_header_1x memclock_table_header = { 0 }; + struct vbios_memory_clock_base_entry_11 memclock_base_entry = { 0 }; + + u8 *mem_entry_ptr = NULL; + int index; + + gk20a_dbg_info(""); + + if (!(g->ops.bios.get_perf_table_ptrs && + g->ops.bios.execute_script)) { + goto done; + } + + mem_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, + g->bios.perf_token, + MEMORY_CLOCK_TABLE); + if (mem_table_ptr == NULL) { + status = -EPERM; + goto done; + } + + memcpy(&memclock_table_header, mem_table_ptr, + sizeof(memclock_table_header)); + + if ((memclock_table_header.version < + VBIOS_MEMORY_CLOCK_HEADER_11_VERSION) || + (memclock_table_header.base_entry_size < + VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_2_SIZE)) { + status = -EINVAL; + goto done; + } + + /* reset and save shadow table map and registers */ + old_fbio_delay = gk20a_readl(g, fb_fbpa_fbio_delay_r()); + old_fbio_cmd_delay = gk20a_readl(g, fb_fbpa_fbio_cmd_delay_r()); + + memset(idx_to_ptr_tbl, 0, sizeof(idx_to_ptr_tbl)); + memset(idx_to_cmd_ptr_tbl, 0, sizeof(idx_to_cmd_ptr_tbl)); + + /* Read table entries */ + mem_entry_ptr = mem_table_ptr + memclock_table_header.header_size; + for (index = 0; index < memclock_table_header.entry_count; index++) { + u8 script_index, cmd_script_index; + u32 script_ptr = 0, cmd_script_ptr = 0; + + memcpy(&memclock_base_entry, mem_entry_ptr, + memclock_table_header.base_entry_size); + if (memclock_base_entry.maximum == 0) + continue; + + script_index = BIOS_GET_FIELD(memclock_base_entry.flags1, + VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX); + + script_ptr = gm206_bios_read_u32(g, + memclock_table_header.script_list_ptr + + script_index * sizeof(u32)); + + if (!script_ptr) + continue; + + /* Link and execute shadow scripts */ + + for (shadow_idx = 0; shadow_idx <= fb_fbpa_fbio_delay_priv_max_v(); + ++shadow_idx) { + if (script_ptr == idx_to_ptr_tbl[shadow_idx]) { + break; + } + } + + /* script has not been executed before */ + if (shadow_idx > fb_fbpa_fbio_delay_priv_max_v()) { + /* find unused index */ + for (shadow_idx = 0; shadow_idx < + fb_fbpa_fbio_delay_priv_max_v(); + ++shadow_idx) { + if (idx_to_ptr_tbl[shadow_idx] == 0) + break; + } + + if (shadow_idx > fb_fbpa_fbio_delay_priv_max_v()) { + gk20a_err(dev_from_gk20a(g), + "invalid shadow reg script index"); + status = -EINVAL; + goto done; + } + + idx_to_ptr_tbl[shadow_idx] = script_ptr; + + gk20a_writel(g, fb_fbpa_fbio_delay_r(), + set_field(old_fbio_delay, + fb_fbpa_fbio_delay_priv_m(), + fb_fbpa_fbio_delay_priv_f(shadow_idx))); + + status = g->ops.bios.execute_script(g, script_ptr); + if (status < 0) { + gk20a_writel(g, fb_fbpa_fbio_delay_r(), + old_fbio_delay); + goto done; + } + + gk20a_writel(g, fb_fbpa_fbio_delay_r(), old_fbio_delay); + + } + + cmd_script_index = BIOS_GET_FIELD(memclock_base_entry.flags2, + VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX); + + cmd_script_ptr = gm206_bios_read_u32(g, + memclock_table_header.cmd_script_list_ptr + + cmd_script_index * sizeof(u32)); + + if (!cmd_script_ptr) + continue; + + /* Link and execute cmd shadow scripts */ + for (cmd_idx = 0; cmd_idx <= fb_fbpa_fbio_cmd_delay_cmd_priv_max_v(); + ++cmd_idx) { + if (cmd_script_ptr == idx_to_cmd_ptr_tbl[cmd_idx]) + break; + } + + /* script has not been executed before */ + if (cmd_idx > fb_fbpa_fbio_cmd_delay_cmd_priv_max_v()) { + /* find unused index */ + for (cmd_idx = 0; cmd_idx < + fb_fbpa_fbio_cmd_delay_cmd_priv_max_v(); + ++cmd_idx) { + if (idx_to_cmd_ptr_tbl[cmd_idx] == 0) + break; + } + + if (cmd_idx > fb_fbpa_fbio_cmd_delay_cmd_priv_max_v()) { + gk20a_err(dev_from_gk20a(g), + "invalid shadow reg cmd script index"); + status = -EINVAL; + goto done; + } + + idx_to_cmd_ptr_tbl[cmd_idx] = cmd_script_ptr; + gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(), + set_field(old_fbio_cmd_delay, + fb_fbpa_fbio_cmd_delay_cmd_priv_m(), + fb_fbpa_fbio_cmd_delay_cmd_priv_f( + cmd_idx))); + + status = g->ops.bios.execute_script(g, cmd_script_ptr); + if (status < 0) { + gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(), + old_fbio_cmd_delay); + goto done; + } + + gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(), + old_fbio_cmd_delay); + + } + + mem_entry_ptr += memclock_table_header.base_entry_size + + memclock_table_header.strap_entry_count * + memclock_table_header.strap_entry_size; + } + +done: + return status; +} + int clk_mclkseq_init_mclk_gddr5(struct gk20a *g) { struct clk_mclk_state *mclk; + int status; gk20a_dbg_fn(""); @@ -2094,8 +2195,10 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g) mclk->speed = gk20a_mclk_low_speed; /* Value from Devinit */ - /* Load Shadow registers */ - mclk_memory_load_shadow_regs(g); + /* Parse VBIOS */ + status = mclk_get_memclk_table(g); + if (status < 0) + return status; /* Load RAM pattern */ mclk_memory_load_training_pattern(g); @@ -2115,6 +2218,8 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g) #endif mclk->change = clk_mclkseq_change_mclk_gddr5; + mclk->init = true; + return mclk->change(g, DEFAULT_BOOT_MCLK_SPEED); } @@ -2125,7 +2230,7 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, enum gk20a_mclk_speed speed) struct nv_pmu_seq_cmd cmd; struct nv_pmu_seq_cmd_run_script *pseq_cmd; u32 seqdesc; - u32 status = 0; + int status = 0; u32 seq_completion_status = ~0x0; u8 *seq_script_ptr = NULL; size_t seq_script_size = 0; @@ -2139,6 +2244,9 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, enum gk20a_mclk_speed speed) mutex_lock(&mclk->mclk_mutex); + if (!mclk->init) + goto exit_status; + if (speed == mclk->speed) goto exit_status; diff --git a/drivers/gpu/nvgpu/clk/clk_mclk.h b/drivers/gpu/nvgpu/clk/clk_mclk.h index c3261eac..edb7eb78 100644 --- a/drivers/gpu/nvgpu/clk/clk_mclk.h +++ b/drivers/gpu/nvgpu/clk/clk_mclk.h @@ -19,13 +19,14 @@ enum gk20a_mclk_speed { gk20a_mclk_low_speed, gk20a_mclk_mid_speed, - gk20a_mclk_high_speed + gk20a_mclk_high_speed, }; struct clk_mclk_state { enum gk20a_mclk_speed speed; struct mutex mclk_mutex; void *vreg_buf; + bool init; /* function pointers */ int (*change)(struct gk20a *g, enum gk20a_mclk_speed speed); diff --git a/drivers/gpu/nvgpu/gp106/bios_gp106.c b/drivers/gpu/nvgpu/gp106/bios_gp106.c new file mode 100644 index 00000000..8be4314d --- /dev/null +++ b/drivers/gpu/nvgpu/gp106/bios_gp106.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "gk20a/gk20a.h" +#include "gm206/bios_gm206.h" +#include "bios_gp106.h" +#include "hw_gc6_gp106.h" + +static void gp106_init_xmemsel_zm_nv_reg_array(struct gk20a *g, bool *condition, + u32 reg, u32 stride, u32 count, u32 data_table_offset) +{ + u8 i; + u32 data, strap, index; + + if (*condition) { + + strap = gk20a_readl(g, gc6_sci_strap_r()) & 0xf; + + index = g->bios.mem_strap_xlat_tbl_ptr ? + gm206_bios_read_u8(g, g->bios.mem_strap_xlat_tbl_ptr + + strap) : strap; + + for (i = 0; i < count; i++) { + data = gm206_bios_read_u32(g, data_table_offset + ((i * + g->bios.mem_strap_data_count + index) * + sizeof(u32))); + gk20a_writel(g, reg, data); + reg += stride; + } + } +} + +static void gp106_init_condition(struct gk20a *g, bool *condition, + u32 condition_id) +{ + struct condition_entry entry; + + entry.cond_addr = gm206_bios_read_u32(g, g->bios.condition_table_ptr + + sizeof(entry)*condition_id); + entry.cond_mask = gm206_bios_read_u32(g, g->bios.condition_table_ptr + + sizeof(entry)*condition_id + 4); + entry.cond_compare = gm206_bios_read_u32(g, g->bios.condition_table_ptr + + sizeof(entry)*condition_id + 8); + + if ((gk20a_readl(g, entry.cond_addr) & entry.cond_mask) + != entry.cond_compare) { + *condition = false; + } +} + +static int gp106_execute_script(struct gk20a *g, u32 offset) +{ + u8 opcode; + u32 ip; + u32 operand[8]; + bool condition, end; + int status = 0; + + ip = offset; + condition = true; + end = false; + + while (!end) { + + opcode = gm206_bios_read_u8(g, ip++); + + switch (opcode) { + + case INIT_XMEMSEL_ZM_NV_REG_ARRAY: + operand[0] = gm206_bios_read_u32(g, ip); + operand[1] = gm206_bios_read_u8(g, ip+4); + operand[2] = gm206_bios_read_u8(g, ip+5); + ip += 6; + + gp106_init_xmemsel_zm_nv_reg_array(g, &condition, + operand[0], operand[1], operand[2], ip); + ip += operand[2] * sizeof(u32) * + g->bios.mem_strap_data_count; + break; + + case INIT_CONDITION: + operand[0] = gm206_bios_read_u8(g, ip); + ip++; + + gp106_init_condition(g, &condition, operand[0]); + break; + + case INIT_RESUME: + condition = true; + break; + + case INIT_DONE: + end = true; + break; + + default: + gk20a_err(dev_from_gk20a(g), "opcode: 0x%02x", opcode); + end = true; + status = -EINVAL; + break; + } + } + + return status; +} + +void gp106_init_bios(struct gpu_ops *gops) +{ + gm206_init_bios(gops); + gops->bios.execute_script = gp106_execute_script; +} diff --git a/drivers/gpu/nvgpu/gp106/bios_gp106.h b/drivers/gpu/nvgpu/gp106/bios_gp106.h new file mode 100644 index 00000000..f47d11ca --- /dev/null +++ b/drivers/gpu/nvgpu/gp106/bios_gp106.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef NVGPU_BIOS_GP106_H +#define NVGPU_BIOS_GP106_H + +struct gpu_ops; + +#define INIT_DONE 0x71 +#define INIT_RESUME 0x72 +#define INIT_CONDITION 0x75 +#define INIT_XMEMSEL_ZM_NV_REG_ARRAY 0x8f + +struct condition_entry { + u32 cond_addr; + u32 cond_mask; + u32 cond_compare; +} __packed; + +void gp106_init_bios(struct gpu_ops *gops); +#endif diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index 2217dfea..89e0e1fd 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c @@ -31,7 +31,7 @@ #include "gp106/therm_gp106.h" #include "gp106/xve_gp106.h" -#include "gm206/bios_gm206.h" +#include "gp106/bios_gp106.h" #include "gm20b/gr_gm20b.h" #include "gm20b/fifo_gm20b.h" @@ -209,7 +209,7 @@ int gp106_init_hal(struct gk20a *g) #if defined(CONFIG_GK20A_CYCLE_STATS) gk20a_init_css_ops(gops); #endif - gm206_init_bios(gops); + gp106_init_bios(gops); gp106_init_therm_ops(gops); gp106_init_xve_ops(gops); diff --git a/drivers/gpu/nvgpu/gp106/hw_fb_gp106.h b/drivers/gpu/nvgpu/gp106/hw_fb_gp106.h index 1ab876cd..d76f78b9 100644 --- a/drivers/gpu/nvgpu/gp106/hw_fb_gp106.h +++ b/drivers/gpu/nvgpu/gp106/hw_fb_gp106.h @@ -502,4 +502,76 @@ static inline u32 fb_mmu_local_memory_range_ecc_mode_v(u32 r) { return (r >> 30) & 0x1; } +static inline u32 fb_fbpa_fbio_delay_r(void) +{ + return 0x9a065c; +} +static inline u32 fb_fbpa_fbio_delay_src_m(void) +{ + return 0x7; +} +static inline u32 fb_fbpa_fbio_delay_src_v(u32 r) +{ + return (r >> 0) & 0x7; +} +static inline u32 fb_fbpa_fbio_delay_src_f(u32 v) +{ + return (v & 0x7) << 0; +} +static inline u32 fb_fbpa_fbio_delay_src_max_v(void) +{ + return 2; +} +static inline u32 fb_fbpa_fbio_delay_priv_m(void) +{ + return 0x7 << 4; +} +static inline u32 fb_fbpa_fbio_delay_priv_v(u32 r) +{ + return (r >> 4) & 0x7; +} +static inline u32 fb_fbpa_fbio_delay_priv_f(u32 v) +{ + return (v & 0x7) << 4; +} +static inline u32 fb_fbpa_fbio_delay_priv_max_v(void) +{ + return 2; +} +static inline u32 fb_fbpa_fbio_cmd_delay_r(void) +{ + return 0x9a08e0; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_m(void) +{ + return 0x7; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_v(u32 r) +{ + return (r >> 0) & 0x7; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_f(u32 v) +{ + return (v & 0x7) << 0; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_max_v(void) +{ + return 1; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_m(void) +{ + return 0x7 << 4; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_v(u32 r) +{ + return (r >> 4) & 0x7; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_f(u32 v) +{ + return (v & 0x7) << 4; +} +static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_max_v(void) +{ + return 1; +} #endif diff --git a/drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h b/drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h new file mode 100644 index 00000000..25aca9b5 --- /dev/null +++ b/drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_gc6_gp106_h_ +#define _hw_gc6_gp106_h_ +static inline u32 gc6_sci_strap_r(void) +{ + return 0x00010ebb0; +} +#endif diff --git a/drivers/gpu/nvgpu/include/bios.h b/drivers/gpu/nvgpu/include/bios.h index 3af5bcf4..83d972e3 100644 --- a/drivers/gpu/nvgpu/include/bios.h +++ b/drivers/gpu/nvgpu/include/bios.h @@ -408,4 +408,98 @@ struct vfield_entry { u16 strap_desc; } __packed; +#define PERF_CLK_DOMAINS_IDX_MAX (32) +#define PERF_CLK_DOMAINS_IDX_INVALID PERF_CLK_DOMAINS_IDX_MAX + +#define VBIOS_PSTATE_TABLE_VERSION_5X 0x50 +#define VBIOS_PSTATE_HEADER_5X_SIZE_10 (10) + +struct vbios_pstate_header_5x { + u8 version; + u8 header_size; + u8 base_entry_size; + u8 base_entry_count; + u8 clock_entry_size; + u8 clock_entry_count; + u8 flags0; + u8 initial_pstate; + u8 cpi_support_level; +u8 cpi_features; +} __packed; + +#define VBIOS_PSTATE_CLOCK_ENTRY_5X_SIZE_6 6 + +#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_2 0x2 +#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_3 0x3 + +struct vbios_pstate_entry_clock_5x { + u16 param0; + u32 param1; +} __packed; + +struct vbios_pstate_entry_5x { + u8 pstate_level; + u8 flags0; + u8 lpwr_entry_idx; + struct vbios_pstate_entry_clock_5x clockEntry[PERF_CLK_DOMAINS_IDX_MAX]; +} __packed; + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_SHIFT 0 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_MASK 0x00003FFF + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_SHIFT 0 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_MASK 0x00003FFF + +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_SHIFT 14 +#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_MASK 0x0FFFC000 + +#define VBIOS_PERFLEVEL_SKIP_ENTRY 0xFF + +#define VBIOS_MEMORY_CLOCK_HEADER_11_VERSION 0x11 + +#define VBIOS_MEMORY_CLOCK_HEADER_11_0_SIZE 16 +#define VBIOS_MEMORY_CLOCK_HEADER_11_1_SIZE 21 +#define VBIOS_MEMORY_CLOCK_HEADER_11_2_SIZE 26 + +struct vbios_memory_clock_header_1x { + u8 version; + u8 header_size; + u8 base_entry_size; + u8 strap_entry_size; + u8 strap_entry_count; + u8 entry_count; + u8 flags; + u8 fbvdd_settle_time; + u32 cfg_pwrd_val; + u16 fbvddq_high; + u16 fbvddq_low; + u32 script_list_ptr; + u8 script_list_count; + u32 cmd_script_list_ptr; + u8 cmd_script_list_count; +} __packed; + +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_2_SIZE 20 + +struct vbios_memory_clock_base_entry_11 { + u16 minimum; + u16 maximum; + u32 script_pointer; + u8 flags0; + u32 fbpa_config; + u32 fbpa_config1; + u8 flags1; + u8 ref_mpllssf_freq_delta; + u8 flags2; +} __packed; + +/* Script Pointer Index */ +/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX 3:2*/ +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_MASK 0xc +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_SHIFT 2 +/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX 1:0*/ +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_MASK 0x3 +#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_SHIFT 0 + #endif + -- cgit v1.2.2