diff options
author | David Nieto <dmartineznie@nvidia.com> | 2016-08-19 20:09:35 -0400 |
---|---|---|
committer | Deepak Nibade <dnibade@nvidia.com> | 2016-12-27 04:56:50 -0500 |
commit | 905f1c0392bf244b321f56f82661eeb2fe00ee05 (patch) | |
tree | d525a6d5554b537e0a34ca7917c90364176dbb2e /drivers/gpu/nvgpu/gp106/bios_gp106.c | |
parent | 4a94ce451b0352ce67e11a2971bbbd75c2e58df1 (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>
Diffstat (limited to 'drivers/gpu/nvgpu/gp106/bios_gp106.c')
-rw-r--r-- | drivers/gpu/nvgpu/gp106/bios_gp106.c | 121 |
1 files changed, 121 insertions, 0 deletions
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 | |||
19 | static 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 | |||
43 | static 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 | |||
61 | static 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 | |||
117 | void gp106_init_bios(struct gpu_ops *gops) | ||
118 | { | ||
119 | gm206_init_bios(gops); | ||
120 | gops->bios.execute_script = gp106_execute_script; | ||
121 | } | ||