summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2016-08-19 20:09:35 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:50 -0500
commit905f1c0392bf244b321f56f82661eeb2fe00ee05 (patch)
treed525a6d5554b537e0a34ca7917c90364176dbb2e
parent4a94ce451b0352ce67e11a2971bbbd75c2e58df1 (diff)
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 <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1214956 Reviewed-on: http://git-master/r/1237293 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/Makefile.nvgpu-t18x1
-rw-r--r--drivers/gpu/nvgpu/clk/clk_mclk.c278
-rw-r--r--drivers/gpu/nvgpu/clk/clk_mclk.h3
-rw-r--r--drivers/gpu/nvgpu/gp106/bios_gp106.c121
-rw-r--r--drivers/gpu/nvgpu/gp106/bios_gp106.h31
-rw-r--r--drivers/gpu/nvgpu/gp106/hal_gp106.c4
-rw-r--r--drivers/gpu/nvgpu/gp106/hw_fb_gp106.h72
-rw-r--r--drivers/gpu/nvgpu/gp106/hw_gc6_gp106.h56
-rw-r--r--drivers/gpu/nvgpu/include/bios.h94
9 files changed, 572 insertions, 88 deletions
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 += \
29 $(nvgpu-t18x)/gp106/fifo_gp106.o \ 29 $(nvgpu-t18x)/gp106/fifo_gp106.o \
30 $(nvgpu-t18x)/gp106/ltc_gp106.o \ 30 $(nvgpu-t18x)/gp106/ltc_gp106.o \
31 $(nvgpu-t18x)/gp106/fb_gp106.o \ 31 $(nvgpu-t18x)/gp106/fb_gp106.o \
32 $(nvgpu-t18x)/gp106/bios_gp106.o \
32 $(nvgpu-t18x)/clk/clk_mclk.o \ 33 $(nvgpu-t18x)/clk/clk_mclk.o \
33 $(nvgpu-t18x)/pstate/pstate.o \ 34 $(nvgpu-t18x)/pstate/pstate.o \
34 $(nvgpu-t18x)/clk/clk_vin.o \ 35 $(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 @@
17#include "gm206/bios_gm206.h" 17#include "gm206/bios_gm206.h"
18#include "gk20a/pmu_gk20a.h" 18#include "gk20a/pmu_gk20a.h"
19#include "gk20a/hw_pwr_gk20a.h" 19#include "gk20a/hw_pwr_gk20a.h"
20#include "gp106/hw_fb_gp106.h"
21
22#include "include/bios.h"
20 23
21#define VREG_COUNT 24 24#define VREG_COUNT 24
22 25
@@ -29,63 +32,6 @@ struct memory_link_training_pattern {
29 u32 writeval; 32 u32 writeval;
30}; 33};
31 34
32static struct memory_link_training_pattern memory_shadow_p0_reglist[] = {
33 {0x9a065c, 0x20},
34 {0x98467c, 0xffff0000},
35 {0x984708, 0x30550},
36 {0x98470c, 0x4C4C},
37 {0x9006a0, 0x03030303},
38 {0x9006a4, 0x03030303},
39 {0x9046a0, 0x03030303},
40 {0x9046a4, 0x03030303},
41 {0x9086a0, 0x03030303},
42 {0x9086a4, 0x03030303},
43 {0x9846a8, 0x03030303},
44 {0x9846ac, 0x03030303},
45 {0x9a065c, 0x00},
46};
47
48static struct memory_link_training_pattern memory_shadow_p5_reglist[] = {
49 {0x9a065c, 0x10},
50 {0x98467c, 0xfff10000},
51 {0x984708, 0x30002},
52 {0x98470c, 0x1414},
53 {0x9006a0, 0x12121212},
54 {0x9006a4, 0x12121212},
55 {0x9046a0, 0x12121212},
56 {0x9046a4, 0x12121212},
57 {0x9086a0, 0x12121212},
58 {0x9086a4, 0x12121212},
59 {0x90c6a0, 0x12121212},
60 {0x90c6a4, 0x12121212},
61 {0x9106a0, 0x12121212},
62 {0x9106a4, 0x12121212},
63 {0x9146a0, 0x12121212},
64 {0x9146a4, 0x12121212},
65 {0x9a065c, 0x0},
66 {0x9a08e0, 0x10},
67 {0x9846a8, 0x0f0f0f0f},
68 {0x9846ac, 0x0f0f0f0f},
69 {0x984d98, 0x22222222},
70 {0x984d9c, 0x22222222},
71 {0x984da0, 0x22222222},
72 {0x984da4, 0x22222222},
73 {0x984da8, 0x22222222},
74 {0x984dac, 0x22222222},
75 {0x984dac, 0x22222222},
76 {0x984d70, 0x0},
77 {0x984d74, 0x0},
78 {0x984d78, 0x0},
79 {0x984d7c, 0x0},
80 {0x984d80, 0x0},
81 {0x984d84, 0x0},
82 {0x984d88, 0x0},
83 {0x984d8c, 0x0},
84 {0x984d90, 0x0},
85 {0x984d94, 0x0},
86 {0x9a08e0, 0x0},
87};
88
89static struct memory_link_training_pattern memory_pattern_reglist[] = { 35static struct memory_link_training_pattern memory_pattern_reglist[] = {
90 {0x9a0968, 0x0}, 36 {0x9a0968, 0x0},
91 {0x9a0920, 0x0}, 37 {0x9a0920, 0x0},
@@ -2026,31 +1972,6 @@ static void mclk_memory_load_training_pattern(struct gk20a *g)
2026 gk20a_dbg_fn("done"); 1972 gk20a_dbg_fn("done");
2027} 1973}
2028 1974
2029static void mclk_memory_load_shadow_regs(struct gk20a *g)
2030{
2031 u32 reg_writes;
2032 u32 index;
2033
2034 gk20a_dbg_info("");
2035
2036 reg_writes = ((sizeof(memory_shadow_p0_reglist) /
2037 sizeof((memory_shadow_p0_reglist)[0])));
2038 for (index = 0; index < reg_writes; index++) {
2039 gk20a_writel(g, memory_shadow_p0_reglist[index].regaddr,
2040 memory_shadow_p0_reglist[index].writeval);
2041 }
2042
2043 reg_writes = ((sizeof(memory_shadow_p5_reglist) /
2044 sizeof((memory_shadow_p5_reglist)[0])));
2045 for (index = 0; index < reg_writes; index++) {
2046 gk20a_writel(g, memory_shadow_p5_reglist[index].regaddr,
2047 memory_shadow_p5_reglist[index].writeval);
2048 }
2049
2050 gk20a_dbg_fn("done");
2051
2052}
2053
2054static void mclk_seq_pmucmdhandler(struct gk20a *g, struct pmu_msg *_msg, 1975static void mclk_seq_pmucmdhandler(struct gk20a *g, struct pmu_msg *_msg,
2055 void *param, u32 handle, u32 status) 1976 void *param, u32 handle, u32 status)
2056{ 1977{
@@ -2082,9 +2003,189 @@ status_update:
2082 *((u32 *)param) = msg_status; 2003 *((u32 *)param) = msg_status;
2083} 2004}
2084 2005
2006static int mclk_get_memclk_table(struct gk20a *g)
2007{
2008 int status = 0;
2009 u8 *mem_table_ptr = NULL;
2010 u32 idx_to_ptr_tbl[8];
2011 u32 idx_to_cmd_ptr_tbl[8];
2012
2013 u32 old_fbio_delay;
2014 u32 old_fbio_cmd_delay;
2015
2016 u32 cmd_idx;
2017 u32 shadow_idx;
2018
2019 struct vbios_memory_clock_header_1x memclock_table_header = { 0 };
2020 struct vbios_memory_clock_base_entry_11 memclock_base_entry = { 0 };
2021
2022 u8 *mem_entry_ptr = NULL;
2023 int index;
2024
2025 gk20a_dbg_info("");
2026
2027 if (!(g->ops.bios.get_perf_table_ptrs &&
2028 g->ops.bios.execute_script)) {
2029 goto done;
2030 }
2031
2032 mem_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g,
2033 g->bios.perf_token,
2034 MEMORY_CLOCK_TABLE);
2035 if (mem_table_ptr == NULL) {
2036 status = -EPERM;
2037 goto done;
2038 }
2039
2040 memcpy(&memclock_table_header, mem_table_ptr,
2041 sizeof(memclock_table_header));
2042
2043 if ((memclock_table_header.version <
2044 VBIOS_MEMORY_CLOCK_HEADER_11_VERSION) ||
2045 (memclock_table_header.base_entry_size <
2046 VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_2_SIZE)) {
2047 status = -EINVAL;
2048 goto done;
2049 }
2050
2051 /* reset and save shadow table map and registers */
2052 old_fbio_delay = gk20a_readl(g, fb_fbpa_fbio_delay_r());
2053 old_fbio_cmd_delay = gk20a_readl(g, fb_fbpa_fbio_cmd_delay_r());
2054
2055 memset(idx_to_ptr_tbl, 0, sizeof(idx_to_ptr_tbl));
2056 memset(idx_to_cmd_ptr_tbl, 0, sizeof(idx_to_cmd_ptr_tbl));
2057
2058 /* Read table entries */
2059 mem_entry_ptr = mem_table_ptr + memclock_table_header.header_size;
2060 for (index = 0; index < memclock_table_header.entry_count; index++) {
2061 u8 script_index, cmd_script_index;
2062 u32 script_ptr = 0, cmd_script_ptr = 0;
2063
2064 memcpy(&memclock_base_entry, mem_entry_ptr,
2065 memclock_table_header.base_entry_size);
2066 if (memclock_base_entry.maximum == 0)
2067 continue;
2068
2069 script_index = BIOS_GET_FIELD(memclock_base_entry.flags1,
2070 VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX);
2071
2072 script_ptr = gm206_bios_read_u32(g,
2073 memclock_table_header.script_list_ptr +
2074 script_index * sizeof(u32));
2075
2076 if (!script_ptr)
2077 continue;
2078
2079 /* Link and execute shadow scripts */
2080
2081 for (shadow_idx = 0; shadow_idx <= fb_fbpa_fbio_delay_priv_max_v();
2082 ++shadow_idx) {
2083 if (script_ptr == idx_to_ptr_tbl[shadow_idx]) {
2084 break;
2085 }
2086 }
2087
2088 /* script has not been executed before */
2089 if (shadow_idx > fb_fbpa_fbio_delay_priv_max_v()) {
2090 /* find unused index */
2091 for (shadow_idx = 0; shadow_idx <
2092 fb_fbpa_fbio_delay_priv_max_v();
2093 ++shadow_idx) {
2094 if (idx_to_ptr_tbl[shadow_idx] == 0)
2095 break;
2096 }
2097
2098 if (shadow_idx > fb_fbpa_fbio_delay_priv_max_v()) {
2099 gk20a_err(dev_from_gk20a(g),
2100 "invalid shadow reg script index");
2101 status = -EINVAL;
2102 goto done;
2103 }
2104
2105 idx_to_ptr_tbl[shadow_idx] = script_ptr;
2106
2107 gk20a_writel(g, fb_fbpa_fbio_delay_r(),
2108 set_field(old_fbio_delay,
2109 fb_fbpa_fbio_delay_priv_m(),
2110 fb_fbpa_fbio_delay_priv_f(shadow_idx)));
2111
2112 status = g->ops.bios.execute_script(g, script_ptr);
2113 if (status < 0) {
2114 gk20a_writel(g, fb_fbpa_fbio_delay_r(),
2115 old_fbio_delay);
2116 goto done;
2117 }
2118
2119 gk20a_writel(g, fb_fbpa_fbio_delay_r(), old_fbio_delay);
2120
2121 }
2122
2123 cmd_script_index = BIOS_GET_FIELD(memclock_base_entry.flags2,
2124 VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX);
2125
2126 cmd_script_ptr = gm206_bios_read_u32(g,
2127 memclock_table_header.cmd_script_list_ptr +
2128 cmd_script_index * sizeof(u32));
2129
2130 if (!cmd_script_ptr)
2131 continue;
2132
2133 /* Link and execute cmd shadow scripts */
2134 for (cmd_idx = 0; cmd_idx <= fb_fbpa_fbio_cmd_delay_cmd_priv_max_v();
2135 ++cmd_idx) {
2136 if (cmd_script_ptr == idx_to_cmd_ptr_tbl[cmd_idx])
2137 break;
2138 }
2139
2140 /* script has not been executed before */
2141 if (cmd_idx > fb_fbpa_fbio_cmd_delay_cmd_priv_max_v()) {
2142 /* find unused index */
2143 for (cmd_idx = 0; cmd_idx <
2144 fb_fbpa_fbio_cmd_delay_cmd_priv_max_v();
2145 ++cmd_idx) {
2146 if (idx_to_cmd_ptr_tbl[cmd_idx] == 0)
2147 break;
2148 }
2149
2150 if (cmd_idx > fb_fbpa_fbio_cmd_delay_cmd_priv_max_v()) {
2151 gk20a_err(dev_from_gk20a(g),
2152 "invalid shadow reg cmd script index");
2153 status = -EINVAL;
2154 goto done;
2155 }
2156
2157 idx_to_cmd_ptr_tbl[cmd_idx] = cmd_script_ptr;
2158 gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(),
2159 set_field(old_fbio_cmd_delay,
2160 fb_fbpa_fbio_cmd_delay_cmd_priv_m(),
2161 fb_fbpa_fbio_cmd_delay_cmd_priv_f(
2162 cmd_idx)));
2163
2164 status = g->ops.bios.execute_script(g, cmd_script_ptr);
2165 if (status < 0) {
2166 gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(),
2167 old_fbio_cmd_delay);
2168 goto done;
2169 }
2170
2171 gk20a_writel(g, fb_fbpa_fbio_cmd_delay_r(),
2172 old_fbio_cmd_delay);
2173
2174 }
2175
2176 mem_entry_ptr += memclock_table_header.base_entry_size +
2177 memclock_table_header.strap_entry_count *
2178 memclock_table_header.strap_entry_size;
2179 }
2180
2181done:
2182 return status;
2183}
2184
2085int clk_mclkseq_init_mclk_gddr5(struct gk20a *g) 2185int clk_mclkseq_init_mclk_gddr5(struct gk20a *g)
2086{ 2186{
2087 struct clk_mclk_state *mclk; 2187 struct clk_mclk_state *mclk;
2188 int status;
2088 2189
2089 gk20a_dbg_fn(""); 2190 gk20a_dbg_fn("");
2090 2191
@@ -2094,8 +2195,10 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g)
2094 2195
2095 mclk->speed = gk20a_mclk_low_speed; /* Value from Devinit */ 2196 mclk->speed = gk20a_mclk_low_speed; /* Value from Devinit */
2096 2197
2097 /* Load Shadow registers */ 2198 /* Parse VBIOS */
2098 mclk_memory_load_shadow_regs(g); 2199 status = mclk_get_memclk_table(g);
2200 if (status < 0)
2201 return status;
2099 2202
2100 /* Load RAM pattern */ 2203 /* Load RAM pattern */
2101 mclk_memory_load_training_pattern(g); 2204 mclk_memory_load_training_pattern(g);
@@ -2115,6 +2218,8 @@ int clk_mclkseq_init_mclk_gddr5(struct gk20a *g)
2115#endif 2218#endif
2116 mclk->change = clk_mclkseq_change_mclk_gddr5; 2219 mclk->change = clk_mclkseq_change_mclk_gddr5;
2117 2220
2221 mclk->init = true;
2222
2118 return mclk->change(g, DEFAULT_BOOT_MCLK_SPEED); 2223 return mclk->change(g, DEFAULT_BOOT_MCLK_SPEED);
2119} 2224}
2120 2225
@@ -2125,7 +2230,7 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, enum gk20a_mclk_speed speed)
2125 struct nv_pmu_seq_cmd cmd; 2230 struct nv_pmu_seq_cmd cmd;
2126 struct nv_pmu_seq_cmd_run_script *pseq_cmd; 2231 struct nv_pmu_seq_cmd_run_script *pseq_cmd;
2127 u32 seqdesc; 2232 u32 seqdesc;
2128 u32 status = 0; 2233 int status = 0;
2129 u32 seq_completion_status = ~0x0; 2234 u32 seq_completion_status = ~0x0;
2130 u8 *seq_script_ptr = NULL; 2235 u8 *seq_script_ptr = NULL;
2131 size_t seq_script_size = 0; 2236 size_t seq_script_size = 0;
@@ -2139,6 +2244,9 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, enum gk20a_mclk_speed speed)
2139 2244
2140 mutex_lock(&mclk->mclk_mutex); 2245 mutex_lock(&mclk->mclk_mutex);
2141 2246
2247 if (!mclk->init)
2248 goto exit_status;
2249
2142 if (speed == mclk->speed) 2250 if (speed == mclk->speed)
2143 goto exit_status; 2251 goto exit_status;
2144 2252
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 @@
19enum gk20a_mclk_speed { 19enum gk20a_mclk_speed {
20 gk20a_mclk_low_speed, 20 gk20a_mclk_low_speed,
21 gk20a_mclk_mid_speed, 21 gk20a_mclk_mid_speed,
22 gk20a_mclk_high_speed 22 gk20a_mclk_high_speed,
23}; 23};
24 24
25struct clk_mclk_state { 25struct clk_mclk_state {
26 enum gk20a_mclk_speed speed; 26 enum gk20a_mclk_speed speed;
27 struct mutex mclk_mutex; 27 struct mutex mclk_mutex;
28 void *vreg_buf; 28 void *vreg_buf;
29 bool init;
29 30
30 /* function pointers */ 31 /* function pointers */
31 int (*change)(struct gk20a *g, enum gk20a_mclk_speed speed); 32 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 @@
1/*
2 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#include "gk20a/gk20a.h"
15#include "gm206/bios_gm206.h"
16#include "bios_gp106.h"
17#include "hw_gc6_gp106.h"
18
19static void gp106_init_xmemsel_zm_nv_reg_array(struct gk20a *g, bool *condition,
20 u32 reg, u32 stride, u32 count, u32 data_table_offset)
21{
22 u8 i;
23 u32 data, strap, index;
24
25 if (*condition) {
26
27 strap = gk20a_readl(g, gc6_sci_strap_r()) & 0xf;
28
29 index = g->bios.mem_strap_xlat_tbl_ptr ?
30 gm206_bios_read_u8(g, g->bios.mem_strap_xlat_tbl_ptr +
31 strap) : strap;
32
33 for (i = 0; i < count; i++) {
34 data = gm206_bios_read_u32(g, data_table_offset + ((i *
35 g->bios.mem_strap_data_count + index) *
36 sizeof(u32)));
37 gk20a_writel(g, reg, data);
38 reg += stride;
39 }
40 }
41}
42
43static void gp106_init_condition(struct gk20a *g, bool *condition,
44 u32 condition_id)
45{
46 struct condition_entry entry;
47
48 entry.cond_addr = gm206_bios_read_u32(g, g->bios.condition_table_ptr +
49 sizeof(entry)*condition_id);
50 entry.cond_mask = gm206_bios_read_u32(g, g->bios.condition_table_ptr +
51 sizeof(entry)*condition_id + 4);
52 entry.cond_compare = gm206_bios_read_u32(g, g->bios.condition_table_ptr +
53 sizeof(entry)*condition_id + 8);
54
55 if ((gk20a_readl(g, entry.cond_addr) & entry.cond_mask)
56 != entry.cond_compare) {
57 *condition = false;
58 }
59}
60
61static int gp106_execute_script(struct gk20a *g, u32 offset)
62{
63 u8 opcode;
64 u32 ip;
65 u32 operand[8];
66 bool condition, end;
67 int status = 0;
68
69 ip = offset;
70 condition = true;
71 end = false;
72
73 while (!end) {
74
75 opcode = gm206_bios_read_u8(g, ip++);
76
77 switch (opcode) {
78
79 case INIT_XMEMSEL_ZM_NV_REG_ARRAY:
80 operand[0] = gm206_bios_read_u32(g, ip);
81 operand[1] = gm206_bios_read_u8(g, ip+4);
82 operand[2] = gm206_bios_read_u8(g, ip+5);
83 ip += 6;
84
85 gp106_init_xmemsel_zm_nv_reg_array(g, &condition,
86 operand[0], operand[1], operand[2], ip);
87 ip += operand[2] * sizeof(u32) *
88 g->bios.mem_strap_data_count;
89 break;
90
91 case INIT_CONDITION:
92 operand[0] = gm206_bios_read_u8(g, ip);
93 ip++;
94
95 gp106_init_condition(g, &condition, operand[0]);
96 break;
97
98 case INIT_RESUME:
99 condition = true;
100 break;
101
102 case INIT_DONE:
103 end = true;
104 break;
105
106 default:
107 gk20a_err(dev_from_gk20a(g), "opcode: 0x%02x", opcode);
108 end = true;
109 status = -EINVAL;
110 break;
111 }
112 }
113
114 return status;
115}
116
117void gp106_init_bios(struct gpu_ops *gops)
118{
119 gm206_init_bios(gops);
120 gops->bios.execute_script = gp106_execute_script;
121}
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 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#ifndef NVGPU_BIOS_GP106_H
15#define NVGPU_BIOS_GP106_H
16
17struct gpu_ops;
18
19#define INIT_DONE 0x71
20#define INIT_RESUME 0x72
21#define INIT_CONDITION 0x75
22#define INIT_XMEMSEL_ZM_NV_REG_ARRAY 0x8f
23
24struct condition_entry {
25 u32 cond_addr;
26 u32 cond_mask;
27 u32 cond_compare;
28} __packed;
29
30void gp106_init_bios(struct gpu_ops *gops);
31#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 @@
31#include "gp106/therm_gp106.h" 31#include "gp106/therm_gp106.h"
32#include "gp106/xve_gp106.h" 32#include "gp106/xve_gp106.h"
33 33
34#include "gm206/bios_gm206.h" 34#include "gp106/bios_gp106.h"
35 35
36#include "gm20b/gr_gm20b.h" 36#include "gm20b/gr_gm20b.h"
37#include "gm20b/fifo_gm20b.h" 37#include "gm20b/fifo_gm20b.h"
@@ -209,7 +209,7 @@ int gp106_init_hal(struct gk20a *g)
209#if defined(CONFIG_GK20A_CYCLE_STATS) 209#if defined(CONFIG_GK20A_CYCLE_STATS)
210 gk20a_init_css_ops(gops); 210 gk20a_init_css_ops(gops);
211#endif 211#endif
212 gm206_init_bios(gops); 212 gp106_init_bios(gops);
213 gp106_init_therm_ops(gops); 213 gp106_init_therm_ops(gops);
214 gp106_init_xve_ops(gops); 214 gp106_init_xve_ops(gops);
215 215
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)
502{ 502{
503 return (r >> 30) & 0x1; 503 return (r >> 30) & 0x1;
504} 504}
505static inline u32 fb_fbpa_fbio_delay_r(void)
506{
507 return 0x9a065c;
508}
509static inline u32 fb_fbpa_fbio_delay_src_m(void)
510{
511 return 0x7;
512}
513static inline u32 fb_fbpa_fbio_delay_src_v(u32 r)
514{
515 return (r >> 0) & 0x7;
516}
517static inline u32 fb_fbpa_fbio_delay_src_f(u32 v)
518{
519 return (v & 0x7) << 0;
520}
521static inline u32 fb_fbpa_fbio_delay_src_max_v(void)
522{
523 return 2;
524}
525static inline u32 fb_fbpa_fbio_delay_priv_m(void)
526{
527 return 0x7 << 4;
528}
529static inline u32 fb_fbpa_fbio_delay_priv_v(u32 r)
530{
531 return (r >> 4) & 0x7;
532}
533static inline u32 fb_fbpa_fbio_delay_priv_f(u32 v)
534{
535 return (v & 0x7) << 4;
536}
537static inline u32 fb_fbpa_fbio_delay_priv_max_v(void)
538{
539 return 2;
540}
541static inline u32 fb_fbpa_fbio_cmd_delay_r(void)
542{
543 return 0x9a08e0;
544}
545static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_m(void)
546{
547 return 0x7;
548}
549static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_v(u32 r)
550{
551 return (r >> 0) & 0x7;
552}
553static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_f(u32 v)
554{
555 return (v & 0x7) << 0;
556}
557static inline u32 fb_fbpa_fbio_cmd_delay_cmd_src_max_v(void)
558{
559 return 1;
560}
561static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_m(void)
562{
563 return 0x7 << 4;
564}
565static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_v(u32 r)
566{
567 return (r >> 4) & 0x7;
568}
569static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_f(u32 v)
570{
571 return (v & 0x7) << 4;
572}
573static inline u32 fb_fbpa_fbio_cmd_delay_cmd_priv_max_v(void)
574{
575 return 1;
576}
505#endif 577#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 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16/*
17 * Function naming determines intended use:
18 *
19 * <x>_r(void) : Returns the offset for register <x>.
20 *
21 * <x>_o(void) : Returns the offset for element <x>.
22 *
23 * <x>_w(void) : Returns the word offset for word (4 byte) element <x>.
24 *
25 * <x>_<y>_s(void) : Returns size of field <y> of register <x> in bits.
26 *
27 * <x>_<y>_f(u32 v) : Returns a value based on 'v' which has been shifted
28 * and masked to place it at field <y> of register <x>. This value
29 * can be |'d with others to produce a full register value for
30 * register <x>.
31 *
32 * <x>_<y>_m(void) : Returns a mask for field <y> of register <x>. This
33 * value can be ~'d and then &'d to clear the value of field <y> for
34 * register <x>.
35 *
36 * <x>_<y>_<z>_f(void) : Returns the constant value <z> after being shifted
37 * to place it at field <y> of register <x>. This value can be |'d
38 * with others to produce a full register value for <x>.
39 *
40 * <x>_<y>_v(u32 r) : Returns the value of field <y> from a full register
41 * <x> value 'r' after being shifted to place its LSB at bit 0.
42 * This value is suitable for direct comparison with other unshifted
43 * values appropriate for use in field <y> of register <x>.
44 *
45 * <x>_<y>_<z>_v(void) : Returns the constant value for <z> defined for
46 * field <y> of register <x>. This value is suitable for direct
47 * comparison with unshifted values appropriate for use in field <y>
48 * of register <x>.
49 */
50#ifndef _hw_gc6_gp106_h_
51#define _hw_gc6_gp106_h_
52static inline u32 gc6_sci_strap_r(void)
53{
54 return 0x00010ebb0;
55}
56#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 {
408 u16 strap_desc; 408 u16 strap_desc;
409} __packed; 409} __packed;
410 410
411#define PERF_CLK_DOMAINS_IDX_MAX (32)
412#define PERF_CLK_DOMAINS_IDX_INVALID PERF_CLK_DOMAINS_IDX_MAX
413
414#define VBIOS_PSTATE_TABLE_VERSION_5X 0x50
415#define VBIOS_PSTATE_HEADER_5X_SIZE_10 (10)
416
417struct vbios_pstate_header_5x {
418 u8 version;
419 u8 header_size;
420 u8 base_entry_size;
421 u8 base_entry_count;
422 u8 clock_entry_size;
423 u8 clock_entry_count;
424 u8 flags0;
425 u8 initial_pstate;
426 u8 cpi_support_level;
427u8 cpi_features;
428} __packed;
429
430#define VBIOS_PSTATE_CLOCK_ENTRY_5X_SIZE_6 6
431
432#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_2 0x2
433#define VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_3 0x3
434
435struct vbios_pstate_entry_clock_5x {
436 u16 param0;
437 u32 param1;
438} __packed;
439
440struct vbios_pstate_entry_5x {
441 u8 pstate_level;
442 u8 flags0;
443 u8 lpwr_entry_idx;
444 struct vbios_pstate_entry_clock_5x clockEntry[PERF_CLK_DOMAINS_IDX_MAX];
445} __packed;
446
447#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_SHIFT 0
448#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_MASK 0x00003FFF
449
450#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_SHIFT 0
451#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ_MASK 0x00003FFF
452
453#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_SHIFT 14
454#define VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ_MASK 0x0FFFC000
455
456#define VBIOS_PERFLEVEL_SKIP_ENTRY 0xFF
457
458#define VBIOS_MEMORY_CLOCK_HEADER_11_VERSION 0x11
459
460#define VBIOS_MEMORY_CLOCK_HEADER_11_0_SIZE 16
461#define VBIOS_MEMORY_CLOCK_HEADER_11_1_SIZE 21
462#define VBIOS_MEMORY_CLOCK_HEADER_11_2_SIZE 26
463
464struct vbios_memory_clock_header_1x {
465 u8 version;
466 u8 header_size;
467 u8 base_entry_size;
468 u8 strap_entry_size;
469 u8 strap_entry_count;
470 u8 entry_count;
471 u8 flags;
472 u8 fbvdd_settle_time;
473 u32 cfg_pwrd_val;
474 u16 fbvddq_high;
475 u16 fbvddq_low;
476 u32 script_list_ptr;
477 u8 script_list_count;
478 u32 cmd_script_list_ptr;
479 u8 cmd_script_list_count;
480} __packed;
481
482#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_2_SIZE 20
483
484struct vbios_memory_clock_base_entry_11 {
485 u16 minimum;
486 u16 maximum;
487 u32 script_pointer;
488 u8 flags0;
489 u32 fbpa_config;
490 u32 fbpa_config1;
491 u8 flags1;
492 u8 ref_mpllssf_freq_delta;
493 u8 flags2;
494} __packed;
495
496/* Script Pointer Index */
497/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX 3:2*/
498#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_MASK 0xc
499#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_11_FLAGS1_SCRIPT_INDEX_SHIFT 2
500/* #define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX 1:0*/
501#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_MASK 0x3
502#define VBIOS_MEMORY_CLOCK_BASE_ENTRY_12_FLAGS2_CMD_SCRIPT_INDEX_SHIFT 0
503
411#endif 504#endif
505