diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev')
49 files changed, 6355 insertions, 3395 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild index ee2c38f50..642d27dc9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild @@ -8,6 +8,7 @@ include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild include $(src)/nvkm/subdev/i2c/Kbuild include $(src)/nvkm/subdev/ibus/Kbuild +include $(src)/nvkm/subdev/iccsense/Kbuild include $(src)/nvkm/subdev/instmem/Kbuild include $(src)/nvkm/subdev/ltc/Kbuild include $(src)/nvkm/subdev/mc/Kbuild @@ -15,6 +16,7 @@ include $(src)/nvkm/subdev/mmu/Kbuild include $(src)/nvkm/subdev/mxm/Kbuild include $(src)/nvkm/subdev/pci/Kbuild include $(src)/nvkm/subdev/pmu/Kbuild +include $(src)/nvkm/subdev/secboot/Kbuild include $(src)/nvkm/subdev/therm/Kbuild include $(src)/nvkm/subdev/timer/Kbuild include $(src)/nvkm/subdev/volt/Kbuild diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild index 64730d5e9..dbcb0ef21 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/Kbuild @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/bios/extdev.o nvkm-y += nvkm/subdev/bios/fan.o nvkm-y += nvkm/subdev/bios/gpio.o nvkm-y += nvkm/subdev/bios/i2c.o +nvkm-y += nvkm/subdev/bios/iccsense.o nvkm-y += nvkm/subdev/bios/image.o nvkm-y += nvkm/subdev/bios/init.o nvkm-y += nvkm/subdev/bios/mxm.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c index c9e6f6ff7..b8578359e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/extdev.c @@ -32,7 +32,7 @@ extdev_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt) u16 dcb, extdev = 0; dcb = dcb_table(bios, &dcb_ver, &dcb_hdr, &dcb_cnt, &dcb_len); - if (!dcb || (dcb_ver != 0x30 && dcb_ver != 0x40)) + if (!dcb || (dcb_ver != 0x30 && dcb_ver != 0x40 && dcb_ver != 0x41)) return 0x0000; extdev = nvbios_rd16(bios, dcb + 18); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c new file mode 100644 index 000000000..084328028 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -0,0 +1,100 @@ +/* + * Copyright 2015 Martin Peres + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Martin Peres + */ +#include <subdev/bios.h> +#include <subdev/bios/bit.h> +#include <subdev/bios/iccsense.h> + +static u16 +nvbios_iccsense_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, + u8 *len) +{ + struct bit_entry bit_P; + u16 iccsense; + + if (bit_entry(bios, 'P', &bit_P) || bit_P.version != 2 || + bit_P.length < 0x2c) + return 0; + + iccsense = nvbios_rd16(bios, bit_P.offset + 0x28); + if (!iccsense) + return 0; + + *ver = nvbios_rd08(bios, iccsense + 0); + switch (*ver) { + case 0x10: + case 0x20: + *hdr = nvbios_rd08(bios, iccsense + 1); + *len = nvbios_rd08(bios, iccsense + 2); + *cnt = nvbios_rd08(bios, iccsense + 3); + return iccsense; + default: + break; + } + + return 0; +} + +int +nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) +{ + struct nvkm_subdev *subdev = &bios->subdev; + u8 ver, hdr, cnt, len, i; + u16 table, entry; + + table = nvbios_iccsense_table(bios, &ver, &hdr, &cnt, &len); + if (!table || !cnt) + return -EINVAL; + + if (ver != 0x10 && ver != 0x20) { + nvkm_error(subdev, "ICCSENSE version 0x%02x unknown\n", ver); + return -EINVAL; + } + + iccsense->nr_entry = cnt; + iccsense->rail = kmalloc(sizeof(struct pwr_rail_t) * cnt, GFP_KERNEL); + if (!iccsense->rail) + return -ENOMEM; + + for (i = 0; i < cnt; ++i) { + struct pwr_rail_t *rail = &iccsense->rail[i]; + entry = table + hdr + i * len; + + switch(ver) { + case 0x10: + rail->mode = nvbios_rd08(bios, entry + 0x1); + rail->extdev_id = nvbios_rd08(bios, entry + 0x2); + rail->resistor_mohm = nvbios_rd08(bios, entry + 0x3); + rail->rail = nvbios_rd08(bios, entry + 0x4); + break; + case 0x20: + rail->mode = nvbios_rd08(bios, entry); + rail->extdev_id = nvbios_rd08(bios, entry + 0x1); + rail->resistor_mohm = nvbios_rd08(bios, entry + 0x5); + rail->rail = nvbios_rd08(bios, entry + 0x6); + break; + }; + } + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index a7d69ce7a..38ed09fd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c @@ -786,20 +786,20 @@ init_io_flag_condition(struct nvbios_init *init) } /** - * INIT_DP_CONDITION - opcode 0x3a + * INIT_GENERIC_CONDITION - opcode 0x3a * */ static void -init_dp_condition(struct nvbios_init *init) +init_generic_condition(struct nvbios_init *init) { struct nvkm_bios *bios = init->bios; struct nvbios_dpout info; u8 cond = nvbios_rd08(bios, init->offset + 1); - u8 unkn = nvbios_rd08(bios, init->offset + 2); + u8 size = nvbios_rd08(bios, init->offset + 2); u8 ver, hdr, cnt, len; u16 data; - trace("DP_CONDITION\t0x%02x 0x%02x\n", cond, unkn); + trace("GENERIC_CONDITION\t0x%02x 0x%02x\n", cond, size); init->offset += 3; switch (cond) { @@ -828,7 +828,8 @@ init_dp_condition(struct nvbios_init *init) init_exec_set(init, false); break; default: - warn("unknown dp condition 0x%02x\n", cond); + warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond); + init->offset += size; break; } } @@ -2205,7 +2206,7 @@ static struct nvbios_init_opcode { [0x37] = { init_copy }, [0x38] = { init_not }, [0x39] = { init_io_flag_condition }, - [0x3a] = { init_dp_condition }, + [0x3a] = { init_generic_condition }, [0x3b] = { init_io_mask_or }, [0x3c] = { init_io_or }, [0x47] = { init_andn_reg }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild index ed7717bcc..87d94883f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/Kbuild @@ -8,6 +8,7 @@ nvkm-y += nvkm/subdev/clk/mcp77.o nvkm-y += nvkm/subdev/clk/gf100.o nvkm-y += nvkm/subdev/clk/gk104.o nvkm-y += nvkm/subdev/clk/gk20a.o +nvkm-y += nvkm/subdev/clk/gm20b.o nvkm-y += nvkm/subdev/clk/pllnv04.o nvkm-y += nvkm/subdev/clk/pllgt215.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c index 5da2aa8cc..5f0ee24e3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,19 +22,17 @@ * Shamelessly ripped off from ChromeOS's gk20a/clk_pllg.c * */ -#define gk20a_clk(p) container_of((p), struct gk20a_clk, base) #include "priv.h" +#include "gk20a.h" #include <core/tegra.h> #include <subdev/timer.h> -#define MHZ (1000 * 1000) +#define KHZ (1000) +#define MHZ (KHZ * 1000) #define MASK(w) ((1 << w) - 1) -#define SYS_GPCPLL_CFG_BASE 0x00137000 -#define GPC_BCASE_GPCPLL_CFG_BASE 0x00132800 - #define GPCPLL_CFG (SYS_GPCPLL_CFG_BASE + 0) #define GPCPLL_CFG_ENABLE BIT(0) #define GPCPLL_CFG_IDDQ BIT(1) @@ -56,6 +54,7 @@ #define GPCPLL_CFG3 (SYS_GPCPLL_CFG_BASE + 0x18) #define GPCPLL_CFG3_PLL_STEPB_SHIFT 16 +#define GPC_BCASE_GPCPLL_CFG_BASE 0x00132800 #define GPCPLL_NDIV_SLOWDOWN (SYS_GPCPLL_CFG_BASE + 0x1c) #define GPCPLL_NDIV_SLOWDOWN_NDIV_LO_SHIFT 0 #define GPCPLL_NDIV_SLOWDOWN_NDIV_MID_SHIFT 8 @@ -75,7 +74,7 @@ #define GPC2CLK_OUT_VCODIV1 0 #define GPC2CLK_OUT_VCODIV_MASK (MASK(GPC2CLK_OUT_VCODIV_WIDTH) << \ GPC2CLK_OUT_VCODIV_SHIFT) -#define GPC2CLK_OUT_BYPDIV_WIDTH 6 +#define GPC2CLK_OUT_BYPDIV_WIDTH 6 #define GPC2CLK_OUT_BYPDIV_SHIFT 0 #define GPC2CLK_OUT_BYPDIV31 0x3c #define GPC2CLK_OUT_INIT_MASK ((MASK(GPC2CLK_OUT_SDIV14_INDIV4_WIDTH) << \ @@ -92,45 +91,49 @@ #define GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_MASK \ (0x1 << GPC_BCAST_NDIV_SLOWDOWN_DEBUG_PLL_DYNRAMP_DONE_SYNCED_SHIFT) -static const u8 pl_to_div[] = { +static const u8 _pl_to_div[] = { /* PL: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 */ /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32, }; -/* All frequencies in Mhz */ -struct gk20a_clk_pllg_params { - u32 min_vco, max_vco; - u32 min_u, max_u; - u32 min_m, max_m; - u32 min_n, max_n; - u32 min_pl, max_pl; -}; +static u32 pl_to_div(u32 pl) +{ + if (pl >= ARRAY_SIZE(_pl_to_div)) + return 1; + + return _pl_to_div[pl]; +} + +static u32 div_to_pl(u32 div) +{ + u32 pl; + + for (pl = 0; pl < ARRAY_SIZE(_pl_to_div) - 1; pl++) { + if (_pl_to_div[pl] >= div) + return pl; + } + + return ARRAY_SIZE(_pl_to_div) - 1; +} static const struct gk20a_clk_pllg_params gk20a_pllg_params = { - .min_vco = 1000, .max_vco = 2064, - .min_u = 12, .max_u = 38, + .min_vco = 1000000, .max_vco = 2064000, + .min_u = 12000, .max_u = 38000, .min_m = 1, .max_m = 255, .min_n = 8, .max_n = 255, .min_pl = 1, .max_pl = 32, }; -struct gk20a_clk { - struct nvkm_clk base; - const struct gk20a_clk_pllg_params *params; - u32 m, n, pl; - u32 parent_rate; -}; - static void -gk20a_pllg_read_mnp(struct gk20a_clk *clk) +gk20a_pllg_read_mnp(struct gk20a_clk *clk, struct gk20a_pll *pll) { struct nvkm_device *device = clk->base.subdev.device; u32 val; val = nvkm_rd32(device, GPCPLL_COEFF); - clk->m = (val >> GPCPLL_COEFF_M_SHIFT) & MASK(GPCPLL_COEFF_M_WIDTH); - clk->n = (val >> GPCPLL_COEFF_N_SHIFT) & MASK(GPCPLL_COEFF_N_WIDTH); - clk->pl = (val >> GPCPLL_COEFF_P_SHIFT) & MASK(GPCPLL_COEFF_P_WIDTH); + pll->m = (val >> GPCPLL_COEFF_M_SHIFT) & MASK(GPCPLL_COEFF_M_WIDTH); + pll->n = (val >> GPCPLL_COEFF_N_SHIFT) & MASK(GPCPLL_COEFF_N_WIDTH); + pll->pl = (val >> GPCPLL_COEFF_P_SHIFT) & MASK(GPCPLL_COEFF_P_WIDTH); } static u32 @@ -139,8 +142,8 @@ gk20a_pllg_calc_rate(struct gk20a_clk *clk) u32 rate; u32 divider; - rate = clk->parent_rate * clk->n; - divider = clk->m * pl_to_div[clk->pl]; + rate = clk->parent_rate * clk->pll.n; + divider = clk->pll.m * clk->pl_to_div(clk->pll.pl); return rate / divider / 2; } @@ -152,15 +155,13 @@ gk20a_pllg_calc_mnp(struct gk20a_clk *clk, unsigned long rate) u32 target_clk_f, ref_clk_f, target_freq; u32 min_vco_f, max_vco_f; u32 low_pl, high_pl, best_pl; - u32 target_vco_f, vco_f; + u32 target_vco_f; u32 best_m, best_n; - u32 u_f; - u32 m, n, n2; - u32 delta, lwv, best_delta = ~0; + u32 best_delta = ~0; u32 pl; - target_clk_f = rate * 2 / MHZ; - ref_clk_f = clk->parent_rate / MHZ; + target_clk_f = rate * 2 / KHZ; + ref_clk_f = clk->parent_rate / KHZ; max_vco_f = clk->params->max_vco; min_vco_f = clk->params->min_vco; @@ -176,33 +177,26 @@ gk20a_pllg_calc_mnp(struct gk20a_clk *clk, unsigned long rate) high_pl = (max_vco_f + target_vco_f - 1) / target_vco_f; high_pl = min(high_pl, clk->params->max_pl); high_pl = max(high_pl, clk->params->min_pl); + high_pl = clk->div_to_pl(high_pl); /* min_pl <= low_pl <= max_pl */ low_pl = min_vco_f / target_vco_f; low_pl = min(low_pl, clk->params->max_pl); low_pl = max(low_pl, clk->params->min_pl); - - /* Find Indices of high_pl and low_pl */ - for (pl = 0; pl < ARRAY_SIZE(pl_to_div) - 1; pl++) { - if (pl_to_div[pl] >= low_pl) { - low_pl = pl; - break; - } - } - for (pl = 0; pl < ARRAY_SIZE(pl_to_div) - 1; pl++) { - if (pl_to_div[pl] >= high_pl) { - high_pl = pl; - break; - } - } + low_pl = clk->div_to_pl(low_pl); nvkm_debug(subdev, "low_PL %d(div%d), high_PL %d(div%d)", low_pl, - pl_to_div[low_pl], high_pl, pl_to_div[high_pl]); + clk->pl_to_div(low_pl), high_pl, clk->pl_to_div(high_pl)); /* Select lowest possible VCO */ for (pl = low_pl; pl <= high_pl; pl++) { - target_vco_f = target_clk_f * pl_to_div[pl]; + u32 m, n, n2; + + target_vco_f = target_clk_f * clk->pl_to_div(pl); + for (m = clk->params->min_m; m <= clk->params->max_m; m++) { + u32 u_f, vco_f; + u_f = ref_clk_f / m; if (u_f < clk->params->min_u) @@ -225,8 +219,10 @@ gk20a_pllg_calc_mnp(struct gk20a_clk *clk, unsigned long rate) vco_f = ref_clk_f * n / m; if (vco_f >= min_vco_f && vco_f <= max_vco_f) { - lwv = (vco_f + (pl_to_div[pl] / 2)) - / pl_to_div[pl]; + u32 delta, lwv; + + lwv = (vco_f + (clk->pl_to_div(pl) / 2)) + / clk->pl_to_div(pl); delta = abs(lwv - target_clk_f); if (delta < best_delta) { @@ -249,17 +245,18 @@ found_match: if (best_delta != 0) nvkm_debug(subdev, "no best match for target @ %dMHz on gpc_pll", - target_clk_f); + target_clk_f / KHZ); - clk->m = best_m; - clk->n = best_n; - clk->pl = best_pl; + clk->pll.m = best_m; + clk->pll.n = best_n; + clk->pll.pl = best_pl; - target_freq = gk20a_pllg_calc_rate(clk) / MHZ; + target_freq = gk20a_pllg_calc_rate(clk); nvkm_debug(subdev, "actual target freq %d MHz, M %d, N %d, PL %d(div%d)\n", - target_freq, clk->m, clk->n, clk->pl, pl_to_div[clk->pl]); + target_freq / MHZ, clk->pll.m, clk->pll.n, clk->pll.pl, + clk->pl_to_div(clk->pll.pl)); return 0; } @@ -323,17 +320,19 @@ gk20a_pllg_slide(struct gk20a_clk *clk, u32 n) } static void -_gk20a_pllg_enable(struct gk20a_clk *clk) +gk20a_pllg_enable(struct gk20a_clk *clk) { struct nvkm_device *device = clk->base.subdev.device; + nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_ENABLE, GPCPLL_CFG_ENABLE); nvkm_rd32(device, GPCPLL_CFG); } static void -_gk20a_pllg_disable(struct gk20a_clk *clk) +gk20a_pllg_disable(struct gk20a_clk *clk) { struct nvkm_device *device = clk->base.subdev.device; + nvkm_mask(device, GPCPLL_CFG, GPCPLL_CFG_ENABLE, 0); nvkm_rd32(device, GPCPLL_CFG); } @@ -344,25 +343,26 @@ _gk20a_pllg_program_mnp(struct gk20a_clk *clk, bool allow_slide) struct nvkm_subdev *subdev = &clk->base.subdev; struct nvkm_device *device = subdev->device; u32 val, cfg; - u32 m_old, pl_old, n_lo; + struct gk20a_pll old_pll; + u32 n_lo; /* get old coefficients */ - val = nvkm_rd32(device, GPCPLL_COEFF); - m_old = (val >> GPCPLL_COEFF_M_SHIFT) & MASK(GPCPLL_COEFF_M_WIDTH); - pl_old = (val >> GPCPLL_COEFF_P_SHIFT) & MASK(GPCPLL_COEFF_P_WIDTH); + gk20a_pllg_read_mnp(clk, &old_pll); /* do NDIV slide if there is no change in M and PL */ cfg = nvkm_rd32(device, GPCPLL_CFG); - if (allow_slide && clk->m == m_old && clk->pl == pl_old && - (cfg & GPCPLL_CFG_ENABLE)) { - return gk20a_pllg_slide(clk, clk->n); + if (allow_slide && clk->pll.m == old_pll.m && + clk->pll.pl == old_pll.pl && (cfg & GPCPLL_CFG_ENABLE)) { + return gk20a_pllg_slide(clk, clk->pll.n); } /* slide down to NDIV_LO */ - n_lo = DIV_ROUND_UP(m_old * clk->params->min_vco, - clk->parent_rate / MHZ); if (allow_slide && (cfg & GPCPLL_CFG_ENABLE)) { - int ret = gk20a_pllg_slide(clk, n_lo); + int ret; + + n_lo = DIV_ROUND_UP(old_pll.m * clk->params->min_vco, + clk->parent_rate / KHZ); + ret = gk20a_pllg_slide(clk, n_lo); if (ret) return ret; @@ -387,19 +387,19 @@ _gk20a_pllg_program_mnp(struct gk20a_clk *clk, bool allow_slide) udelay(2); } - _gk20a_pllg_disable(clk); + gk20a_pllg_disable(clk); nvkm_debug(subdev, "%s: m=%d n=%d pl=%d\n", __func__, - clk->m, clk->n, clk->pl); + clk->pll.m, clk->pll.n, clk->pll.pl); - n_lo = DIV_ROUND_UP(clk->m * clk->params->min_vco, - clk->parent_rate / MHZ); - val = clk->m << GPCPLL_COEFF_M_SHIFT; - val |= (allow_slide ? n_lo : clk->n) << GPCPLL_COEFF_N_SHIFT; - val |= clk->pl << GPCPLL_COEFF_P_SHIFT; + n_lo = DIV_ROUND_UP(clk->pll.m * clk->params->min_vco, + clk->parent_rate / KHZ); + val = clk->pll.m << GPCPLL_COEFF_M_SHIFT; + val |= (allow_slide ? n_lo : clk->pll.n) << GPCPLL_COEFF_N_SHIFT; + val |= clk->pll.pl << GPCPLL_COEFF_P_SHIFT; nvkm_wr32(device, GPCPLL_COEFF, val); - _gk20a_pllg_enable(clk); + gk20a_pllg_enable(clk); val = nvkm_rd32(device, GPCPLL_CFG); if (val & GPCPLL_CFG_LOCK_DET_OFF) { @@ -414,16 +414,24 @@ _gk20a_pllg_program_mnp(struct gk20a_clk *clk, bool allow_slide) return -ETIMEDOUT; /* switch to VCO mode */ - nvkm_mask(device, SEL_VCO, 0, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT)); + nvkm_mask(device, SEL_VCO, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT), + BIT(SEL_VCO_GPC2CLK_OUT_SHIFT)); /* restore out divider 1:1 */ val = nvkm_rd32(device, GPC2CLK_OUT); - val &= ~GPC2CLK_OUT_VCODIV_MASK; - udelay(2); - nvkm_wr32(device, GPC2CLK_OUT, val); + if ((val & GPC2CLK_OUT_VCODIV_MASK) != + (GPC2CLK_OUT_VCODIV1 << GPC2CLK_OUT_VCODIV_SHIFT)) { + val &= ~GPC2CLK_OUT_VCODIV_MASK; + val |= GPC2CLK_OUT_VCODIV1 << GPC2CLK_OUT_VCODIV_SHIFT; + udelay(2); + nvkm_wr32(device, GPC2CLK_OUT, val); + /* Intentional 2nd write to assure linear divider operation */ + nvkm_wr32(device, GPC2CLK_OUT, val); + nvkm_rd32(device, GPC2CLK_OUT); + } /* slide up to new NDIV */ - return allow_slide ? gk20a_pllg_slide(clk, clk->n) : 0; + return allow_slide ? gk20a_pllg_slide(clk, clk->pll.n) : 0; } static int @@ -438,32 +446,6 @@ gk20a_pllg_program_mnp(struct gk20a_clk *clk) return err; } -static void -gk20a_pllg_disable(struct gk20a_clk *clk) -{ - struct nvkm_device *device = clk->base.subdev.device; - u32 val; - - /* slide to VCO min */ - val = nvkm_rd32(device, GPCPLL_CFG); - if (val & GPCPLL_CFG_ENABLE) { - u32 coeff, m, n_lo; - - coeff = nvkm_rd32(device, GPCPLL_COEFF); - m = (coeff >> GPCPLL_COEFF_M_SHIFT) & MASK(GPCPLL_COEFF_M_WIDTH); - n_lo = DIV_ROUND_UP(m * clk->params->min_vco, - clk->parent_rate / MHZ); - gk20a_pllg_slide(clk, n_lo); - } - - /* put PLL in bypass before disabling it */ - nvkm_mask(device, SEL_VCO, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT), 0); - - _gk20a_pllg_disable(clk); -} - -#define GK20A_CLK_GPC_MDIV 1000 - static struct nvkm_pstate gk20a_pstates[] = { { @@ -558,7 +540,7 @@ gk20a_pstates[] = { }, }; -static int +int gk20a_clk_read(struct nvkm_clk *base, enum nv_clk_src src) { struct gk20a_clk *clk = gk20a_clk(base); @@ -569,7 +551,7 @@ gk20a_clk_read(struct nvkm_clk *base, enum nv_clk_src src) case nv_clk_src_crystal: return device->crystal; case nv_clk_src_gpc: - gk20a_pllg_read_mnp(clk); + gk20a_pllg_read_mnp(clk, &clk->pll); return gk20a_pllg_calc_rate(clk) / GK20A_CLK_GPC_MDIV; default: nvkm_error(subdev, "invalid clock source %d\n", src); @@ -577,7 +559,7 @@ gk20a_clk_read(struct nvkm_clk *base, enum nv_clk_src src) } } -static int +int gk20a_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate) { struct gk20a_clk *clk = gk20a_clk(base); @@ -586,7 +568,7 @@ gk20a_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate) GK20A_CLK_GPC_MDIV); } -static int +int gk20a_clk_prog(struct nvkm_clk *base) { struct gk20a_clk *clk = gk20a_clk(base); @@ -594,15 +576,33 @@ gk20a_clk_prog(struct nvkm_clk *base) return gk20a_pllg_program_mnp(clk); } -static void +void gk20a_clk_tidy(struct nvkm_clk *base) { } -static void +void gk20a_clk_fini(struct nvkm_clk *base) { + struct nvkm_device *device = base->subdev.device; struct gk20a_clk *clk = gk20a_clk(base); + u32 val; + + /* slide to VCO min */ + val = nvkm_rd32(device, GPCPLL_CFG); + if (val & GPCPLL_CFG_ENABLE) { + struct gk20a_pll pll; + u32 n_lo; + + gk20a_pllg_read_mnp(clk, &pll); + n_lo = DIV_ROUND_UP(pll.m * clk->params->min_vco, + clk->parent_rate / KHZ); + gk20a_pllg_slide(clk, n_lo); + } + + /* put PLL in bypass before disabling it */ + nvkm_mask(device, SEL_VCO, BIT(SEL_VCO_GPC2CLK_OUT_SHIFT), 0); + gk20a_pllg_disable(clk); } @@ -614,9 +614,12 @@ gk20a_clk_init(struct nvkm_clk *base) struct nvkm_device *device = subdev->device; int ret; - nvkm_mask(device, GPC2CLK_OUT, GPC2CLK_OUT_INIT_MASK, GPC2CLK_OUT_INIT_VAL); + nvkm_mask(device, GPC2CLK_OUT, GPC2CLK_OUT_INIT_MASK, + GPC2CLK_OUT_INIT_VAL); - ret = gk20a_clk_prog(&clk->base); + /* Start with lowest frequency */ + base->func->calc(base, &base->func->pstates[0].base); + ret = base->func->prog(&clk->base); if (ret) { nvkm_error(subdev, "cannot initialize clock\n"); return ret; @@ -643,27 +646,50 @@ gk20a_clk = { }; int -gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk) +_gk20a_clk_ctor(struct nvkm_device *device, int index, + const struct nvkm_clk_func *func, + const struct gk20a_clk_pllg_params *params, + struct gk20a_clk *clk) { struct nvkm_device_tegra *tdev = device->func->tegra(device); + int ret; + int i; + + /* Finish initializing the pstates */ + for (i = 0; i < func->nr_pstates; i++) { + INIT_LIST_HEAD(&func->pstates[i].list); + func->pstates[i].pstate = i + 1; + } + + clk->params = params; + clk->parent_rate = clk_get_rate(tdev->clk); + + ret = nvkm_clk_ctor(func, device, index, true, &clk->base); + if (ret) + return ret; + + nvkm_debug(&clk->base.subdev, "parent clock rate: %d Khz\n", + clk->parent_rate / KHZ); + + return 0; +} + +int +gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk) +{ struct gk20a_clk *clk; - int ret, i; + int ret; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) return -ENOMEM; *pclk = &clk->base; - /* Finish initializing the pstates */ - for (i = 0; i < ARRAY_SIZE(gk20a_pstates); i++) { - INIT_LIST_HEAD(&gk20a_pstates[i].list); - gk20a_pstates[i].pstate = i + 1; - } + ret = _gk20a_clk_ctor(device, index, &gk20a_clk, &gk20a_pllg_params, + clk); - clk->params = &gk20a_pllg_params; - clk->parent_rate = clk_get_rate(tdev->clk); + clk->pl_to_div = pl_to_div; + clk->div_to_pl = div_to_pl; - ret = nvkm_clk_ctor(&gk20a_clk, device, index, true, &clk->base); - nvkm_info(&clk->base.subdev, "parent clock rate: %d Mhz\n", - clk->parent_rate / MHZ); return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.h b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.h new file mode 100644 index 000000000..13c467401 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __NVKM_CLK_GK20A_H__ +#define __NVKM_CLK_GK20A_H__ + +#define GK20A_CLK_GPC_MDIV 1000 + +#define SYS_GPCPLL_CFG_BASE 0x00137000 + +/* All frequencies in Khz */ +struct gk20a_clk_pllg_params { + u32 min_vco, max_vco; + u32 min_u, max_u; + u32 min_m, max_m; + u32 min_n, max_n; + u32 min_pl, max_pl; +}; + +struct gk20a_pll { + u32 m; + u32 n; + u32 pl; +}; + +struct gk20a_clk { + struct nvkm_clk base; + const struct gk20a_clk_pllg_params *params; + struct gk20a_pll pll; + u32 parent_rate; + + u32 (*div_to_pl)(u32); + u32 (*pl_to_div)(u32); +}; +#define gk20a_clk(p) container_of((p), struct gk20a_clk, base) + +int _gk20a_clk_ctor(struct nvkm_device *, int, const struct nvkm_clk_func *, + const struct gk20a_clk_pllg_params *, struct gk20a_clk *); +void gk20a_clk_fini(struct nvkm_clk *); +int gk20a_clk_read(struct nvkm_clk *, enum nv_clk_src); +int gk20a_clk_calc(struct nvkm_clk *, struct nvkm_cstate *); +int gk20a_clk_prog(struct nvkm_clk *); +void gk20a_clk_tidy(struct nvkm_clk *); + +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c new file mode 100644 index 000000000..71b2bbb61 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <subdev/clk.h> +#include <core/device.h> + +#include "priv.h" +#include "gk20a.h" + +#define KHZ (1000) +#define MHZ (KHZ * 1000) + +#define MASK(w) ((1 << w) - 1) + +#define BYPASSCTRL_SYS (SYS_GPCPLL_CFG_BASE + 0x340) +#define BYPASSCTRL_SYS_GPCPLL_SHIFT 0 +#define BYPASSCTRL_SYS_GPCPLL_WIDTH 1 + +static u32 pl_to_div(u32 pl) +{ + return pl; +} + +static u32 div_to_pl(u32 div) +{ + return div; +} + +static const struct gk20a_clk_pllg_params gm20b_pllg_params = { + .min_vco = 1300000, .max_vco = 2600000, + .min_u = 12000, .max_u = 38400, + .min_m = 1, .max_m = 255, + .min_n = 8, .max_n = 255, + .min_pl = 1, .max_pl = 31, +}; + +static struct nvkm_pstate +gm20b_pstates[] = { + { + .base = { + .domain[nv_clk_src_gpc] = 76800, + .voltage = 0, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 153600, + .voltage = 1, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 230400, + .voltage = 2, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 307200, + .voltage = 3, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 384000, + .voltage = 4, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 460800, + .voltage = 5, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 537600, + .voltage = 6, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 614400, + .voltage = 7, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 691200, + .voltage = 8, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 768000, + .voltage = 9, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 844800, + .voltage = 10, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 921600, + .voltage = 11, + }, + }, + { + .base = { + .domain[nv_clk_src_gpc] = 998400, + .voltage = 12, + }, + }, + +}; + +static int +gm20b_clk_init(struct nvkm_clk *base) +{ + struct gk20a_clk *clk = gk20a_clk(base); + struct nvkm_subdev *subdev = &clk->base.subdev; + struct nvkm_device *device = subdev->device; + int ret; + + /* Set the global bypass control to VCO */ + nvkm_mask(device, BYPASSCTRL_SYS, + MASK(BYPASSCTRL_SYS_GPCPLL_WIDTH) << BYPASSCTRL_SYS_GPCPLL_SHIFT, + 0); + + /* Start with lowest frequency */ + base->func->calc(base, &base->func->pstates[0].base); + ret = base->func->prog(&clk->base); + if (ret) { + nvkm_error(subdev, "cannot initialize clock\n"); + return ret; + } + + return 0; +} + +static const struct nvkm_clk_func +gm20b_clk_speedo0 = { + .init = gm20b_clk_init, + .fini = gk20a_clk_fini, + .read = gk20a_clk_read, + .calc = gk20a_clk_calc, + .prog = gk20a_clk_prog, + .tidy = gk20a_clk_tidy, + .pstates = gm20b_pstates, + .nr_pstates = ARRAY_SIZE(gm20b_pstates) - 1, + .domains = { + { nv_clk_src_crystal, 0xff }, + { nv_clk_src_gpc, 0xff, 0, "core", GK20A_CLK_GPC_MDIV }, + { nv_clk_src_max }, + }, +}; + +int +gm20b_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk) +{ + struct gk20a_clk *clk; + int ret; + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + *pclk = &clk->base; + + ret = _gk20a_clk_ctor(device, index, &gm20b_clk_speedo0, + &gm20b_pllg_params, clk); + + clk->pl_to_div = pl_to_div; + clk->div_to_pl = div_to_pl; + + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild index 793e73d16..eac88e3dc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/Kbuild @@ -11,4 +11,4 @@ nvkm-y += nvkm/subdev/devinit/gt215.o nvkm-y += nvkm/subdev/devinit/mcp89.o nvkm-y += nvkm/subdev/devinit/gf100.o nvkm-y += nvkm/subdev/devinit/gm107.o -nvkm-y += nvkm/subdev/devinit/gm204.o +nvkm-y += nvkm/subdev/devinit/gm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c index 22b0140e2..2923598b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c @@ -90,9 +90,21 @@ gf100_devinit_disable(struct nvkm_devinit *init) return disable; } +void +gf100_devinit_preinit(struct nvkm_devinit *base) +{ + struct nv50_devinit *init = nv50_devinit(base); + struct nvkm_subdev *subdev = &init->base.subdev; + struct nvkm_device *device = subdev->device; + + /* This bit is set by devinit, and flips back to 0 on suspend */ + if (!base->post) + base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0); +} + static const struct nvkm_devinit_func gf100_devinit = { - .preinit = nv50_devinit_preinit, + .preinit = gf100_devinit_preinit, .init = nv50_devinit_init, .post = nv04_devinit_post, .pll_set = gf100_devinit_pll_set, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c index 2be98bd78..28ca01be3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c @@ -46,7 +46,7 @@ gm107_devinit_disable(struct nvkm_devinit *init) static const struct nvkm_devinit_func gm107_devinit = { - .preinit = nv50_devinit_preinit, + .preinit = gf100_devinit_preinit, .init = nv50_devinit_init, .post = nv04_devinit_post, .pll_set = gf100_devinit_pll_set, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c index 2b9c3f11b..a410c0db8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm200.c @@ -107,7 +107,7 @@ pmu_load(struct nv50_devinit *init, u8 type, bool post, } static int -gm204_devinit_post(struct nvkm_devinit *base, bool post) +gm200_devinit_post(struct nvkm_devinit *base, bool post) { struct nv50_devinit *init = nv50_devinit(base); struct nvkm_subdev *subdev = &init->base.subdev; @@ -165,17 +165,17 @@ gm204_devinit_post(struct nvkm_devinit *base, bool post) } static const struct nvkm_devinit_func -gm204_devinit = { - .preinit = nv50_devinit_preinit, +gm200_devinit = { + .preinit = gf100_devinit_preinit, .init = nv50_devinit_init, - .post = gm204_devinit_post, + .post = gm200_devinit_post, .pll_set = gf100_devinit_pll_set, .disable = gm107_devinit_disable, }; int -gm204_devinit_new(struct nvkm_device *device, int index, +gm200_devinit_new(struct nvkm_device *device, int index, struct nvkm_devinit **pinit) { - return nv50_devinit_new_(&gm204_devinit, device, index, pinit); + return nv50_devinit_new_(&gm200_devinit, device, index, pinit); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c index 337c2c692..c714b0977 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c @@ -93,28 +93,27 @@ nv50_devinit_disable(struct nvkm_devinit *init) void nv50_devinit_preinit(struct nvkm_devinit *base) { - struct nv50_devinit *init = nv50_devinit(base); - struct nvkm_subdev *subdev = &init->base.subdev; + struct nvkm_subdev *subdev = &base->subdev; struct nvkm_device *device = subdev->device; /* our heuristics can't detect whether the board has had its * devinit scripts executed or not if the display engine is * missing, assume it's a secondary gpu which requires post */ - if (!init->base.post) { - u64 disable = nvkm_devinit_disable(&init->base); + if (!base->post) { + u64 disable = nvkm_devinit_disable(base); if (disable & (1ULL << NVKM_ENGINE_DISP)) - init->base.post = true; + base->post = true; } /* magic to detect whether or not x86 vbios code has executed * the devinit scripts to initialise the board */ - if (!init->base.post) { + if (!base->post) { if (!nvkm_rdvgac(device, 0, 0x00) && !nvkm_rdvgac(device, 0, 0x1a)) { nvkm_debug(subdev, "adaptor not initialised\n"); - init->base.post = true; + base->post = true; } } } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h index 5de70a848..25d2ae3af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.h @@ -20,6 +20,7 @@ int gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *, struct nvkm_oclass *, void *, u32, struct nvkm_object **); int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32); +void gf100_devinit_preinit(struct nvkm_devinit *); u64 gm107_devinit_disable(struct nvkm_devinit *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild index 1f730613c..48f01e40b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild @@ -6,7 +6,7 @@ nvkm-y += nvkm/subdev/i2c/g94.o nvkm-y += nvkm/subdev/i2c/gf117.o nvkm-y += nvkm/subdev/i2c/gf119.o nvkm-y += nvkm/subdev/i2c/gk104.o -nvkm-y += nvkm/subdev/i2c/gm204.o +nvkm-y += nvkm/subdev/i2c/gm200.o nvkm-y += nvkm/subdev/i2c/pad.o nvkm-y += nvkm/subdev/i2c/padnv04.o @@ -14,7 +14,7 @@ nvkm-y += nvkm/subdev/i2c/padnv4e.o nvkm-y += nvkm/subdev/i2c/padnv50.o nvkm-y += nvkm/subdev/i2c/padg94.o nvkm-y += nvkm/subdev/i2c/padgf119.o -nvkm-y += nvkm/subdev/i2c/padgm204.o +nvkm-y += nvkm/subdev/i2c/padgm200.o nvkm-y += nvkm/subdev/i2c/bus.o nvkm-y += nvkm/subdev/i2c/busnv04.o @@ -25,6 +25,6 @@ nvkm-y += nvkm/subdev/i2c/bit.o nvkm-y += nvkm/subdev/i2c/aux.o nvkm-y += nvkm/subdev/i2c/auxg94.o -nvkm-y += nvkm/subdev/i2c/auxgm204.o +nvkm-y += nvkm/subdev/i2c/auxgm200.o nvkm-y += nvkm/subdev/i2c/anx9805.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h index 35a892e4a..fc6b162fa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h @@ -18,7 +18,7 @@ int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, u32 addr, u8 *data, u8 size); int g94_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **); -int gm204_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **); +int gm200_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **); #define AUX_MSG(b,l,f,a...) do { \ struct nvkm_i2c_aux *_aux = (b); \ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index bed231b56..61d729b82 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -21,23 +21,23 @@ * * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#define gm204_i2c_aux(p) container_of((p), struct gm204_i2c_aux, base) +#define gm200_i2c_aux(p) container_of((p), struct gm200_i2c_aux, base) #include "aux.h" -struct gm204_i2c_aux { +struct gm200_i2c_aux { struct nvkm_i2c_aux base; int ch; }; static void -gm204_i2c_aux_fini(struct gm204_i2c_aux *aux) +gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) { struct nvkm_device *device = aux->base.pad->i2c->subdev.device; nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00310000, 0x00000000); } static int -gm204_i2c_aux_init(struct gm204_i2c_aux *aux) +gm200_i2c_aux_init(struct gm200_i2c_aux *aux) { struct nvkm_device *device = aux->base.pad->i2c->subdev.device; const u32 unksel = 1; /* nfi which to use, or if it matters.. */ @@ -64,7 +64,7 @@ gm204_i2c_aux_init(struct gm204_i2c_aux *aux) udelay(1); if (!timeout--) { AUX_ERR(&aux->base, "magic wait %08x", ctrl); - gm204_i2c_aux_fini(aux); + gm200_i2c_aux_fini(aux); return -EBUSY; } } while ((ctrl & 0x03000000) != urep); @@ -73,10 +73,10 @@ gm204_i2c_aux_init(struct gm204_i2c_aux *aux) } static int -gm204_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, +gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, u8 type, u32 addr, u8 *data, u8 size) { - struct gm204_i2c_aux *aux = gm204_i2c_aux(obj); + struct gm200_i2c_aux *aux = gm200_i2c_aux(obj); struct nvkm_device *device = aux->base.pad->i2c->subdev.device; const u32 base = aux->ch * 0x50; u32 ctrl, stat, timeout, retries; @@ -85,7 +85,7 @@ gm204_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, AUX_TRACE(&aux->base, "%d: %08x %d", type, addr, size); - ret = gm204_i2c_aux_init(aux); + ret = gm200_i2c_aux_init(aux); if (ret < 0) goto out; @@ -155,26 +155,26 @@ gm204_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry, } out: - gm204_i2c_aux_fini(aux); + gm200_i2c_aux_fini(aux); return ret < 0 ? ret : (stat & 0x000f0000) >> 16; } static const struct nvkm_i2c_aux_func -gm204_i2c_aux_func = { - .xfer = gm204_i2c_aux_xfer, +gm200_i2c_aux_func = { + .xfer = gm200_i2c_aux_xfer, }; int -gm204_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive, +gm200_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive, struct nvkm_i2c_aux **paux) { - struct gm204_i2c_aux *aux; + struct gm200_i2c_aux *aux; if (!(aux = kzalloc(sizeof(*aux), GFP_KERNEL))) return -ENOMEM; *paux = &aux->base; - nvkm_i2c_aux_ctor(&gm204_i2c_aux_func, pad, index, &aux->base); + nvkm_i2c_aux_ctor(&gm200_i2c_aux_func, pad, index, &aux->base); aux->ch = drive; aux->base.intr = 1 << aux->ch; return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm200.c index ff9f7d62f..a23c5f315 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/gm200.c @@ -25,16 +25,16 @@ #include "pad.h" static const struct nvkm_i2c_func -gm204_i2c = { +gm200_i2c = { .pad_x_new = gf119_i2c_pad_x_new, - .pad_s_new = gm204_i2c_pad_s_new, + .pad_s_new = gm200_i2c_pad_s_new, .aux = 8, .aux_stat = gk104_aux_stat, .aux_mask = gk104_aux_mask, }; int -gm204_i2c_new(struct nvkm_device *device, int index, struct nvkm_i2c **pi2c) +gm200_i2c_new(struct nvkm_device *device, int index, struct nvkm_i2c **pi2c) { - return nvkm_i2c_new_(&gm204_i2c, device, index, pi2c); + return nvkm_i2c_new_(&gm200_i2c, device, index, pi2c); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h index 9eeb99294..316c4536f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.h @@ -49,11 +49,11 @@ int nv4e_i2c_pad_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int nv50_i2c_pad_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int g94_i2c_pad_x_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int gf119_i2c_pad_x_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); -int gm204_i2c_pad_x_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); +int gm200_i2c_pad_x_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int g94_i2c_pad_s_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int gf119_i2c_pad_s_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); -int gm204_i2c_pad_s_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); +int gm200_i2c_pad_s_new(struct nvkm_i2c *, int, struct nvkm_i2c_pad **); int anx9805_pad_new(struct nvkm_i2c_bus *, int, u8, struct nvkm_i2c_pad **); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c index 24a4d760c..7d417f6a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgm200.c @@ -26,7 +26,7 @@ #include "bus.h" static void -gm204_i2c_pad_mode(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode) +gm200_i2c_pad_mode(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode) { struct nvkm_subdev *subdev = &pad->i2c->subdev; struct nvkm_device *device = subdev->device; @@ -51,26 +51,26 @@ gm204_i2c_pad_mode(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode) } static const struct nvkm_i2c_pad_func -gm204_i2c_pad_s_func = { +gm200_i2c_pad_s_func = { .bus_new_4 = gf119_i2c_bus_new, - .aux_new_6 = gm204_i2c_aux_new, - .mode = gm204_i2c_pad_mode, + .aux_new_6 = gm200_i2c_aux_new, + .mode = gm200_i2c_pad_mode, }; int -gm204_i2c_pad_s_new(struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad) +gm200_i2c_pad_s_new(struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad) { - return nvkm_i2c_pad_new_(&gm204_i2c_pad_s_func, i2c, id, ppad); + return nvkm_i2c_pad_new_(&gm200_i2c_pad_s_func, i2c, id, ppad); } static const struct nvkm_i2c_pad_func -gm204_i2c_pad_x_func = { +gm200_i2c_pad_x_func = { .bus_new_4 = gf119_i2c_bus_new, - .aux_new_6 = gm204_i2c_aux_new, + .aux_new_6 = gm200_i2c_aux_new, }; int -gm204_i2c_pad_x_new(struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad) +gm200_i2c_pad_x_new(struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad) { - return nvkm_i2c_pad_new_(&gm204_i2c_pad_x_func, i2c, id, ppad); + return nvkm_i2c_pad_new_(&gm200_i2c_pad_x_func, i2c, id, ppad); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild index 7e77a7466..ad572d3b5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild @@ -2,4 +2,4 @@ nvkm-y += nvkm/subdev/ibus/gf100.o nvkm-y += nvkm/subdev/ibus/gf117.o nvkm-y += nvkm/subdev/ibus/gk104.o nvkm-y += nvkm/subdev/ibus/gk20a.o -nvkm-y += nvkm/subdev/ibus/gm204.o +nvkm-y += nvkm/subdev/ibus/gm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c index b3839dc25..ef0b7f3b1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c @@ -24,17 +24,17 @@ #include "priv.h" static const struct nvkm_subdev_func -gm204_ibus = { +gm200_ibus = { .intr = gk104_ibus_intr, }; int -gm204_ibus_new(struct nvkm_device *device, int index, +gm200_ibus_new(struct nvkm_device *device, int index, struct nvkm_subdev **pibus) { struct nvkm_subdev *ibus; if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL))) return -ENOMEM; - nvkm_subdev_ctor(&gm204_ibus, device, index, 0, ibus); + nvkm_subdev_ctor(&gm200_ibus, device, index, 0, ibus); return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/Kbuild new file mode 100644 index 000000000..98a4bd3e9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/Kbuild @@ -0,0 +1,2 @@ +nvkm-y += nvkm/subdev/iccsense/base.o +nvkm-y += nvkm/subdev/iccsense/gf100.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c new file mode 100644 index 000000000..c44a85228 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c @@ -0,0 +1,232 @@ +/* + * Copyright 2015 Martin Peres + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Martin Peres + */ +#include "priv.h" + +#include <subdev/bios.h> +#include <subdev/bios/extdev.h> +#include <subdev/bios/iccsense.h> +#include <subdev/i2c.h> + +static bool +nvkm_iccsense_validate_device(struct i2c_adapter *i2c, u8 addr, + enum nvbios_extdev_type type, u8 rail) +{ + switch (type) { + case NVBIOS_EXTDEV_INA209: + case NVBIOS_EXTDEV_INA219: + return rail == 0 && nv_rd16i2cr(i2c, addr, 0x0) >= 0; + case NVBIOS_EXTDEV_INA3221: + return rail <= 3 && + nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 && + nv_rd16i2cr(i2c, addr, 0xfe) == 0x5449; + default: + return false; + } +} + +static int +nvkm_iccsense_poll_lane(struct i2c_adapter *i2c, u8 addr, u8 shunt_reg, + u8 shunt_shift, u8 bus_reg, u8 bus_shift, u8 shunt, + u16 lsb) +{ + int vshunt = nv_rd16i2cr(i2c, addr, shunt_reg); + int vbus = nv_rd16i2cr(i2c, addr, bus_reg); + + if (vshunt < 0 || vbus < 0) + return -EINVAL; + + vshunt >>= shunt_shift; + vbus >>= bus_shift; + + return vbus * vshunt * lsb / shunt; +} + +static int +nvkm_iccsense_ina2x9_read(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_rail *rail, + u8 shunt_reg, u8 bus_reg) +{ + return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, shunt_reg, 0, + bus_reg, 3, rail->mohm, 10 * 4); +} + +static int +nvkm_iccsense_ina209_read(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_rail *rail) +{ + return nvkm_iccsense_ina2x9_read(iccsense, rail, 3, 4); +} + +static int +nvkm_iccsense_ina219_read(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_rail *rail) +{ + return nvkm_iccsense_ina2x9_read(iccsense, rail, 1, 2); +} + +static int +nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense, + struct nvkm_iccsense_rail *rail) +{ + return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, + 1 + (rail->rail * 2), 3, + 2 + (rail->rail * 2), 3, rail->mohm, + 40 * 8); +} + +int +nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx) +{ + struct nvkm_iccsense_rail *rail; + + if (!iccsense || idx >= iccsense->rail_count) + return -EINVAL; + + rail = &iccsense->rails[idx]; + if (!rail->read) + return -ENODEV; + + return rail->read(iccsense, rail); +} + +int +nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense) +{ + int result = 0, i; + for (i = 0; i < iccsense->rail_count; ++i) { + int res = nvkm_iccsense_read(iccsense, i); + if (res >= 0) + result += res; + else + return res; + } + return result; +} + +static void * +nvkm_iccsense_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev); + + if (iccsense->rails) + kfree(iccsense->rails); + + return iccsense; +} + +static int +nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) +{ + struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev); + struct nvkm_bios *bios = subdev->device->bios; + struct nvkm_i2c *i2c = subdev->device->i2c; + struct nvbios_iccsense stbl; + int i; + + if (!i2c || !bios || nvbios_iccsense_parse(bios, &stbl) + || !stbl.nr_entry) + return 0; + + iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry, + GFP_KERNEL); + if (!iccsense->rails) + return -ENOMEM; + + iccsense->data_valid = true; + for (i = 0; i < stbl.nr_entry; ++i) { + struct pwr_rail_t *r = &stbl.rail[i]; + struct nvbios_extdev_func extdev; + struct nvkm_iccsense_rail *rail; + struct nvkm_i2c_bus *i2c_bus; + u8 addr; + + if (!r->mode || r->resistor_mohm == 0) + continue; + + if (nvbios_extdev_parse(bios, r->extdev_id, &extdev)) + continue; + + if (extdev.type == 0xff) + continue; + + if (extdev.bus) + i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC); + else + i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI); + if (!i2c_bus) + continue; + + addr = extdev.addr >> 1; + if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr, + extdev.type, r->rail)) { + iccsense->data_valid = false; + nvkm_warn(subdev, "found unknown or invalid rail entry" + " type 0x%x rail %i, power reading might be" + " invalid\n", extdev.type, r->rail); + continue; + } + + rail = &iccsense->rails[iccsense->rail_count]; + switch (extdev.type) { + case NVBIOS_EXTDEV_INA209: + rail->read = nvkm_iccsense_ina209_read; + break; + case NVBIOS_EXTDEV_INA219: + rail->read = nvkm_iccsense_ina219_read; + break; + case NVBIOS_EXTDEV_INA3221: + rail->read = nvkm_iccsense_ina3221_read; + break; + } + + rail->addr = addr; + rail->rail = r->rail; + rail->mohm = r->resistor_mohm; + rail->i2c = &i2c_bus->i2c; + ++iccsense->rail_count; + } + return 0; +} + +struct nvkm_subdev_func iccsense_func = { + .oneinit = nvkm_iccsense_oneinit, + .dtor = nvkm_iccsense_dtor, +}; + +void +nvkm_iccsense_ctor(struct nvkm_device *device, int index, + struct nvkm_iccsense *iccsense) +{ + nvkm_subdev_ctor(&iccsense_func, device, index, 0, &iccsense->subdev); +} + +int +nvkm_iccsense_new_(struct nvkm_device *device, int index, + struct nvkm_iccsense **iccsense) +{ + if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL))) + return -ENOMEM; + nvkm_iccsense_ctor(device, index, *iccsense); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/gf100.c new file mode 100644 index 000000000..cccff1c8a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/gf100.c @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Karol Herbst + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Karol Herbst + */ +#include "priv.h" + +int +gf100_iccsense_new(struct nvkm_device *device, int index, + struct nvkm_iccsense **piccsense) +{ + return nvkm_iccsense_new_(device, index, piccsense); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h new file mode 100644 index 000000000..ed398b81e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h @@ -0,0 +1,16 @@ +#ifndef __NVKM_ICCSENSE_PRIV_H__ +#define __NVKM_ICCSENSE_PRIV_H__ +#define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev) +#include <subdev/iccsense.h> + +struct nvkm_iccsense_rail { + int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *); + struct i2c_adapter *i2c; + u8 addr; + u8 rail; + u8 mohm; +}; + +void nvkm_iccsense_ctor(struct nvkm_device *, int, struct nvkm_iccsense *); +int nvkm_iccsense_new_(struct nvkm_device *, int, struct nvkm_iccsense **); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 4c20fec64..6b8f2a19b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -228,6 +228,8 @@ gk20a_instobj_release_dma(struct nvkm_memory *memory) struct gk20a_instmem *imem = node->imem; struct nvkm_ltc *ltc = imem->base.subdev.device->ltc; + /* in case we got a write-combined mapping */ + wmb(); nvkm_ltc_invalidate(ltc); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild index f8108df3c..932b36659 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild @@ -2,4 +2,4 @@ nvkm-y += nvkm/subdev/ltc/base.o nvkm-y += nvkm/subdev/ltc/gf100.o nvkm-y += nvkm/subdev/ltc/gk104.o nvkm-y += nvkm/subdev/ltc/gm107.o -nvkm-y += nvkm/subdev/ltc/gm204.o +nvkm-y += nvkm/subdev/ltc/gm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c index fb0de83da..c9eb67796 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c @@ -129,9 +129,7 @@ gf100_ltc_invalidate(struct nvkm_ltc *ltc) s64 taken; nvkm_wr32(device, 0x70004, 0x00000001); - taken = nvkm_wait_msec(device, 2, 0x70004, 0x00000003, 0x00000000); - if (taken < 0) - nvkm_warn(<c->subdev, "LTC invalidate timeout\n"); + taken = nvkm_wait_msec(device, 2000, 0x70004, 0x00000003, 0x00000000); if (taken > 0) nvkm_debug(<c->subdev, "LTC invalidate took %lld ns\n", taken); @@ -144,9 +142,7 @@ gf100_ltc_flush(struct nvkm_ltc *ltc) s64 taken; nvkm_wr32(device, 0x70010, 0x00000001); - taken = nvkm_wait_msec(device, 2, 0x70010, 0x00000003, 0x00000000); - if (taken < 0) - nvkm_warn(<c->subdev, "LTC flush timeout\n"); + taken = nvkm_wait_msec(device, 2000, 0x70010, 0x00000003, 0x00000000); if (taken > 0) nvkm_debug(<c->subdev, "LTC flush took %lld ns\n", taken); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c index 2af1f9e10..e292f5679 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c @@ -43,10 +43,8 @@ gm107_ltc_cbc_wait(struct nvkm_ltc *ltc) for (c = 0; c < ltc->ltc_nr; c++) { for (s = 0; s < ltc->lts_nr; s++) { const u32 addr = 0x14046c + (c * 0x2000) + (s * 0x200); - nvkm_msec(device, 2000, - if (!nvkm_rd32(device, addr)) - break; - ); + nvkm_wait_msec(device, 2000, addr, + 0x00000004, 0x00000000); } } } @@ -75,7 +73,7 @@ gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s) { struct nvkm_subdev *subdev = <c->subdev; struct nvkm_device *device = subdev->device; - u32 base = 0x140000 + (c * 0x2000) + (s * 0x400); + u32 base = 0x140000 + (c * 0x2000) + (s * 0x200); u32 stat = nvkm_rd32(device, base + 0x00c); if (stat) { diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm204.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c index 5ad6fb9d0..2a29bfd51 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c @@ -27,7 +27,7 @@ #include <subdev/timer.h> static int -gm204_ltc_oneinit(struct nvkm_ltc *ltc) +gm200_ltc_oneinit(struct nvkm_ltc *ltc) { struct nvkm_device *device = ltc->subdev.device; @@ -37,15 +37,15 @@ gm204_ltc_oneinit(struct nvkm_ltc *ltc) return gf100_ltc_oneinit_tag_ram(ltc); } static void -gm204_ltc_init(struct nvkm_ltc *ltc) +gm200_ltc_init(struct nvkm_ltc *ltc) { nvkm_wr32(ltc->subdev.device, 0x17e278, ltc->tag_base); } static const struct nvkm_ltc_func -gm204_ltc = { - .oneinit = gm204_ltc_oneinit, - .init = gm204_ltc_init, +gm200_ltc = { + .oneinit = gm200_ltc_oneinit, + .init = gm200_ltc_init, .intr = gm107_ltc_intr, /*XXX: not validated */ .cbc_clear = gm107_ltc_cbc_clear, .cbc_wait = gm107_ltc_cbc_wait, @@ -57,7 +57,7 @@ gm204_ltc = { }; int -gm204_ltc_new(struct nvkm_device *device, int index, struct nvkm_ltc **pltc) +gm200_ltc_new(struct nvkm_device *device, int index, struct nvkm_ltc **pltc) { - return nvkm_ltc_new_(&gm204_ltc, device, index, pltc); + return nvkm_ltc_new_(&gm200_ltc, device, index, pltc); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h index 770294457..e2faccffe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h @@ -24,8 +24,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, /* 0x0058: proc_list_head */ 0x54534f48, - 0x00000507, - 0x000004a4, + 0x0000050a, + 0x000004a7, 0x00000000, 0x00000000, 0x00000000, @@ -46,8 +46,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, 0x00000000, 0x584d454d, - 0x00000753, - 0x00000745, + 0x00000756, + 0x00000748, 0x00000000, 0x00000000, 0x00000000, @@ -68,8 +68,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, 0x00000000, 0x46524550, - 0x00000757, - 0x00000755, + 0x0000075a, + 0x00000758, 0x00000000, 0x00000000, 0x00000000, @@ -90,8 +90,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, 0x00000000, 0x5f433249, - 0x00000b87, - 0x00000a2a, + 0x00000b8a, + 0x00000a2d, 0x00000000, 0x00000000, 0x00000000, @@ -112,8 +112,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, 0x00000000, 0x54534554, - 0x00000bb0, - 0x00000b89, + 0x00000bb3, + 0x00000b8c, 0x00000000, 0x00000000, 0x00000000, @@ -134,8 +134,8 @@ uint32_t gf100_pmu_data[] = { 0x00000000, 0x00000000, 0x454c4449, - 0x00000bbc, - 0x00000bba, + 0x00000bbf, + 0x00000bbd, 0x00000000, 0x00000000, 0x00000000, @@ -229,26 +229,26 @@ uint32_t gf100_pmu_data[] = { /* 0x0370: memx_func_head */ 0x00000001, 0x00000000, - 0x00000546, + 0x00000549, /* 0x037c: memx_func_next */ 0x00000002, 0x00000000, - 0x000005d0, + 0x000005d3, 0x00000003, 0x00000002, - 0x0000069a, + 0x0000069d, 0x00040004, 0x00000000, - 0x000006b6, + 0x000006b9, 0x00010005, 0x00000000, - 0x000006d3, + 0x000006d6, 0x00010006, 0x00000000, - 0x00000658, + 0x0000065b, 0x00000007, 0x00000000, - 0x000006de, + 0x000006e1, /* 0x03c4: memx_func_tail */ /* 0x03c4: memx_ts_start */ 0x00000000, @@ -917,887 +917,887 @@ uint32_t gf100_pmu_data[] = { }; uint32_t gf100_pmu_code[] = { - 0x03930ef5, + 0x03920ef5, /* 0x0004: rd32 */ 0x07a007f1, 0xd00604b6, 0x04bd000e, - 0xf001d7f0, - 0x07f101d3, - 0x04b607ac, - 0x000dd006, -/* 0x0022: rd32_wait */ - 0xd7f104bd, - 0xd4b607ac, - 0x00ddcf06, - 0x7000d4f1, - 0xf1f21bf4, - 0xb607a4d7, - 0xddcf06d4, -/* 0x003f: wr32 */ - 0xf100f800, - 0xb607a007, - 0x0ed00604, - 0xf104bd00, - 0xb607a407, + 0x0001d7f1, + 0xf101d3f0, + 0xb607ac07, 0x0dd00604, - 0xf004bd00, - 0xd5f002d7, - 0x01d3f0f0, - 0x07ac07f1, +/* 0x0023: rd32_wait */ + 0xf104bd00, + 0xb607acd7, + 0xddcf06d4, + 0x00d4f100, + 0xf21bf470, + 0x07a4d7f1, + 0xcf06d4b6, + 0x00f800dd, +/* 0x0040: wr32 */ + 0x07a007f1, + 0xd00604b6, + 0x04bd000e, + 0x07a407f1, 0xd00604b6, 0x04bd000d, -/* 0x006c: wr32_wait */ - 0x07acd7f1, - 0xcf06d4b6, - 0xd4f100dd, - 0x1bf47000, -/* 0x007f: nsec */ - 0xf900f8f2, - 0xf080f990, - 0x84b62c87, - 0x0088cf06, -/* 0x008c: nsec_loop */ - 0xb62c97f0, - 0x99cf0694, - 0x0298bb00, - 0xf4069eb8, - 0x80fcf11e, - 0x00f890fc, -/* 0x00a4: wait */ - 0x80f990f9, - 0xb62c87f0, - 0x88cf0684, -/* 0x00b1: wait_loop */ - 0x02eeb900, - 0xb90421f4, - 0xadfd02da, - 0x06acb804, - 0xf0150bf4, + 0x00f2d7f1, + 0xf101d3f0, + 0xb607ac07, + 0x0dd00604, +/* 0x006b: wr32_wait */ + 0xf104bd00, + 0xb607acd7, + 0xddcf06d4, + 0x00d4f100, + 0xf21bf470, +/* 0x007e: nsec */ + 0x90f900f8, + 0x87f080f9, + 0x0684b62c, +/* 0x008b: nsec_loop */ + 0xf00088cf, 0x94b62c97, 0x0099cf06, 0xb80298bb, - 0x1ef4069b, -/* 0x00d5: wait_done */ - 0xfc80fcdf, -/* 0x00db: intr_watchdog */ - 0x9800f890, - 0x96b003e9, - 0x2a0bf400, - 0xbb9a0a98, - 0x1cf4029a, - 0x01d7f00f, - 0x02d221f5, - 0x0ef494bd, -/* 0x00f9: intr_watchdog_next_time */ - 0x9b0a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x0108: intr_watchdog_next_time_set */ -/* 0x010b: intr_watchdog_next_proc */ - 0x809b0980, - 0xe0b603e9, - 0x68e6b158, - 0xc61bf402, -/* 0x011a: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x84b605d0, + 0x1ef4069e, + 0xfc80fcf1, +/* 0x00a3: wait */ + 0xf900f890, + 0xf080f990, + 0x84b62c87, 0x0088cf06, - 0xf10180b6, - 0xb605d007, +/* 0x00b0: wait_loop */ + 0xf402eeb9, + 0xdab90421, + 0x04adfd02, + 0xf406acb8, + 0x97f0150b, + 0x0694b62c, + 0xbb0099cf, + 0x9bb80298, + 0xdf1ef406, +/* 0x00d4: wait_done */ + 0x90fc80fc, +/* 0x00da: intr_watchdog */ + 0xe99800f8, + 0x0096b003, + 0x982a0bf4, + 0x9abb9a0a, + 0x0f1cf402, + 0xf501d7f0, + 0xbd02d121, + 0x150ef494, +/* 0x00f8: intr_watchdog_next_time */ + 0xb09b0a98, + 0x0bf400a6, + 0x069ab809, +/* 0x0107: intr_watchdog_next_time_set */ + 0x80061cf4, +/* 0x010a: intr_watchdog_next_proc */ + 0xe9809b09, + 0x58e0b603, + 0x0268e6b1, + 0xf8c61bf4, +/* 0x0119: intr */ + 0xbd00f900, + 0xf980f904, + 0xf9a0f990, + 0xf9c0f9b0, + 0xf9e0f9d0, + 0x00f7f0f0, + 0xf90188fe, + 0xd087f180, + 0x0684b605, + 0xb60088cf, + 0x07f10180, + 0x04b605d0, + 0x0008d006, + 0x87f004bd, + 0x0684b608, + 0xc40088cf, + 0x0bf40289, + 0x9b008023, + 0xf458e7f0, + 0x0998da21, + 0x0096b09b, + 0xf0110bf4, + 0x04b63407, + 0x0009d006, + 0x098004bd, +/* 0x017d: intr_skip_watchdog */ + 0x0089e49a, + 0x480bf408, + 0x068897f1, + 0xcf0694b6, + 0x9ac40099, + 0x2c0bf402, + 0x04c0c7f1, + 0xcf06c4b6, + 0xc0f900cc, + 0x4f48e7f1, + 0x5453e3f1, + 0xf500d7f0, + 0xfc033621, + 0xc007f1c0, + 0x0604b604, + 0xbd000cd0, +/* 0x01bd: intr_subintr_skip_fifo */ + 0x8807f104, + 0x0604b606, + 0xbd0009d0, +/* 0x01c9: intr_skip_subintr */ + 0xe097f104, + 0xfd90bd00, + 0x07f00489, + 0x0604b604, + 0xbd0008d0, + 0xfe80fc04, + 0xf0fc0088, + 0xd0fce0fc, + 0xb0fcc0fc, + 0x90fca0fc, + 0x00fc80fc, + 0xf80032f4, +/* 0x01f9: ticks_from_ns */ + 0xf9c0f901, + 0xcbd7f1b0, + 0x00d3f000, + 0x040b21f5, + 0x03e8ccec, + 0xf400b4b0, + 0xeeec120b, + 0xd7f103e8, + 0xd3f000cb, + 0x0b21f500, +/* 0x0221: ticks_from_ns_quit */ + 0x02ceb904, + 0xc0fcb0fc, +/* 0x022a: ticks_from_us */ + 0xc0f900f8, + 0xd7f1b0f9, + 0xd3f000cb, + 0x0b21f500, + 0x02ceb904, + 0xf400b4b0, + 0xe4bd050b, +/* 0x0244: ticks_from_us_quit */ + 0xc0fcb0fc, +/* 0x024a: ticks_to_us */ + 0xd7f100f8, + 0xd3f000cb, + 0xecedff00, +/* 0x0256: timer */ + 0x90f900f8, + 0x32f480f9, + 0x03f89810, + 0xf40086b0, + 0x84bd651c, + 0xb63807f0, 0x08d00604, 0xf004bd00, - 0x84b60887, + 0x84b63487, 0x0088cf06, - 0xf40289c4, - 0x0080230b, - 0x58e7f09b, - 0x98db21f4, - 0x96b09b09, - 0x110bf400, + 0xbb9a0998, + 0xe9bb0298, + 0x03fe8000, + 0xb60887f0, + 0x88cf0684, + 0x0284f000, + 0xf0261bf4, + 0x84b63487, + 0x0088cf06, + 0xf406e0b8, + 0xe8b8090b, + 0x111cf406, +/* 0x02ac: timer_reset */ 0xb63407f0, - 0x09d00604, + 0x0ed00604, 0x8004bd00, -/* 0x017e: intr_skip_watchdog */ - 0x89e49a09, - 0x0bf40800, - 0x8897f148, - 0x0694b606, - 0xc40099cf, - 0x0bf4029a, - 0xc0c7f12c, - 0x06c4b604, - 0xf900cccf, - 0x48e7f1c0, - 0x53e3f14f, - 0x00d7f054, - 0x033721f5, - 0x07f1c0fc, - 0x04b604c0, - 0x000cd006, -/* 0x01be: intr_subintr_skip_fifo */ - 0x07f104bd, - 0x04b60688, - 0x0009d006, -/* 0x01ca: intr_skip_subintr */ - 0x97f104bd, - 0x90bd00e0, - 0xf00489fd, - 0x04b60407, - 0x0008d006, - 0x80fc04bd, - 0xfc0088fe, - 0xfce0fcf0, - 0xfcc0fcd0, - 0xfca0fcb0, - 0xfc80fc90, - 0x0032f400, -/* 0x01fa: ticks_from_ns */ - 0xc0f901f8, - 0xd7f1b0f9, - 0xd3f000cb, - 0x0821f500, - 0xe8ccec04, - 0x00b4b003, - 0xec120bf4, - 0xf103e8ee, - 0xf000cbd7, - 0x21f500d3, -/* 0x0222: ticks_from_ns_quit */ - 0xceb90408, - 0xfcb0fc02, -/* 0x022b: ticks_from_us */ - 0xf900f8c0, - 0xf1b0f9c0, - 0xf000cbd7, - 0x21f500d3, - 0xceb90408, - 0x00b4b002, - 0xbd050bf4, -/* 0x0245: ticks_from_us_quit */ - 0xfcb0fce4, -/* 0x024b: ticks_to_us */ - 0xf100f8c0, - 0xf000cbd7, - 0xedff00d3, -/* 0x0257: timer */ - 0xf900f8ec, - 0xf480f990, - 0xf8981032, - 0x0086b003, - 0xbd651cf4, - 0x3807f084, +/* 0x02ba: timer_enable */ + 0x87f09a0e, + 0x3807f001, 0xd00604b6, 0x04bd0008, - 0xb63487f0, - 0x88cf0684, - 0x9a099800, - 0xbb0298bb, - 0xfe8000e9, - 0x0887f003, - 0xcf0684b6, - 0x84f00088, - 0x261bf402, - 0xb63487f0, - 0x88cf0684, - 0x06e0b800, - 0xb8090bf4, - 0x1cf406e8, -/* 0x02ad: timer_reset */ - 0x3407f011, - 0xd00604b6, - 0x04bd000e, -/* 0x02bb: timer_enable */ - 0xf09a0e80, - 0x07f00187, - 0x0604b638, - 0xbd0008d0, -/* 0x02c9: timer_done */ - 0x1031f404, +/* 0x02c8: timer_done */ + 0xfc1031f4, + 0xf890fc80, +/* 0x02d1: send_proc */ + 0xf980f900, + 0x05e89890, + 0xf004e998, + 0x89b80486, + 0x2a0bf406, + 0x940398c4, + 0x80b60488, + 0x008ebb18, + 0x8000fa98, + 0x8d80008a, + 0x028c8001, + 0xb6038b80, + 0x94f00190, + 0x04e98007, +/* 0x030b: send_done */ + 0xfc0231f4, + 0xf880fc90, +/* 0x0311: find */ + 0xf080f900, + 0x31f45887, +/* 0x0319: find_loop */ + 0x008a9801, + 0xf406aeb8, + 0x80b6100b, + 0x6886b158, + 0xf01bf402, +/* 0x032f: find_done */ + 0xb90132f4, + 0x80fc028e, +/* 0x0336: send */ + 0x21f500f8, + 0x01f40311, +/* 0x033f: recv */ + 0xf900f897, + 0x9880f990, + 0xe99805e8, + 0x0132f404, + 0xf40689b8, + 0x89c43d0b, + 0x0180b603, + 0x800784f0, + 0xea9805e8, + 0xfef0f902, + 0xf0f9018f, + 0x9402efb9, + 0xe9bb0499, + 0x18e0b600, + 0x9803eb98, + 0xed9802ec, + 0x00ee9801, + 0xf0fca5f9, + 0xf400f8fe, + 0xf0fc0131, +/* 0x038c: recv_done */ 0x90fc80fc, -/* 0x02d2: send_proc */ - 0x80f900f8, - 0xe89890f9, - 0x04e99805, - 0xb80486f0, - 0x0bf40689, - 0x0398c42a, - 0xb6048894, - 0x8ebb1880, - 0x00fa9800, - 0x80008a80, - 0x8c80018d, - 0x038b8002, - 0xf00190b6, - 0xe9800794, - 0x0231f404, -/* 0x030c: send_done */ - 0x80fc90fc, -/* 0x0312: find */ - 0x80f900f8, - 0xf45887f0, -/* 0x031a: find_loop */ - 0x8a980131, - 0x06aeb800, - 0xb6100bf4, - 0x86b15880, - 0x1bf40268, - 0x0132f4f0, -/* 0x0330: find_done */ - 0xfc028eb9, -/* 0x0337: send */ - 0xf500f880, - 0xf4031221, - 0x00f89701, -/* 0x0340: recv */ - 0x80f990f9, - 0x9805e898, - 0x32f404e9, - 0x0689b801, - 0xc43d0bf4, - 0x80b60389, - 0x0784f001, - 0x9805e880, - 0xf0f902ea, - 0xf9018ffe, - 0x02efb9f0, - 0xbb049994, - 0xe0b600e9, - 0x03eb9818, - 0x9802ec98, - 0xee9801ed, - 0xfca5f900, - 0x00f8fef0, - 0xfc0131f4, -/* 0x038d: recv_done */ - 0xfc80fcf0, -/* 0x0393: init */ - 0xf100f890, - 0xb6010817, - 0x11cf0614, - 0x0911e700, - 0x0814b601, - 0xf10014fe, - 0xf000e017, - 0x07f00013, - 0x0604b61c, - 0xbd0001d0, - 0xff17f004, - 0xb61407f0, - 0x01d00604, - 0xf004bd00, - 0x15f10217, - 0x07f00800, - 0x0604b610, - 0xbd0001d0, - 0x1a17f104, - 0x0013f001, - 0xf40010fe, - 0x17f01031, - 0x3807f001, +/* 0x0392: init */ + 0x17f100f8, + 0x14b60108, + 0x0011cf06, + 0x010911e7, + 0xfe0814b6, + 0x17f10014, + 0x13f000e0, + 0x1c07f000, + 0xd00604b6, + 0x04bd0001, + 0xf0ff17f0, + 0x04b61407, + 0x0001d006, + 0x17f004bd, + 0x0015f102, + 0x1007f008, 0xd00604b6, 0x04bd0001, -/* 0x03f7: init_proc */ - 0x9858f7f0, - 0x16b001f1, - 0xfa0bf400, - 0xf0b615f9, - 0xf20ef458, -/* 0x0408: mulu32_32_64 */ - 0x20f910f9, - 0x40f930f9, - 0x9510e195, - 0xc4bd10d2, - 0xedffb4bd, - 0x301dffc0, - 0xf10234b9, - 0xb6ffff34, - 0x45b61034, - 0x00c3bb10, - 0xff01b4bb, - 0x34b930e2, - 0xff34f102, - 0x1034b6ff, - 0xbb1045b6, - 0xb4bb00c3, - 0x3012ff01, - 0xfc00b3bb, - 0xfc30fc40, - 0xf810fc20, -/* 0x0459: host_send */ - 0xb017f100, + 0x011917f1, + 0xf10013f0, + 0xfeffff14, + 0x31f40010, + 0x0117f010, + 0xb63807f0, + 0x01d00604, + 0xf004bd00, +/* 0x03fa: init_proc */ + 0xf19858f7, + 0x0016b001, + 0xf9fa0bf4, + 0x58f0b615, +/* 0x040b: mulu32_32_64 */ + 0xf9f20ef4, + 0xf920f910, + 0x9540f930, + 0xd29510e1, + 0xbdc4bd10, + 0xc0edffb4, + 0xb9301dff, + 0x34f10234, + 0x34b6ffff, + 0x1045b610, + 0xbb00c3bb, + 0xe2ff01b4, + 0x0234b930, + 0xffff34f1, + 0xb61034b6, + 0xc3bb1045, + 0x01b4bb00, + 0xbb3012ff, + 0x40fc00b3, + 0x20fc30fc, + 0x00f810fc, +/* 0x045c: host_send */ + 0x04b017f1, + 0xcf0614b6, + 0x27f10011, + 0x24b604a0, + 0x0022cf06, + 0xf40612b8, + 0x1ec4320b, + 0x04ee9407, + 0x0270e0b7, + 0x9803eb98, + 0xed9802ec, + 0x00ee9801, + 0x033621f5, + 0xc40110b6, + 0x07f10f1e, + 0x04b604b0, + 0x000ed006, + 0x0ef404bd, +/* 0x04a5: host_send_done */ +/* 0x04a7: host_recv */ + 0xf100f8ba, + 0xf14e4917, + 0xb8525413, + 0x0bf406e1, +/* 0x04b5: host_recv_wait */ + 0xcc17f1aa, 0x0614b604, 0xf10011cf, - 0xb604a027, + 0xb604c827, 0x22cf0624, - 0x0612b800, - 0xc4320bf4, - 0xee94071e, - 0x70e0b704, - 0x03eb9802, - 0x9802ec98, - 0xee9801ed, - 0x3721f500, - 0x0110b603, - 0xf10f1ec4, - 0xb604b007, - 0x0ed00604, - 0xf404bd00, -/* 0x04a2: host_send_done */ - 0x00f8ba0e, -/* 0x04a4: host_recv */ - 0x4e4917f1, - 0x525413f1, - 0xf406e1b8, -/* 0x04b2: host_recv_wait */ - 0x17f1aa0b, - 0x14b604cc, - 0x0011cf06, - 0x04c827f1, - 0xcf0624b6, - 0x16f00022, - 0x0612b808, - 0xc4e60bf4, - 0x34b60723, - 0xf030b704, - 0x033b8002, - 0x80023c80, - 0x3e80013d, - 0x0120b600, - 0xf10f24f0, - 0xb604c807, - 0x02d00604, - 0xf004bd00, - 0x07f04027, - 0x0604b600, - 0xbd0002d0, -/* 0x0507: host_init */ - 0xf100f804, - 0xb6008017, - 0x15f11014, - 0x07f10270, - 0x04b604d0, - 0x0001d006, - 0x17f104bd, + 0x0816f000, + 0xf40612b8, + 0x23c4e60b, + 0x0434b607, + 0x02f030b7, + 0x80033b80, + 0x3d80023c, + 0x003e8001, + 0xf00120b6, + 0x07f10f24, + 0x04b604c8, + 0x0002d006, + 0x27f004bd, + 0x0007f040, + 0xd00604b6, + 0x04bd0002, +/* 0x050a: host_init */ + 0x17f100f8, 0x14b60080, - 0xf015f110, - 0xdc07f102, + 0x7015f110, + 0xd007f102, 0x0604b604, 0xbd0001d0, - 0x0117f004, - 0x04c407f1, + 0x8017f104, + 0x1014b600, + 0x02f015f1, + 0x04dc07f1, 0xd00604b6, 0x04bd0001, -/* 0x0546: memx_func_enter */ - 0x67f100f8, - 0x77f11620, - 0x73f1f55d, - 0x6eb9ffff, - 0x0421f402, - 0xfd02d8b9, - 0x60f90487, - 0xd0fc80f9, - 0x21f4e0fc, - 0xfe77f13f, - 0xff73f1ff, + 0xf10117f0, + 0xb604c407, + 0x01d00604, + 0xf804bd00, +/* 0x0549: memx_func_enter */ + 0x2067f100, + 0x5d77f116, + 0xff73f1f5, 0x026eb9ff, 0xb90421f4, 0x87fd02d8, 0xf960f904, 0xfcd0fc80, - 0x3f21f4e0, - 0x26f067f1, + 0x4021f4e0, + 0xfffe77f1, + 0xffff73f1, 0xf4026eb9, 0xd8b90421, 0x0487fd02, 0x80f960f9, 0xe0fcd0fc, - 0xf03f21f4, + 0xf14021f4, + 0xb926f067, + 0x21f4026e, + 0x02d8b904, + 0xf90487fd, + 0xfc80f960, + 0xf4e0fcd0, + 0x67f04021, + 0xe007f104, + 0x0604b607, + 0xbd0006d0, +/* 0x05b5: memx_func_enter_wait */ + 0xc067f104, + 0x0664b607, + 0xf00066cf, + 0x0bf40464, + 0x2c67f0f3, + 0xcf0664b6, + 0x06800066, +/* 0x05d3: memx_func_leave */ + 0xf000f8f1, + 0x64b62c67, + 0x0066cf06, + 0xf0f20680, 0x07f10467, - 0x04b607e0, + 0x04b607e4, 0x0006d006, -/* 0x05b2: memx_func_enter_wait */ +/* 0x05ee: memx_func_leave_wait */ 0x67f104bd, 0x64b607c0, 0x0066cf06, 0xf40464f0, - 0x67f0f30b, - 0x0664b62c, - 0x800066cf, - 0x00f8f106, -/* 0x05d0: memx_func_leave */ - 0xb62c67f0, - 0x66cf0664, - 0xf2068000, - 0xf10467f0, - 0xb607e407, - 0x06d00604, -/* 0x05eb: memx_func_leave_wait */ - 0xf104bd00, - 0xb607c067, - 0x66cf0664, - 0x0464f000, - 0xf1f31bf4, - 0xf126f067, - 0xf0000177, + 0x67f1f31b, + 0x77f126f0, + 0x73f00001, + 0x026eb900, + 0xb90421f4, + 0x87fd02d8, + 0xf960f905, + 0xfcd0fc80, + 0x4021f4e0, + 0x162067f1, + 0xf4026eb9, + 0xd8b90421, + 0x0587fd02, + 0x80f960f9, + 0xe0fcd0fc, + 0xf14021f4, + 0xf00aa277, 0x6eb90073, 0x0421f402, 0xfd02d8b9, 0x60f90587, 0xd0fc80f9, 0x21f4e0fc, - 0x2067f13f, - 0x026eb916, - 0xb90421f4, - 0x87fd02d8, - 0xf960f905, - 0xfcd0fc80, - 0x3f21f4e0, - 0x0aa277f1, - 0xb90073f0, - 0x21f4026e, - 0x02d8b904, - 0xf90587fd, - 0xfc80f960, - 0xf4e0fcd0, - 0x00f83f21, -/* 0x0658: memx_func_wait_vblank */ - 0xb0001698, - 0x0bf40066, - 0x0166b013, - 0xf4060bf4, -/* 0x066a: memx_func_wait_vblank_head1 */ - 0x77f12e0e, - 0x0ef40020, -/* 0x0671: memx_func_wait_vblank_head0 */ - 0x0877f107, -/* 0x0675: memx_func_wait_vblank_0 */ - 0xc467f100, - 0x0664b607, - 0xfd0066cf, - 0x1bf40467, -/* 0x0685: memx_func_wait_vblank_1 */ - 0xc467f1f3, - 0x0664b607, - 0xfd0066cf, - 0x0bf40467, -/* 0x0695: memx_func_wait_vblank_fini */ - 0x0410b6f3, -/* 0x069a: memx_func_wr32 */ - 0x169800f8, - 0x01159800, - 0xf90810b6, - 0xfc50f960, - 0xf4e0fcd0, - 0x42b63f21, - 0xe91bf402, -/* 0x06b6: memx_func_wait */ - 0x87f000f8, - 0x0684b62c, - 0x980088cf, - 0x1d98001e, - 0x021c9801, - 0xb6031b98, - 0x21f41010, -/* 0x06d3: memx_func_delay */ - 0x9800f8a4, - 0x10b6001e, - 0x7f21f404, -/* 0x06de: memx_func_train */ - 0x00f800f8, -/* 0x06e0: memx_exec */ - 0xd0f9e0f9, - 0xb902c1b9, -/* 0x06ea: memx_exec_next */ - 0x139802b2, +/* 0x065b: memx_func_wait_vblank */ + 0x9800f840, + 0x66b00016, + 0x130bf400, + 0xf40166b0, + 0x0ef4060b, +/* 0x066d: memx_func_wait_vblank_head1 */ + 0x2077f12e, + 0x070ef400, +/* 0x0674: memx_func_wait_vblank_head0 */ + 0x000877f1, +/* 0x0678: memx_func_wait_vblank_0 */ + 0x07c467f1, + 0xcf0664b6, + 0x67fd0066, + 0xf31bf404, +/* 0x0688: memx_func_wait_vblank_1 */ + 0x07c467f1, + 0xcf0664b6, + 0x67fd0066, + 0xf30bf404, +/* 0x0698: memx_func_wait_vblank_fini */ + 0xf80410b6, +/* 0x069d: memx_func_wr32 */ + 0x00169800, + 0xb6011598, + 0x60f90810, + 0xd0fc50f9, + 0x21f4e0fc, + 0x0242b640, + 0xf8e91bf4, +/* 0x06b9: memx_func_wait */ + 0x2c87f000, + 0xcf0684b6, + 0x1e980088, + 0x011d9800, + 0x98021c98, + 0x10b6031b, + 0xa321f410, +/* 0x06d6: memx_func_delay */ + 0x1e9800f8, 0x0410b600, - 0x01f034e7, - 0x01e033e7, - 0xf00132b6, - 0x35980c30, - 0xb855f9de, - 0x1ef40612, - 0xf10b98e4, - 0xbbf20c98, - 0xb7f102cb, - 0xb4b607c4, - 0x00bbcf06, - 0xe0fcd0fc, - 0x033721f5, -/* 0x0726: memx_info */ - 0xc67000f8, - 0x0e0bf401, -/* 0x072c: memx_info_data */ - 0x03ccc7f1, - 0x0800b7f1, -/* 0x0737: memx_info_train */ - 0xf10b0ef4, - 0xf10bccc7, -/* 0x073f: memx_info_send */ - 0xf50100b7, - 0xf8033721, -/* 0x0745: memx_recv */ - 0x01d6b000, - 0xb0980bf4, - 0x0bf400d6, -/* 0x0753: memx_init */ - 0xf800f8d8, -/* 0x0755: perf_recv */ -/* 0x0757: perf_init */ - 0xf800f800, -/* 0x0759: i2c_drive_scl */ - 0x0036b000, - 0xf1110bf4, - 0xb607e007, - 0x01d00604, - 0xf804bd00, -/* 0x076d: i2c_drive_scl_lo */ - 0xe407f100, - 0x0604b607, - 0xbd0001d0, -/* 0x077b: i2c_drive_sda */ - 0xb000f804, - 0x0bf40036, - 0xe007f111, - 0x0604b607, - 0xbd0002d0, -/* 0x078f: i2c_drive_sda_lo */ - 0xf100f804, - 0xb607e407, - 0x02d00604, - 0xf804bd00, -/* 0x079d: i2c_sense_scl */ - 0x0132f400, - 0x07c437f1, - 0xcf0634b6, - 0x31fd0033, - 0x060bf404, -/* 0x07b3: i2c_sense_scl_done */ - 0xf80131f4, -/* 0x07b5: i2c_sense_sda */ - 0x0132f400, - 0x07c437f1, - 0xcf0634b6, - 0x32fd0033, - 0x060bf404, -/* 0x07cb: i2c_sense_sda_done */ - 0xf80131f4, -/* 0x07cd: i2c_raise_scl */ - 0xf140f900, - 0xf0089847, - 0x21f50137, -/* 0x07da: i2c_raise_scl_wait */ - 0xe7f10759, - 0x21f403e8, - 0x9d21f57f, - 0x0901f407, - 0xf40142b6, -/* 0x07ee: i2c_raise_scl_done */ - 0x40fcef1b, -/* 0x07f2: i2c_start */ - 0x21f500f8, - 0x11f4079d, - 0xb521f50d, - 0x0611f407, -/* 0x0803: i2c_start_rep */ - 0xf0300ef4, - 0x21f50037, - 0x37f00759, - 0x7b21f501, - 0x0076bb07, - 0xf90465b6, - 0x04659450, - 0xbd0256bb, - 0x0475fd50, - 0x21f550fc, - 0x64b607cd, - 0x1f11f404, -/* 0x0830: i2c_start_send */ - 0xf50037f0, - 0xf1077b21, - 0xf41388e7, - 0x37f07f21, - 0x5921f500, - 0x88e7f107, - 0x7f21f413, -/* 0x084c: i2c_start_out */ -/* 0x084e: i2c_stop */ - 0x37f000f8, - 0x5921f500, - 0x0037f007, - 0x077b21f5, - 0x03e8e7f1, - 0xf07f21f4, - 0x21f50137, - 0xe7f10759, - 0x21f41388, - 0x0137f07f, - 0x077b21f5, - 0x1388e7f1, - 0xf87f21f4, -/* 0x0881: i2c_bitw */ - 0x7b21f500, - 0xe8e7f107, - 0x7f21f403, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xcd21f550, - 0x0464b607, - 0xf11811f4, - 0xf41388e7, - 0x37f07f21, - 0x5921f500, - 0x88e7f107, - 0x7f21f413, -/* 0x08c0: i2c_bitw_out */ -/* 0x08c2: i2c_bitr */ - 0x37f000f8, - 0x7b21f501, + 0xf87e21f4, +/* 0x06e1: memx_func_train */ +/* 0x06e3: memx_exec */ + 0xf900f800, + 0xb9d0f9e0, + 0xb2b902c1, +/* 0x06ed: memx_exec_next */ + 0x00139802, + 0xe70410b6, + 0xe701f034, + 0xb601e033, + 0x30f00132, + 0xde35980c, + 0x12b855f9, + 0xe41ef406, + 0x98f10b98, + 0xcbbbf20c, + 0xc4b7f102, + 0x06b4b607, + 0xfc00bbcf, + 0xf5e0fcd0, + 0xf8033621, +/* 0x0729: memx_info */ + 0x01c67000, +/* 0x072f: memx_info_data */ + 0xf10e0bf4, + 0xf103ccc7, + 0xf40800b7, +/* 0x073a: memx_info_train */ + 0xc7f10b0e, + 0xb7f10bcc, +/* 0x0742: memx_info_send */ + 0x21f50100, + 0x00f80336, +/* 0x0748: memx_recv */ + 0xf401d6b0, + 0xd6b0980b, + 0xd80bf400, +/* 0x0756: memx_init */ + 0x00f800f8, +/* 0x0758: perf_recv */ +/* 0x075a: perf_init */ + 0x00f800f8, +/* 0x075c: i2c_drive_scl */ + 0xf40036b0, + 0x07f1110b, + 0x04b607e0, + 0x0001d006, + 0x00f804bd, +/* 0x0770: i2c_drive_scl_lo */ + 0x07e407f1, + 0xd00604b6, + 0x04bd0001, +/* 0x077e: i2c_drive_sda */ + 0x36b000f8, + 0x110bf400, + 0x07e007f1, + 0xd00604b6, + 0x04bd0002, +/* 0x0792: i2c_drive_sda_lo */ + 0x07f100f8, + 0x04b607e4, + 0x0002d006, + 0x00f804bd, +/* 0x07a0: i2c_sense_scl */ + 0xf10132f4, + 0xb607c437, + 0x33cf0634, + 0x0431fd00, + 0xf4060bf4, +/* 0x07b6: i2c_sense_scl_done */ + 0x00f80131, +/* 0x07b8: i2c_sense_sda */ + 0xf10132f4, + 0xb607c437, + 0x33cf0634, + 0x0432fd00, + 0xf4060bf4, +/* 0x07ce: i2c_sense_sda_done */ + 0x00f80131, +/* 0x07d0: i2c_raise_scl */ + 0x47f140f9, + 0x37f00898, + 0x5c21f501, +/* 0x07dd: i2c_raise_scl_wait */ 0xe8e7f107, - 0x7f21f403, + 0x7e21f403, + 0x07a021f5, + 0xb60901f4, + 0x1bf40142, +/* 0x07f1: i2c_raise_scl_done */ + 0xf840fcef, +/* 0x07f5: i2c_start */ + 0xa021f500, + 0x0d11f407, + 0x07b821f5, + 0xf40611f4, +/* 0x0806: i2c_start_rep */ + 0x37f0300e, + 0x5c21f500, + 0x0137f007, + 0x077e21f5, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0xcd21f550, + 0xd021f550, 0x0464b607, - 0xf51b11f4, - 0xf007b521, +/* 0x0833: i2c_start_send */ + 0xf01f11f4, 0x21f50037, - 0xe7f10759, + 0xe7f1077e, 0x21f41388, - 0x013cf07f, -/* 0x0907: i2c_bitr_done */ - 0xf80131f4, -/* 0x0909: i2c_get_byte */ - 0x0057f000, -/* 0x090f: i2c_get_byte_next */ - 0xb60847f0, - 0x76bb0154, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb608c221, - 0x11f40464, - 0x0553fd2b, - 0xf40142b6, - 0x37f0d81b, + 0x0037f07e, + 0x075c21f5, + 0x1388e7f1, +/* 0x084f: i2c_start_out */ + 0xf87e21f4, +/* 0x0851: i2c_stop */ + 0x0037f000, + 0x075c21f5, + 0xf50037f0, + 0xf1077e21, + 0xf403e8e7, + 0x37f07e21, + 0x5c21f501, + 0x88e7f107, + 0x7e21f413, + 0xf50137f0, + 0xf1077e21, + 0xf41388e7, + 0x00f87e21, +/* 0x0884: i2c_bitw */ + 0x077e21f5, + 0x03e8e7f1, + 0xbb7e21f4, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x07d021f5, + 0xf40464b6, + 0xe7f11811, + 0x21f41388, + 0x0037f07e, + 0x075c21f5, + 0x1388e7f1, +/* 0x08c3: i2c_bitw_out */ + 0xf87e21f4, +/* 0x08c5: i2c_bitr */ + 0x0137f000, + 0x077e21f5, + 0x03e8e7f1, + 0xbb7e21f4, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x07d021f5, + 0xf40464b6, + 0x21f51b11, + 0x37f007b8, + 0x5c21f500, + 0x88e7f107, + 0x7e21f413, + 0xf4013cf0, +/* 0x090a: i2c_bitr_done */ + 0x00f80131, +/* 0x090c: i2c_get_byte */ + 0xf00057f0, +/* 0x0912: i2c_get_byte_next */ + 0x54b60847, 0x0076bb01, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, 0x21f550fc, - 0x64b60881, -/* 0x0959: i2c_get_byte_done */ -/* 0x095b: i2c_put_byte */ - 0xf000f804, -/* 0x095e: i2c_put_byte_next */ - 0x42b60847, - 0x3854ff01, + 0x64b608c5, + 0x2b11f404, + 0xb60553fd, + 0x1bf40142, + 0x0137f0d8, + 0xb60076bb, + 0x50f90465, + 0xbb046594, + 0x50bd0256, + 0xfc0475fd, + 0x8421f550, + 0x0464b608, +/* 0x095c: i2c_get_byte_done */ +/* 0x095e: i2c_put_byte */ + 0x47f000f8, +/* 0x0961: i2c_put_byte_next */ + 0x0142b608, + 0xbb3854ff, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x088421f5, + 0xf40464b6, + 0x46b03411, + 0xd81bf400, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0x8121f550, + 0xc521f550, 0x0464b608, - 0xb03411f4, - 0x1bf40046, - 0x0076bbd8, + 0xbb0f11f4, + 0x36b00076, + 0x061bf401, +/* 0x09b7: i2c_put_byte_done */ + 0xf80132f4, +/* 0x09b9: i2c_addr */ + 0x0076bb00, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, 0x21f550fc, - 0x64b608c2, - 0x0f11f404, - 0xb00076bb, - 0x1bf40136, - 0x0132f406, -/* 0x09b4: i2c_put_byte_done */ -/* 0x09b6: i2c_addr */ - 0x76bb00f8, + 0x64b607f5, + 0x2911f404, + 0x012ec3e7, + 0xfd0134b6, + 0x76bb0553, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0xf550fc04, - 0xb607f221, - 0x11f40464, - 0x2ec3e729, - 0x0134b601, - 0xbb0553fd, + 0xb6095e21, +/* 0x09fe: i2c_addr_done */ + 0x00f80464, +/* 0x0a00: i2c_acquire_addr */ + 0xb6f8cec7, + 0xe0b702e4, + 0xee980d1c, +/* 0x0a0f: i2c_acquire */ + 0xf500f800, + 0xf40a0021, + 0xd9f00421, + 0x4021f403, +/* 0x0a1e: i2c_release */ + 0x21f500f8, + 0x21f40a00, + 0x03daf004, + 0xf84021f4, +/* 0x0a2d: i2c_recv */ + 0x0132f400, + 0xb6f8c1c7, + 0x16b00214, + 0x3a1ff528, + 0xf413a001, + 0x0032980c, + 0x0ccc13a0, + 0xf4003198, + 0xd0f90231, + 0xd0f9e0f9, + 0x000067f1, + 0x100063f1, + 0xbb016792, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x095b21f5, -/* 0x09fb: i2c_addr_done */ - 0xf80464b6, -/* 0x09fd: i2c_acquire_addr */ - 0xf8cec700, - 0xb702e4b6, - 0x980d1ce0, - 0x00f800ee, -/* 0x0a0c: i2c_acquire */ - 0x09fd21f5, - 0xf00421f4, - 0x21f403d9, -/* 0x0a1b: i2c_release */ - 0xf500f83f, - 0xf409fd21, - 0xdaf00421, - 0x3f21f403, -/* 0x0a2a: i2c_recv */ - 0x32f400f8, - 0xf8c1c701, - 0xb00214b6, - 0x1ff52816, - 0x13a0013a, - 0x32980cf4, - 0xcc13a000, - 0x0031980c, - 0xf90231f4, - 0xf9e0f9d0, - 0x0067f1d0, - 0x0063f100, - 0x01679210, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x0c21f550, - 0x0464b60a, - 0xd6b0d0fc, - 0xb31bf500, - 0x0057f000, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xb621f550, - 0x0464b609, - 0x00d011f5, - 0xbbe0c5c7, + 0x0a0f21f5, + 0xfc0464b6, + 0x00d6b0d0, + 0x00b31bf5, + 0xbb0057f0, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x095b21f5, + 0x09b921f5, 0xf50464b6, - 0xf000ad11, - 0x76bb0157, + 0xc700d011, + 0x76bbe0c5, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0xf550fc04, - 0xb609b621, + 0xb6095e21, 0x11f50464, - 0x76bb008a, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb6090921, - 0x11f40464, - 0xe05bcb6a, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x4e21f550, - 0x0464b608, - 0xbd025bb9, - 0x430ef474, -/* 0x0b30: i2c_recv_not_rd08 */ - 0xf401d6b0, - 0x57f03d1b, - 0xb621f500, - 0x3311f409, - 0xf5e0c5c7, - 0xf4095b21, - 0x57f02911, - 0xb621f500, - 0x1f11f409, - 0xf5e0b5c7, - 0xf4095b21, - 0x21f51511, - 0x74bd084e, - 0xf408c5c7, - 0x32f4091b, - 0x030ef402, -/* 0x0b70: i2c_recv_not_wr08 */ -/* 0x0b70: i2c_recv_done */ - 0xf5f8cec7, - 0xfc0a1b21, - 0xf4d0fce0, - 0x7cb90a12, - 0x3721f502, -/* 0x0b85: i2c_recv_exit */ -/* 0x0b87: i2c_init */ - 0xf800f803, -/* 0x0b89: test_recv */ - 0xd817f100, - 0x0614b605, - 0xb60011cf, - 0x07f10110, - 0x04b605d8, - 0x0001d006, - 0xe7f104bd, - 0xe3f1d900, - 0x21f5134f, - 0x00f80257, -/* 0x0bb0: test_init */ - 0x0800e7f1, - 0x025721f5, -/* 0x0bba: idle_recv */ + 0x57f000ad, + 0x0076bb01, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b609b9, + 0x8a11f504, + 0x0076bb00, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b6090c, + 0x6a11f404, + 0xbbe05bcb, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x085121f5, + 0xb90464b6, + 0x74bd025b, +/* 0x0b33: i2c_recv_not_rd08 */ + 0xb0430ef4, + 0x1bf401d6, + 0x0057f03d, + 0x09b921f5, + 0xc73311f4, + 0x21f5e0c5, + 0x11f4095e, + 0x0057f029, + 0x09b921f5, + 0xc71f11f4, + 0x21f5e0b5, + 0x11f4095e, + 0x5121f515, + 0xc774bd08, + 0x1bf408c5, + 0x0232f409, +/* 0x0b73: i2c_recv_not_wr08 */ +/* 0x0b73: i2c_recv_done */ + 0xc7030ef4, + 0x21f5f8ce, + 0xe0fc0a1e, + 0x12f4d0fc, + 0x027cb90a, + 0x033621f5, +/* 0x0b88: i2c_recv_exit */ +/* 0x0b8a: i2c_init */ 0x00f800f8, -/* 0x0bbc: idle */ - 0xf10031f4, - 0xb605d417, - 0x11cf0614, - 0x0110b600, - 0x05d407f1, - 0xd00604b6, - 0x04bd0001, -/* 0x0bd8: idle_loop */ - 0xf45817f0, -/* 0x0bde: idle_proc */ -/* 0x0bde: idle_proc_exec */ - 0x10f90232, - 0xf5021eb9, - 0xfc034021, - 0x0911f410, - 0xf40231f4, -/* 0x0bf2: idle_proc_next */ - 0x10b6ef0e, - 0x061fb858, - 0xf4e61bf4, - 0x28f4dd02, - 0xbb0ef400, - 0x00000000, +/* 0x0b8c: test_recv */ + 0x05d817f1, + 0xcf0614b6, + 0x10b60011, + 0xd807f101, + 0x0604b605, + 0xbd0001d0, + 0x00e7f104, + 0x4fe3f1d9, + 0x5621f513, +/* 0x0bb3: test_init */ + 0xf100f802, + 0xf50800e7, + 0xf8025621, +/* 0x0bbd: idle_recv */ +/* 0x0bbf: idle */ + 0xf400f800, + 0x17f10031, + 0x14b605d4, + 0x0011cf06, + 0xf10110b6, + 0xb605d407, + 0x01d00604, +/* 0x0bdb: idle_loop */ + 0xf004bd00, + 0x32f45817, +/* 0x0be1: idle_proc */ +/* 0x0be1: idle_proc_exec */ + 0xb910f902, + 0x21f5021e, + 0x10fc033f, + 0xf40911f4, + 0x0ef40231, +/* 0x0bf5: idle_proc_next */ + 0x5810b6ef, + 0xf4061fb8, + 0x02f4e61b, + 0x0028f4dd, + 0x00bb0ef4, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h index 7bf6b39ed..2d5bdc539 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h @@ -24,8 +24,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, /* 0x0058: proc_list_head */ 0x54534f48, - 0x00000492, - 0x0000043b, + 0x00000495, + 0x0000043e, 0x00000000, 0x00000000, 0x00000000, @@ -46,8 +46,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, 0x00000000, 0x584d454d, - 0x00000680, - 0x00000672, + 0x00000683, + 0x00000675, 0x00000000, 0x00000000, 0x00000000, @@ -68,8 +68,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, 0x00000000, 0x46524550, - 0x00000684, - 0x00000682, + 0x00000687, + 0x00000685, 0x00000000, 0x00000000, 0x00000000, @@ -90,8 +90,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, 0x00000000, 0x5f433249, - 0x00000a9f, - 0x00000942, + 0x00000aa2, + 0x00000945, 0x00000000, 0x00000000, 0x00000000, @@ -112,8 +112,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, 0x00000000, 0x54534554, - 0x00000ac2, - 0x00000aa1, + 0x00000ac5, + 0x00000aa4, 0x00000000, 0x00000000, 0x00000000, @@ -134,8 +134,8 @@ uint32_t gf119_pmu_data[] = { 0x00000000, 0x00000000, 0x454c4449, - 0x00000ace, - 0x00000acc, + 0x00000ad1, + 0x00000acf, 0x00000000, 0x00000000, 0x00000000, @@ -229,26 +229,26 @@ uint32_t gf119_pmu_data[] = { /* 0x0370: memx_func_head */ 0x00000001, 0x00000000, - 0x000004c8, + 0x000004cb, /* 0x037c: memx_func_next */ 0x00000002, 0x00000000, - 0x00000549, + 0x0000054c, 0x00000003, 0x00000002, - 0x000005cd, + 0x000005d0, 0x00040004, 0x00000000, - 0x000005e9, + 0x000005ec, 0x00010005, 0x00000000, - 0x00000603, + 0x00000606, 0x00010006, 0x00000000, - 0x000005c8, + 0x000005cb, 0x00000007, 0x00000000, - 0x0000060e, + 0x00000611, /* 0x03c4: memx_func_tail */ /* 0x03c4: memx_ts_start */ 0x00000000, @@ -916,821 +916,821 @@ uint32_t gf119_pmu_data[] = { }; uint32_t gf119_pmu_code[] = { - 0x03420ef5, + 0x03410ef5, /* 0x0004: rd32 */ 0x07a007f1, 0xbd000ed0, - 0x01d7f004, - 0xf101d3f0, - 0xd007ac07, - 0x04bd000d, -/* 0x001c: rd32_wait */ - 0x07acd7f1, - 0xf100ddcf, - 0xf47000d4, - 0xd7f1f51b, - 0xddcf07a4, -/* 0x0033: wr32 */ - 0xf100f800, - 0xd007a007, - 0x04bd000e, - 0x07a407f1, + 0x01d7f104, + 0x01d3f000, + 0x07ac07f1, 0xbd000dd0, - 0x02d7f004, - 0xf0f0d5f0, - 0x07f101d3, - 0x0dd007ac, -/* 0x0057: wr32_wait */ - 0xf104bd00, - 0xcf07acd7, - 0xd4f100dd, - 0x1bf47000, -/* 0x0067: nsec */ - 0xf900f8f5, - 0xf080f990, - 0x88cf2c87, -/* 0x0071: nsec_loop */ - 0x2c97f000, - 0xbb0099cf, - 0x9eb80298, - 0xf41ef406, - 0x90fc80fc, -/* 0x0086: wait */ +/* 0x001d: rd32_wait */ + 0xacd7f104, + 0x00ddcf07, + 0x7000d4f1, + 0xf1f51bf4, + 0xcf07a4d7, + 0x00f800dd, +/* 0x0034: wr32 */ + 0x07a007f1, + 0xbd000ed0, + 0xa407f104, + 0x000dd007, + 0xd7f104bd, + 0xd3f000f2, + 0xac07f101, + 0x000dd007, +/* 0x0056: wr32_wait */ + 0xd7f104bd, + 0xddcf07ac, + 0x00d4f100, + 0xf51bf470, +/* 0x0066: nsec */ 0x90f900f8, 0x87f080f9, 0x0088cf2c, -/* 0x0090: wait_loop */ - 0xf402eeb9, - 0xdab90421, - 0x04adfd02, - 0xf406acb8, - 0x97f0120b, - 0x0099cf2c, - 0xb80298bb, - 0x1ef4069b, -/* 0x00b1: wait_done */ - 0xfc80fce2, -/* 0x00b7: intr_watchdog */ - 0x9800f890, - 0x96b003e9, - 0x2a0bf400, - 0xbb9a0a98, - 0x1cf4029a, - 0x01d7f00f, - 0x028121f5, - 0x0ef494bd, -/* 0x00d5: intr_watchdog_next_time */ - 0x9b0a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x00e4: intr_watchdog_next_time_set */ -/* 0x00e7: intr_watchdog_next_proc */ - 0x809b0980, - 0xe0b603e9, - 0x68e6b158, - 0xc61bf402, -/* 0x00f6: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x88cf05d0, - 0x0180b600, - 0x05d007f1, - 0xbd0008d0, - 0x0887f004, - 0xc40088cf, - 0x0bf40289, - 0x9b008020, - 0xf458e7f0, - 0x0998b721, - 0x0096b09b, - 0xf00e0bf4, - 0x09d03407, - 0x8004bd00, -/* 0x014e: intr_skip_watchdog */ - 0x89e49a09, - 0x0bf40800, - 0x8897f13c, - 0x0099cf06, - 0xf4029ac4, - 0xc7f1260b, - 0xcccf04c0, - 0xf1c0f900, - 0xf14f48e7, - 0xf05453e3, - 0x21f500d7, - 0xc0fc02e6, - 0x04c007f1, - 0xbd000cd0, -/* 0x0185: intr_subintr_skip_fifo */ - 0x8807f104, - 0x0009d006, -/* 0x018e: intr_skip_subintr */ - 0x97f104bd, - 0x90bd00e0, - 0xf00489fd, - 0x08d00407, - 0xfc04bd00, - 0x0088fe80, - 0xe0fcf0fc, - 0xc0fcd0fc, - 0xa0fcb0fc, - 0x80fc90fc, - 0x32f400fc, -/* 0x01bb: ticks_from_ns */ - 0xf901f800, +/* 0x0070: nsec_loop */ + 0xcf2c97f0, + 0x98bb0099, + 0x069eb802, + 0xfcf41ef4, + 0xf890fc80, +/* 0x0085: wait */ + 0xf990f900, + 0x2c87f080, +/* 0x008f: wait_loop */ + 0xb90088cf, + 0x21f402ee, + 0x02dab904, + 0xb804adfd, + 0x0bf406ac, + 0x2c97f012, + 0xbb0099cf, + 0x9bb80298, + 0xe21ef406, +/* 0x00b0: wait_done */ + 0x90fc80fc, +/* 0x00b6: intr_watchdog */ + 0xe99800f8, + 0x0096b003, + 0x982a0bf4, + 0x9abb9a0a, + 0x0f1cf402, + 0xf501d7f0, + 0xbd028021, + 0x150ef494, +/* 0x00d4: intr_watchdog_next_time */ + 0xb09b0a98, + 0x0bf400a6, + 0x069ab809, +/* 0x00e3: intr_watchdog_next_time_set */ + 0x80061cf4, +/* 0x00e6: intr_watchdog_next_proc */ + 0xe9809b09, + 0x58e0b603, + 0x0268e6b1, + 0xf8c61bf4, +/* 0x00f5: intr */ + 0xbd00f900, + 0xf980f904, + 0xf9a0f990, + 0xf9c0f9b0, + 0xf9e0f9d0, + 0x00f7f0f0, + 0xf90188fe, + 0xd087f180, + 0x0088cf05, + 0xf10180b6, + 0xd005d007, + 0x04bd0008, + 0xcf0887f0, + 0x89c40088, + 0x200bf402, + 0xf09b0080, + 0x21f458e7, + 0x9b0998b6, + 0xf40096b0, + 0x07f00e0b, + 0x0009d034, + 0x098004bd, +/* 0x014d: intr_skip_watchdog */ + 0x0089e49a, + 0x3c0bf408, + 0x068897f1, + 0xc40099cf, + 0x0bf4029a, + 0xc0c7f126, + 0x00cccf04, + 0xe7f1c0f9, + 0xe3f14f48, + 0xd7f05453, + 0xe521f500, + 0xf1c0fc02, + 0xd004c007, + 0x04bd000c, +/* 0x0184: intr_subintr_skip_fifo */ + 0x068807f1, + 0xbd0009d0, +/* 0x018d: intr_skip_subintr */ + 0xe097f104, + 0xfd90bd00, + 0x07f00489, + 0x0008d004, + 0x80fc04bd, + 0xfc0088fe, + 0xfce0fcf0, + 0xfcc0fcd0, + 0xfca0fcb0, + 0xfc80fc90, + 0x0032f400, +/* 0x01ba: ticks_from_ns */ + 0xc0f901f8, + 0xd7f1b0f9, + 0xd3f00144, + 0xab21f500, + 0xe8ccec03, + 0x00b4b003, + 0xec120bf4, + 0xf103e8ee, + 0xf00144d7, + 0x21f500d3, +/* 0x01e2: ticks_from_ns_quit */ + 0xceb903ab, + 0xfcb0fc02, +/* 0x01eb: ticks_from_us */ + 0xf900f8c0, 0xf1b0f9c0, 0xf00144d7, 0x21f500d3, - 0xccec03a8, - 0xb4b003e8, - 0x120bf400, - 0x03e8eeec, - 0x0144d7f1, - 0xf500d3f0, -/* 0x01e3: ticks_from_ns_quit */ - 0xb903a821, - 0xb0fc02ce, - 0x00f8c0fc, -/* 0x01ec: ticks_from_us */ - 0xb0f9c0f9, - 0x0144d7f1, - 0xf500d3f0, - 0xb903a821, - 0xb4b002ce, - 0x050bf400, -/* 0x0206: ticks_from_us_quit */ - 0xb0fce4bd, - 0x00f8c0fc, -/* 0x020c: ticks_to_us */ - 0x0144d7f1, - 0xff00d3f0, - 0x00f8eced, -/* 0x0218: timer */ - 0x80f990f9, - 0x981032f4, - 0x86b003f8, - 0x531cf400, - 0x07f084bd, - 0x0008d038, - 0x87f004bd, - 0x0088cf34, - 0xbb9a0998, - 0xe9bb0298, - 0x03fe8000, - 0xcf0887f0, - 0x84f00088, - 0x201bf402, - 0xcf3487f0, - 0xe0b80088, - 0x090bf406, - 0xf406e8b8, -/* 0x0262: timer_reset */ - 0x07f00e1c, - 0x000ed034, - 0x0e8004bd, -/* 0x026d: timer_enable */ - 0x0187f09a, - 0xd03807f0, - 0x04bd0008, -/* 0x0278: timer_done */ - 0xfc1031f4, + 0xceb903ab, + 0x00b4b002, + 0xbd050bf4, +/* 0x0205: ticks_from_us_quit */ + 0xfcb0fce4, +/* 0x020b: ticks_to_us */ + 0xf100f8c0, + 0xf00144d7, + 0xedff00d3, +/* 0x0217: timer */ + 0xf900f8ec, + 0xf480f990, + 0xf8981032, + 0x0086b003, + 0xbd531cf4, + 0x3807f084, + 0xbd0008d0, + 0x3487f004, + 0x980088cf, + 0x98bb9a09, + 0x00e9bb02, + 0xf003fe80, + 0x88cf0887, + 0x0284f000, + 0xf0201bf4, + 0x88cf3487, + 0x06e0b800, + 0xb8090bf4, + 0x1cf406e8, +/* 0x0261: timer_reset */ + 0x3407f00e, + 0xbd000ed0, + 0x9a0e8004, +/* 0x026c: timer_enable */ + 0xf00187f0, + 0x08d03807, +/* 0x0277: timer_done */ + 0xf404bd00, + 0x80fc1031, + 0x00f890fc, +/* 0x0280: send_proc */ + 0x90f980f9, + 0x9805e898, + 0x86f004e9, + 0x0689b804, + 0xc42a0bf4, + 0x88940398, + 0x1880b604, + 0x98008ebb, + 0x8a8000fa, + 0x018d8000, + 0x80028c80, + 0x90b6038b, + 0x0794f001, + 0xf404e980, +/* 0x02ba: send_done */ + 0x90fc0231, + 0x00f880fc, +/* 0x02c0: find */ + 0x87f080f9, + 0x0131f458, +/* 0x02c8: find_loop */ + 0xb8008a98, + 0x0bf406ae, + 0x5880b610, + 0x026886b1, + 0xf4f01bf4, +/* 0x02de: find_done */ + 0x8eb90132, + 0xf880fc02, +/* 0x02e5: send */ + 0xc021f500, + 0x9701f402, +/* 0x02ee: recv */ + 0x90f900f8, + 0xe89880f9, + 0x04e99805, + 0xb80132f4, + 0x0bf40689, + 0x0389c43d, + 0xf00180b6, + 0xe8800784, + 0x02ea9805, + 0x8ffef0f9, + 0xb9f0f901, + 0x999402ef, + 0x00e9bb04, + 0x9818e0b6, + 0xec9803eb, + 0x01ed9802, + 0xf900ee98, + 0xfef0fca5, + 0x31f400f8, +/* 0x033b: recv_done */ + 0xfcf0fc01, 0xf890fc80, -/* 0x0281: send_proc */ - 0xf980f900, - 0x05e89890, - 0xf004e998, - 0x89b80486, - 0x2a0bf406, - 0x940398c4, - 0x80b60488, - 0x008ebb18, - 0x8000fa98, - 0x8d80008a, - 0x028c8001, - 0xb6038b80, - 0x94f00190, - 0x04e98007, -/* 0x02bb: send_done */ - 0xfc0231f4, - 0xf880fc90, -/* 0x02c1: find */ - 0xf080f900, - 0x31f45887, -/* 0x02c9: find_loop */ - 0x008a9801, - 0xf406aeb8, - 0x80b6100b, - 0x6886b158, - 0xf01bf402, -/* 0x02df: find_done */ - 0xb90132f4, - 0x80fc028e, -/* 0x02e6: send */ - 0x21f500f8, - 0x01f402c1, -/* 0x02ef: recv */ - 0xf900f897, - 0x9880f990, - 0xe99805e8, - 0x0132f404, - 0xf40689b8, - 0x89c43d0b, - 0x0180b603, - 0x800784f0, - 0xea9805e8, - 0xfef0f902, - 0xf0f9018f, - 0x9402efb9, - 0xe9bb0499, - 0x18e0b600, - 0x9803eb98, - 0xed9802ec, - 0x00ee9801, - 0xf0fca5f9, - 0xf400f8fe, - 0xf0fc0131, -/* 0x033c: recv_done */ - 0x90fc80fc, -/* 0x0342: init */ - 0x17f100f8, - 0x11cf0108, - 0x0911e700, - 0x0814b601, - 0xf10014fe, - 0xf000e017, - 0x07f00013, - 0x0001d01c, - 0x17f004bd, - 0x1407f0ff, +/* 0x0341: init */ + 0x0817f100, + 0x0011cf01, + 0x010911e7, + 0xfe0814b6, + 0x17f10014, + 0x13f000e0, + 0x1c07f000, 0xbd0001d0, - 0x0217f004, - 0x080015f1, - 0xd01007f0, - 0x04bd0001, - 0x00f617f1, - 0xfe0013f0, - 0x31f40010, - 0x0117f010, - 0xd03807f0, + 0xff17f004, + 0xd01407f0, 0x04bd0001, -/* 0x0397: init_proc */ - 0x9858f7f0, - 0x16b001f1, - 0xfa0bf400, - 0xf0b615f9, - 0xf20ef458, -/* 0x03a8: mulu32_32_64 */ - 0x20f910f9, - 0x40f930f9, - 0x9510e195, - 0xc4bd10d2, - 0xedffb4bd, - 0x301dffc0, - 0xf10234b9, - 0xb6ffff34, - 0x45b61034, - 0x00c3bb10, - 0xff01b4bb, - 0x34b930e2, - 0xff34f102, - 0x1034b6ff, - 0xbb1045b6, - 0xb4bb00c3, - 0x3012ff01, - 0xfc00b3bb, - 0xfc30fc40, - 0xf810fc20, -/* 0x03f9: host_send */ - 0xb017f100, - 0x0011cf04, - 0x04a027f1, - 0xb80022cf, - 0x0bf40612, - 0x071ec42f, - 0xb704ee94, - 0x980270e0, - 0xec9803eb, - 0x01ed9802, - 0xf500ee98, - 0xb602e621, - 0x1ec40110, - 0xb007f10f, - 0x000ed004, - 0x0ef404bd, -/* 0x0439: host_send_done */ -/* 0x043b: host_recv */ - 0xf100f8c3, - 0xf14e4917, - 0xb8525413, - 0x0bf406e1, -/* 0x0449: host_recv_wait */ - 0xcc17f1b3, - 0x0011cf04, - 0x04c827f1, - 0xf00022cf, - 0x12b80816, - 0xec0bf406, - 0xb60723c4, - 0x30b70434, - 0x3b8002f0, - 0x023c8003, - 0x80013d80, - 0x20b6003e, - 0x0f24f001, - 0x04c807f1, - 0xbd0002d0, - 0x4027f004, - 0xd00007f0, - 0x04bd0002, -/* 0x0492: host_init */ + 0xf10217f0, + 0xf0080015, + 0x01d01007, + 0xf104bd00, + 0xf000f517, + 0x14f10013, + 0x10feffff, + 0x1031f400, + 0xf00117f0, + 0x01d03807, + 0xf004bd00, +/* 0x039a: init_proc */ + 0xf19858f7, + 0x0016b001, + 0xf9fa0bf4, + 0x58f0b615, +/* 0x03ab: mulu32_32_64 */ + 0xf9f20ef4, + 0xf920f910, + 0x9540f930, + 0xd29510e1, + 0xbdc4bd10, + 0xc0edffb4, + 0xb9301dff, + 0x34f10234, + 0x34b6ffff, + 0x1045b610, + 0xbb00c3bb, + 0xe2ff01b4, + 0x0234b930, + 0xffff34f1, + 0xb61034b6, + 0xc3bb1045, + 0x01b4bb00, + 0xbb3012ff, + 0x40fc00b3, + 0x20fc30fc, + 0x00f810fc, +/* 0x03fc: host_send */ + 0x04b017f1, + 0xf10011cf, + 0xcf04a027, + 0x12b80022, + 0x2f0bf406, + 0x94071ec4, + 0xe0b704ee, + 0xeb980270, + 0x02ec9803, + 0x9801ed98, + 0x21f500ee, + 0x10b602e5, + 0x0f1ec401, + 0x04b007f1, + 0xbd000ed0, + 0xc30ef404, +/* 0x043c: host_send_done */ +/* 0x043e: host_recv */ 0x17f100f8, - 0x14b60080, - 0x7015f110, - 0xd007f102, - 0x0001d004, - 0x17f104bd, - 0x14b60080, - 0xf015f110, - 0xdc07f102, - 0x0001d004, - 0x17f004bd, - 0xc407f101, - 0x0001d004, - 0x00f804bd, -/* 0x04c8: memx_func_enter */ - 0x162067f1, - 0xf55d77f1, - 0xffff73f1, - 0xf4026eb9, - 0xd8b90421, - 0x0487fd02, - 0x80f960f9, - 0xe0fcd0fc, - 0xf13321f4, - 0xf1fffe77, + 0x13f14e49, + 0xe1b85254, + 0xb30bf406, +/* 0x044c: host_recv_wait */ + 0x04cc17f1, + 0xf10011cf, + 0xcf04c827, + 0x16f00022, + 0x0612b808, + 0xc4ec0bf4, + 0x34b60723, + 0xf030b704, + 0x033b8002, + 0x80023c80, + 0x3e80013d, + 0x0120b600, + 0xf10f24f0, + 0xd004c807, + 0x04bd0002, + 0xf04027f0, + 0x02d00007, + 0xf804bd00, +/* 0x0495: host_init */ + 0x8017f100, + 0x1014b600, + 0x027015f1, + 0x04d007f1, + 0xbd0001d0, + 0x8017f104, + 0x1014b600, + 0x02f015f1, + 0x04dc07f1, + 0xbd0001d0, + 0x0117f004, + 0x04c407f1, + 0xbd0001d0, +/* 0x04cb: memx_func_enter */ + 0xf100f804, + 0xf1162067, + 0xf1f55d77, 0xb9ffff73, 0x21f4026e, 0x02d8b904, 0xf90487fd, 0xfc80f960, 0xf4e0fcd0, - 0x67f13321, - 0x6eb926f0, + 0x77f13421, + 0x73f1fffe, + 0x6eb9ffff, 0x0421f402, 0xfd02d8b9, 0x60f90487, 0xd0fc80f9, 0x21f4e0fc, - 0x0467f033, - 0x07e007f1, + 0xf067f134, + 0x026eb926, + 0xb90421f4, + 0x87fd02d8, + 0xf960f904, + 0xfcd0fc80, + 0x3421f4e0, + 0xf10467f0, + 0xd007e007, + 0x04bd0006, +/* 0x0534: memx_func_enter_wait */ + 0x07c067f1, + 0xf00066cf, + 0x0bf40464, + 0x2c67f0f6, + 0x800066cf, + 0x00f8f106, +/* 0x054c: memx_func_leave */ + 0xcf2c67f0, + 0x06800066, + 0x0467f0f2, + 0x07e407f1, 0xbd0006d0, -/* 0x0531: memx_func_enter_wait */ +/* 0x0561: memx_func_leave_wait */ 0xc067f104, 0x0066cf07, 0xf40464f0, - 0x67f0f60b, - 0x0066cf2c, - 0xf8f10680, -/* 0x0549: memx_func_leave */ - 0x2c67f000, - 0x800066cf, - 0x67f0f206, - 0xe407f104, - 0x0006d007, -/* 0x055e: memx_func_leave_wait */ - 0x67f104bd, - 0x66cf07c0, - 0x0464f000, - 0xf1f61bf4, - 0xf126f067, - 0xf0000177, + 0x67f1f61b, + 0x77f126f0, + 0x73f00001, + 0x026eb900, + 0xb90421f4, + 0x87fd02d8, + 0xf960f905, + 0xfcd0fc80, + 0x3421f4e0, + 0x162067f1, + 0xf4026eb9, + 0xd8b90421, + 0x0587fd02, + 0x80f960f9, + 0xe0fcd0fc, + 0xf13421f4, + 0xf00aa277, 0x6eb90073, 0x0421f402, 0xfd02d8b9, 0x60f90587, 0xd0fc80f9, 0x21f4e0fc, - 0x2067f133, - 0x026eb916, - 0xb90421f4, - 0x87fd02d8, - 0xf960f905, - 0xfcd0fc80, - 0x3321f4e0, - 0x0aa277f1, - 0xb90073f0, - 0x21f4026e, - 0x02d8b904, - 0xf90587fd, - 0xfc80f960, - 0xf4e0fcd0, - 0x00f83321, -/* 0x05c8: memx_func_wait_vblank */ - 0xf80410b6, -/* 0x05cd: memx_func_wr32 */ - 0x00169800, - 0xb6011598, - 0x60f90810, - 0xd0fc50f9, - 0x21f4e0fc, - 0x0242b633, - 0xf8e91bf4, -/* 0x05e9: memx_func_wait */ - 0x2c87f000, - 0x980088cf, - 0x1d98001e, - 0x021c9801, - 0xb6031b98, - 0x21f41010, -/* 0x0603: memx_func_delay */ - 0x9800f886, - 0x10b6001e, - 0x6721f404, -/* 0x060e: memx_func_train */ - 0x00f800f8, -/* 0x0610: memx_exec */ - 0xd0f9e0f9, - 0xb902c1b9, -/* 0x061a: memx_exec_next */ - 0x139802b2, +/* 0x05cb: memx_func_wait_vblank */ + 0xb600f834, + 0x00f80410, +/* 0x05d0: memx_func_wr32 */ + 0x98001698, + 0x10b60115, + 0xf960f908, + 0xfcd0fc50, + 0x3421f4e0, + 0xf40242b6, + 0x00f8e91b, +/* 0x05ec: memx_func_wait */ + 0xcf2c87f0, + 0x1e980088, + 0x011d9800, + 0x98021c98, + 0x10b6031b, + 0x8521f410, +/* 0x0606: memx_func_delay */ + 0x1e9800f8, 0x0410b600, - 0x01f034e7, - 0x01e033e7, - 0xf00132b6, - 0x35980c30, - 0xb855f9de, - 0x1ef40612, - 0xf10b98e4, - 0xbbf20c98, - 0xb7f102cb, - 0xbbcf07c4, - 0xfcd0fc00, - 0xe621f5e0, -/* 0x0653: memx_info */ - 0x7000f802, - 0x0bf401c6, -/* 0x0659: memx_info_data */ - 0xccc7f10e, - 0x00b7f103, - 0x0b0ef408, -/* 0x0664: memx_info_train */ - 0x0bccc7f1, - 0x0100b7f1, -/* 0x066c: memx_info_send */ - 0x02e621f5, -/* 0x0672: memx_recv */ - 0xd6b000f8, - 0x9b0bf401, - 0xf400d6b0, - 0x00f8d80b, -/* 0x0680: memx_init */ -/* 0x0682: perf_recv */ - 0x00f800f8, -/* 0x0684: perf_init */ -/* 0x0686: i2c_drive_scl */ - 0x36b000f8, - 0x0e0bf400, - 0x07e007f1, - 0xbd0001d0, -/* 0x0697: i2c_drive_scl_lo */ - 0xf100f804, - 0xd007e407, + 0xf86621f4, +/* 0x0611: memx_func_train */ +/* 0x0613: memx_exec */ + 0xf900f800, + 0xb9d0f9e0, + 0xb2b902c1, +/* 0x061d: memx_exec_next */ + 0x00139802, + 0xe70410b6, + 0xe701f034, + 0xb601e033, + 0x30f00132, + 0xde35980c, + 0x12b855f9, + 0xe41ef406, + 0x98f10b98, + 0xcbbbf20c, + 0xc4b7f102, + 0x00bbcf07, + 0xe0fcd0fc, + 0x02e521f5, +/* 0x0656: memx_info */ + 0xc67000f8, + 0x0e0bf401, +/* 0x065c: memx_info_data */ + 0x03ccc7f1, + 0x0800b7f1, +/* 0x0667: memx_info_train */ + 0xf10b0ef4, + 0xf10bccc7, +/* 0x066f: memx_info_send */ + 0xf50100b7, + 0xf802e521, +/* 0x0675: memx_recv */ + 0x01d6b000, + 0xb09b0bf4, + 0x0bf400d6, +/* 0x0683: memx_init */ + 0xf800f8d8, +/* 0x0685: perf_recv */ +/* 0x0687: perf_init */ + 0xf800f800, +/* 0x0689: i2c_drive_scl */ + 0x0036b000, + 0xf10e0bf4, + 0xd007e007, 0x04bd0001, -/* 0x06a2: i2c_drive_sda */ - 0x36b000f8, - 0x0e0bf400, - 0x07e007f1, - 0xbd0002d0, -/* 0x06b3: i2c_drive_sda_lo */ - 0xf100f804, - 0xd007e407, +/* 0x069a: i2c_drive_scl_lo */ + 0x07f100f8, + 0x01d007e4, + 0xf804bd00, +/* 0x06a5: i2c_drive_sda */ + 0x0036b000, + 0xf10e0bf4, + 0xd007e007, 0x04bd0002, -/* 0x06be: i2c_sense_scl */ +/* 0x06b6: i2c_drive_sda_lo */ + 0x07f100f8, + 0x02d007e4, + 0xf804bd00, +/* 0x06c1: i2c_sense_scl */ + 0x0132f400, + 0x07c437f1, + 0xfd0033cf, + 0x0bf40431, + 0x0131f406, +/* 0x06d4: i2c_sense_scl_done */ +/* 0x06d6: i2c_sense_sda */ 0x32f400f8, 0xc437f101, 0x0033cf07, - 0xf40431fd, + 0xf40432fd, 0x31f4060b, -/* 0x06d1: i2c_sense_scl_done */ -/* 0x06d3: i2c_sense_sda */ - 0xf400f801, - 0x37f10132, - 0x33cf07c4, - 0x0432fd00, - 0xf4060bf4, -/* 0x06e6: i2c_sense_sda_done */ - 0x00f80131, -/* 0x06e8: i2c_raise_scl */ - 0x47f140f9, - 0x37f00898, - 0x8621f501, -/* 0x06f5: i2c_raise_scl_wait */ - 0xe8e7f106, - 0x6721f403, - 0x06be21f5, - 0xb60901f4, - 0x1bf40142, -/* 0x0709: i2c_raise_scl_done */ - 0xf840fcef, -/* 0x070d: i2c_start */ - 0xbe21f500, - 0x0d11f406, - 0x06d321f5, - 0xf40611f4, -/* 0x071e: i2c_start_rep */ - 0x37f0300e, - 0x8621f500, - 0x0137f006, - 0x06a221f5, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xe821f550, - 0x0464b606, -/* 0x074b: i2c_start_send */ - 0xf01f11f4, - 0x21f50037, - 0xe7f106a2, - 0x21f41388, - 0x0037f067, - 0x068621f5, - 0x1388e7f1, -/* 0x0767: i2c_start_out */ - 0xf86721f4, -/* 0x0769: i2c_stop */ - 0x0037f000, - 0x068621f5, - 0xf50037f0, - 0xf106a221, - 0xf403e8e7, - 0x37f06721, - 0x8621f501, - 0x88e7f106, - 0x6721f413, - 0xf50137f0, - 0xf106a221, - 0xf41388e7, - 0x00f86721, -/* 0x079c: i2c_bitw */ - 0x06a221f5, +/* 0x06e9: i2c_sense_sda_done */ +/* 0x06eb: i2c_raise_scl */ + 0xf900f801, + 0x9847f140, + 0x0137f008, + 0x068921f5, +/* 0x06f8: i2c_raise_scl_wait */ 0x03e8e7f1, - 0xbb6721f4, + 0xf56621f4, + 0xf406c121, + 0x42b60901, + 0xef1bf401, +/* 0x070c: i2c_raise_scl_done */ + 0x00f840fc, +/* 0x0710: i2c_start */ + 0x06c121f5, + 0xf50d11f4, + 0xf406d621, + 0x0ef40611, +/* 0x0721: i2c_start_rep */ + 0x0037f030, + 0x068921f5, + 0xf50137f0, + 0xbb06a521, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x06e821f5, + 0x06eb21f5, 0xf40464b6, - 0xe7f11811, +/* 0x074e: i2c_start_send */ + 0x37f01f11, + 0xa521f500, + 0x88e7f106, + 0x6621f413, + 0xf50037f0, + 0xf1068921, + 0xf41388e7, +/* 0x076a: i2c_start_out */ + 0x00f86621, +/* 0x076c: i2c_stop */ + 0xf50037f0, + 0xf0068921, + 0x21f50037, + 0xe7f106a5, + 0x21f403e8, + 0x0137f066, + 0x068921f5, + 0x1388e7f1, + 0xf06621f4, + 0x21f50137, + 0xe7f106a5, 0x21f41388, - 0x0037f067, - 0x068621f5, +/* 0x079f: i2c_bitw */ + 0xf500f866, + 0xf106a521, + 0xf403e8e7, + 0x76bb6621, + 0x0465b600, + 0x659450f9, + 0x0256bb04, + 0x75fd50bd, + 0xf550fc04, + 0xb606eb21, + 0x11f40464, + 0x88e7f118, + 0x6621f413, + 0xf50037f0, + 0xf1068921, + 0xf41388e7, +/* 0x07de: i2c_bitw_out */ + 0x00f86621, +/* 0x07e0: i2c_bitr */ + 0xf50137f0, + 0xf106a521, + 0xf403e8e7, + 0x76bb6621, + 0x0465b600, + 0x659450f9, + 0x0256bb04, + 0x75fd50bd, + 0xf550fc04, + 0xb606eb21, + 0x11f40464, + 0xd621f51b, + 0x0037f006, + 0x068921f5, 0x1388e7f1, -/* 0x07db: i2c_bitw_out */ - 0xf86721f4, -/* 0x07dd: i2c_bitr */ - 0x0137f000, - 0x06a221f5, - 0x03e8e7f1, - 0xbb6721f4, - 0x65b60076, - 0x9450f904, - 0x56bb0465, - 0xfd50bd02, - 0x50fc0475, - 0x06e821f5, - 0xf40464b6, - 0x21f51b11, - 0x37f006d3, - 0x8621f500, - 0x88e7f106, - 0x6721f413, - 0xf4013cf0, -/* 0x0822: i2c_bitr_done */ - 0x00f80131, -/* 0x0824: i2c_get_byte */ - 0xf00057f0, -/* 0x082a: i2c_get_byte_next */ - 0x54b60847, - 0x0076bb01, - 0xf90465b6, - 0x04659450, - 0xbd0256bb, - 0x0475fd50, - 0x21f550fc, - 0x64b607dd, - 0x2b11f404, - 0xb60553fd, - 0x1bf40142, - 0x0137f0d8, + 0xf06621f4, + 0x31f4013c, +/* 0x0825: i2c_bitr_done */ +/* 0x0827: i2c_get_byte */ + 0xf000f801, + 0x47f00057, +/* 0x082d: i2c_get_byte_next */ + 0x0154b608, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0x9c21f550, + 0xe021f550, 0x0464b607, -/* 0x0874: i2c_get_byte_done */ -/* 0x0876: i2c_put_byte */ - 0x47f000f8, -/* 0x0879: i2c_put_byte_next */ - 0x0142b608, - 0xbb3854ff, + 0xfd2b11f4, + 0x42b60553, + 0xd81bf401, + 0xbb0137f0, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x079f21f5, +/* 0x0877: i2c_get_byte_done */ + 0xf80464b6, +/* 0x0879: i2c_put_byte */ + 0x0847f000, +/* 0x087c: i2c_put_byte_next */ + 0xff0142b6, + 0x76bb3854, + 0x0465b600, + 0x659450f9, + 0x0256bb04, + 0x75fd50bd, + 0xf550fc04, + 0xb6079f21, + 0x11f40464, + 0x0046b034, + 0xbbd81bf4, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x079c21f5, + 0x07e021f5, 0xf40464b6, - 0x46b03411, - 0xd81bf400, + 0x76bb0f11, + 0x0136b000, + 0xf4061bf4, +/* 0x08d2: i2c_put_byte_done */ + 0x00f80132, +/* 0x08d4: i2c_addr */ 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0xdd21f550, + 0x1021f550, 0x0464b607, - 0xbb0f11f4, - 0x36b00076, - 0x061bf401, -/* 0x08cf: i2c_put_byte_done */ - 0xf80132f4, -/* 0x08d1: i2c_addr */ - 0x0076bb00, + 0xe72911f4, + 0xb6012ec3, + 0x53fd0134, + 0x0076bb05, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, 0x21f550fc, - 0x64b6070d, - 0x2911f404, - 0x012ec3e7, - 0xfd0134b6, - 0x76bb0553, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb6087621, -/* 0x0916: i2c_addr_done */ - 0x00f80464, -/* 0x0918: i2c_acquire_addr */ - 0xb6f8cec7, - 0xe0b705e4, - 0x00f8d014, -/* 0x0924: i2c_acquire */ - 0x091821f5, - 0xf00421f4, - 0x21f403d9, -/* 0x0933: i2c_release */ - 0xf500f833, - 0xf4091821, - 0xdaf00421, - 0x3321f403, -/* 0x0942: i2c_recv */ - 0x32f400f8, - 0xf8c1c701, - 0xb00214b6, - 0x1ff52816, - 0x13a0013a, - 0x32980cf4, - 0xcc13a000, - 0x0031980c, - 0xf90231f4, - 0xf9e0f9d0, - 0x0067f1d0, - 0x0063f100, - 0x01679210, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x2421f550, - 0x0464b609, - 0xd6b0d0fc, - 0xb31bf500, - 0x0057f000, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xd121f550, - 0x0464b608, - 0x00d011f5, - 0xbbe0c5c7, + 0x64b60879, +/* 0x0919: i2c_addr_done */ +/* 0x091b: i2c_acquire_addr */ + 0xc700f804, + 0xe4b6f8ce, + 0x14e0b705, +/* 0x0927: i2c_acquire */ + 0xf500f8d0, + 0xf4091b21, + 0xd9f00421, + 0x3421f403, +/* 0x0936: i2c_release */ + 0x21f500f8, + 0x21f4091b, + 0x03daf004, + 0xf83421f4, +/* 0x0945: i2c_recv */ + 0x0132f400, + 0xb6f8c1c7, + 0x16b00214, + 0x3a1ff528, + 0xf413a001, + 0x0032980c, + 0x0ccc13a0, + 0xf4003198, + 0xd0f90231, + 0xd0f9e0f9, + 0x000067f1, + 0x100063f1, + 0xbb016792, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x087621f5, + 0x092721f5, + 0xfc0464b6, + 0x00d6b0d0, + 0x00b31bf5, + 0xbb0057f0, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x08d421f5, 0xf50464b6, - 0xf000ad11, - 0x76bb0157, + 0xc700d011, + 0x76bbe0c5, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0xf550fc04, - 0xb608d121, + 0xb6087921, 0x11f50464, - 0x76bb008a, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb6082421, - 0x11f40464, - 0xe05bcb6a, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x6921f550, - 0x0464b607, - 0xbd025bb9, - 0x430ef474, -/* 0x0a48: i2c_recv_not_rd08 */ - 0xf401d6b0, - 0x57f03d1b, - 0xd121f500, - 0x3311f408, - 0xf5e0c5c7, - 0xf4087621, - 0x57f02911, - 0xd121f500, - 0x1f11f408, - 0xf5e0b5c7, - 0xf4087621, - 0x21f51511, - 0x74bd0769, - 0xf408c5c7, - 0x32f4091b, - 0x030ef402, -/* 0x0a88: i2c_recv_not_wr08 */ -/* 0x0a88: i2c_recv_done */ - 0xf5f8cec7, - 0xfc093321, - 0xf4d0fce0, - 0x7cb90a12, - 0xe621f502, -/* 0x0a9d: i2c_recv_exit */ -/* 0x0a9f: i2c_init */ + 0x57f000ad, + 0x0076bb01, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b608d4, + 0x8a11f504, + 0x0076bb00, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b60827, + 0x6a11f404, + 0xbbe05bcb, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x076c21f5, + 0xb90464b6, + 0x74bd025b, +/* 0x0a4b: i2c_recv_not_rd08 */ + 0xb0430ef4, + 0x1bf401d6, + 0x0057f03d, + 0x08d421f5, + 0xc73311f4, + 0x21f5e0c5, + 0x11f40879, + 0x0057f029, + 0x08d421f5, + 0xc71f11f4, + 0x21f5e0b5, + 0x11f40879, + 0x6c21f515, + 0xc774bd07, + 0x1bf408c5, + 0x0232f409, +/* 0x0a8b: i2c_recv_not_wr08 */ +/* 0x0a8b: i2c_recv_done */ + 0xc7030ef4, + 0x21f5f8ce, + 0xe0fc0936, + 0x12f4d0fc, + 0x027cb90a, + 0x02e521f5, +/* 0x0aa0: i2c_recv_exit */ +/* 0x0aa2: i2c_init */ + 0x00f800f8, +/* 0x0aa4: test_recv */ + 0x05d817f1, + 0xb60011cf, + 0x07f10110, + 0x01d005d8, + 0xf104bd00, + 0xf1d900e7, + 0xf5134fe3, + 0xf8021721, +/* 0x0ac5: test_init */ + 0x00e7f100, + 0x1721f508, +/* 0x0acf: idle_recv */ 0xf800f802, -/* 0x0aa1: test_recv */ - 0xd817f100, - 0x0011cf05, - 0xf10110b6, - 0xd005d807, - 0x04bd0001, - 0xd900e7f1, - 0x134fe3f1, - 0x021821f5, -/* 0x0ac2: test_init */ - 0xe7f100f8, - 0x21f50800, - 0x00f80218, -/* 0x0acc: idle_recv */ -/* 0x0ace: idle */ - 0x31f400f8, - 0xd417f100, - 0x0011cf05, - 0xf10110b6, - 0xd005d407, - 0x04bd0001, -/* 0x0ae4: idle_loop */ - 0xf45817f0, -/* 0x0aea: idle_proc */ -/* 0x0aea: idle_proc_exec */ - 0x10f90232, - 0xf5021eb9, - 0xfc02ef21, - 0x0911f410, - 0xf40231f4, -/* 0x0afe: idle_proc_next */ - 0x10b6ef0e, - 0x061fb858, - 0xf4e61bf4, - 0x28f4dd02, - 0xc10ef400, - 0x00000000, +/* 0x0ad1: idle */ + 0x0031f400, + 0x05d417f1, + 0xb60011cf, + 0x07f10110, + 0x01d005d4, +/* 0x0ae7: idle_loop */ + 0xf004bd00, + 0x32f45817, +/* 0x0aed: idle_proc */ +/* 0x0aed: idle_proc_exec */ + 0xb910f902, + 0x21f5021e, + 0x10fc02ee, + 0xf40911f4, + 0x0ef40231, +/* 0x0b01: idle_proc_next */ + 0x5810b6ef, + 0xf4061fb8, + 0x02f4e61b, + 0x0028f4dd, + 0x00c10ef4, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h index 8a2b62864..3c731ff12 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h @@ -24,8 +24,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, /* 0x0058: proc_list_head */ 0x54534f48, - 0x00000447, - 0x000003f8, + 0x0000042c, + 0x000003df, 0x00000000, 0x00000000, 0x00000000, @@ -46,8 +46,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, 0x00000000, 0x584d454d, - 0x00000621, - 0x00000613, + 0x000005f3, + 0x000005e5, 0x00000000, 0x00000000, 0x00000000, @@ -68,8 +68,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, 0x00000000, 0x46524550, - 0x00000625, - 0x00000623, + 0x000005f7, + 0x000005f5, 0x00000000, 0x00000000, 0x00000000, @@ -90,8 +90,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, 0x00000000, 0x5f433249, - 0x00000a29, - 0x000008d0, + 0x000009f8, + 0x000008a2, 0x00000000, 0x00000000, 0x00000000, @@ -112,8 +112,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, 0x00000000, 0x54534554, - 0x00000a4a, - 0x00000a2b, + 0x00000a16, + 0x000009fa, 0x00000000, 0x00000000, 0x00000000, @@ -134,8 +134,8 @@ uint32_t gk208_pmu_data[] = { 0x00000000, 0x00000000, 0x454c4449, - 0x00000a55, - 0x00000a53, + 0x00000a21, + 0x00000a1f, 0x00000000, 0x00000000, 0x00000000, @@ -229,26 +229,26 @@ uint32_t gk208_pmu_data[] = { /* 0x0370: memx_func_head */ 0x00000001, 0x00000000, - 0x00000477, + 0x0000045c, /* 0x037c: memx_func_next */ 0x00000002, 0x00000000, - 0x000004f4, + 0x000004cf, 0x00000003, 0x00000002, - 0x00000574, + 0x00000546, 0x00040004, 0x00000000, - 0x00000591, + 0x00000563, 0x00010005, 0x00000000, - 0x000005ab, + 0x0000057d, 0x00010006, 0x00000000, - 0x0000056f, + 0x00000541, 0x00000007, 0x00000000, - 0x000005b7, + 0x00000589, /* 0x03c4: memx_func_tail */ /* 0x03c4: memx_ts_start */ 0x00000000, @@ -916,784 +916,771 @@ uint32_t gk208_pmu_data[] = { }; uint32_t gk208_pmu_code[] = { - 0x03100ef5, + 0x02f90ef5, /* 0x0004: rd32 */ 0xf607a040, 0x04bd000e, - 0xd3f0010d, + 0x0100018d, + 0xf607ac40, + 0x04bd000d, +/* 0x0018: rd32_wait */ + 0xcf07ac4d, + 0xd4f100dd, + 0x1bf47000, + 0x07a44df6, + 0xf800ddcf, +/* 0x002d: wr32 */ + 0x07a04000, + 0xbd000ef6, + 0x07a44004, + 0xbd000df6, + 0x00f28d04, 0x07ac4001, 0xbd000df6, -/* 0x0019: rd32_wait */ +/* 0x0049: wr32_wait */ 0x07ac4d04, 0xf100ddcf, 0xf47000d4, - 0xa44df61b, - 0x00ddcf07, -/* 0x002e: wr32 */ - 0xa04000f8, - 0x000ef607, - 0xa44004bd, - 0x000df607, - 0x020d04bd, - 0xf0f0d5f0, - 0xac4001d3, - 0x000df607, -/* 0x004e: wr32_wait */ - 0xac4d04bd, - 0x00ddcf07, - 0x7000d4f1, - 0xf8f61bf4, -/* 0x005d: nsec */ - 0xf990f900, - 0xcf2c0880, -/* 0x0066: nsec_loop */ - 0x2c090088, - 0xbb0099cf, - 0x9ea60298, - 0xfcf61ef4, - 0xf890fc80, -/* 0x0079: wait */ - 0xf990f900, - 0xcf2c0880, -/* 0x0082: wait_loop */ - 0xeeb20088, - 0x0000047e, - 0xadfddab2, - 0xf4aca604, - 0x2c09100b, - 0xbb0099cf, - 0x9ba60298, -/* 0x009f: wait_done */ - 0xfce61ef4, - 0xf890fc80, -/* 0x00a5: intr_watchdog */ - 0x03e99800, + 0x00f8f61b, +/* 0x0058: nsec */ + 0x80f990f9, + 0x88cf2c08, +/* 0x0061: nsec_loop */ + 0xcf2c0900, + 0x98bb0099, + 0xf49ea602, + 0x80fcf61e, + 0x00f890fc, +/* 0x0074: wait */ + 0x80f990f9, + 0x88cf2c08, +/* 0x007d: wait_loop */ + 0x7eeeb200, + 0xb2000004, + 0x04adfdda, + 0x0bf4aca6, + 0xcf2c0910, + 0x98bb0099, + 0xf49ba602, +/* 0x009a: wait_done */ + 0x80fce61e, + 0x00f890fc, +/* 0x00a0: intr_watchdog */ + 0xb003e998, + 0x0bf40096, + 0x9a0a9828, + 0xf4029abb, + 0x010d0e1c, + 0x00023e7e, + 0x0ef494bd, +/* 0x00bd: intr_watchdog_next_time */ + 0x9b0a9814, + 0xf400a6b0, + 0x9aa6080b, +/* 0x00cb: intr_watchdog_next_time_set */ + 0xb5061cf4, +/* 0x00ce: intr_watchdog_next_proc */ + 0xe9b59b09, + 0x58e0b603, + 0x0268e6b1, + 0xf8c81bf4, +/* 0x00dd: intr */ + 0xbd00f900, + 0xf980f904, + 0xf9a0f990, + 0xf9c0f9b0, + 0xf9e0f9d0, + 0xfe000ff0, + 0x80f90188, + 0xcf045048, + 0x80b60088, + 0x04504001, + 0xbd0008f6, + 0xcf080804, + 0x89c40088, + 0x1f0bf402, + 0x0e9b00b5, + 0x00a07e58, + 0x9b099800, 0xf40096b0, - 0x0a98280b, - 0x029abb9a, - 0x0d0e1cf4, - 0x02557e01, - 0xf494bd00, -/* 0x00c2: intr_watchdog_next_time */ - 0x0a98140e, - 0x00a6b09b, - 0xa6080bf4, - 0x061cf49a, -/* 0x00d0: intr_watchdog_next_time_set */ -/* 0x00d3: intr_watchdog_next_proc */ - 0xb59b09b5, - 0xe0b603e9, - 0x68e6b158, - 0xc81bf402, -/* 0x00e2: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0x000ff0f9, - 0xf90188fe, - 0x04504880, - 0xb60088cf, - 0x50400180, - 0x0008f604, - 0x080804bd, - 0xc40088cf, - 0x0bf40289, - 0x9b00b51f, - 0xa57e580e, - 0x09980000, - 0x0096b09b, - 0x000d0bf4, - 0x0009f634, - 0x09b504bd, -/* 0x0135: intr_skip_watchdog */ - 0x0089e49a, - 0x360bf408, - 0xcf068849, - 0x9ac40099, - 0x220bf402, - 0xcf04c04c, - 0xc0f900cc, - 0xf14f484e, - 0x0d5453e3, - 0x02b67e00, - 0x40c0fc00, - 0x0cf604c0, -/* 0x0167: intr_subintr_skip_fifo */ - 0x4004bd00, - 0x09f60688, -/* 0x016f: intr_skip_subintr */ - 0x4904bd00, - 0x90bd00e0, - 0x000489fd, - 0x0008f604, - 0x80fc04bd, - 0xfc0088fe, - 0xfce0fcf0, - 0xfcc0fcd0, - 0xfca0fcb0, - 0xfc80fc90, - 0x0032f400, -/* 0x019a: ticks_from_ns */ - 0xc0f901f8, - 0xd7f1b0f9, - 0xd3f00144, - 0x6b21f500, - 0xe8ccec03, - 0x00b4b003, - 0xec120bf4, - 0xf103e8ee, - 0xf00144d7, - 0x21f500d3, -/* 0x01c2: ticks_from_ns_quit */ - 0xceb2036b, + 0x34000d0b, + 0xbd0009f6, + 0x9a09b504, +/* 0x0130: intr_skip_watchdog */ + 0x080089e4, + 0x49340bf4, + 0x99cf0688, + 0x029ac400, + 0x4c200bf4, + 0xcccf04c0, + 0xdec0f900, + 0x54534f48, + 0x9f7e000d, + 0xc0fc0002, + 0xf604c040, + 0x04bd000c, +/* 0x0160: intr_subintr_skip_fifo */ + 0xf6068840, + 0x04bd0009, +/* 0x0168: intr_skip_subintr */ + 0xbd00e049, + 0x0489fd90, + 0x08f60400, + 0xfc04bd00, + 0x0088fe80, + 0xe0fcf0fc, + 0xc0fcd0fc, + 0xa0fcb0fc, + 0x80fc90fc, + 0x32f400fc, +/* 0x0193: ticks_from_ns */ + 0xf901f800, + 0x4db0f9c0, + 0x527e0144, + 0xccec0003, + 0xb4b003e8, + 0x0e0bf400, + 0x03e8eeec, + 0x7e01444d, +/* 0x01b3: ticks_from_ns_quit */ + 0xb2000352, + 0xfcb0fcce, +/* 0x01bb: ticks_from_us */ + 0xf900f8c0, + 0x4db0f9c0, + 0x527e0144, + 0xceb20003, + 0xf400b4b0, + 0xe4bd050b, +/* 0x01d0: ticks_from_us_quit */ 0xc0fcb0fc, -/* 0x01ca: ticks_from_us */ - 0xc0f900f8, - 0xd7f1b0f9, - 0xd3f00144, - 0x6b21f500, - 0xb0ceb203, - 0x0bf400b4, -/* 0x01e3: ticks_from_us_quit */ - 0xfce4bd05, - 0xf8c0fcb0, -/* 0x01e9: ticks_to_us */ - 0x44d7f100, - 0x00d3f001, - 0xf8ecedff, -/* 0x01f5: timer */ - 0xf990f900, - 0x1032f480, - 0xb003f898, - 0x1cf40086, - 0x0084bd4a, - 0x0008f638, - 0x340804bd, - 0x980088cf, - 0x98bb9a09, - 0x00e9bb02, - 0x0803feb5, - 0x0088cf08, - 0xf40284f0, - 0x34081c1b, - 0xa60088cf, - 0x080bf4e0, - 0x1cf4e8a6, -/* 0x0239: timer_reset */ - 0xf634000d, - 0x04bd000e, -/* 0x0243: timer_enable */ - 0x089a0eb5, - 0xf6380001, - 0x04bd0008, -/* 0x024c: timer_done */ - 0xfc1031f4, +/* 0x01d6: ticks_to_us */ + 0x444d00f8, + 0xecedff01, +/* 0x01de: timer */ + 0x90f900f8, + 0x32f480f9, + 0x03f89810, + 0xf40086b0, + 0x84bd4a1c, + 0x08f63800, + 0x0804bd00, + 0x0088cf34, + 0xbb9a0998, + 0xe9bb0298, + 0x03feb500, + 0x88cf0808, + 0x0284f000, + 0x081c1bf4, + 0x0088cf34, + 0x0bf4e0a6, + 0xf4e8a608, +/* 0x0222: timer_reset */ + 0x34000d1c, + 0xbd000ef6, + 0x9a0eb504, +/* 0x022c: timer_enable */ + 0x38000108, + 0xbd0008f6, +/* 0x0235: timer_done */ + 0x1031f404, + 0x90fc80fc, +/* 0x023e: send_proc */ + 0x80f900f8, + 0xe89890f9, + 0x04e99805, + 0xa60486f0, + 0x2a0bf489, + 0x940398c4, + 0x80b60488, + 0x008ebb18, + 0xb500fa98, + 0x8db5008a, + 0x028cb501, + 0xb6038bb5, + 0x94f00190, + 0x04e9b507, +/* 0x0277: send_done */ + 0xfc0231f4, + 0xf880fc90, +/* 0x027d: find */ + 0x0880f900, + 0x0131f458, +/* 0x0284: find_loop */ + 0xa6008a98, + 0x100bf4ae, + 0xb15880b6, + 0xf4026886, + 0x32f4f11b, +/* 0x0299: find_done */ + 0xfc8eb201, +/* 0x029f: send */ + 0x7e00f880, + 0xf400027d, + 0x00f89b01, +/* 0x02a8: recv */ + 0x80f990f9, + 0x9805e898, + 0x32f404e9, + 0xf489a601, + 0x89c43c0b, + 0x0180b603, + 0xb50784f0, + 0xea9805e8, + 0xfef0f902, + 0xf0f9018f, + 0x9994efb2, + 0x00e9bb04, + 0x9818e0b6, + 0xec9803eb, + 0x01ed9802, + 0xf900ee98, + 0xfef0fca5, + 0x31f400f8, +/* 0x02f3: recv_done */ + 0xfcf0fc01, 0xf890fc80, -/* 0x0255: send_proc */ - 0xf980f900, - 0x05e89890, - 0xf004e998, - 0x89a60486, - 0xc42a0bf4, - 0x88940398, - 0x1880b604, - 0x98008ebb, - 0x8ab500fa, - 0x018db500, - 0xb5028cb5, - 0x90b6038b, - 0x0794f001, - 0xf404e9b5, -/* 0x028e: send_done */ - 0x90fc0231, - 0x00f880fc, -/* 0x0294: find */ - 0x580880f9, -/* 0x029b: find_loop */ - 0x980131f4, - 0xaea6008a, - 0xb6100bf4, - 0x86b15880, - 0x1bf40268, - 0x0132f4f1, -/* 0x02b0: find_done */ - 0x80fc8eb2, -/* 0x02b6: send */ - 0x947e00f8, - 0x01f40002, -/* 0x02bf: recv */ - 0xf900f89b, - 0x9880f990, - 0xe99805e8, - 0x0132f404, - 0x0bf489a6, - 0x0389c43c, - 0xf00180b6, - 0xe8b50784, - 0x02ea9805, - 0x8ffef0f9, - 0xb2f0f901, - 0x049994ef, - 0xb600e9bb, - 0xeb9818e0, - 0x02ec9803, - 0x9801ed98, - 0xa5f900ee, - 0xf8fef0fc, - 0x0131f400, -/* 0x030a: recv_done */ - 0x80fcf0fc, - 0x00f890fc, -/* 0x0310: init */ - 0xcf010841, - 0x11e70011, - 0x14b60109, - 0x0014fe08, - 0xf000e041, - 0x1c000013, - 0xbd0001f6, - 0x00ff0104, - 0x0001f614, - 0x020104bd, - 0x080015f1, - 0x01f61000, - 0x4104bd00, - 0x13f000e2, - 0x0010fe00, - 0x011031f4, - 0xf6380001, +/* 0x02f9: init */ + 0x01084100, + 0xe70011cf, + 0xb6010911, + 0x14fe0814, + 0x00e04100, + 0x01f61c00, + 0x0104bd00, + 0xf61400ff, 0x04bd0001, -/* 0x035a: init_proc */ - 0xf198580f, - 0x0016b001, - 0xf9fa0bf4, - 0x58f0b615, -/* 0x036b: mulu32_32_64 */ - 0xf9f20ef4, - 0xf920f910, - 0x9540f930, - 0xd29510e1, - 0xbdc4bd10, - 0xc0edffb4, - 0xb2301dff, + 0x15f10201, + 0x10000800, + 0xbd0001f6, + 0x00dd4104, + 0xffff14f1, + 0xf40010fe, + 0x01011031, + 0x01f63800, + 0x0f04bd00, +/* 0x0341: init_proc */ + 0x01f19858, + 0xf40016b0, + 0x15f9fa0b, + 0xf458f0b6, +/* 0x0352: mulu32_32_64 */ + 0x10f9f20e, + 0x30f920f9, + 0xe19540f9, + 0x10d29510, + 0xb4bdc4bd, + 0xffc0edff, + 0x34b2301d, + 0xffff34f1, + 0xb61034b6, + 0xc3bb1045, + 0x01b4bb00, + 0xb230e2ff, 0xff34f134, 0x1034b6ff, 0xbb1045b6, 0xb4bb00c3, - 0x30e2ff01, - 0x34f134b2, - 0x34b6ffff, - 0x1045b610, - 0xbb00c3bb, - 0x12ff01b4, - 0x00b3bb30, - 0x30fc40fc, - 0x10fc20fc, -/* 0x03ba: host_send */ - 0xb04100f8, - 0x0011cf04, - 0xcf04a042, - 0x12a60022, - 0xc42e0bf4, - 0xee94071e, - 0x70e0b704, - 0x03eb9802, - 0x9802ec98, - 0xee9801ed, - 0x02b67e00, - 0x0110b600, - 0x400f1ec4, - 0x0ef604b0, - 0xf404bd00, -/* 0x03f6: host_send_done */ - 0x00f8c70e, -/* 0x03f8: host_recv */ - 0xf14e4941, - 0xa6525413, - 0xb90bf4e1, -/* 0x0404: host_recv_wait */ - 0xcf04cc41, - 0xc8420011, - 0x0022cf04, - 0xa60816f0, - 0xef0bf412, - 0xb60723c4, - 0x30b70434, - 0x3bb502f0, - 0x023cb503, - 0xb5013db5, - 0x20b6003e, - 0x0f24f001, - 0xf604c840, - 0x04bd0002, - 0x00004002, + 0x3012ff01, + 0xfc00b3bb, + 0xfc30fc40, + 0xf810fc20, +/* 0x03a1: host_send */ + 0x04b04100, + 0x420011cf, + 0x22cf04a0, + 0xf412a600, + 0x1ec42e0b, + 0x04ee9407, + 0x0270e0b7, + 0x9803eb98, + 0xed9802ec, + 0x00ee9801, + 0x00029f7e, + 0xc40110b6, + 0xb0400f1e, + 0x000ef604, + 0x0ef404bd, +/* 0x03dd: host_send_done */ +/* 0x03df: host_recv */ + 0xd100f8c7, + 0x52544e49, + 0x0bf4e1a6, +/* 0x03e9: host_recv_wait */ + 0x04cc41bb, + 0x420011cf, + 0x22cf04c8, + 0x0816f000, + 0x0bf412a6, + 0x0723c4ef, + 0xb70434b6, + 0xb502f030, + 0x3cb5033b, + 0x013db502, + 0xb6003eb5, + 0x24f00120, + 0x04c8400f, 0xbd0002f6, -/* 0x0447: host_init */ - 0x4100f804, - 0x14b60080, - 0x7015f110, - 0x04d04002, - 0xbd0001f6, - 0x00804104, - 0xf11014b6, - 0x4002f015, - 0x01f604dc, - 0x0104bd00, - 0x04c44001, - 0xbd0001f6, -/* 0x0477: memx_func_enter */ - 0xf100f804, - 0xf1162067, - 0xf1f55d77, - 0xb2ffff73, - 0x00047e6e, - 0xfdd8b200, - 0x60f90487, - 0xd0fc80f9, - 0x2e7ee0fc, - 0x77f10000, - 0x73f1fffe, - 0x6eb2ffff, - 0x0000047e, - 0x87fdd8b2, - 0xf960f904, - 0xfcd0fc80, - 0x002e7ee0, - 0xf067f100, - 0x7e6eb226, + 0x00400204, + 0x0002f600, + 0x00f804bd, +/* 0x042c: host_init */ + 0xb6008041, + 0x15f11014, + 0xd0400270, + 0x0001f604, + 0x804104bd, + 0x1014b600, + 0x02f015f1, + 0xf604dc40, + 0x04bd0001, + 0xc4400101, + 0x0001f604, + 0x00f804bd, +/* 0x045c: memx_func_enter */ + 0x162067f1, + 0xf55d77f1, + 0x047e6eb2, + 0xd8b20000, + 0xf90487fd, + 0xfc80f960, + 0x7ee0fcd0, + 0x0700002d, + 0x7e6eb2fe, 0xb2000004, 0x0487fdd8, 0x80f960f9, 0xe0fcd0fc, - 0x00002e7e, - 0xe0400406, - 0x0006f607, -/* 0x04de: memx_func_enter_wait */ - 0xc04604bd, - 0x0066cf07, - 0xf40464f0, - 0x2c06f70b, - 0xb50066cf, - 0x00f8f106, -/* 0x04f4: memx_func_leave */ - 0x66cf2c06, - 0xf206b500, - 0xe4400406, - 0x0006f607, -/* 0x0506: memx_func_leave_wait */ - 0xc04604bd, - 0x0066cf07, - 0xf40464f0, - 0x67f1f71b, - 0x77f126f0, - 0x73f00001, - 0x7e6eb200, - 0xb2000004, - 0x0587fdd8, - 0x80f960f9, - 0xe0fcd0fc, - 0x00002e7e, - 0x162067f1, + 0x00002d7e, + 0x26f067f1, 0x047e6eb2, 0xd8b20000, - 0xf90587fd, + 0xf90487fd, 0xfc80f960, 0x7ee0fcd0, - 0xf100002e, - 0xf00aa277, - 0x6eb20073, + 0x0600002d, + 0x07e04004, + 0xbd0006f6, +/* 0x04b9: memx_func_enter_wait */ + 0x07c04604, + 0xf00066cf, + 0x0bf40464, + 0xcf2c06f7, + 0x06b50066, +/* 0x04cf: memx_func_leave */ + 0x0600f8f1, + 0x0066cf2c, + 0x06f206b5, + 0x07e44004, + 0xbd0006f6, +/* 0x04e1: memx_func_leave_wait */ + 0x07c04604, + 0xf00066cf, + 0x1bf40464, + 0xf067f1f7, + 0xb2010726, + 0x00047e6e, + 0xfdd8b200, + 0x60f90587, + 0xd0fc80f9, + 0x2d7ee0fc, + 0x67f10000, + 0x6eb21620, 0x0000047e, 0x87fdd8b2, 0xf960f905, 0xfcd0fc80, - 0x002e7ee0, -/* 0x056f: memx_func_wait_vblank */ - 0xb600f800, - 0x00f80410, -/* 0x0574: memx_func_wr32 */ - 0x98001698, - 0x10b60115, - 0xf960f908, - 0xfcd0fc50, - 0x002e7ee0, - 0x0242b600, - 0xf8e81bf4, -/* 0x0591: memx_func_wait */ - 0xcf2c0800, - 0x1e980088, - 0x011d9800, - 0x98021c98, - 0x10b6031b, - 0x00797e10, -/* 0x05ab: memx_func_delay */ - 0x9800f800, - 0x10b6001e, - 0x005d7e04, -/* 0x05b7: memx_func_train */ - 0xf800f800, -/* 0x05b9: memx_exec */ - 0xf9e0f900, - 0xb2c1b2d0, -/* 0x05c1: memx_exec_next */ - 0x001398b2, - 0xe70410b6, - 0xe701f034, - 0xb601e033, - 0x30f00132, - 0xde35980c, - 0x12a655f9, - 0x98e51ef4, - 0x0c98f10b, - 0x02cbbbf2, - 0xcf07c44b, - 0xd0fc00bb, - 0xb67ee0fc, - 0x00f80002, -/* 0x05f8: memx_info */ - 0xf401c670, -/* 0x05fe: memx_info_data */ - 0xcc4c0c0b, - 0x08004b03, -/* 0x0607: memx_info_train */ - 0x4c090ef4, - 0x004b0bcc, -/* 0x060d: memx_info_send */ - 0x02b67e01, -/* 0x0613: memx_recv */ - 0xb000f800, - 0x0bf401d6, - 0x00d6b0a3, - 0xf8dc0bf4, -/* 0x0621: memx_init */ -/* 0x0623: perf_recv */ + 0x002d7ee0, + 0x0aa24700, + 0x047e6eb2, + 0xd8b20000, + 0xf90587fd, + 0xfc80f960, + 0x7ee0fcd0, + 0xf800002d, +/* 0x0541: memx_func_wait_vblank */ + 0x0410b600, +/* 0x0546: memx_func_wr32 */ + 0x169800f8, + 0x01159800, + 0xf90810b6, + 0xfc50f960, + 0x7ee0fcd0, + 0xb600002d, + 0x1bf40242, +/* 0x0563: memx_func_wait */ + 0x0800f8e8, + 0x0088cf2c, + 0x98001e98, + 0x1c98011d, + 0x031b9802, + 0x7e1010b6, + 0xf8000074, +/* 0x057d: memx_func_delay */ + 0x001e9800, + 0x7e0410b6, + 0xf8000058, +/* 0x0589: memx_func_train */ +/* 0x058b: memx_exec */ + 0xf900f800, + 0xb2d0f9e0, +/* 0x0593: memx_exec_next */ + 0x98b2b2c1, + 0x10b60013, + 0xf034e704, + 0xe033e701, + 0x0132b601, + 0x980c30f0, + 0x55f9de35, + 0x1ef412a6, + 0xf10b98e5, + 0xbbf20c98, + 0xc44b02cb, + 0x00bbcf07, + 0xe0fcd0fc, + 0x00029f7e, +/* 0x05ca: memx_info */ + 0xc67000f8, + 0x0c0bf401, +/* 0x05d0: memx_info_data */ + 0x4b03cc4c, + 0x0ef40800, +/* 0x05d9: memx_info_train */ + 0x0bcc4c09, +/* 0x05df: memx_info_send */ + 0x7e01004b, + 0xf800029f, +/* 0x05e5: memx_recv */ + 0x01d6b000, + 0xb0a30bf4, + 0x0bf400d6, +/* 0x05f3: memx_init */ + 0xf800f8dc, +/* 0x05f5: perf_recv */ +/* 0x05f7: perf_init */ 0xf800f800, -/* 0x0625: perf_init */ -/* 0x0627: i2c_drive_scl */ - 0xb000f800, - 0x0bf40036, - 0x07e0400d, - 0xbd0001f6, -/* 0x0637: i2c_drive_scl_lo */ - 0x4000f804, - 0x01f607e4, - 0xf804bd00, -/* 0x0641: i2c_drive_sda */ +/* 0x05f9: i2c_drive_scl */ 0x0036b000, 0x400d0bf4, - 0x02f607e0, + 0x01f607e0, 0xf804bd00, -/* 0x0651: i2c_drive_sda_lo */ +/* 0x0609: i2c_drive_scl_lo */ 0x07e44000, + 0xbd0001f6, +/* 0x0613: i2c_drive_sda */ + 0xb000f804, + 0x0bf40036, + 0x07e0400d, 0xbd0002f6, -/* 0x065b: i2c_sense_scl */ - 0xf400f804, - 0xc4430132, - 0x0033cf07, - 0xf40431fd, - 0x31f4060b, -/* 0x066d: i2c_sense_scl_done */ -/* 0x066f: i2c_sense_sda */ - 0xf400f801, - 0xc4430132, - 0x0033cf07, - 0xf40432fd, - 0x31f4060b, -/* 0x0681: i2c_sense_sda_done */ -/* 0x0683: i2c_raise_scl */ - 0xf900f801, - 0x08984440, - 0x277e0103, -/* 0x068e: i2c_raise_scl_wait */ - 0xe84e0006, - 0x005d7e03, - 0x065b7e00, - 0x0901f400, - 0xf40142b6, -/* 0x06a2: i2c_raise_scl_done */ - 0x40fcef1b, -/* 0x06a6: i2c_start */ - 0x5b7e00f8, - 0x11f40006, - 0x066f7e0d, - 0x0611f400, -/* 0x06b7: i2c_start_rep */ - 0x032e0ef4, - 0x06277e00, - 0x7e010300, - 0xbb000641, - 0x65b60076, - 0x9450f904, - 0x56bb0465, - 0xfd50bd02, - 0x50fc0475, - 0x0006837e, - 0xf40464b6, -/* 0x06e2: i2c_start_send */ - 0x00031d11, - 0x0006417e, - 0x7e13884e, - 0x0300005d, - 0x06277e00, +/* 0x0623: i2c_drive_sda_lo */ + 0x4000f804, + 0x02f607e4, + 0xf804bd00, +/* 0x062d: i2c_sense_scl */ + 0x0132f400, + 0xcf07c443, + 0x31fd0033, + 0x060bf404, +/* 0x063f: i2c_sense_scl_done */ + 0xf80131f4, +/* 0x0641: i2c_sense_sda */ + 0x0132f400, + 0xcf07c443, + 0x32fd0033, + 0x060bf404, +/* 0x0653: i2c_sense_sda_done */ + 0xf80131f4, +/* 0x0655: i2c_raise_scl */ + 0x4440f900, + 0x01030898, + 0x0005f97e, +/* 0x0660: i2c_raise_scl_wait */ + 0x7e03e84e, + 0x7e000058, + 0xf400062d, + 0x42b60901, + 0xef1bf401, +/* 0x0674: i2c_raise_scl_done */ + 0x00f840fc, +/* 0x0678: i2c_start */ + 0x00062d7e, + 0x7e0d11f4, + 0xf4000641, + 0x0ef40611, +/* 0x0689: i2c_start_rep */ + 0x7e00032e, + 0x030005f9, + 0x06137e01, + 0x0076bb00, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x557e50fc, + 0x64b60006, + 0x1d11f404, +/* 0x06b4: i2c_start_send */ + 0x137e0003, + 0x884e0006, + 0x00587e13, + 0x7e000300, + 0x4e0005f9, + 0x587e1388, +/* 0x06ce: i2c_start_out */ + 0x00f80000, +/* 0x06d0: i2c_stop */ + 0xf97e0003, + 0x00030005, + 0x0006137e, + 0x7e03e84e, + 0x03000058, + 0x05f97e01, 0x13884e00, - 0x00005d7e, -/* 0x06fc: i2c_start_out */ -/* 0x06fe: i2c_stop */ - 0x000300f8, - 0x0006277e, - 0x417e0003, - 0xe84e0006, - 0x005d7e03, - 0x7e010300, - 0x4e000627, - 0x5d7e1388, - 0x01030000, - 0x0006417e, - 0x7e13884e, - 0xf800005d, -/* 0x072d: i2c_bitw */ - 0x06417e00, - 0x03e84e00, - 0x00005d7e, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x06837e50, - 0x0464b600, - 0x4e1711f4, - 0x5d7e1388, - 0x00030000, - 0x0006277e, - 0x7e13884e, -/* 0x076b: i2c_bitw_out */ - 0xf800005d, -/* 0x076d: i2c_bitr */ - 0x7e010300, - 0x4e000641, - 0x5d7e03e8, + 0x0000587e, + 0x137e0103, + 0x884e0006, + 0x00587e13, +/* 0x06ff: i2c_bitw */ + 0x7e00f800, + 0x4e000613, + 0x587e03e8, 0x76bb0000, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0x7e50fc04, - 0xb6000683, + 0xb6000655, 0x11f40464, - 0x066f7e1a, - 0x7e000300, - 0x4e000627, - 0x5d7e1388, - 0x3cf00000, - 0x0131f401, -/* 0x07b0: i2c_bitr_done */ -/* 0x07b2: i2c_get_byte */ - 0x000500f8, -/* 0x07b6: i2c_get_byte_next */ - 0x54b60804, - 0x0076bb01, - 0xf90465b6, - 0x04659450, - 0xbd0256bb, - 0x0475fd50, - 0x6d7e50fc, - 0x64b60007, - 0x2a11f404, - 0xb60553fd, - 0x1bf40142, - 0xbb0103d8, + 0x13884e17, + 0x0000587e, + 0xf97e0003, + 0x884e0005, + 0x00587e13, +/* 0x073d: i2c_bitw_out */ +/* 0x073f: i2c_bitr */ + 0x0300f800, + 0x06137e01, + 0x03e84e00, + 0x0000587e, + 0xb60076bb, + 0x50f90465, + 0xbb046594, + 0x50bd0256, + 0xfc0475fd, + 0x06557e50, + 0x0464b600, + 0x7e1a11f4, + 0x03000641, + 0x05f97e00, + 0x13884e00, + 0x0000587e, + 0xf4013cf0, +/* 0x0782: i2c_bitr_done */ + 0x00f80131, +/* 0x0784: i2c_get_byte */ + 0x08040005, +/* 0x0788: i2c_get_byte_next */ + 0xbb0154b6, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x00072d7e, -/* 0x07ff: i2c_get_byte_done */ - 0xf80464b6, -/* 0x0801: i2c_put_byte */ -/* 0x0803: i2c_put_byte_next */ - 0xb6080400, - 0x54ff0142, - 0x0076bb38, + 0x00073f7e, + 0xf40464b6, + 0x53fd2a11, + 0x0142b605, + 0x03d81bf4, + 0x0076bb01, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, - 0x2d7e50fc, - 0x64b60007, - 0x3411f404, - 0xf40046b0, - 0x76bbd81b, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0x7e50fc04, - 0xb600076d, - 0x11f40464, - 0x0076bb0f, - 0xf40136b0, - 0x32f4061b, -/* 0x0859: i2c_put_byte_done */ -/* 0x085b: i2c_addr */ - 0xbb00f801, + 0xff7e50fc, + 0x64b60006, +/* 0x07d1: i2c_get_byte_done */ +/* 0x07d3: i2c_put_byte */ + 0x0400f804, +/* 0x07d5: i2c_put_byte_next */ + 0x0142b608, + 0xbb3854ff, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x0006a67e, + 0x0006ff7e, 0xf40464b6, - 0xc3e72911, - 0x34b6012e, - 0x0553fd01, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x08017e50, - 0x0464b600, -/* 0x08a0: i2c_addr_done */ -/* 0x08a2: i2c_acquire_addr */ - 0xcec700f8, - 0x05e4b6f8, - 0xd014e0b7, -/* 0x08ae: i2c_acquire */ - 0xa27e00f8, - 0x047e0008, - 0xd9f00000, - 0x002e7e03, -/* 0x08bf: i2c_release */ - 0x7e00f800, - 0x7e0008a2, - 0xf0000004, - 0x2e7e03da, - 0x00f80000, -/* 0x08d0: i2c_recv */ - 0xc70132f4, - 0x14b6f8c1, - 0x2816b002, - 0x01371ff5, - 0x0cf413b8, - 0x00329800, - 0x0ccc13b8, - 0x00319800, - 0xf90231f4, - 0xf9e0f9d0, - 0x0067f1d0, - 0x0063f100, - 0x01679210, + 0x46b03411, + 0xd81bf400, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0x08ae7e50, + 0x073f7e50, 0x0464b600, - 0xd6b0d0fc, - 0xb01bf500, - 0xbb000500, + 0xbb0f11f4, + 0x36b00076, + 0x061bf401, +/* 0x082b: i2c_put_byte_done */ + 0xf80132f4, +/* 0x082d: i2c_addr */ + 0x0076bb00, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x787e50fc, + 0x64b60006, + 0x2911f404, + 0x012ec3e7, + 0xfd0134b6, + 0x76bb0553, + 0x0465b600, + 0x659450f9, + 0x0256bb04, + 0x75fd50bd, + 0x7e50fc04, + 0xb60007d3, +/* 0x0872: i2c_addr_done */ + 0x00f80464, +/* 0x0874: i2c_acquire_addr */ + 0xb6f8cec7, + 0xe0b705e4, + 0x00f8d014, +/* 0x0880: i2c_acquire */ + 0x0008747e, + 0x0000047e, + 0x7e03d9f0, + 0xf800002d, +/* 0x0891: i2c_release */ + 0x08747e00, + 0x00047e00, + 0x03daf000, + 0x00002d7e, +/* 0x08a2: i2c_recv */ + 0x32f400f8, + 0xf8c1c701, + 0xb00214b6, + 0x1ff52816, + 0x13b80134, + 0x98000cf4, + 0x13b80032, + 0x98000ccc, + 0x31f40031, + 0xf9d0f902, + 0xd6d0f9e0, + 0x10000000, + 0xbb016792, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x00085b7e, - 0xf50464b6, - 0xc700cc11, - 0x76bbe0c5, + 0x0008807e, + 0xfc0464b6, + 0x00d6b0d0, + 0x00b01bf5, + 0x76bb0005, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0x7e50fc04, - 0xb6000801, + 0xb600082d, 0x11f50464, - 0x010500a9, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x085b7e50, - 0x0464b600, - 0x008711f5, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x07b27e50, - 0x0464b600, - 0xcb6711f4, - 0x76bbe05b, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0x7e50fc04, - 0xb60006fe, - 0x5bb20464, - 0x0ef474bd, -/* 0x09d5: i2c_recv_not_rd08 */ - 0x01d6b041, - 0x053b1bf4, - 0x085b7e00, - 0x3211f400, - 0x7ee0c5c7, - 0xf4000801, - 0x00052811, - 0x00085b7e, - 0xc71f11f4, - 0x017ee0b5, - 0x11f40008, - 0x06fe7e15, - 0xc774bd00, - 0x1bf408c5, - 0x0232f409, -/* 0x0a13: i2c_recv_not_wr08 */ -/* 0x0a13: i2c_recv_done */ - 0xc7030ef4, - 0xbf7ef8ce, - 0xe0fc0008, - 0x12f4d0fc, - 0x7e7cb209, -/* 0x0a27: i2c_recv_exit */ - 0xf80002b6, -/* 0x0a29: i2c_init */ -/* 0x0a2b: test_recv */ - 0x4100f800, - 0x11cf0458, - 0x0110b600, - 0xf6045840, - 0x04bd0001, - 0xd900e7f1, - 0x134fe3f1, - 0x0001f57e, -/* 0x0a4a: test_init */ + 0xc5c700cc, + 0x0076bbe0, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0xd37e50fc, + 0x64b60007, + 0xa911f504, + 0xbb010500, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x00082d7e, + 0xf50464b6, + 0xbb008711, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x0007847e, + 0xf40464b6, + 0x5bcb6711, + 0x0076bbe0, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0xd07e50fc, + 0x64b60006, + 0xbd5bb204, + 0x410ef474, +/* 0x09a4: i2c_recv_not_rd08 */ + 0xf401d6b0, + 0x00053b1b, + 0x00082d7e, + 0xc73211f4, + 0xd37ee0c5, + 0x11f40007, + 0x7e000528, + 0xf400082d, + 0xb5c71f11, + 0x07d37ee0, + 0x1511f400, + 0x0006d07e, + 0xc5c774bd, + 0x091bf408, + 0xf40232f4, +/* 0x09e2: i2c_recv_not_wr08 */ +/* 0x09e2: i2c_recv_done */ + 0xcec7030e, + 0x08917ef8, + 0xfce0fc00, + 0x0912f4d0, + 0x9f7e7cb2, +/* 0x09f6: i2c_recv_exit */ + 0x00f80002, +/* 0x09f8: i2c_init */ +/* 0x09fa: test_recv */ + 0x584100f8, + 0x0011cf04, + 0x400110b6, + 0x01f60458, + 0xde04bd00, + 0x134fd900, + 0x0001de7e, +/* 0x0a16: test_init */ 0x004e00f8, - 0x01f57e08, -/* 0x0a53: idle_recv */ + 0x01de7e08, +/* 0x0a1f: idle_recv */ 0xf800f800, -/* 0x0a55: idle */ +/* 0x0a21: idle */ 0x0031f400, 0xcf045441, 0x10b60011, 0x04544001, 0xbd0001f6, -/* 0x0a69: idle_loop */ +/* 0x0a35: idle_loop */ 0xf4580104, -/* 0x0a6e: idle_proc */ -/* 0x0a6e: idle_proc_exec */ +/* 0x0a3a: idle_proc */ +/* 0x0a3a: idle_proc_exec */ 0x10f90232, - 0xbf7e1eb2, + 0xa87e1eb2, 0x10fc0002, 0xf40911f4, 0x0ef40231, -/* 0x0a81: idle_proc_next */ +/* 0x0a4d: idle_proc_next */ 0x5810b6f0, 0x1bf41fa6, 0xe002f4e8, @@ -1726,4 +1713,17 @@ uint32_t gk208_pmu_code[] = { 0x00000000, 0x00000000, 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h index 516569270..e83341815 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h @@ -24,8 +24,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, /* 0x0058: proc_list_head */ 0x54534f48, - 0x00000507, - 0x000004a4, + 0x0000050a, + 0x000004a7, 0x00000000, 0x00000000, 0x00000000, @@ -46,8 +46,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, 0x00000000, 0x584d454d, - 0x00000837, - 0x00000829, + 0x0000083a, + 0x0000082c, 0x00000000, 0x00000000, 0x00000000, @@ -68,8 +68,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, 0x00000000, 0x46524550, - 0x0000083b, - 0x00000839, + 0x0000083e, + 0x0000083c, 0x00000000, 0x00000000, 0x00000000, @@ -90,8 +90,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, 0x00000000, 0x5f433249, - 0x00000c6b, - 0x00000b0e, + 0x00000c6e, + 0x00000b11, 0x00000000, 0x00000000, 0x00000000, @@ -112,8 +112,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, 0x00000000, 0x54534554, - 0x00000c94, - 0x00000c6d, + 0x00000c97, + 0x00000c70, 0x00000000, 0x00000000, 0x00000000, @@ -134,8 +134,8 @@ uint32_t gt215_pmu_data[] = { 0x00000000, 0x00000000, 0x454c4449, - 0x00000ca0, - 0x00000c9e, + 0x00000ca3, + 0x00000ca1, 0x00000000, 0x00000000, 0x00000000, @@ -229,26 +229,26 @@ uint32_t gt215_pmu_data[] = { /* 0x0370: memx_func_head */ 0x00000001, 0x00000000, - 0x00000546, + 0x00000549, /* 0x037c: memx_func_next */ 0x00000002, 0x00000000, - 0x0000059d, + 0x000005a0, 0x00000003, 0x00000002, - 0x0000062f, + 0x00000632, 0x00040004, 0x00000000, - 0x0000064b, + 0x0000064e, 0x00010005, 0x00000000, - 0x00000668, + 0x0000066b, 0x00010006, 0x00000000, - 0x000005ed, + 0x000005f0, 0x00000007, 0x00000000, - 0x00000673, + 0x00000676, /* 0x03c4: memx_func_tail */ /* 0x03c4: memx_ts_start */ 0x00000000, @@ -917,947 +917,947 @@ uint32_t gt215_pmu_data[] = { }; uint32_t gt215_pmu_code[] = { - 0x03930ef5, + 0x03920ef5, /* 0x0004: rd32 */ 0x07a007f1, 0xd00604b6, 0x04bd000e, - 0xf001d7f0, - 0x07f101d3, - 0x04b607ac, - 0x000dd006, -/* 0x0022: rd32_wait */ - 0xd7f104bd, - 0xd4b607ac, - 0x00ddcf06, - 0x7000d4f1, - 0xf1f21bf4, - 0xb607a4d7, - 0xddcf06d4, -/* 0x003f: wr32 */ - 0xf100f800, - 0xb607a007, - 0x0ed00604, - 0xf104bd00, - 0xb607a407, + 0x0001d7f1, + 0xf101d3f0, + 0xb607ac07, 0x0dd00604, - 0xf004bd00, - 0xd5f002d7, - 0x01d3f0f0, - 0x07ac07f1, +/* 0x0023: rd32_wait */ + 0xf104bd00, + 0xb607acd7, + 0xddcf06d4, + 0x00d4f100, + 0xf21bf470, + 0x07a4d7f1, + 0xcf06d4b6, + 0x00f800dd, +/* 0x0040: wr32 */ + 0x07a007f1, + 0xd00604b6, + 0x04bd000e, + 0x07a407f1, 0xd00604b6, 0x04bd000d, -/* 0x006c: wr32_wait */ - 0x07acd7f1, - 0xcf06d4b6, - 0xd4f100dd, - 0x1bf47000, -/* 0x007f: nsec */ - 0xf900f8f2, - 0xf080f990, - 0x84b62c87, - 0x0088cf06, -/* 0x008c: nsec_loop */ - 0xb62c97f0, - 0x99cf0694, - 0x0298bb00, - 0xf4069eb8, - 0x80fcf11e, - 0x00f890fc, -/* 0x00a4: wait */ - 0x80f990f9, - 0xb62c87f0, - 0x88cf0684, -/* 0x00b1: wait_loop */ - 0x02eeb900, - 0xb90421f4, - 0xadfd02da, - 0x06acb804, - 0xf0150bf4, + 0x00f2d7f1, + 0xf101d3f0, + 0xb607ac07, + 0x0dd00604, +/* 0x006b: wr32_wait */ + 0xf104bd00, + 0xb607acd7, + 0xddcf06d4, + 0x00d4f100, + 0xf21bf470, +/* 0x007e: nsec */ + 0x90f900f8, + 0x87f080f9, + 0x0684b62c, +/* 0x008b: nsec_loop */ + 0xf00088cf, 0x94b62c97, 0x0099cf06, 0xb80298bb, - 0x1ef4069b, -/* 0x00d5: wait_done */ - 0xfc80fcdf, -/* 0x00db: intr_watchdog */ - 0x9800f890, - 0x96b003e9, - 0x2a0bf400, - 0xbb9a0a98, - 0x1cf4029a, - 0x01d7f00f, - 0x02d221f5, - 0x0ef494bd, -/* 0x00f9: intr_watchdog_next_time */ - 0x9b0a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x0108: intr_watchdog_next_time_set */ -/* 0x010b: intr_watchdog_next_proc */ - 0x809b0980, - 0xe0b603e9, - 0x68e6b158, - 0xc61bf402, -/* 0x011a: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x84b605d0, + 0x1ef4069e, + 0xfc80fcf1, +/* 0x00a3: wait */ + 0xf900f890, + 0xf080f990, + 0x84b62c87, 0x0088cf06, - 0xf10180b6, - 0xb605d007, +/* 0x00b0: wait_loop */ + 0xf402eeb9, + 0xdab90421, + 0x04adfd02, + 0xf406acb8, + 0x97f0150b, + 0x0694b62c, + 0xbb0099cf, + 0x9bb80298, + 0xdf1ef406, +/* 0x00d4: wait_done */ + 0x90fc80fc, +/* 0x00da: intr_watchdog */ + 0xe99800f8, + 0x0096b003, + 0x982a0bf4, + 0x9abb9a0a, + 0x0f1cf402, + 0xf501d7f0, + 0xbd02d121, + 0x150ef494, +/* 0x00f8: intr_watchdog_next_time */ + 0xb09b0a98, + 0x0bf400a6, + 0x069ab809, +/* 0x0107: intr_watchdog_next_time_set */ + 0x80061cf4, +/* 0x010a: intr_watchdog_next_proc */ + 0xe9809b09, + 0x58e0b603, + 0x0268e6b1, + 0xf8c61bf4, +/* 0x0119: intr */ + 0xbd00f900, + 0xf980f904, + 0xf9a0f990, + 0xf9c0f9b0, + 0xf9e0f9d0, + 0x00f7f0f0, + 0xf90188fe, + 0xd087f180, + 0x0684b605, + 0xb60088cf, + 0x07f10180, + 0x04b605d0, + 0x0008d006, + 0x87f004bd, + 0x0684b608, + 0xc40088cf, + 0x0bf40289, + 0x9b008023, + 0xf458e7f0, + 0x0998da21, + 0x0096b09b, + 0xf0110bf4, + 0x04b63407, + 0x0009d006, + 0x098004bd, +/* 0x017d: intr_skip_watchdog */ + 0x0089e49a, + 0x480bf408, + 0x068897f1, + 0xcf0694b6, + 0x9ac40099, + 0x2c0bf402, + 0x04c0c7f1, + 0xcf06c4b6, + 0xc0f900cc, + 0x4f48e7f1, + 0x5453e3f1, + 0xf500d7f0, + 0xfc033621, + 0xc007f1c0, + 0x0604b604, + 0xbd000cd0, +/* 0x01bd: intr_subintr_skip_fifo */ + 0x8807f104, + 0x0604b606, + 0xbd0009d0, +/* 0x01c9: intr_skip_subintr */ + 0xe097f104, + 0xfd90bd00, + 0x07f00489, + 0x0604b604, + 0xbd0008d0, + 0xfe80fc04, + 0xf0fc0088, + 0xd0fce0fc, + 0xb0fcc0fc, + 0x90fca0fc, + 0x00fc80fc, + 0xf80032f4, +/* 0x01f9: ticks_from_ns */ + 0xf9c0f901, + 0xcbd7f1b0, + 0x00d3f000, + 0x040b21f5, + 0x03e8ccec, + 0xf400b4b0, + 0xeeec120b, + 0xd7f103e8, + 0xd3f000cb, + 0x0b21f500, +/* 0x0221: ticks_from_ns_quit */ + 0x02ceb904, + 0xc0fcb0fc, +/* 0x022a: ticks_from_us */ + 0xc0f900f8, + 0xd7f1b0f9, + 0xd3f000cb, + 0x0b21f500, + 0x02ceb904, + 0xf400b4b0, + 0xe4bd050b, +/* 0x0244: ticks_from_us_quit */ + 0xc0fcb0fc, +/* 0x024a: ticks_to_us */ + 0xd7f100f8, + 0xd3f000cb, + 0xecedff00, +/* 0x0256: timer */ + 0x90f900f8, + 0x32f480f9, + 0x03f89810, + 0xf40086b0, + 0x84bd651c, + 0xb63807f0, 0x08d00604, 0xf004bd00, - 0x84b60887, + 0x84b63487, 0x0088cf06, - 0xf40289c4, - 0x0080230b, - 0x58e7f09b, - 0x98db21f4, - 0x96b09b09, - 0x110bf400, + 0xbb9a0998, + 0xe9bb0298, + 0x03fe8000, + 0xb60887f0, + 0x88cf0684, + 0x0284f000, + 0xf0261bf4, + 0x84b63487, + 0x0088cf06, + 0xf406e0b8, + 0xe8b8090b, + 0x111cf406, +/* 0x02ac: timer_reset */ 0xb63407f0, - 0x09d00604, + 0x0ed00604, 0x8004bd00, -/* 0x017e: intr_skip_watchdog */ - 0x89e49a09, - 0x0bf40800, - 0x8897f148, - 0x0694b606, - 0xc40099cf, - 0x0bf4029a, - 0xc0c7f12c, - 0x06c4b604, - 0xf900cccf, - 0x48e7f1c0, - 0x53e3f14f, - 0x00d7f054, - 0x033721f5, - 0x07f1c0fc, - 0x04b604c0, - 0x000cd006, -/* 0x01be: intr_subintr_skip_fifo */ - 0x07f104bd, - 0x04b60688, - 0x0009d006, -/* 0x01ca: intr_skip_subintr */ - 0x97f104bd, - 0x90bd00e0, - 0xf00489fd, - 0x04b60407, - 0x0008d006, - 0x80fc04bd, - 0xfc0088fe, - 0xfce0fcf0, - 0xfcc0fcd0, - 0xfca0fcb0, - 0xfc80fc90, - 0x0032f400, -/* 0x01fa: ticks_from_ns */ - 0xc0f901f8, - 0xd7f1b0f9, - 0xd3f000cb, - 0x0821f500, - 0xe8ccec04, - 0x00b4b003, - 0xec120bf4, - 0xf103e8ee, - 0xf000cbd7, - 0x21f500d3, -/* 0x0222: ticks_from_ns_quit */ - 0xceb90408, - 0xfcb0fc02, -/* 0x022b: ticks_from_us */ - 0xf900f8c0, - 0xf1b0f9c0, - 0xf000cbd7, - 0x21f500d3, - 0xceb90408, - 0x00b4b002, - 0xbd050bf4, -/* 0x0245: ticks_from_us_quit */ - 0xfcb0fce4, -/* 0x024b: ticks_to_us */ - 0xf100f8c0, - 0xf000cbd7, - 0xedff00d3, -/* 0x0257: timer */ - 0xf900f8ec, - 0xf480f990, - 0xf8981032, - 0x0086b003, - 0xbd651cf4, - 0x3807f084, +/* 0x02ba: timer_enable */ + 0x87f09a0e, + 0x3807f001, 0xd00604b6, 0x04bd0008, - 0xb63487f0, - 0x88cf0684, - 0x9a099800, - 0xbb0298bb, - 0xfe8000e9, - 0x0887f003, - 0xcf0684b6, - 0x84f00088, - 0x261bf402, - 0xb63487f0, - 0x88cf0684, - 0x06e0b800, - 0xb8090bf4, - 0x1cf406e8, -/* 0x02ad: timer_reset */ - 0x3407f011, - 0xd00604b6, - 0x04bd000e, -/* 0x02bb: timer_enable */ - 0xf09a0e80, - 0x07f00187, - 0x0604b638, - 0xbd0008d0, -/* 0x02c9: timer_done */ - 0x1031f404, +/* 0x02c8: timer_done */ + 0xfc1031f4, + 0xf890fc80, +/* 0x02d1: send_proc */ + 0xf980f900, + 0x05e89890, + 0xf004e998, + 0x89b80486, + 0x2a0bf406, + 0x940398c4, + 0x80b60488, + 0x008ebb18, + 0x8000fa98, + 0x8d80008a, + 0x028c8001, + 0xb6038b80, + 0x94f00190, + 0x04e98007, +/* 0x030b: send_done */ + 0xfc0231f4, + 0xf880fc90, +/* 0x0311: find */ + 0xf080f900, + 0x31f45887, +/* 0x0319: find_loop */ + 0x008a9801, + 0xf406aeb8, + 0x80b6100b, + 0x6886b158, + 0xf01bf402, +/* 0x032f: find_done */ + 0xb90132f4, + 0x80fc028e, +/* 0x0336: send */ + 0x21f500f8, + 0x01f40311, +/* 0x033f: recv */ + 0xf900f897, + 0x9880f990, + 0xe99805e8, + 0x0132f404, + 0xf40689b8, + 0x89c43d0b, + 0x0180b603, + 0x800784f0, + 0xea9805e8, + 0xfef0f902, + 0xf0f9018f, + 0x9402efb9, + 0xe9bb0499, + 0x18e0b600, + 0x9803eb98, + 0xed9802ec, + 0x00ee9801, + 0xf0fca5f9, + 0xf400f8fe, + 0xf0fc0131, +/* 0x038c: recv_done */ 0x90fc80fc, -/* 0x02d2: send_proc */ - 0x80f900f8, - 0xe89890f9, - 0x04e99805, - 0xb80486f0, - 0x0bf40689, - 0x0398c42a, - 0xb6048894, - 0x8ebb1880, - 0x00fa9800, - 0x80008a80, - 0x8c80018d, - 0x038b8002, - 0xf00190b6, - 0xe9800794, - 0x0231f404, -/* 0x030c: send_done */ - 0x80fc90fc, -/* 0x0312: find */ - 0x80f900f8, - 0xf45887f0, -/* 0x031a: find_loop */ - 0x8a980131, - 0x06aeb800, - 0xb6100bf4, - 0x86b15880, - 0x1bf40268, - 0x0132f4f0, -/* 0x0330: find_done */ - 0xfc028eb9, -/* 0x0337: send */ - 0xf500f880, - 0xf4031221, - 0x00f89701, -/* 0x0340: recv */ - 0x80f990f9, - 0x9805e898, - 0x32f404e9, - 0x0689b801, - 0xc43d0bf4, - 0x80b60389, - 0x0784f001, - 0x9805e880, - 0xf0f902ea, - 0xf9018ffe, - 0x02efb9f0, - 0xbb049994, - 0xe0b600e9, - 0x03eb9818, - 0x9802ec98, - 0xee9801ed, - 0xfca5f900, - 0x00f8fef0, - 0xfc0131f4, -/* 0x038d: recv_done */ - 0xfc80fcf0, -/* 0x0393: init */ - 0xf100f890, - 0xb6010817, - 0x11cf0614, - 0x0911e700, - 0x0814b601, - 0xf10014fe, - 0xf000e017, - 0x07f00013, - 0x0604b61c, - 0xbd0001d0, - 0xff17f004, - 0xb61407f0, - 0x01d00604, - 0xf004bd00, - 0x15f10217, - 0x07f00800, - 0x0604b610, - 0xbd0001d0, - 0x1a17f104, - 0x0013f001, - 0xf40010fe, - 0x17f01031, - 0x3807f001, +/* 0x0392: init */ + 0x17f100f8, + 0x14b60108, + 0x0011cf06, + 0x010911e7, + 0xfe0814b6, + 0x17f10014, + 0x13f000e0, + 0x1c07f000, + 0xd00604b6, + 0x04bd0001, + 0xf0ff17f0, + 0x04b61407, + 0x0001d006, + 0x17f004bd, + 0x0015f102, + 0x1007f008, 0xd00604b6, 0x04bd0001, -/* 0x03f7: init_proc */ - 0x9858f7f0, - 0x16b001f1, - 0xfa0bf400, - 0xf0b615f9, - 0xf20ef458, -/* 0x0408: mulu32_32_64 */ - 0x20f910f9, - 0x40f930f9, - 0x9510e195, - 0xc4bd10d2, - 0xedffb4bd, - 0x301dffc0, - 0xf10234b9, - 0xb6ffff34, - 0x45b61034, - 0x00c3bb10, - 0xff01b4bb, - 0x34b930e2, - 0xff34f102, - 0x1034b6ff, - 0xbb1045b6, - 0xb4bb00c3, - 0x3012ff01, - 0xfc00b3bb, - 0xfc30fc40, - 0xf810fc20, -/* 0x0459: host_send */ - 0xb017f100, + 0x011917f1, + 0xf10013f0, + 0xfeffff14, + 0x31f40010, + 0x0117f010, + 0xb63807f0, + 0x01d00604, + 0xf004bd00, +/* 0x03fa: init_proc */ + 0xf19858f7, + 0x0016b001, + 0xf9fa0bf4, + 0x58f0b615, +/* 0x040b: mulu32_32_64 */ + 0xf9f20ef4, + 0xf920f910, + 0x9540f930, + 0xd29510e1, + 0xbdc4bd10, + 0xc0edffb4, + 0xb9301dff, + 0x34f10234, + 0x34b6ffff, + 0x1045b610, + 0xbb00c3bb, + 0xe2ff01b4, + 0x0234b930, + 0xffff34f1, + 0xb61034b6, + 0xc3bb1045, + 0x01b4bb00, + 0xbb3012ff, + 0x40fc00b3, + 0x20fc30fc, + 0x00f810fc, +/* 0x045c: host_send */ + 0x04b017f1, + 0xcf0614b6, + 0x27f10011, + 0x24b604a0, + 0x0022cf06, + 0xf40612b8, + 0x1ec4320b, + 0x04ee9407, + 0x0270e0b7, + 0x9803eb98, + 0xed9802ec, + 0x00ee9801, + 0x033621f5, + 0xc40110b6, + 0x07f10f1e, + 0x04b604b0, + 0x000ed006, + 0x0ef404bd, +/* 0x04a5: host_send_done */ +/* 0x04a7: host_recv */ + 0xf100f8ba, + 0xf14e4917, + 0xb8525413, + 0x0bf406e1, +/* 0x04b5: host_recv_wait */ + 0xcc17f1aa, 0x0614b604, 0xf10011cf, - 0xb604a027, + 0xb604c827, 0x22cf0624, - 0x0612b800, - 0xc4320bf4, - 0xee94071e, - 0x70e0b704, - 0x03eb9802, - 0x9802ec98, - 0xee9801ed, - 0x3721f500, - 0x0110b603, - 0xf10f1ec4, - 0xb604b007, - 0x0ed00604, - 0xf404bd00, -/* 0x04a2: host_send_done */ - 0x00f8ba0e, -/* 0x04a4: host_recv */ - 0x4e4917f1, - 0x525413f1, - 0xf406e1b8, -/* 0x04b2: host_recv_wait */ - 0x17f1aa0b, - 0x14b604cc, - 0x0011cf06, - 0x04c827f1, - 0xcf0624b6, - 0x16f00022, - 0x0612b808, - 0xc4e60bf4, - 0x34b60723, - 0xf030b704, - 0x033b8002, - 0x80023c80, - 0x3e80013d, - 0x0120b600, - 0xf10f24f0, - 0xb604c807, - 0x02d00604, - 0xf004bd00, - 0x07f04027, - 0x0604b600, - 0xbd0002d0, -/* 0x0507: host_init */ - 0xf100f804, - 0xb6008017, - 0x15f11014, - 0x07f10270, - 0x04b604d0, - 0x0001d006, - 0x17f104bd, + 0x0816f000, + 0xf40612b8, + 0x23c4e60b, + 0x0434b607, + 0x02f030b7, + 0x80033b80, + 0x3d80023c, + 0x003e8001, + 0xf00120b6, + 0x07f10f24, + 0x04b604c8, + 0x0002d006, + 0x27f004bd, + 0x0007f040, + 0xd00604b6, + 0x04bd0002, +/* 0x050a: host_init */ + 0x17f100f8, 0x14b60080, - 0xf015f110, - 0xdc07f102, + 0x7015f110, + 0xd007f102, 0x0604b604, 0xbd0001d0, - 0x0117f004, - 0x04c407f1, + 0x8017f104, + 0x1014b600, + 0x02f015f1, + 0x04dc07f1, 0xd00604b6, 0x04bd0001, -/* 0x0546: memx_func_enter */ - 0x87f100f8, - 0x8eb91610, - 0x0421f402, - 0xf102d7b9, - 0xf1fffc67, - 0xfdffff63, - 0x67f10476, - 0x76fd0002, - 0xf980f905, - 0xfcd0fc70, - 0x3f21f4e0, + 0xf10117f0, + 0xb604c407, + 0x01d00604, + 0xf804bd00, +/* 0x0549: memx_func_enter */ + 0x1087f100, + 0x028eb916, + 0xb90421f4, + 0x67f102d7, + 0x63f1fffc, + 0x76fdffff, + 0x0267f104, + 0x0576fd00, + 0x70f980f9, + 0xe0fcd0fc, + 0xf04021f4, + 0x07f10467, + 0x04b607e0, + 0x0006d006, +/* 0x0582: memx_func_enter_wait */ + 0x67f104bd, + 0x64b607c0, + 0x0066cf06, + 0xf40464f0, + 0x67f0f30b, + 0x0664b62c, + 0x800066cf, + 0x00f8f106, +/* 0x05a0: memx_func_leave */ + 0xb62c67f0, + 0x66cf0664, + 0xf2068000, 0xf10467f0, - 0xb607e007, + 0xb607e407, 0x06d00604, -/* 0x057f: memx_func_enter_wait */ +/* 0x05bb: memx_func_leave_wait */ 0xf104bd00, 0xb607c067, 0x66cf0664, 0x0464f000, - 0xf0f30bf4, - 0x64b62c67, - 0x0066cf06, - 0xf8f10680, -/* 0x059d: memx_func_leave */ - 0x2c67f000, - 0xcf0664b6, - 0x06800066, - 0x0467f0f2, - 0x07e407f1, - 0xd00604b6, - 0x04bd0006, -/* 0x05b8: memx_func_leave_wait */ - 0x07c067f1, - 0xcf0664b6, - 0x64f00066, - 0xf31bf404, - 0x161087f1, - 0xf4028eb9, - 0xd7b90421, - 0xcc67f102, - 0xff63f1ff, - 0x0476fdff, - 0x70f980f9, - 0xe0fcd0fc, - 0xf83f21f4, -/* 0x05ed: memx_func_wait_vblank */ - 0x00169800, - 0xf40066b0, - 0x66b0130b, - 0x060bf401, -/* 0x05ff: memx_func_wait_vblank_head1 */ - 0xf12e0ef4, - 0xf4002077, -/* 0x0606: memx_func_wait_vblank_head0 */ - 0x77f1070e, -/* 0x060a: memx_func_wait_vblank_0 */ - 0x67f10008, - 0x64b607c4, - 0x0066cf06, - 0xf40467fd, -/* 0x061a: memx_func_wait_vblank_1 */ - 0x67f1f31b, - 0x64b607c4, - 0x0066cf06, - 0xf40467fd, -/* 0x062a: memx_func_wait_vblank_fini */ - 0x10b6f30b, -/* 0x062f: memx_func_wr32 */ - 0x9800f804, - 0x15980016, - 0x0810b601, - 0x50f960f9, - 0xe0fcd0fc, - 0xb63f21f4, - 0x1bf40242, -/* 0x064b: memx_func_wait */ - 0xf000f8e9, - 0x84b62c87, - 0x0088cf06, - 0x98001e98, - 0x1c98011d, - 0x031b9802, - 0xf41010b6, - 0x00f8a421, -/* 0x0668: memx_func_delay */ - 0xb6001e98, - 0x21f40410, -/* 0x0673: memx_func_train */ - 0xf100f87f, - 0xf1000357, - 0xf1000077, - 0xf0000097, - 0x9eb97093, - 0x0421f402, - 0xf102d8b9, - 0xf42710e7, -/* 0x0692: memx_func_train_loop_outer */ - 0x58e07f21, - 0x83f10101, - 0x97f10200, - 0x93f011e0, - 0xf990f911, - 0xfcd0fc80, - 0x3f21f4e0, - 0x67f150f9, -/* 0x06b2: memx_func_train_loop_inner */ - 0x87f10000, - 0x68ff1111, - 0x10989490, - 0xf10589fd, - 0xf0072097, - 0x90f91093, - 0xd0fc80f9, - 0x21f4e0fc, - 0x8097f13f, - 0x1093f000, - 0xf4029eb9, - 0xd8b90421, - 0x2088c502, + 0xf1f31bf4, + 0xb9161087, + 0x21f4028e, + 0x02d7b904, + 0xffcc67f1, + 0xffff63f1, + 0xf90476fd, + 0xfc70f980, + 0xf4e0fcd0, + 0x00f84021, +/* 0x05f0: memx_func_wait_vblank */ + 0xb0001698, + 0x0bf40066, + 0x0166b013, + 0xf4060bf4, +/* 0x0602: memx_func_wait_vblank_head1 */ + 0x77f12e0e, + 0x0ef40020, +/* 0x0609: memx_func_wait_vblank_head0 */ + 0x0877f107, +/* 0x060d: memx_func_wait_vblank_0 */ + 0xc467f100, + 0x0664b607, + 0xfd0066cf, + 0x1bf40467, +/* 0x061d: memx_func_wait_vblank_1 */ + 0xc467f1f3, + 0x0664b607, + 0xfd0066cf, + 0x0bf40467, +/* 0x062d: memx_func_wait_vblank_fini */ + 0x0410b6f3, +/* 0x0632: memx_func_wr32 */ + 0x169800f8, + 0x01159800, + 0xf90810b6, + 0xfc50f960, + 0xf4e0fcd0, + 0x42b64021, + 0xe91bf402, +/* 0x064e: memx_func_wait */ + 0x87f000f8, + 0x0684b62c, + 0x980088cf, + 0x1d98001e, + 0x021c9801, + 0xb6031b98, + 0x21f41010, +/* 0x066b: memx_func_delay */ + 0x9800f8a3, + 0x10b6001e, + 0x7e21f404, +/* 0x0676: memx_func_train */ + 0x57f100f8, + 0x77f10003, + 0x97f10000, + 0x93f00000, + 0x029eb970, + 0xb90421f4, + 0xe7f102d8, + 0x21f42710, +/* 0x0695: memx_func_train_loop_outer */ + 0x0158e07e, + 0x0083f101, + 0xe097f102, + 0x1193f011, 0x80f990f9, 0xe0fcd0fc, - 0xf13f21f4, - 0xf0053c97, - 0x87f11093, - 0x83f13002, - 0x90f98000, - 0xd0fc80f9, - 0x21f4e0fc, - 0x60e7f13f, - 0x10e3f005, - 0x0000d7f1, - 0x8000d3f1, - 0xf100dc90, - 0xf08480b7, - 0x21f41eb3, - 0x0057f1a4, - 0xff97f100, - 0x0093f1ff, -/* 0x0731: memx_func_train_loop_4x */ - 0x80a7f183, - 0x10a3f000, - 0xf402aeb9, - 0xd8b90421, - 0xdfb7f102, - 0xffb3f1ff, - 0x048bfdff, - 0x80f9a0f9, - 0xe0fcd0fc, - 0xf13f21f4, - 0xf0053ca7, - 0x87f110a3, - 0x83f13002, - 0xa0f98000, - 0xd0fc80f9, - 0x21f4e0fc, - 0x60e7f13f, - 0x10e3f005, - 0x0000d7f1, - 0x8000d3f1, - 0xf102dcb9, - 0xf02710b7, - 0x21f400b3, - 0x02eeb9a4, - 0xb90421f4, - 0x9dff02dd, - 0x0150b694, - 0xf4045670, - 0x7aa0921e, - 0xa9800bcc, - 0x0160b600, - 0x700470b6, - 0x1ef51066, - 0x50fcff00, + 0xf94021f4, + 0x0067f150, +/* 0x06b5: memx_func_train_loop_inner */ + 0x1187f100, + 0x9068ff11, + 0xfd109894, + 0x97f10589, + 0x93f00720, + 0xf990f910, + 0xfcd0fc80, + 0x4021f4e0, + 0x008097f1, + 0xb91093f0, + 0x21f4029e, + 0x02d8b904, + 0xf92088c5, + 0xfc80f990, + 0xf4e0fcd0, + 0x97f14021, + 0x93f0053c, + 0x0287f110, + 0x0083f130, + 0xf990f980, + 0xfcd0fc80, + 0x4021f4e0, + 0x0560e7f1, + 0xf110e3f0, + 0xf10000d7, + 0x908000d3, + 0xb7f100dc, + 0xb3f08480, + 0xa321f41e, + 0x000057f1, + 0xffff97f1, + 0x830093f1, +/* 0x0734: memx_func_train_loop_4x */ + 0x0080a7f1, + 0xb910a3f0, + 0x21f402ae, + 0x02d8b904, + 0xffdfb7f1, + 0xffffb3f1, + 0xf9048bfd, + 0xfc80f9a0, + 0xf4e0fcd0, + 0xa7f14021, + 0xa3f0053c, + 0x0287f110, + 0x0083f130, + 0xf9a0f980, + 0xfcd0fc80, + 0x4021f4e0, + 0x0560e7f1, + 0xf110e3f0, + 0xf10000d7, + 0xb98000d3, + 0xb7f102dc, + 0xb3f02710, + 0xa321f400, + 0xf402eeb9, + 0xddb90421, + 0x949dff02, 0x700150b6, - 0x1ef50756, - 0x00f8fed4, -/* 0x07c4: memx_exec */ - 0xd0f9e0f9, - 0xb902c1b9, -/* 0x07ce: memx_exec_next */ - 0x139802b2, - 0x0410b600, - 0x01f034e7, - 0x01e033e7, - 0xf00132b6, - 0x35980c30, - 0xb855f9de, - 0x1ef40612, - 0xf10b98e4, - 0xbbf20c98, - 0xb7f102cb, - 0xb4b607c4, - 0x00bbcf06, - 0xe0fcd0fc, - 0x033721f5, -/* 0x080a: memx_info */ - 0xc67000f8, - 0x0e0bf401, -/* 0x0810: memx_info_data */ - 0x03ccc7f1, - 0x0800b7f1, -/* 0x081b: memx_info_train */ - 0xf10b0ef4, - 0xf10bccc7, -/* 0x0823: memx_info_send */ - 0xf50100b7, - 0xf8033721, -/* 0x0829: memx_recv */ - 0x01d6b000, - 0xb0980bf4, - 0x0bf400d6, -/* 0x0837: memx_init */ - 0xf800f8d8, -/* 0x0839: perf_recv */ -/* 0x083b: perf_init */ - 0xf800f800, -/* 0x083d: i2c_drive_scl */ - 0x0036b000, - 0xf1110bf4, - 0xb607e007, - 0x01d00604, - 0xf804bd00, -/* 0x0851: i2c_drive_scl_lo */ - 0xe407f100, - 0x0604b607, - 0xbd0001d0, -/* 0x085f: i2c_drive_sda */ - 0xb000f804, - 0x0bf40036, - 0xe007f111, - 0x0604b607, - 0xbd0002d0, -/* 0x0873: i2c_drive_sda_lo */ - 0xf100f804, - 0xb607e407, - 0x02d00604, - 0xf804bd00, -/* 0x0881: i2c_sense_scl */ - 0x0132f400, - 0x07c437f1, - 0xcf0634b6, - 0x31fd0033, - 0x060bf404, -/* 0x0897: i2c_sense_scl_done */ - 0xf80131f4, -/* 0x0899: i2c_sense_sda */ - 0x0132f400, - 0x07c437f1, - 0xcf0634b6, - 0x32fd0033, - 0x060bf404, -/* 0x08af: i2c_sense_sda_done */ - 0xf80131f4, -/* 0x08b1: i2c_raise_scl */ - 0xf140f900, - 0xf0089847, - 0x21f50137, -/* 0x08be: i2c_raise_scl_wait */ - 0xe7f1083d, - 0x21f403e8, - 0x8121f57f, - 0x0901f408, - 0xf40142b6, -/* 0x08d2: i2c_raise_scl_done */ - 0x40fcef1b, -/* 0x08d6: i2c_start */ - 0x21f500f8, - 0x11f40881, - 0x9921f50d, - 0x0611f408, -/* 0x08e7: i2c_start_rep */ - 0xf0300ef4, - 0x21f50037, - 0x37f0083d, - 0x5f21f501, - 0x0076bb08, - 0xf90465b6, - 0x04659450, - 0xbd0256bb, - 0x0475fd50, - 0x21f550fc, - 0x64b608b1, - 0x1f11f404, -/* 0x0914: i2c_start_send */ - 0xf50037f0, - 0xf1085f21, - 0xf41388e7, - 0x37f07f21, - 0x3d21f500, - 0x88e7f108, - 0x7f21f413, -/* 0x0930: i2c_start_out */ -/* 0x0932: i2c_stop */ - 0x37f000f8, - 0x3d21f500, - 0x0037f008, - 0x085f21f5, - 0x03e8e7f1, - 0xf07f21f4, - 0x21f50137, - 0xe7f1083d, - 0x21f41388, - 0x0137f07f, - 0x085f21f5, - 0x1388e7f1, - 0xf87f21f4, -/* 0x0965: i2c_bitw */ - 0x5f21f500, - 0xe8e7f108, - 0x7f21f403, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xb121f550, - 0x0464b608, - 0xf11811f4, - 0xf41388e7, - 0x37f07f21, - 0x3d21f500, - 0x88e7f108, - 0x7f21f413, -/* 0x09a4: i2c_bitw_out */ -/* 0x09a6: i2c_bitr */ - 0x37f000f8, - 0x5f21f501, + 0x1ef40456, + 0xcc7aa092, + 0x00a9800b, + 0xb60160b6, + 0x66700470, + 0x001ef510, + 0xb650fcff, + 0x56700150, + 0xd41ef507, +/* 0x07c7: memx_exec */ + 0xf900f8fe, + 0xb9d0f9e0, + 0xb2b902c1, +/* 0x07d1: memx_exec_next */ + 0x00139802, + 0xe70410b6, + 0xe701f034, + 0xb601e033, + 0x30f00132, + 0xde35980c, + 0x12b855f9, + 0xe41ef406, + 0x98f10b98, + 0xcbbbf20c, + 0xc4b7f102, + 0x06b4b607, + 0xfc00bbcf, + 0xf5e0fcd0, + 0xf8033621, +/* 0x080d: memx_info */ + 0x01c67000, +/* 0x0813: memx_info_data */ + 0xf10e0bf4, + 0xf103ccc7, + 0xf40800b7, +/* 0x081e: memx_info_train */ + 0xc7f10b0e, + 0xb7f10bcc, +/* 0x0826: memx_info_send */ + 0x21f50100, + 0x00f80336, +/* 0x082c: memx_recv */ + 0xf401d6b0, + 0xd6b0980b, + 0xd80bf400, +/* 0x083a: memx_init */ + 0x00f800f8, +/* 0x083c: perf_recv */ +/* 0x083e: perf_init */ + 0x00f800f8, +/* 0x0840: i2c_drive_scl */ + 0xf40036b0, + 0x07f1110b, + 0x04b607e0, + 0x0001d006, + 0x00f804bd, +/* 0x0854: i2c_drive_scl_lo */ + 0x07e407f1, + 0xd00604b6, + 0x04bd0001, +/* 0x0862: i2c_drive_sda */ + 0x36b000f8, + 0x110bf400, + 0x07e007f1, + 0xd00604b6, + 0x04bd0002, +/* 0x0876: i2c_drive_sda_lo */ + 0x07f100f8, + 0x04b607e4, + 0x0002d006, + 0x00f804bd, +/* 0x0884: i2c_sense_scl */ + 0xf10132f4, + 0xb607c437, + 0x33cf0634, + 0x0431fd00, + 0xf4060bf4, +/* 0x089a: i2c_sense_scl_done */ + 0x00f80131, +/* 0x089c: i2c_sense_sda */ + 0xf10132f4, + 0xb607c437, + 0x33cf0634, + 0x0432fd00, + 0xf4060bf4, +/* 0x08b2: i2c_sense_sda_done */ + 0x00f80131, +/* 0x08b4: i2c_raise_scl */ + 0x47f140f9, + 0x37f00898, + 0x4021f501, +/* 0x08c1: i2c_raise_scl_wait */ 0xe8e7f108, - 0x7f21f403, + 0x7e21f403, + 0x088421f5, + 0xb60901f4, + 0x1bf40142, +/* 0x08d5: i2c_raise_scl_done */ + 0xf840fcef, +/* 0x08d9: i2c_start */ + 0x8421f500, + 0x0d11f408, + 0x089c21f5, + 0xf40611f4, +/* 0x08ea: i2c_start_rep */ + 0x37f0300e, + 0x4021f500, + 0x0137f008, + 0x086221f5, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0xb121f550, + 0xb421f550, 0x0464b608, - 0xf51b11f4, - 0xf0089921, +/* 0x0917: i2c_start_send */ + 0xf01f11f4, 0x21f50037, - 0xe7f1083d, + 0xe7f10862, 0x21f41388, - 0x013cf07f, -/* 0x09eb: i2c_bitr_done */ - 0xf80131f4, -/* 0x09ed: i2c_get_byte */ - 0x0057f000, -/* 0x09f3: i2c_get_byte_next */ - 0xb60847f0, - 0x76bb0154, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb609a621, - 0x11f40464, - 0x0553fd2b, - 0xf40142b6, - 0x37f0d81b, + 0x0037f07e, + 0x084021f5, + 0x1388e7f1, +/* 0x0933: i2c_start_out */ + 0xf87e21f4, +/* 0x0935: i2c_stop */ + 0x0037f000, + 0x084021f5, + 0xf50037f0, + 0xf1086221, + 0xf403e8e7, + 0x37f07e21, + 0x4021f501, + 0x88e7f108, + 0x7e21f413, + 0xf50137f0, + 0xf1086221, + 0xf41388e7, + 0x00f87e21, +/* 0x0968: i2c_bitw */ + 0x086221f5, + 0x03e8e7f1, + 0xbb7e21f4, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x08b421f5, + 0xf40464b6, + 0xe7f11811, + 0x21f41388, + 0x0037f07e, + 0x084021f5, + 0x1388e7f1, +/* 0x09a7: i2c_bitw_out */ + 0xf87e21f4, +/* 0x09a9: i2c_bitr */ + 0x0137f000, + 0x086221f5, + 0x03e8e7f1, + 0xbb7e21f4, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x08b421f5, + 0xf40464b6, + 0x21f51b11, + 0x37f0089c, + 0x4021f500, + 0x88e7f108, + 0x7e21f413, + 0xf4013cf0, +/* 0x09ee: i2c_bitr_done */ + 0x00f80131, +/* 0x09f0: i2c_get_byte */ + 0xf00057f0, +/* 0x09f6: i2c_get_byte_next */ + 0x54b60847, 0x0076bb01, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, 0x21f550fc, - 0x64b60965, -/* 0x0a3d: i2c_get_byte_done */ -/* 0x0a3f: i2c_put_byte */ - 0xf000f804, -/* 0x0a42: i2c_put_byte_next */ - 0x42b60847, - 0x3854ff01, + 0x64b609a9, + 0x2b11f404, + 0xb60553fd, + 0x1bf40142, + 0x0137f0d8, 0xb60076bb, 0x50f90465, 0xbb046594, 0x50bd0256, 0xfc0475fd, - 0x6521f550, + 0x6821f550, 0x0464b609, - 0xb03411f4, - 0x1bf40046, - 0x0076bbd8, +/* 0x0a40: i2c_get_byte_done */ +/* 0x0a42: i2c_put_byte */ + 0x47f000f8, +/* 0x0a45: i2c_put_byte_next */ + 0x0142b608, + 0xbb3854ff, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x096821f5, + 0xf40464b6, + 0x46b03411, + 0xd81bf400, + 0xb60076bb, + 0x50f90465, + 0xbb046594, + 0x50bd0256, + 0xfc0475fd, + 0xa921f550, + 0x0464b609, + 0xbb0f11f4, + 0x36b00076, + 0x061bf401, +/* 0x0a9b: i2c_put_byte_done */ + 0xf80132f4, +/* 0x0a9d: i2c_addr */ + 0x0076bb00, 0xf90465b6, 0x04659450, 0xbd0256bb, 0x0475fd50, 0x21f550fc, - 0x64b609a6, - 0x0f11f404, - 0xb00076bb, - 0x1bf40136, - 0x0132f406, -/* 0x0a98: i2c_put_byte_done */ -/* 0x0a9a: i2c_addr */ - 0x76bb00f8, + 0x64b608d9, + 0x2911f404, + 0x012ec3e7, + 0xfd0134b6, + 0x76bb0553, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0xf550fc04, - 0xb608d621, - 0x11f40464, - 0x2ec3e729, - 0x0134b601, - 0xbb0553fd, + 0xb60a4221, +/* 0x0ae2: i2c_addr_done */ + 0x00f80464, +/* 0x0ae4: i2c_acquire_addr */ + 0xb6f8cec7, + 0xe0b702e4, + 0xee980d1c, +/* 0x0af3: i2c_acquire */ + 0xf500f800, + 0xf40ae421, + 0xd9f00421, + 0x4021f403, +/* 0x0b02: i2c_release */ + 0x21f500f8, + 0x21f40ae4, + 0x03daf004, + 0xf84021f4, +/* 0x0b11: i2c_recv */ + 0x0132f400, + 0xb6f8c1c7, + 0x16b00214, + 0x3a1ff528, + 0xf413a001, + 0x0032980c, + 0x0ccc13a0, + 0xf4003198, + 0xd0f90231, + 0xd0f9e0f9, + 0x000067f1, + 0x100063f1, + 0xbb016792, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x0a3f21f5, -/* 0x0adf: i2c_addr_done */ - 0xf80464b6, -/* 0x0ae1: i2c_acquire_addr */ - 0xf8cec700, - 0xb702e4b6, - 0x980d1ce0, - 0x00f800ee, -/* 0x0af0: i2c_acquire */ - 0x0ae121f5, - 0xf00421f4, - 0x21f403d9, -/* 0x0aff: i2c_release */ - 0xf500f83f, - 0xf40ae121, - 0xdaf00421, - 0x3f21f403, -/* 0x0b0e: i2c_recv */ - 0x32f400f8, - 0xf8c1c701, - 0xb00214b6, - 0x1ff52816, - 0x13a0013a, - 0x32980cf4, - 0xcc13a000, - 0x0031980c, - 0xf90231f4, - 0xf9e0f9d0, - 0x0067f1d0, - 0x0063f100, - 0x01679210, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0xf021f550, - 0x0464b60a, - 0xd6b0d0fc, - 0xb31bf500, - 0x0057f000, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x9a21f550, - 0x0464b60a, - 0x00d011f5, - 0xbbe0c5c7, + 0x0af321f5, + 0xfc0464b6, + 0x00d6b0d0, + 0x00b31bf5, + 0xbb0057f0, 0x65b60076, 0x9450f904, 0x56bb0465, 0xfd50bd02, 0x50fc0475, - 0x0a3f21f5, + 0x0a9d21f5, 0xf50464b6, - 0xf000ad11, - 0x76bb0157, + 0xc700d011, + 0x76bbe0c5, 0x0465b600, 0x659450f9, 0x0256bb04, 0x75fd50bd, 0xf550fc04, - 0xb60a9a21, + 0xb60a4221, 0x11f50464, - 0x76bb008a, - 0x0465b600, - 0x659450f9, - 0x0256bb04, - 0x75fd50bd, - 0xf550fc04, - 0xb609ed21, - 0x11f40464, - 0xe05bcb6a, - 0xb60076bb, - 0x50f90465, - 0xbb046594, - 0x50bd0256, - 0xfc0475fd, - 0x3221f550, - 0x0464b609, - 0xbd025bb9, - 0x430ef474, -/* 0x0c14: i2c_recv_not_rd08 */ - 0xf401d6b0, - 0x57f03d1b, - 0x9a21f500, - 0x3311f40a, - 0xf5e0c5c7, - 0xf40a3f21, - 0x57f02911, - 0x9a21f500, - 0x1f11f40a, - 0xf5e0b5c7, - 0xf40a3f21, - 0x21f51511, - 0x74bd0932, - 0xf408c5c7, - 0x32f4091b, - 0x030ef402, -/* 0x0c54: i2c_recv_not_wr08 */ -/* 0x0c54: i2c_recv_done */ - 0xf5f8cec7, - 0xfc0aff21, - 0xf4d0fce0, - 0x7cb90a12, - 0x3721f502, -/* 0x0c69: i2c_recv_exit */ -/* 0x0c6b: i2c_init */ - 0xf800f803, -/* 0x0c6d: test_recv */ - 0xd817f100, - 0x0614b605, - 0xb60011cf, - 0x07f10110, - 0x04b605d8, - 0x0001d006, - 0xe7f104bd, - 0xe3f1d900, - 0x21f5134f, - 0x00f80257, -/* 0x0c94: test_init */ - 0x0800e7f1, - 0x025721f5, -/* 0x0c9e: idle_recv */ + 0x57f000ad, + 0x0076bb01, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b60a9d, + 0x8a11f504, + 0x0076bb00, + 0xf90465b6, + 0x04659450, + 0xbd0256bb, + 0x0475fd50, + 0x21f550fc, + 0x64b609f0, + 0x6a11f404, + 0xbbe05bcb, + 0x65b60076, + 0x9450f904, + 0x56bb0465, + 0xfd50bd02, + 0x50fc0475, + 0x093521f5, + 0xb90464b6, + 0x74bd025b, +/* 0x0c17: i2c_recv_not_rd08 */ + 0xb0430ef4, + 0x1bf401d6, + 0x0057f03d, + 0x0a9d21f5, + 0xc73311f4, + 0x21f5e0c5, + 0x11f40a42, + 0x0057f029, + 0x0a9d21f5, + 0xc71f11f4, + 0x21f5e0b5, + 0x11f40a42, + 0x3521f515, + 0xc774bd09, + 0x1bf408c5, + 0x0232f409, +/* 0x0c57: i2c_recv_not_wr08 */ +/* 0x0c57: i2c_recv_done */ + 0xc7030ef4, + 0x21f5f8ce, + 0xe0fc0b02, + 0x12f4d0fc, + 0x027cb90a, + 0x033621f5, +/* 0x0c6c: i2c_recv_exit */ +/* 0x0c6e: i2c_init */ 0x00f800f8, -/* 0x0ca0: idle */ - 0xf10031f4, - 0xb605d417, - 0x11cf0614, - 0x0110b600, - 0x05d407f1, - 0xd00604b6, - 0x04bd0001, -/* 0x0cbc: idle_loop */ - 0xf45817f0, -/* 0x0cc2: idle_proc */ -/* 0x0cc2: idle_proc_exec */ - 0x10f90232, - 0xf5021eb9, - 0xfc034021, - 0x0911f410, - 0xf40231f4, -/* 0x0cd6: idle_proc_next */ - 0x10b6ef0e, - 0x061fb858, - 0xf4e61bf4, - 0x28f4dd02, - 0xbb0ef400, - 0x00000000, +/* 0x0c70: test_recv */ + 0x05d817f1, + 0xcf0614b6, + 0x10b60011, + 0xd807f101, + 0x0604b605, + 0xbd0001d0, + 0x00e7f104, + 0x4fe3f1d9, + 0x5621f513, +/* 0x0c97: test_init */ + 0xf100f802, + 0xf50800e7, + 0xf8025621, +/* 0x0ca1: idle_recv */ +/* 0x0ca3: idle */ + 0xf400f800, + 0x17f10031, + 0x14b605d4, + 0x0011cf06, + 0xf10110b6, + 0xb605d407, + 0x01d00604, +/* 0x0cbf: idle_loop */ + 0xf004bd00, + 0x32f45817, +/* 0x0cc5: idle_proc */ +/* 0x0cc5: idle_proc_exec */ + 0xb910f902, + 0x21f5021e, + 0x10fc033f, + 0xf40911f4, + 0x0ef40231, +/* 0x0cd9: idle_proc_next */ + 0x5810b6ef, + 0xf4061fb8, + 0x02f4e61b, + 0x0028f4dd, + 0x00bb0ef4, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc index c2bb616a8..f2420a37f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc @@ -98,8 +98,7 @@ host_send: // $r0 - zero host_recv: // message from intr handler == HOST->PWR comms pending - mov $r1 (PROC_KERN & 0x0000ffff) - sethi $r1 (PROC_KERN & 0xffff0000) + imm32($r1, PROC_KERN) cmp b32 $r14 $r1 bra e #host_send diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc index ad35fa57b..c20a3bd33 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc @@ -51,8 +51,7 @@ time_next: .b32 0 // $r0 - zero rd32: nv_iowr(NV_PPWR_MMIO_ADDR, $r14) - mov $r13 NV_PPWR_MMIO_CTRL_OP_RD - sethi $r13 NV_PPWR_MMIO_CTRL_TRIGGER + imm32($r13, NV_PPWR_MMIO_CTRL_OP_RD | NV_PPWR_MMIO_CTRL_TRIGGER) nv_iowr(NV_PPWR_MMIO_CTRL, $r13) rd32_wait: nv_iord($r13, NV_PPWR_MMIO_CTRL) @@ -70,9 +69,7 @@ rd32: wr32: nv_iowr(NV_PPWR_MMIO_ADDR, $r14) nv_iowr(NV_PPWR_MMIO_DATA, $r13) - mov $r13 NV_PPWR_MMIO_CTRL_OP_WR - or $r13 NV_PPWR_MMIO_CTRL_MASK_B32_0 - sethi $r13 NV_PPWR_MMIO_CTRL_TRIGGER + imm32($r13, NV_PPWR_MMIO_CTRL_OP_WR | NV_PPWR_MMIO_CTRL_MASK_B32_0 | NV_PPWR_MMIO_CTRL_TRIGGER) #ifdef NVKM_FALCON_MMIO_TRAP push $r13 @@ -215,8 +212,7 @@ intr: bra z #intr_subintr_skip_fifo nv_iord($r12, NV_PPWR_FIFO_INTR) push $r12 - mov $r14 (PROC_HOST & 0x0000ffff) - sethi $r14 (PROC_HOST & 0xffff0000) + imm32($r14, PROC_HOST) mov $r13 KMSG_FIFO call(send) pop $r12 @@ -256,7 +252,7 @@ ticks_from_ns: /* try not losing precision (multiply then divide) */ imm32($r13, HW_TICKS_PER_US) - call #mulu32_32_64 + call(mulu32_32_64) /* use an immeditate, it's ok because HW_TICKS_PER_US < 16 bits */ div $r12 $r12 1000 @@ -268,7 +264,7 @@ ticks_from_ns: /* let's divide then multiply, too bad for the precision! */ div $r14 $r14 1000 imm32($r13, HW_TICKS_PER_US) - call #mulu32_32_64 + call(mulu32_32_64) /* this cannot overflow as long as HW_TICKS_PER_US < 1000 */ @@ -290,7 +286,7 @@ ticks_from_us: /* simply multiply $us by HW_TICKS_PER_US */ imm32($r13, HW_TICKS_PER_US) - call #mulu32_32_64 + call(mulu32_32_64) mov b32 $r14 $r12 /* check if there wasn't any overflow */ @@ -511,14 +507,12 @@ init: #ifdef NVKM_FALCON_MMIO_UAS // somehow allows the magic "access mmio via D[]" stuff that's // used by the nv_rd32/nv_wr32 macros to work - mov $r1 0x0010 - sethi $r1 NV_PPWR_UAS_CONFIG_ENABLE + imm32($r1, 0x10 | NV_PPWR_UAS_CONFIG_ENABLE) nv_iowrs(NV_PPWR_UAS_CONFIG, $r1) #endif // route all interrupts except user0/1 and pause to fuc - mov $r1 0x00e0 - sethi $r1 0x00000000 + imm32($r1, 0xe0) nv_iowr(NV_PPWR_INTR_ROUTE, $r1) // enable watchdog and subintr intrs @@ -529,8 +523,8 @@ init: nv_iowr(NV_PPWR_INTR_EN_SET, $r1) // enable interrupts globally - mov $r1 #intr - sethi $r1 0x00000000 + imm32($r1, #intr) + and $r1 0xffff mov $iv0 $r1 bset $flags ie0 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc index 96fc984da..3737bd27f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc @@ -169,7 +169,7 @@ */ .b32 0 /* */ .skip 64 -#if NV_PPWR_CHIPSET < GK208 +#if NVKM_PPWR_CHIPSET < GK208 #define imm32(reg,val) /* */ movw reg ((val) & 0x0000ffff) /* */ sethi reg ((val) & 0xffff0000) @@ -252,12 +252,12 @@ #endif #define st(size, addr, reg) /* -*/ movw $r0 addr /* +*/ imm32($r0, addr) /* */ st size D[$r0] reg /* */ clear b32 $r0 #define ld(size, reg, addr) /* -*/ movw $r0 addr /* +*/ imm32($r0, addr) /* */ ld size reg D[$r0] /* */ clear b32 $r0 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc index 0c3a71bf5..9e3f4e690 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc @@ -48,8 +48,7 @@ test_recv: nv_iord($r1, NV_PPWR_DSCRATCH(2)) add b32 $r1 1 nv_iowr(NV_PPWR_DSCRATCH(2), $r1) - mov $r14 -0x2700 /* 0xd900, envyas grrr! */ - sethi $r14 0x134f0000 + imm32($r14, 0x134fd900) call(timer) ret diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild new file mode 100644 index 000000000..b02b868a6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild @@ -0,0 +1,3 @@ +nvkm-y += nvkm/subdev/secboot/base.o +nvkm-y += nvkm/subdev/secboot/gm200.o +nvkm-y += nvkm/subdev/secboot/gm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c new file mode 100644 index 000000000..520facf9b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "priv.h" +#include <subdev/timer.h> + +static const char * +managed_falcons_names[] = { + [NVKM_SECBOOT_FALCON_PMU] = "PMU", + [NVKM_SECBOOT_FALCON_RESERVED] = "<reserved>", + [NVKM_SECBOOT_FALCON_FECS] = "FECS", + [NVKM_SECBOOT_FALCON_GPCCS] = "GPCCS", + [NVKM_SECBOOT_FALCON_END] = "<invalid>", +}; + +/* + * Helper falcon functions + */ + +static int +falcon_clear_halt_interrupt(struct nvkm_device *device, u32 base) +{ + int ret; + + /* clear halt interrupt */ + nvkm_mask(device, base + 0x004, 0x10, 0x10); + /* wait until halt interrupt is cleared */ + ret = nvkm_wait_msec(device, 10, base + 0x008, 0x10, 0x0); + if (ret < 0) + return ret; + + return 0; +} + +static int +falcon_wait_idle(struct nvkm_device *device, u32 base) +{ + int ret; + + ret = nvkm_wait_msec(device, 10, base + 0x04c, 0xffff, 0x0); + if (ret < 0) + return ret; + + return 0; +} + +static int +nvkm_secboot_falcon_enable(struct nvkm_secboot *sb) +{ + struct nvkm_device *device = sb->subdev.device; + int ret; + + /* enable engine */ + nvkm_mask(device, 0x200, sb->enable_mask, sb->enable_mask); + nvkm_rd32(device, 0x200); + ret = nvkm_wait_msec(device, 10, sb->base + 0x10c, 0x6, 0x0); + if (ret < 0) { + nvkm_mask(device, 0x200, sb->enable_mask, 0x0); + nvkm_error(&sb->subdev, "Falcon mem scrubbing timeout\n"); + return ret; + } + + ret = falcon_wait_idle(device, sb->base); + if (ret) + return ret; + + /* enable IRQs */ + nvkm_wr32(device, sb->base + 0x010, 0xff); + nvkm_mask(device, 0x640, sb->irq_mask, sb->irq_mask); + nvkm_mask(device, 0x644, sb->irq_mask, sb->irq_mask); + + return 0; +} + +static int +nvkm_secboot_falcon_disable(struct nvkm_secboot *sb) +{ + struct nvkm_device *device = sb->subdev.device; + + /* disable IRQs and wait for any previous code to complete */ + nvkm_mask(device, 0x644, sb->irq_mask, 0x0); + nvkm_mask(device, 0x640, sb->irq_mask, 0x0); + nvkm_wr32(device, sb->base + 0x014, 0xff); + + falcon_wait_idle(device, sb->base); + + /* disable engine */ + nvkm_mask(device, 0x200, sb->enable_mask, 0x0); + + return 0; +} + +int +nvkm_secboot_falcon_reset(struct nvkm_secboot *sb) +{ + int ret; + + ret = nvkm_secboot_falcon_disable(sb); + if (ret) + return ret; + + ret = nvkm_secboot_falcon_enable(sb); + if (ret) + return ret; + + return 0; +} + +/** + * nvkm_secboot_falcon_run - run the falcon that will perform secure boot + * + * This function is to be called after all chip-specific preparations have + * been completed. It will start the falcon to perform secure boot, wait for + * it to halt, and report if an error occurred. + */ +int +nvkm_secboot_falcon_run(struct nvkm_secboot *sb) +{ + struct nvkm_device *device = sb->subdev.device; + int ret; + + /* Start falcon */ + nvkm_wr32(device, sb->base + 0x100, 0x2); + + /* Wait for falcon halt */ + ret = nvkm_wait_msec(device, 100, sb->base + 0x100, 0x10, 0x10); + if (ret < 0) + return ret; + + /* If mailbox register contains an error code, then ACR has failed */ + ret = nvkm_rd32(device, sb->base + 0x040); + if (ret) { + nvkm_error(&sb->subdev, "ACR boot failed, ret 0x%08x", ret); + falcon_clear_halt_interrupt(device, sb->base); + return -EINVAL; + } + + return 0; +} + + +/** + * nvkm_secboot_reset() - reset specified falcon + */ +int +nvkm_secboot_reset(struct nvkm_secboot *sb, u32 falcon) +{ + /* Unmanaged falcon? */ + if (!(BIT(falcon) & sb->func->managed_falcons)) { + nvkm_error(&sb->subdev, "cannot reset unmanaged falcon!\n"); + return -EINVAL; + } + + return sb->func->reset(sb, falcon); +} + +/** + * nvkm_secboot_start() - start specified falcon + */ +int +nvkm_secboot_start(struct nvkm_secboot *sb, u32 falcon) +{ + /* Unmanaged falcon? */ + if (!(BIT(falcon) & sb->func->managed_falcons)) { + nvkm_error(&sb->subdev, "cannot start unmanaged falcon!\n"); + return -EINVAL; + } + + return sb->func->start(sb, falcon); +} + +/** + * nvkm_secboot_is_managed() - check whether a given falcon is securely-managed + */ +bool +nvkm_secboot_is_managed(struct nvkm_secboot *secboot, + enum nvkm_secboot_falcon fid) +{ + if (!secboot) + return false; + + return secboot->func->managed_falcons & BIT(fid); +} + +static int +nvkm_secboot_oneinit(struct nvkm_subdev *subdev) +{ + struct nvkm_secboot *sb = nvkm_secboot(subdev); + int ret = 0; + + /* Call chip-specific init function */ + if (sb->func->init) + ret = sb->func->init(sb); + if (ret) { + nvkm_error(subdev, "Secure Boot initialization failed: %d\n", + ret); + return ret; + } + + /* + * Build all blobs - the same blobs can be used to perform secure boot + * multiple times + */ + if (sb->func->prepare_blobs) + ret = sb->func->prepare_blobs(sb); + + return ret; +} + +static int +nvkm_secboot_fini(struct nvkm_subdev *subdev, bool suspend) +{ + struct nvkm_secboot *sb = nvkm_secboot(subdev); + int ret = 0; + + if (sb->func->fini) + ret = sb->func->fini(sb, suspend); + + return ret; +} + +static void * +nvkm_secboot_dtor(struct nvkm_subdev *subdev) +{ + struct nvkm_secboot *sb = nvkm_secboot(subdev); + void *ret = NULL; + + if (sb->func->dtor) + ret = sb->func->dtor(sb); + + return ret; +} + +static const struct nvkm_subdev_func +nvkm_secboot = { + .oneinit = nvkm_secboot_oneinit, + .fini = nvkm_secboot_fini, + .dtor = nvkm_secboot_dtor, +}; + +int +nvkm_secboot_ctor(const struct nvkm_secboot_func *func, + struct nvkm_device *device, int index, + struct nvkm_secboot *sb) +{ + unsigned long fid; + + nvkm_subdev_ctor(&nvkm_secboot, device, index, 0, &sb->subdev); + sb->func = func; + + /* setup the performing falcon's base address and masks */ + switch (func->boot_falcon) { + case NVKM_SECBOOT_FALCON_PMU: + sb->base = 0x10a000; + sb->irq_mask = 0x1000000; + sb->enable_mask = 0x2000; + break; + default: + nvkm_error(&sb->subdev, "invalid secure boot falcon\n"); + return -EINVAL; + }; + + nvkm_debug(&sb->subdev, "securely managed falcons:\n"); + for_each_set_bit(fid, &sb->func->managed_falcons, + NVKM_SECBOOT_FALCON_END) + nvkm_debug(&sb->subdev, "- %s\n", managed_falcons_names[fid]); + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c new file mode 100644 index 000000000..cefd0a923 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c @@ -0,0 +1,1443 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* + * Secure boot is the process by which NVIDIA-signed firmware is loaded into + * some of the falcons of a GPU. For production devices this is the only way + * for the firmware to access useful (but sensitive) registers. + * + * A Falcon microprocessor supporting advanced security modes can run in one of + * three modes: + * + * - Non-secure (NS). In this mode, functionality is similar to Falcon + * architectures before security modes were introduced (pre-Maxwell), but + * capability is restricted. In particular, certain registers may be + * inaccessible for reads and/or writes, and physical memory access may be + * disabled (on certain Falcon instances). This is the only possible mode that + * can be used if you don't have microcode cryptographically signed by NVIDIA. + * + * - Heavy Secure (HS). In this mode, the microprocessor is a black box - it's + * not possible to read or write any Falcon internal state or Falcon registers + * from outside the Falcon (for example, from the host system). The only way + * to enable this mode is by loading microcode that has been signed by NVIDIA. + * (The loading process involves tagging the IMEM block as secure, writing the + * signature into a Falcon register, and starting execution. The hardware will + * validate the signature, and if valid, grant HS privileges.) + * + * - Light Secure (LS). In this mode, the microprocessor has more privileges + * than NS but fewer than HS. Some of the microprocessor state is visible to + * host software to ease debugging. The only way to enable this mode is by HS + * microcode enabling LS mode. Some privileges available to HS mode are not + * available here. LS mode is introduced in GM20x. + * + * Secure boot consists in temporarily switching a HS-capable falcon (typically + * PMU) into HS mode in order to validate the LS firmwares of managed falcons, + * load them, and switch managed falcons into LS mode. Once secure boot + * completes, no falcon remains in HS mode. + * + * Secure boot requires a write-protected memory region (WPR) which can only be + * written by the secure falcon. On dGPU, the driver sets up the WPR region in + * video memory. On Tegra, it is set up by the bootloader and its location and + * size written into memory controller registers. + * + * The secure boot process takes place as follows: + * + * 1) A LS blob is constructed that contains all the LS firmwares we want to + * load, along with their signatures and bootloaders. + * + * 2) A HS blob (also called ACR) is created that contains the signed HS + * firmware in charge of loading the LS firmwares into their respective + * falcons. + * + * 3) The HS blob is loaded (via its own bootloader) and executed on the + * HS-capable falcon. It authenticates itself, switches the secure falcon to + * HS mode and setup the WPR region around the LS blob (dGPU) or copies the + * LS blob into the WPR region (Tegra). + * + * 4) The LS blob is now secure from all external tampering. The HS falcon + * checks the signatures of the LS firmwares and, if valid, switches the + * managed falcons to LS mode and makes them ready to run the LS firmware. + * + * 5) The managed falcons remain in LS mode and can be started. + * + */ + +#include "priv.h" + +#include <core/gpuobj.h> +#include <core/firmware.h> +#include <subdev/fb.h> + +enum { + FALCON_DMAIDX_UCODE = 0, + FALCON_DMAIDX_VIRT = 1, + FALCON_DMAIDX_PHYS_VID = 2, + FALCON_DMAIDX_PHYS_SYS_COH = 3, + FALCON_DMAIDX_PHYS_SYS_NCOH = 4, +}; + +/** + * struct fw_bin_header - header of firmware files + * @bin_magic: always 0x3b1d14f0 + * @bin_ver: version of the bin format + * @bin_size: entire image size including this header + * @header_offset: offset of the firmware/bootloader header in the file + * @data_offset: offset of the firmware/bootloader payload in the file + * @data_size: size of the payload + * + * This header is located at the beginning of the HS firmware and HS bootloader + * files, to describe where the headers and data can be found. + */ +struct fw_bin_header { + u32 bin_magic; + u32 bin_ver; + u32 bin_size; + u32 header_offset; + u32 data_offset; + u32 data_size; +}; + +/** + * struct fw_bl_desc - firmware bootloader descriptor + * @start_tag: starting tag of bootloader + * @desc_dmem_load_off: DMEM offset of flcn_bl_dmem_desc + * @code_off: offset of code section + * @code_size: size of code section + * @data_off: offset of data section + * @data_size: size of data section + * + * This structure is embedded in bootloader firmware files at to describe the + * IMEM and DMEM layout expected by the bootloader. + */ +struct fw_bl_desc { + u32 start_tag; + u32 dmem_load_off; + u32 code_off; + u32 code_size; + u32 data_off; + u32 data_size; +}; + + +/* + * + * LS blob structures + * + */ + +/** + * struct lsf_ucode_desc - LS falcon signatures + * @prd_keys: signature to use when the GPU is in production mode + * @dgb_keys: signature to use when the GPU is in debug mode + * @b_prd_present: whether the production key is present + * @b_dgb_present: whether the debug key is present + * @falcon_id: ID of the falcon the ucode applies to + * + * Directly loaded from a signature file. + */ +struct lsf_ucode_desc { + u8 prd_keys[2][16]; + u8 dbg_keys[2][16]; + u32 b_prd_present; + u32 b_dbg_present; + u32 falcon_id; +}; + +/** + * struct lsf_lsb_header - LS firmware header + * @signature: signature to verify the firmware against + * @ucode_off: offset of the ucode blob in the WPR region. The ucode + * blob contains the bootloader, code and data of the + * LS falcon + * @ucode_size: size of the ucode blob, including bootloader + * @data_size: size of the ucode blob data + * @bl_code_size: size of the bootloader code + * @bl_imem_off: offset in imem of the bootloader + * @bl_data_off: offset of the bootloader data in WPR region + * @bl_data_size: size of the bootloader data + * @app_code_off: offset of the app code relative to ucode_off + * @app_code_size: size of the app code + * @app_data_off: offset of the app data relative to ucode_off + * @app_data_size: size of the app data + * @flags: flags for the secure bootloader + * + * This structure is written into the WPR region for each managed falcon. Each + * instance is referenced by the lsb_offset member of the corresponding + * lsf_wpr_header. + */ +struct lsf_lsb_header { + struct lsf_ucode_desc signature; + u32 ucode_off; + u32 ucode_size; + u32 data_size; + u32 bl_code_size; + u32 bl_imem_off; + u32 bl_data_off; + u32 bl_data_size; + u32 app_code_off; + u32 app_code_size; + u32 app_data_off; + u32 app_data_size; + u32 flags; +#define LSF_FLAG_LOAD_CODE_AT_0 1 +#define LSF_FLAG_DMACTL_REQ_CTX 4 +#define LSF_FLAG_FORCE_PRIV_LOAD 8 +}; + +/** + * struct lsf_wpr_header - LS blob WPR Header + * @falcon_id: LS falcon ID + * @lsb_offset: offset of the lsb_lsf_header in the WPR region + * @bootstrap_owner: secure falcon reponsible for bootstrapping the LS falcon + * @lazy_bootstrap: skip bootstrapping by ACR + * @status: bootstrapping status + * + * An array of these is written at the beginning of the WPR region, one for + * each managed falcon. The array is terminated by an instance which falcon_id + * is LSF_FALCON_ID_INVALID. + */ +struct lsf_wpr_header { + u32 falcon_id; + u32 lsb_offset; + u32 bootstrap_owner; + u32 lazy_bootstrap; + u32 status; +#define LSF_IMAGE_STATUS_NONE 0 +#define LSF_IMAGE_STATUS_COPY 1 +#define LSF_IMAGE_STATUS_VALIDATION_CODE_FAILED 2 +#define LSF_IMAGE_STATUS_VALIDATION_DATA_FAILED 3 +#define LSF_IMAGE_STATUS_VALIDATION_DONE 4 +#define LSF_IMAGE_STATUS_VALIDATION_SKIPPED 5 +#define LSF_IMAGE_STATUS_BOOTSTRAP_READY 6 +}; + + +/** + * struct ls_ucode_img_desc - descriptor of firmware image + * @descriptor_size: size of this descriptor + * @image_size: size of the whole image + * @bootloader_start_offset: start offset of the bootloader in ucode image + * @bootloader_size: size of the bootloader + * @bootloader_imem_offset: start off set of the bootloader in IMEM + * @bootloader_entry_point: entry point of the bootloader in IMEM + * @app_start_offset: start offset of the LS firmware + * @app_size: size of the LS firmware's code and data + * @app_imem_offset: offset of the app in IMEM + * @app_imem_entry: entry point of the app in IMEM + * @app_dmem_offset: offset of the data in DMEM + * @app_resident_code_offset: offset of app code from app_start_offset + * @app_resident_code_size: size of the code + * @app_resident_data_offset: offset of data from app_start_offset + * @app_resident_data_size: size of data + * + * A firmware image contains the code, data, and bootloader of a given LS + * falcon in a single blob. This structure describes where everything is. + * + * This can be generated from a (bootloader, code, data) set if they have + * been loaded separately, or come directly from a file. + */ +struct ls_ucode_img_desc { + u32 descriptor_size; + u32 image_size; + u32 tools_version; + u32 app_version; + char date[64]; + u32 bootloader_start_offset; + u32 bootloader_size; + u32 bootloader_imem_offset; + u32 bootloader_entry_point; + u32 app_start_offset; + u32 app_size; + u32 app_imem_offset; + u32 app_imem_entry; + u32 app_dmem_offset; + u32 app_resident_code_offset; + u32 app_resident_code_size; + u32 app_resident_data_offset; + u32 app_resident_data_size; + u32 nb_overlays; + struct {u32 start; u32 size; } load_ovl[64]; + u32 compressed; +}; + +/** + * struct ls_ucode_img - temporary storage for loaded LS firmwares + * @node: to link within lsf_ucode_mgr + * @falcon_id: ID of the falcon this LS firmware is for + * @ucode_desc: loaded or generated map of ucode_data + * @ucode_header: header of the firmware + * @ucode_data: firmware payload (code and data) + * @ucode_size: size in bytes of data in ucode_data + * @wpr_header: WPR header to be written to the LS blob + * @lsb_header: LSB header to be written to the LS blob + * + * Preparing the WPR LS blob requires information about all the LS firmwares + * (size, etc) to be known. This structure contains all the data of one LS + * firmware. + */ +struct ls_ucode_img { + struct list_head node; + enum nvkm_secboot_falcon falcon_id; + + struct ls_ucode_img_desc ucode_desc; + u32 *ucode_header; + u8 *ucode_data; + u32 ucode_size; + + struct lsf_wpr_header wpr_header; + struct lsf_lsb_header lsb_header; +}; + +/** + * struct ls_ucode_mgr - manager for all LS falcon firmwares + * @count: number of managed LS falcons + * @wpr_size: size of the required WPR region in bytes + * @img_list: linked list of lsf_ucode_img + */ +struct ls_ucode_mgr { + u16 count; + u32 wpr_size; + struct list_head img_list; +}; + + +/* + * + * HS blob structures + * + */ + +/** + * struct hsf_fw_header - HS firmware descriptor + * @sig_dbg_offset: offset of the debug signature + * @sig_dbg_size: size of the debug signature + * @sig_prod_offset: offset of the production signature + * @sig_prod_size: size of the production signature + * @patch_loc: offset of the offset (sic) of where the signature is + * @patch_sig: offset of the offset (sic) to add to sig_*_offset + * @hdr_offset: offset of the load header (see struct hs_load_header) + * @hdr_size: size of above header + * + * This structure is embedded in the HS firmware image at + * hs_bin_hdr.header_offset. + */ +struct hsf_fw_header { + u32 sig_dbg_offset; + u32 sig_dbg_size; + u32 sig_prod_offset; + u32 sig_prod_size; + u32 patch_loc; + u32 patch_sig; + u32 hdr_offset; + u32 hdr_size; +}; + +/** + * struct hsf_load_header - HS firmware load header + */ +struct hsf_load_header { + u32 non_sec_code_off; + u32 non_sec_code_size; + u32 data_dma_base; + u32 data_size; + u32 num_apps; + struct { + u32 sec_code_off; + u32 sec_code_size; + } app[0]; +}; + +/** + * Convenience function to duplicate a firmware file in memory and check that + * it has the required minimum size. + */ +static void * +gm200_secboot_load_firmware(struct nvkm_subdev *subdev, const char *name, + size_t min_size) +{ + const struct firmware *fw; + void *blob; + int ret; + + ret = nvkm_firmware_get(subdev->device, name, &fw); + if (ret) + return ERR_PTR(ret); + if (fw->size < min_size) { + nvkm_error(subdev, "%s is smaller than expected size %zu\n", + name, min_size); + nvkm_firmware_put(fw); + return ERR_PTR(-EINVAL); + } + blob = kmemdup(fw->data, fw->size, GFP_KERNEL); + nvkm_firmware_put(fw); + if (!blob) + return ERR_PTR(-ENOMEM); + + return blob; +} + + +/* + * Low-secure blob creation + */ + +#define BL_DESC_BLK_SIZE 256 +/** + * Build a ucode image and descriptor from provided bootloader, code and data. + * + * @bl: bootloader image, including 16-bytes descriptor + * @code: LS firmware code segment + * @data: LS firmware data segment + * @desc: ucode descriptor to be written + * + * Return: allocated ucode image with corresponding descriptor information. desc + * is also updated to contain the right offsets within returned image. + */ +static void * +ls_ucode_img_build(const struct firmware *bl, const struct firmware *code, + const struct firmware *data, struct ls_ucode_img_desc *desc) +{ + struct fw_bin_header *bin_hdr = (void *)bl->data; + struct fw_bl_desc *bl_desc = (void *)bl->data + bin_hdr->header_offset; + void *bl_data = (void *)bl->data + bin_hdr->data_offset; + u32 pos = 0; + void *image; + + desc->bootloader_start_offset = pos; + desc->bootloader_size = ALIGN(bl_desc->code_size, sizeof(u32)); + desc->bootloader_imem_offset = bl_desc->start_tag * 256; + desc->bootloader_entry_point = bl_desc->start_tag * 256; + + pos = ALIGN(pos + desc->bootloader_size, BL_DESC_BLK_SIZE); + desc->app_start_offset = pos; + desc->app_size = ALIGN(code->size, BL_DESC_BLK_SIZE) + + ALIGN(data->size, BL_DESC_BLK_SIZE); + desc->app_imem_offset = 0; + desc->app_imem_entry = 0; + desc->app_dmem_offset = 0; + desc->app_resident_code_offset = 0; + desc->app_resident_code_size = ALIGN(code->size, BL_DESC_BLK_SIZE); + + pos = ALIGN(pos + desc->app_resident_code_size, BL_DESC_BLK_SIZE); + desc->app_resident_data_offset = pos - desc->app_start_offset; + desc->app_resident_data_size = ALIGN(data->size, BL_DESC_BLK_SIZE); + + desc->image_size = ALIGN(bl_desc->code_size, BL_DESC_BLK_SIZE) + + desc->app_size; + + image = kzalloc(desc->image_size, GFP_KERNEL); + if (!image) + return ERR_PTR(-ENOMEM); + + memcpy(image + desc->bootloader_start_offset, bl_data, + bl_desc->code_size); + memcpy(image + desc->app_start_offset, code->data, code->size); + memcpy(image + desc->app_start_offset + desc->app_resident_data_offset, + data->data, data->size); + + return image; +} + +/** + * ls_ucode_img_load_generic() - load and prepare a LS ucode image + * + * Load the LS microcode, bootloader and signature and pack them into a single + * blob. Also generate the corresponding ucode descriptor. + */ +static int +ls_ucode_img_load_generic(struct nvkm_subdev *subdev, + struct ls_ucode_img *img, const char *falcon_name, + const u32 falcon_id) +{ + const struct firmware *bl, *code, *data; + struct lsf_ucode_desc *lsf_desc; + char f[64]; + int ret; + + img->ucode_header = NULL; + + snprintf(f, sizeof(f), "gr/%s_bl", falcon_name); + ret = nvkm_firmware_get(subdev->device, f, &bl); + if (ret) + goto error; + + snprintf(f, sizeof(f), "gr/%s_inst", falcon_name); + ret = nvkm_firmware_get(subdev->device, f, &code); + if (ret) + goto free_bl; + + snprintf(f, sizeof(f), "gr/%s_data", falcon_name); + ret = nvkm_firmware_get(subdev->device, f, &data); + if (ret) + goto free_inst; + + img->ucode_data = ls_ucode_img_build(bl, code, data, + &img->ucode_desc); + if (IS_ERR(img->ucode_data)) { + ret = PTR_ERR(img->ucode_data); + goto free_data; + } + img->ucode_size = img->ucode_desc.image_size; + + snprintf(f, sizeof(f), "gr/%s_sig", falcon_name); + lsf_desc = gm200_secboot_load_firmware(subdev, f, sizeof(*lsf_desc)); + if (IS_ERR(lsf_desc)) { + ret = PTR_ERR(lsf_desc); + goto free_image; + } + /* not needed? the signature should already have the right value */ + lsf_desc->falcon_id = falcon_id; + memcpy(&img->lsb_header.signature, lsf_desc, sizeof(*lsf_desc)); + img->falcon_id = lsf_desc->falcon_id; + kfree(lsf_desc); + + /* success path - only free requested firmware files */ + goto free_data; + +free_image: + kfree(img->ucode_data); +free_data: + nvkm_firmware_put(data); +free_inst: + nvkm_firmware_put(code); +free_bl: + nvkm_firmware_put(bl); +error: + return ret; +} + +typedef int (*lsf_load_func)(struct nvkm_subdev *, struct ls_ucode_img *); + +static int +ls_ucode_img_load_fecs(struct nvkm_subdev *subdev, struct ls_ucode_img *img) +{ + return ls_ucode_img_load_generic(subdev, img, "fecs", + NVKM_SECBOOT_FALCON_FECS); +} + +static int +ls_ucode_img_load_gpccs(struct nvkm_subdev *subdev, struct ls_ucode_img *img) +{ + return ls_ucode_img_load_generic(subdev, img, "gpccs", + NVKM_SECBOOT_FALCON_GPCCS); +} + +/** + * ls_ucode_img_load() - create a lsf_ucode_img and load it + */ +static struct ls_ucode_img * +ls_ucode_img_load(struct nvkm_subdev *subdev, lsf_load_func load_func) +{ + struct ls_ucode_img *img; + int ret; + + img = kzalloc(sizeof(*img), GFP_KERNEL); + if (!img) + return ERR_PTR(-ENOMEM); + + ret = load_func(subdev, img); + if (ret) { + kfree(img); + return ERR_PTR(ret); + } + + return img; +} + +static const lsf_load_func lsf_load_funcs[] = { + [NVKM_SECBOOT_FALCON_END] = NULL, /* reserve enough space */ + [NVKM_SECBOOT_FALCON_FECS] = ls_ucode_img_load_fecs, + [NVKM_SECBOOT_FALCON_GPCCS] = ls_ucode_img_load_gpccs, +}; + +/** + * ls_ucode_img_populate_bl_desc() - populate a DMEM BL descriptor for LS image + * @img: ucode image to generate against + * @desc: descriptor to populate + * @sb: secure boot state to use for base addresses + * + * Populate the DMEM BL descriptor with the information contained in a + * ls_ucode_desc. + * + */ +static void +ls_ucode_img_populate_bl_desc(struct ls_ucode_img *img, u64 wpr_addr, + struct gm200_flcn_bl_desc *desc) +{ + struct ls_ucode_img_desc *pdesc = &img->ucode_desc; + u64 addr_base; + + addr_base = wpr_addr + img->lsb_header.ucode_off + + pdesc->app_start_offset; + + memset(desc, 0, sizeof(*desc)); + desc->ctx_dma = FALCON_DMAIDX_UCODE; + desc->code_dma_base.lo = lower_32_bits( + (addr_base + pdesc->app_resident_code_offset)); + desc->code_dma_base.hi = upper_32_bits( + (addr_base + pdesc->app_resident_code_offset)); + desc->non_sec_code_size = pdesc->app_resident_code_size; + desc->data_dma_base.lo = lower_32_bits( + (addr_base + pdesc->app_resident_data_offset)); + desc->data_dma_base.hi = upper_32_bits( + (addr_base + pdesc->app_resident_data_offset)); + desc->data_size = pdesc->app_resident_data_size; + desc->code_entry_point = pdesc->app_imem_entry; +} + +#define LSF_LSB_HEADER_ALIGN 256 +#define LSF_BL_DATA_ALIGN 256 +#define LSF_BL_DATA_SIZE_ALIGN 256 +#define LSF_BL_CODE_SIZE_ALIGN 256 +#define LSF_UCODE_DATA_ALIGN 4096 + +/** + * ls_ucode_img_fill_headers - fill the WPR and LSB headers of an image + * @gsb: secure boot device used + * @img: image to generate for + * @offset: offset in the WPR region where this image starts + * + * Allocate space in the WPR area from offset and write the WPR and LSB headers + * accordingly. + * + * Return: offset at the end of this image. + */ +static u32 +ls_ucode_img_fill_headers(struct gm200_secboot *gsb, struct ls_ucode_img *img, + u32 offset) +{ + struct lsf_wpr_header *whdr = &img->wpr_header; + struct lsf_lsb_header *lhdr = &img->lsb_header; + struct ls_ucode_img_desc *desc = &img->ucode_desc; + + if (img->ucode_header) { + nvkm_fatal(&gsb->base.subdev, + "images withough loader are not supported yet!\n"); + return offset; + } + + /* Fill WPR header */ + whdr->falcon_id = img->falcon_id; + whdr->bootstrap_owner = gsb->base.func->boot_falcon; + whdr->status = LSF_IMAGE_STATUS_COPY; + + /* Align, save off, and include an LSB header size */ + offset = ALIGN(offset, LSF_LSB_HEADER_ALIGN); + whdr->lsb_offset = offset; + offset += sizeof(struct lsf_lsb_header); + + /* + * Align, save off, and include the original (static) ucode + * image size + */ + offset = ALIGN(offset, LSF_UCODE_DATA_ALIGN); + lhdr->ucode_off = offset; + offset += img->ucode_size; + + /* + * For falcons that use a boot loader (BL), we append a loader + * desc structure on the end of the ucode image and consider + * this the boot loader data. The host will then copy the loader + * desc args to this space within the WPR region (before locking + * down) and the HS bin will then copy them to DMEM 0 for the + * loader. + */ + lhdr->bl_code_size = ALIGN(desc->bootloader_size, + LSF_BL_CODE_SIZE_ALIGN); + lhdr->ucode_size = ALIGN(desc->app_resident_data_offset, + LSF_BL_CODE_SIZE_ALIGN) + lhdr->bl_code_size; + lhdr->data_size = ALIGN(desc->app_size, LSF_BL_CODE_SIZE_ALIGN) + + lhdr->bl_code_size - lhdr->ucode_size; + /* + * Though the BL is located at 0th offset of the image, the VA + * is different to make sure that it doesn't collide the actual + * OS VA range + */ + lhdr->bl_imem_off = desc->bootloader_imem_offset; + lhdr->app_code_off = desc->app_start_offset + + desc->app_resident_code_offset; + lhdr->app_code_size = desc->app_resident_code_size; + lhdr->app_data_off = desc->app_start_offset + + desc->app_resident_data_offset; + lhdr->app_data_size = desc->app_resident_data_size; + + lhdr->flags = 0; + if (img->falcon_id == gsb->base.func->boot_falcon) + lhdr->flags = LSF_FLAG_DMACTL_REQ_CTX; + + /* GPCCS will be loaded using PRI */ + if (img->falcon_id == NVKM_SECBOOT_FALCON_GPCCS) + lhdr->flags |= LSF_FLAG_FORCE_PRIV_LOAD; + + /* Align (size bloat) and save off BL descriptor size */ + lhdr->bl_data_size = ALIGN(sizeof(struct gm200_flcn_bl_desc), + LSF_BL_DATA_SIZE_ALIGN); + /* + * Align, save off, and include the additional BL data + */ + offset = ALIGN(offset, LSF_BL_DATA_ALIGN); + lhdr->bl_data_off = offset; + offset += lhdr->bl_data_size; + + return offset; +} + +static void +ls_ucode_mgr_init(struct ls_ucode_mgr *mgr) +{ + memset(mgr, 0, sizeof(*mgr)); + INIT_LIST_HEAD(&mgr->img_list); +} + +static void +ls_ucode_mgr_cleanup(struct ls_ucode_mgr *mgr) +{ + struct ls_ucode_img *img, *t; + + list_for_each_entry_safe(img, t, &mgr->img_list, node) { + kfree(img->ucode_data); + kfree(img->ucode_header); + kfree(img); + } +} + +static void +ls_ucode_mgr_add_img(struct ls_ucode_mgr *mgr, struct ls_ucode_img *img) +{ + mgr->count++; + list_add_tail(&img->node, &mgr->img_list); +} + +/** + * ls_ucode_mgr_fill_headers - fill WPR and LSB headers of all managed images + */ +static void +ls_ucode_mgr_fill_headers(struct gm200_secboot *gsb, struct ls_ucode_mgr *mgr) +{ + struct ls_ucode_img *img; + u32 offset; + + /* + * Start with an array of WPR headers at the base of the WPR. + * The expectation here is that the secure falcon will do a single DMA + * read of this array and cache it internally so it's ok to pack these. + * Also, we add 1 to the falcon count to indicate the end of the array. + */ + offset = sizeof(struct lsf_wpr_header) * (mgr->count + 1); + + /* + * Walk the managed falcons, accounting for the LSB structs + * as well as the ucode images. + */ + list_for_each_entry(img, &mgr->img_list, node) { + offset = ls_ucode_img_fill_headers(gsb, img, offset); + } + + mgr->wpr_size = offset; +} + +/** + * ls_ucode_mgr_write_wpr - write the WPR blob contents + */ +static int +ls_ucode_mgr_write_wpr(struct gm200_secboot *gsb, struct ls_ucode_mgr *mgr, + struct nvkm_gpuobj *wpr_blob) +{ + struct ls_ucode_img *img; + u32 pos = 0; + + nvkm_kmap(wpr_blob); + + list_for_each_entry(img, &mgr->img_list, node) { + nvkm_gpuobj_memcpy_to(wpr_blob, pos, &img->wpr_header, + sizeof(img->wpr_header)); + + nvkm_gpuobj_memcpy_to(wpr_blob, img->wpr_header.lsb_offset, + &img->lsb_header, sizeof(img->lsb_header)); + + /* Generate and write BL descriptor */ + if (!img->ucode_header) { + u8 desc[gsb->func->bl_desc_size]; + struct gm200_flcn_bl_desc gdesc; + + ls_ucode_img_populate_bl_desc(img, gsb->wpr_addr, + &gdesc); + gsb->func->fixup_bl_desc(&gdesc, &desc); + nvkm_gpuobj_memcpy_to(wpr_blob, + img->lsb_header.bl_data_off, + &desc, gsb->func->bl_desc_size); + } + + /* Copy ucode */ + nvkm_gpuobj_memcpy_to(wpr_blob, img->lsb_header.ucode_off, + img->ucode_data, img->ucode_size); + + pos += sizeof(img->wpr_header); + } + + nvkm_wo32(wpr_blob, pos, NVKM_SECBOOT_FALCON_INVALID); + + nvkm_done(wpr_blob); + + return 0; +} + +/* Both size and address of WPR need to be 128K-aligned */ +#define WPR_ALIGNMENT 0x20000 +/** + * gm200_secboot_prepare_ls_blob() - prepare the LS blob + * + * For each securely managed falcon, load the FW, signatures and bootloaders and + * prepare a ucode blob. Then, compute the offsets in the WPR region for each + * blob, and finally write the headers and ucode blobs into a GPU object that + * will be copied into the WPR region by the HS firmware. + */ +static int +gm200_secboot_prepare_ls_blob(struct gm200_secboot *gsb) +{ + struct nvkm_secboot *sb = &gsb->base; + struct nvkm_device *device = sb->subdev.device; + struct ls_ucode_mgr mgr; + int falcon_id; + int ret; + + ls_ucode_mgr_init(&mgr); + + /* Load all LS blobs */ + for_each_set_bit(falcon_id, &gsb->base.func->managed_falcons, + NVKM_SECBOOT_FALCON_END) { + struct ls_ucode_img *img; + + img = ls_ucode_img_load(&sb->subdev, lsf_load_funcs[falcon_id]); + + if (IS_ERR(img)) { + ret = PTR_ERR(img); + goto cleanup; + } + ls_ucode_mgr_add_img(&mgr, img); + } + + /* + * Fill the WPR and LSF headers with the right offsets and compute + * required WPR size + */ + ls_ucode_mgr_fill_headers(gsb, &mgr); + mgr.wpr_size = ALIGN(mgr.wpr_size, WPR_ALIGNMENT); + + /* Allocate GPU object that will contain the WPR region */ + ret = nvkm_gpuobj_new(device, mgr.wpr_size, WPR_ALIGNMENT, false, NULL, + &gsb->ls_blob); + if (ret) + goto cleanup; + + nvkm_debug(&sb->subdev, "%d managed LS falcons, WPR size is %d bytes\n", + mgr.count, mgr.wpr_size); + + /* If WPR address and size are not fixed, set them to fit the LS blob */ + if (!gsb->wpr_size) { + gsb->wpr_addr = gsb->ls_blob->addr; + gsb->wpr_size = gsb->ls_blob->size; + } + + /* Write LS blob */ + ret = ls_ucode_mgr_write_wpr(gsb, &mgr, gsb->ls_blob); + +cleanup: + ls_ucode_mgr_cleanup(&mgr); + + return ret; +} + +/* + * High-secure blob creation + */ + +/** + * gm200_secboot_hsf_patch_signature() - patch HS blob with correct signature + */ +static void +gm200_secboot_hsf_patch_signature(struct gm200_secboot *gsb, void *acr_image) +{ + struct nvkm_secboot *sb = &gsb->base; + struct fw_bin_header *hsbin_hdr = acr_image; + struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset; + void *hs_data = acr_image + hsbin_hdr->data_offset; + void *sig; + u32 sig_size; + + /* Falcon in debug or production mode? */ + if ((nvkm_rd32(sb->subdev.device, sb->base + 0xc08) >> 20) & 0x1) { + sig = acr_image + fw_hdr->sig_dbg_offset; + sig_size = fw_hdr->sig_dbg_size; + } else { + sig = acr_image + fw_hdr->sig_prod_offset; + sig_size = fw_hdr->sig_prod_size; + } + + /* Patch signature */ + memcpy(hs_data + fw_hdr->patch_loc, sig + fw_hdr->patch_sig, sig_size); +} + +/** + * gm200_secboot_populate_hsf_bl_desc() - populate BL descriptor for HS image + */ +static void +gm200_secboot_populate_hsf_bl_desc(void *acr_image, + struct gm200_flcn_bl_desc *bl_desc) +{ + struct fw_bin_header *hsbin_hdr = acr_image; + struct hsf_fw_header *fw_hdr = acr_image + hsbin_hdr->header_offset; + struct hsf_load_header *load_hdr = acr_image + fw_hdr->hdr_offset; + + /* + * Descriptor for the bootloader that will load the ACR image into + * IMEM/DMEM memory. + */ + fw_hdr = acr_image + hsbin_hdr->header_offset; + load_hdr = acr_image + fw_hdr->hdr_offset; + memset(bl_desc, 0, sizeof(*bl_desc)); + bl_desc->ctx_dma = FALCON_DMAIDX_VIRT; + bl_desc->non_sec_code_off = load_hdr->non_sec_code_off; + bl_desc->non_sec_code_size = load_hdr->non_sec_code_size; + bl_desc->sec_code_off = load_hdr->app[0].sec_code_off; + bl_desc->sec_code_size = load_hdr->app[0].sec_code_size; + bl_desc->code_entry_point = 0; + /* + * We need to set code_dma_base to the virtual address of the acr_blob, + * and add this address to data_dma_base before writing it into DMEM + */ + bl_desc->code_dma_base.lo = 0; + bl_desc->data_dma_base.lo = load_hdr->data_dma_base; + bl_desc->data_size = load_hdr->data_size; +} + +/** + * gm200_secboot_prepare_hs_blob - load and prepare a HS blob and BL descriptor + * + * @gsb secure boot instance to prepare for + * @fw name of the HS firmware to load + * @blob pointer to gpuobj that will be allocated to receive the HS FW payload + * @bl_desc pointer to the BL descriptor to write for this firmware + * @patch whether we should patch the HS descriptor (only for HS loaders) + */ +static int +gm200_secboot_prepare_hs_blob(struct gm200_secboot *gsb, const char *fw, + struct nvkm_gpuobj **blob, + struct gm200_flcn_bl_desc *bl_desc, bool patch) +{ + struct nvkm_subdev *subdev = &gsb->base.subdev; + void *acr_image; + struct fw_bin_header *hsbin_hdr; + struct hsf_fw_header *fw_hdr; + void *acr_data; + struct hsf_load_header *load_hdr; + struct hsflcn_acr_desc *desc; + int ret; + + acr_image = gm200_secboot_load_firmware(subdev, fw, 0); + if (IS_ERR(acr_image)) + return PTR_ERR(acr_image); + hsbin_hdr = acr_image; + + /* Patch signature */ + gm200_secboot_hsf_patch_signature(gsb, acr_image); + + acr_data = acr_image + hsbin_hdr->data_offset; + + /* Patch descriptor? */ + if (patch) { + fw_hdr = acr_image + hsbin_hdr->header_offset; + load_hdr = acr_image + fw_hdr->hdr_offset; + desc = acr_data + load_hdr->data_dma_base; + gsb->func->fixup_hs_desc(gsb, desc); + } + + /* Generate HS BL descriptor */ + gm200_secboot_populate_hsf_bl_desc(acr_image, bl_desc); + + /* Create ACR blob and copy HS data to it */ + ret = nvkm_gpuobj_new(subdev->device, ALIGN(hsbin_hdr->data_size, 256), + 0x1000, false, NULL, blob); + if (ret) + goto cleanup; + + nvkm_kmap(*blob); + nvkm_gpuobj_memcpy_to(*blob, 0, acr_data, hsbin_hdr->data_size); + nvkm_done(*blob); + +cleanup: + kfree(acr_image); + + return ret; +} + +/* + * High-secure bootloader blob creation + */ + +static int +gm200_secboot_prepare_hsbl_blob(struct gm200_secboot *gsb) +{ + struct nvkm_subdev *subdev = &gsb->base.subdev; + + gsb->hsbl_blob = gm200_secboot_load_firmware(subdev, "acr/bl", 0); + if (IS_ERR(gsb->hsbl_blob)) { + int ret = PTR_ERR(gsb->hsbl_blob); + + gsb->hsbl_blob = NULL; + return ret; + } + + return 0; +} + +/** + * gm20x_secboot_prepare_blobs - load blobs common to all GM20X GPUs. + * + * This includes the LS blob, HS ucode loading blob, and HS bootloader. + * + * The HS ucode unload blob is only used on dGPU. + */ +int +gm20x_secboot_prepare_blobs(struct gm200_secboot *gsb) +{ + int ret; + + /* Load and prepare the managed falcon's firmwares */ + ret = gm200_secboot_prepare_ls_blob(gsb); + if (ret) + return ret; + + /* Load the HS firmware that will load the LS firmwares */ + ret = gm200_secboot_prepare_hs_blob(gsb, "acr/ucode_load", + &gsb->acr_load_blob, + &gsb->acr_load_bl_desc, true); + if (ret) + return ret; + + /* Load the HS firmware bootloader */ + ret = gm200_secboot_prepare_hsbl_blob(gsb); + if (ret) + return ret; + + return 0; +} + +static int +gm200_secboot_prepare_blobs(struct nvkm_secboot *sb) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret; + + ret = gm20x_secboot_prepare_blobs(gsb); + if (ret) + return ret; + + /* dGPU only: load the HS firmware that unprotects the WPR region */ + ret = gm200_secboot_prepare_hs_blob(gsb, "acr/ucode_unload", + &gsb->acr_unload_blob, + &gsb->acr_unload_bl_desc, false); + if (ret) + return ret; + + return 0; +} + + + +/* + * Secure Boot Execution + */ + +/** + * gm200_secboot_load_hs_bl() - load HS bootloader into DMEM and IMEM + */ +static void +gm200_secboot_load_hs_bl(struct gm200_secboot *gsb, void *data, u32 data_size) +{ + struct nvkm_device *device = gsb->base.subdev.device; + struct fw_bin_header *hdr = gsb->hsbl_blob; + struct fw_bl_desc *hsbl_desc = gsb->hsbl_blob + hdr->header_offset; + void *blob_data = gsb->hsbl_blob + hdr->data_offset; + void *hsbl_code = blob_data + hsbl_desc->code_off; + void *hsbl_data = blob_data + hsbl_desc->data_off; + u32 code_size = ALIGN(hsbl_desc->code_size, 256); + const u32 base = gsb->base.base; + u32 blk; + u32 tag; + int i; + + /* + * Copy HS bootloader data + */ + nvkm_wr32(device, base + 0x1c0, (0x00000000 | (0x1 << 24))); + for (i = 0; i < hsbl_desc->data_size / 4; i++) + nvkm_wr32(device, base + 0x1c4, ((u32 *)hsbl_data)[i]); + + /* + * Copy HS bootloader interface structure where the HS descriptor + * expects it to be + */ + nvkm_wr32(device, base + 0x1c0, + (hsbl_desc->dmem_load_off | (0x1 << 24))); + for (i = 0; i < data_size / 4; i++) + nvkm_wr32(device, base + 0x1c4, ((u32 *)data)[i]); + + /* Copy HS bootloader code to end of IMEM */ + blk = (nvkm_rd32(device, base + 0x108) & 0x1ff) - (code_size >> 8); + tag = hsbl_desc->start_tag; + nvkm_wr32(device, base + 0x180, ((blk & 0xff) << 8) | (0x1 << 24)); + for (i = 0; i < code_size / 4; i++) { + /* write new tag every 256B */ + if ((i & 0x3f) == 0) { + nvkm_wr32(device, base + 0x188, tag & 0xffff); + tag++; + } + nvkm_wr32(device, base + 0x184, ((u32 *)hsbl_code)[i]); + } + nvkm_wr32(device, base + 0x188, 0); +} + +/** + * gm200_secboot_setup_falcon() - set up the secure falcon for secure boot + */ +static int +gm200_secboot_setup_falcon(struct gm200_secboot *gsb) +{ + struct nvkm_device *device = gsb->base.subdev.device; + struct fw_bin_header *hdr = gsb->hsbl_blob; + struct fw_bl_desc *hsbl_desc = gsb->hsbl_blob + hdr->header_offset; + /* virtual start address for boot vector */ + u32 virt_addr = hsbl_desc->start_tag << 8; + const u32 base = gsb->base.base; + const u32 reg_base = base + 0xe00; + u32 inst_loc; + int ret; + + ret = nvkm_secboot_falcon_reset(&gsb->base); + if (ret) + return ret; + + /* setup apertures - virtual */ + nvkm_wr32(device, reg_base + 4 * (FALCON_DMAIDX_UCODE), 0x4); + nvkm_wr32(device, reg_base + 4 * (FALCON_DMAIDX_VIRT), 0x0); + /* setup apertures - physical */ + nvkm_wr32(device, reg_base + 4 * (FALCON_DMAIDX_PHYS_VID), 0x4); + nvkm_wr32(device, reg_base + 4 * (FALCON_DMAIDX_PHYS_SYS_COH), + 0x4 | 0x1); + nvkm_wr32(device, reg_base + 4 * (FALCON_DMAIDX_PHYS_SYS_NCOH), + 0x4 | 0x2); + + /* Set context */ + if (nvkm_memory_target(gsb->inst->memory) == NVKM_MEM_TARGET_VRAM) + inst_loc = 0x0; /* FB */ + else + inst_loc = 0x3; /* Non-coherent sysmem */ + + nvkm_mask(device, base + 0x048, 0x1, 0x1); + nvkm_wr32(device, base + 0x480, + ((gsb->inst->addr >> 12) & 0xfffffff) | + (inst_loc << 28) | (1 << 30)); + + /* Set boot vector to code's starting virtual address */ + nvkm_wr32(device, base + 0x104, virt_addr); + + return 0; +} + +/** + * gm200_secboot_run_hs_blob() - run the given high-secure blob + */ +static int +gm200_secboot_run_hs_blob(struct gm200_secboot *gsb, struct nvkm_gpuobj *blob, + struct gm200_flcn_bl_desc *desc) +{ + struct nvkm_vma vma; + u64 vma_addr; + const u32 bl_desc_size = gsb->func->bl_desc_size; + u8 bl_desc[bl_desc_size]; + int ret; + + /* Map the HS firmware so the HS bootloader can see it */ + ret = nvkm_gpuobj_map(blob, gsb->vm, NV_MEM_ACCESS_RW, &vma); + if (ret) + return ret; + + /* Add the mapping address to the DMA bases */ + vma_addr = flcn64_to_u64(desc->code_dma_base) + vma.offset; + desc->code_dma_base.lo = lower_32_bits(vma_addr); + desc->code_dma_base.hi = upper_32_bits(vma_addr); + vma_addr = flcn64_to_u64(desc->data_dma_base) + vma.offset; + desc->data_dma_base.lo = lower_32_bits(vma_addr); + desc->data_dma_base.hi = upper_32_bits(vma_addr); + + /* Fixup the BL header */ + gsb->func->fixup_bl_desc(desc, &bl_desc); + + /* Reset the falcon and make it ready to run the HS bootloader */ + ret = gm200_secboot_setup_falcon(gsb); + if (ret) + goto done; + + /* Load the HS bootloader into the falcon's IMEM/DMEM */ + gm200_secboot_load_hs_bl(gsb, &bl_desc, bl_desc_size); + + /* Start the HS bootloader */ + ret = nvkm_secboot_falcon_run(&gsb->base); + if (ret) + goto done; + +done: + /* Restore the original DMA addresses */ + vma_addr = flcn64_to_u64(desc->code_dma_base) - vma.offset; + desc->code_dma_base.lo = lower_32_bits(vma_addr); + desc->code_dma_base.hi = upper_32_bits(vma_addr); + vma_addr = flcn64_to_u64(desc->data_dma_base) - vma.offset; + desc->data_dma_base.lo = lower_32_bits(vma_addr); + desc->data_dma_base.hi = upper_32_bits(vma_addr); + + /* We don't need the ACR firmware anymore */ + nvkm_gpuobj_unmap(&vma); + + return ret; +} + +/* + * gm200_secboot_reset() - execute secure boot from the prepared state + * + * Load the HS bootloader and ask the falcon to run it. This will in turn + * load the HS firmware and run it, so once the falcon stops all the managed + * falcons should have their LS firmware loaded and be ready to run. + */ +int +gm200_secboot_reset(struct nvkm_secboot *sb, enum nvkm_secboot_falcon falcon) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret; + + /* + * Dummy GM200 implementation: perform secure boot each time we are + * called on FECS. Since only FECS and GPCCS are managed and started + * together, this ought to be safe. + * + * Once we have proper PMU firmware and support, this will be changed + * to a proper call to the PMU method. + */ + if (falcon != NVKM_SECBOOT_FALCON_FECS) + goto end; + + /* If WPR is set and we have an unload blob, run it to unlock WPR */ + if (gsb->acr_unload_blob && + gsb->falcon_state[NVKM_SECBOOT_FALCON_FECS] != NON_SECURE) { + ret = gm200_secboot_run_hs_blob(gsb, gsb->acr_unload_blob, + &gsb->acr_unload_bl_desc); + if (ret) + return ret; + } + + /* Reload all managed falcons */ + ret = gm200_secboot_run_hs_blob(gsb, gsb->acr_load_blob, + &gsb->acr_load_bl_desc); + if (ret) + return ret; + +end: + gsb->falcon_state[falcon] = RESET; + return 0; +} + +int +gm200_secboot_start(struct nvkm_secboot *sb, enum nvkm_secboot_falcon falcon) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int base; + + switch (falcon) { + case NVKM_SECBOOT_FALCON_FECS: + base = 0x409000; + break; + case NVKM_SECBOOT_FALCON_GPCCS: + base = 0x41a000; + break; + default: + nvkm_error(&sb->subdev, "cannot start unhandled falcon!\n"); + return -EINVAL; + } + + nvkm_wr32(sb->subdev.device, base + 0x130, 0x00000002); + gsb->falcon_state[falcon] = RUNNING; + + return 0; +} + + + +int +gm200_secboot_init(struct nvkm_secboot *sb) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + struct nvkm_device *device = sb->subdev.device; + struct nvkm_vm *vm; + const u64 vm_area_len = 600 * 1024; + int ret; + + /* Allocate instance block and VM */ + ret = nvkm_gpuobj_new(device, 0x1000, 0, true, NULL, &gsb->inst); + if (ret) + return ret; + + ret = nvkm_gpuobj_new(device, 0x8000, 0, true, NULL, &gsb->pgd); + if (ret) + return ret; + + ret = nvkm_vm_new(device, 0, vm_area_len, 0, NULL, &vm); + if (ret) + return ret; + + atomic_inc(&vm->engref[NVKM_SUBDEV_PMU]); + + ret = nvkm_vm_ref(vm, &gsb->vm, gsb->pgd); + nvkm_vm_ref(NULL, &vm, NULL); + if (ret) + return ret; + + nvkm_kmap(gsb->inst); + nvkm_wo32(gsb->inst, 0x200, lower_32_bits(gsb->pgd->addr)); + nvkm_wo32(gsb->inst, 0x204, upper_32_bits(gsb->pgd->addr)); + nvkm_wo32(gsb->inst, 0x208, lower_32_bits(vm_area_len - 1)); + nvkm_wo32(gsb->inst, 0x20c, upper_32_bits(vm_area_len - 1)); + nvkm_done(gsb->inst); + + return 0; +} + +int +gm200_secboot_fini(struct nvkm_secboot *sb, bool suspend) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret = 0; + int i; + + /* Run the unload blob to unprotect the WPR region */ + if (gsb->acr_unload_blob && + gsb->falcon_state[NVKM_SECBOOT_FALCON_FECS] != NON_SECURE) + ret = gm200_secboot_run_hs_blob(gsb, gsb->acr_unload_blob, + &gsb->acr_unload_bl_desc); + + for (i = 0; i < NVKM_SECBOOT_FALCON_END; i++) + gsb->falcon_state[i] = NON_SECURE; + + return ret; +} + +void * +gm200_secboot_dtor(struct nvkm_secboot *sb) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + + nvkm_gpuobj_del(&gsb->acr_unload_blob); + + kfree(gsb->hsbl_blob); + nvkm_gpuobj_del(&gsb->acr_load_blob); + nvkm_gpuobj_del(&gsb->ls_blob); + + nvkm_vm_ref(NULL, &gsb->vm, gsb->pgd); + nvkm_gpuobj_del(&gsb->pgd); + nvkm_gpuobj_del(&gsb->inst); + + return gsb; +} + + +static const struct nvkm_secboot_func +gm200_secboot = { + .dtor = gm200_secboot_dtor, + .init = gm200_secboot_init, + .fini = gm200_secboot_fini, + .prepare_blobs = gm200_secboot_prepare_blobs, + .reset = gm200_secboot_reset, + .start = gm200_secboot_start, + .managed_falcons = BIT(NVKM_SECBOOT_FALCON_FECS) | + BIT(NVKM_SECBOOT_FALCON_GPCCS), + .boot_falcon = NVKM_SECBOOT_FALCON_PMU, +}; + +/** + * gm200_fixup_bl_desc - just copy the BL descriptor + * + * Use the GM200 descriptor format by default. + */ +static void +gm200_secboot_fixup_bl_desc(const struct gm200_flcn_bl_desc *desc, void *ret) +{ + memcpy(ret, desc, sizeof(*desc)); +} + +static void +gm200_secboot_fixup_hs_desc(struct gm200_secboot *gsb, + struct hsflcn_acr_desc *desc) +{ + desc->ucode_blob_base = gsb->ls_blob->addr; + desc->ucode_blob_size = gsb->ls_blob->size; + + desc->wpr_offset = 0; + + /* WPR region information for the HS binary to set up */ + desc->wpr_region_id = 1; + desc->regions.no_regions = 1; + desc->regions.region_props[0].region_id = 1; + desc->regions.region_props[0].start_addr = gsb->wpr_addr >> 8; + desc->regions.region_props[0].end_addr = + (gsb->wpr_addr + gsb->wpr_size) >> 8; +} + +static const struct gm200_secboot_func +gm200_secboot_func = { + .bl_desc_size = sizeof(struct gm200_flcn_bl_desc), + .fixup_bl_desc = gm200_secboot_fixup_bl_desc, + .fixup_hs_desc = gm200_secboot_fixup_hs_desc, +}; + +int +gm200_secboot_new(struct nvkm_device *device, int index, + struct nvkm_secboot **psb) +{ + int ret; + struct gm200_secboot *gsb; + + gsb = kzalloc(sizeof(*gsb), GFP_KERNEL); + if (!gsb) { + psb = NULL; + return -ENOMEM; + } + *psb = &gsb->base; + + ret = nvkm_secboot_ctor(&gm200_secboot, device, index, &gsb->base); + if (ret) + return ret; + + gsb->func = &gm200_secboot_func; + + return 0; +} + +/*(DEBLOBBED)*/ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c new file mode 100644 index 000000000..77872da73 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "priv.h" + +#include <core/gpuobj.h> + +/* + * The BL header format used by GM20B's firmware is slightly different + * from the one of GM200. Fix the differences here. + */ +struct gm20b_flcn_bl_desc { + u32 reserved[4]; + u32 signature[4]; + u32 ctx_dma; + u32 code_dma_base; + u32 non_sec_code_off; + u32 non_sec_code_size; + u32 sec_code_off; + u32 sec_code_size; + u32 code_entry_point; + u32 data_dma_base; + u32 data_size; +}; + +/** + * gm20b_secboot_fixup_bl_desc - adapt BL descriptor to format used by GM20B FW + * + * There is only a slight format difference (DMA addresses being 32-bits and + * 256B-aligned) to address. + */ +static void +gm20b_secboot_fixup_bl_desc(const struct gm200_flcn_bl_desc *desc, void *ret) +{ + struct gm20b_flcn_bl_desc *gdesc = ret; + u64 addr; + + memcpy(gdesc->reserved, desc->reserved, sizeof(gdesc->reserved)); + memcpy(gdesc->signature, desc->signature, sizeof(gdesc->signature)); + gdesc->ctx_dma = desc->ctx_dma; + addr = desc->code_dma_base.hi; + addr <<= 32; + addr |= desc->code_dma_base.lo; + gdesc->code_dma_base = lower_32_bits(addr >> 8); + gdesc->non_sec_code_off = desc->non_sec_code_off; + gdesc->non_sec_code_size = desc->non_sec_code_size; + gdesc->sec_code_off = desc->sec_code_off; + gdesc->sec_code_size = desc->sec_code_size; + gdesc->code_entry_point = desc->code_entry_point; + addr = desc->data_dma_base.hi; + addr <<= 32; + addr |= desc->data_dma_base.lo; + gdesc->data_dma_base = lower_32_bits(addr >> 8); + gdesc->data_size = desc->data_size; +} + +static void +gm20b_secboot_fixup_hs_desc(struct gm200_secboot *gsb, + struct hsflcn_acr_desc *desc) +{ + desc->ucode_blob_base = gsb->ls_blob->addr; + desc->ucode_blob_size = gsb->ls_blob->size; + + desc->wpr_offset = 0; +} + +static const struct gm200_secboot_func +gm20b_secboot_func = { + .bl_desc_size = sizeof(struct gm20b_flcn_bl_desc), + .fixup_bl_desc = gm20b_secboot_fixup_bl_desc, + .fixup_hs_desc = gm20b_secboot_fixup_hs_desc, +}; + + +#ifdef CONFIG_ARCH_TEGRA +#define TEGRA_MC_BASE 0x70019000 +#define MC_SECURITY_CARVEOUT2_CFG0 0xc58 +#define MC_SECURITY_CARVEOUT2_BOM_0 0xc5c +#define MC_SECURITY_CARVEOUT2_BOM_HI_0 0xc60 +#define MC_SECURITY_CARVEOUT2_SIZE_128K 0xc64 +#define TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED (1 << 1) +/** + * sb_tegra_read_wpr() - read the WPR registers on Tegra + * + * On dGPU, we can manage the WPR region ourselves, but on Tegra the WPR region + * is reserved from system memory by the bootloader and irreversibly locked. + * This function reads the address and size of the pre-configured WPR region. + */ +static int +gm20b_tegra_read_wpr(struct gm200_secboot *gsb) +{ + struct nvkm_secboot *sb = &gsb->base; + void __iomem *mc; + u32 cfg; + + mc = ioremap(TEGRA_MC_BASE, 0xd00); + if (!mc) { + nvkm_error(&sb->subdev, "Cannot map Tegra MC registers\n"); + return PTR_ERR(mc); + } + gsb->wpr_addr = ioread32_native(mc + MC_SECURITY_CARVEOUT2_BOM_0) | + ((u64)ioread32_native(mc + MC_SECURITY_CARVEOUT2_BOM_HI_0) << 32); + gsb->wpr_size = ioread32_native(mc + MC_SECURITY_CARVEOUT2_SIZE_128K) + << 17; + cfg = ioread32_native(mc + MC_SECURITY_CARVEOUT2_CFG0); + iounmap(mc); + + /* Check that WPR settings are valid */ + if (gsb->wpr_size == 0) { + nvkm_error(&sb->subdev, "WPR region is empty\n"); + return -EINVAL; + } + + if (!(cfg & TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED)) { + nvkm_error(&sb->subdev, "WPR region not locked\n"); + return -EINVAL; + } + + return 0; +} +#else +static int +gm20b_tegra_read_wpr(struct gm200_secboot *gsb) +{ + nvkm_error(&gsb->base.subdev, "Tegra support not compiled in\n"); + return -EINVAL; +} +#endif + +static int +gm20b_secboot_prepare_blobs(struct nvkm_secboot *sb) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int acr_size; + int ret; + + ret = gm20x_secboot_prepare_blobs(gsb); + if (ret) + return ret; + + acr_size = gsb->acr_load_blob->size; + /* + * On Tegra the WPR region is set by the bootloader. It is illegal for + * the HS blob to be larger than this region. + */ + if (acr_size > gsb->wpr_size) { + nvkm_error(&sb->subdev, "WPR region too small for FW blob!\n"); + nvkm_error(&sb->subdev, "required: %dB\n", acr_size); + nvkm_error(&sb->subdev, "WPR size: %dB\n", gsb->wpr_size); + return -ENOSPC; + } + + return 0; +} + +static int +gm20b_secboot_init(struct nvkm_secboot *sb) +{ + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret; + + ret = gm20b_tegra_read_wpr(gsb); + if (ret) + return ret; + + return gm200_secboot_init(sb); +} + +static const struct nvkm_secboot_func +gm20b_secboot = { + .dtor = gm200_secboot_dtor, + .init = gm20b_secboot_init, + .prepare_blobs = gm20b_secboot_prepare_blobs, + .reset = gm200_secboot_reset, + .start = gm200_secboot_start, + .managed_falcons = BIT(NVKM_SECBOOT_FALCON_FECS), + .boot_falcon = NVKM_SECBOOT_FALCON_PMU, +}; + +int +gm20b_secboot_new(struct nvkm_device *device, int index, + struct nvkm_secboot **psb) +{ + int ret; + struct gm200_secboot *gsb; + + gsb = kzalloc(sizeof(*gsb), GFP_KERNEL); + if (!gsb) { + psb = NULL; + return -ENOMEM; + } + *psb = &gsb->base; + + ret = nvkm_secboot_ctor(&gm20b_secboot, device, index, &gsb->base); + if (ret) + return ret; + + gsb->func = &gm20b_secboot_func; + + return 0; +} + +/*(DEBLOBBED)*/ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h new file mode 100644 index 000000000..f2b09dee7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVKM_SECBOOT_PRIV_H__ +#define __NVKM_SECBOOT_PRIV_H__ + +#include <subdev/secboot.h> +#include <subdev/mmu.h> + +struct nvkm_secboot_func { + int (*init)(struct nvkm_secboot *); + int (*fini)(struct nvkm_secboot *, bool suspend); + void *(*dtor)(struct nvkm_secboot *); + int (*prepare_blobs)(struct nvkm_secboot *); + int (*reset)(struct nvkm_secboot *, enum nvkm_secboot_falcon); + int (*start)(struct nvkm_secboot *, enum nvkm_secboot_falcon); + + /* ID of the falcon that will perform secure boot */ + enum nvkm_secboot_falcon boot_falcon; + /* Bit-mask of IDs of managed falcons */ + unsigned long managed_falcons; +}; + +int nvkm_secboot_ctor(const struct nvkm_secboot_func *, struct nvkm_device *, + int index, struct nvkm_secboot *); +int nvkm_secboot_falcon_reset(struct nvkm_secboot *); +int nvkm_secboot_falcon_run(struct nvkm_secboot *); + +struct flcn_u64 { + u32 lo; + u32 hi; +}; +static inline u64 flcn64_to_u64(const struct flcn_u64 f) +{ + return ((u64)f.hi) << 32 | f.lo; +} + +/** + * struct gm200_flcn_bl_desc - DMEM bootloader descriptor + * @signature: 16B signature for secure code. 0s if no secure code + * @ctx_dma: DMA context to be used by BL while loading code/data + * @code_dma_base: 256B-aligned Physical FB Address where code is located + * (falcon's $xcbase register) + * @non_sec_code_off: offset from code_dma_base where the non-secure code is + * located. The offset must be multiple of 256 to help perf + * @non_sec_code_size: the size of the nonSecure code part. + * @sec_code_off: offset from code_dma_base where the secure code is + * located. The offset must be multiple of 256 to help perf + * @sec_code_size: offset from code_dma_base where the secure code is + * located. The offset must be multiple of 256 to help perf + * @code_entry_point: code entry point which will be invoked by BL after + * code is loaded. + * @data_dma_base: 256B aligned Physical FB Address where data is located. + * (falcon's $xdbase register) + * @data_size: size of data block. Should be multiple of 256B + * + * Structure used by the bootloader to load the rest of the code. This has + * to be filled by host and copied into DMEM at offset provided in the + * hsflcn_bl_desc.bl_desc_dmem_load_off. + */ +struct gm200_flcn_bl_desc { + u32 reserved[4]; + u32 signature[4]; + u32 ctx_dma; + struct flcn_u64 code_dma_base; + u32 non_sec_code_off; + u32 non_sec_code_size; + u32 sec_code_off; + u32 sec_code_size; + u32 code_entry_point; + struct flcn_u64 data_dma_base; + u32 data_size; +}; + +/** + * struct hsflcn_acr_desc - data section of the HS firmware + * + * This header is to be copied at the beginning of DMEM by the HS bootloader. + * + * @signature: signature of ACR ucode + * @wpr_region_id: region ID holding the WPR header and its details + * @wpr_offset: offset from the WPR region holding the wpr header + * @regions: region descriptors + * @nonwpr_ucode_blob_size: size of LS blob + * @nonwpr_ucode_blob_start: FB location of LS blob is + */ +struct hsflcn_acr_desc { + union { + u8 reserved_dmem[0x200]; + u32 signatures[4]; + } ucode_reserved_space; + u32 wpr_region_id; + u32 wpr_offset; + u32 mmu_mem_range; +#define FLCN_ACR_MAX_REGIONS 2 + struct { + u32 no_regions; + struct { + u32 start_addr; + u32 end_addr; + u32 region_id; + u32 read_mask; + u32 write_mask; + u32 client_mask; + } region_props[FLCN_ACR_MAX_REGIONS]; + } regions; + u32 ucode_blob_size; + u64 ucode_blob_base __aligned(8); + struct { + u32 vpr_enabled; + u32 vpr_start; + u32 vpr_end; + u32 hdcp_policies; + } vpr_desc; +}; + +/** + * Contains the whole secure boot state, allowing it to be performed as needed + * @wpr_addr: physical address of the WPR region + * @wpr_size: size in bytes of the WPR region + * @ls_blob: LS blob of all the LS firmwares, signatures, bootloaders + * @ls_blob_size: size of the LS blob + * @ls_blob_nb_regions: number of LS firmwares that will be loaded + * @acr_blob: HS blob + * @acr_blob_vma: mapping of the HS blob into the secure falcon's VM + * @acr_bl_desc: bootloader descriptor of the HS blob + * @hsbl_blob: HS blob bootloader + * @inst: instance block for HS falcon + * @pgd: page directory for the HS falcon + * @vm: address space used by the HS falcon + * @bl_desc_size: size of the BL descriptor used by this chip. + * @fixup_bl_desc: hook that generates the proper BL descriptor format from + * the generic GM200 format into a data array of size + * bl_desc_size + */ +struct gm200_secboot { + struct nvkm_secboot base; + const struct gm200_secboot_func *func; + + /* + * Address and size of the WPR region. On dGPU this will be the + * address of the LS blob. On Tegra this is a fixed region set by the + * bootloader + */ + u64 wpr_addr; + u32 wpr_size; + + /* + * HS FW - lock WPR region (dGPU only) and load LS FWs + * on Tegra the HS FW copies the LS blob into the fixed WPR instead + */ + struct nvkm_gpuobj *acr_load_blob; + struct gm200_flcn_bl_desc acr_load_bl_desc; + + /* HS FW - unlock WPR region (dGPU only) */ + struct nvkm_gpuobj *acr_unload_blob; + struct gm200_flcn_bl_desc acr_unload_bl_desc; + + /* HS bootloader */ + void *hsbl_blob; + + /* LS FWs, to be loaded by the HS ACR */ + struct nvkm_gpuobj *ls_blob; + + /* Instance block & address space used for HS FW execution */ + struct nvkm_gpuobj *inst; + struct nvkm_gpuobj *pgd; + struct nvkm_vm *vm; + + /* To keep track of the state of all managed falcons */ + enum { + /* In non-secure state, no firmware loaded, no privileges*/ + NON_SECURE = 0, + /* In low-secure mode and ready to be started */ + RESET, + /* In low-secure mode and running */ + RUNNING, + } falcon_state[NVKM_SECBOOT_FALCON_END]; + +}; +#define gm200_secboot(sb) container_of(sb, struct gm200_secboot, base) + +struct gm200_secboot_func { + /* + * Size of the bootloader descriptor for this chip. A block of this + * size is allocated before booting a falcon and the fixup_bl_desc + * callback is called on it + */ + u32 bl_desc_size; + void (*fixup_bl_desc)(const struct gm200_flcn_bl_desc *, void *); + + /* + * Chip-specific modifications of the HS descriptor can be done here. + * On dGPU this is used to fill the information about the WPR region + * we want the HS FW to set up. + */ + void (*fixup_hs_desc)(struct gm200_secboot *, struct hsflcn_acr_desc *); +}; + +int gm200_secboot_init(struct nvkm_secboot *); +void *gm200_secboot_dtor(struct nvkm_secboot *); +int gm200_secboot_reset(struct nvkm_secboot *, u32); +int gm200_secboot_start(struct nvkm_secboot *, u32); + +int gm20x_secboot_prepare_blobs(struct gm200_secboot *); + +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild index b035c6e28..c34076223 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild @@ -3,3 +3,4 @@ nvkm-y += nvkm/subdev/volt/gpio.o nvkm-y += nvkm/subdev/volt/nv40.o nvkm-y += nvkm/subdev/volt/gk104.o nvkm-y += nvkm/subdev/volt/gk20a.o +nvkm-y += nvkm/subdev/volt/gm20b.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c index fd56c6476..d55445532 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -24,21 +24,9 @@ #include <core/tegra.h> -struct cvb_coef { - int c0; - int c1; - int c2; - int c3; - int c4; - int c5; -}; - -struct gk20a_volt { - struct nvkm_volt base; - struct regulator *vdd; -}; +#include "gk20a.h" -const struct cvb_coef gk20a_cvb_coef[] = { +static const struct cvb_coef gk20a_cvb_coef[] = { /* MHz, c0, c1, c2, c3, c4, c5 */ /* 72 */ { 1209886, -36468, 515, 417, -13123, 203}, /* 108 */ { 1130804, -27659, 296, 298, -10834, 221}, @@ -89,7 +77,7 @@ gk20a_volt_get_cvb_t_voltage(int speedo, int temp, int s_scale, int t_scale, return mv; } -static int +int gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo) { int mv; @@ -100,7 +88,7 @@ gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo) return mv * 1000; } -static int +int gk20a_volt_vid_get(struct nvkm_volt *base) { struct gk20a_volt *volt = gk20a_volt(base); @@ -115,7 +103,7 @@ gk20a_volt_vid_get(struct nvkm_volt *base) return -EINVAL; } -static int +int gk20a_volt_vid_set(struct nvkm_volt *base, u8 vid) { struct gk20a_volt *volt = gk20a_volt(base); @@ -125,7 +113,7 @@ gk20a_volt_vid_set(struct nvkm_volt *base, u8 vid) return regulator_set_voltage(volt->vdd, volt->base.vid[vid].uv, 1200000); } -static int +int gk20a_volt_set_id(struct nvkm_volt *base, u8 id, int condition) { struct gk20a_volt *volt = gk20a_volt(base); @@ -155,30 +143,25 @@ gk20a_volt = { }; int -gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) +_gk20a_volt_ctor(struct nvkm_device *device, int index, + const struct cvb_coef *coefs, int nb_coefs, + struct gk20a_volt *volt) { struct nvkm_device_tegra *tdev = device->func->tegra(device); - struct gk20a_volt *volt; int i, uv; - if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL))) - return -ENOMEM; - nvkm_volt_ctor(&gk20a_volt, device, index, &volt->base); - *pvolt = &volt->base; uv = regulator_get_voltage(tdev->vdd); - nvkm_info(&volt->base.subdev, "The default voltage is %duV\n", uv); + nvkm_debug(&volt->base.subdev, "the default voltage is %duV\n", uv); volt->vdd = tdev->vdd; - volt->base.vid_nr = ARRAY_SIZE(gk20a_cvb_coef); - nvkm_debug(&volt->base.subdev, "%s - vid_nr = %d\n", __func__, - volt->base.vid_nr); + volt->base.vid_nr = nb_coefs; for (i = 0; i < volt->base.vid_nr; i++) { volt->base.vid[i].vid = i; volt->base.vid[i].uv = - gk20a_volt_calc_voltage(&gk20a_cvb_coef[i], + gk20a_volt_calc_voltage(&coefs[i], tdev->gpu_speedo); nvkm_debug(&volt->base.subdev, "%2d: vid=%d, uv=%d\n", i, volt->base.vid[i].vid, volt->base.vid[i].uv); @@ -186,3 +169,17 @@ gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) return 0; } + +int +gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) +{ + struct gk20a_volt *volt; + + volt = kzalloc(sizeof(*volt), GFP_KERNEL); + if (!volt) + return -ENOMEM; + *pvolt = &volt->base; + + return _gk20a_volt_ctor(device, index, gk20a_cvb_coef, + ARRAY_SIZE(gk20a_cvb_coef), volt); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.h b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.h new file mode 100644 index 000000000..0fa3b502b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __GK20A_VOLT_H__ +#define __GK20A_VOLT_H__ + +struct cvb_coef { + int c0; + int c1; + int c2; + int c3; + int c4; + int c5; +}; + +struct gk20a_volt { + struct nvkm_volt base; + struct regulator *vdd; +}; + +int _gk20a_volt_ctor(struct nvkm_device *device, int index, + const struct cvb_coef *coefs, int nb_coefs, + struct gk20a_volt *volt); + +int gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo); +int gk20a_volt_vid_get(struct nvkm_volt *volt); +int gk20a_volt_vid_set(struct nvkm_volt *volt, u8 vid); +int gk20a_volt_set_id(struct nvkm_volt *volt, u8 id, int condition); + +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c new file mode 100644 index 000000000..49b5ecb70 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "priv.h" +#include "gk20a.h" + +#include <core/tegra.h> + +const struct cvb_coef gm20b_cvb_coef[] = { + /* KHz, c0, c1, c2 */ + /* 76800 */ { 1786666, -85625, 1632 }, + /* 153600 */ { 1846729, -87525, 1632 }, + /* 230400 */ { 1910480, -89425, 1632 }, + /* 307200 */ { 1977920, -91325, 1632 }, + /* 384000 */ { 2049049, -93215, 1632 }, + /* 460800 */ { 2122872, -95095, 1632 }, + /* 537600 */ { 2201331, -96985, 1632 }, + /* 614400 */ { 2283479, -98885, 1632 }, + /* 691200 */ { 2369315, -100785, 1632 }, + /* 768000 */ { 2458841, -102685, 1632 }, + /* 844800 */ { 2550821, -104555, 1632 }, + /* 921600 */ { 2647676, -106455, 1632 }, +}; + +int +gm20b_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt) +{ + struct gk20a_volt *volt; + + volt = kzalloc(sizeof(*volt), GFP_KERNEL); + if (!volt) + return -ENOMEM; + *pvolt = &volt->base; + + return _gk20a_volt_ctor(device, index, gm20b_cvb_coef, + ARRAY_SIZE(gm20b_cvb_coef), volt); +} |