diff --git a/drivers/gpu/nvgpu/clk/clk_prog.c b/drivers/gpu/nvgpu/clk/clk_prog.c index 7d2e8e78d..10da7b81e 100644 --- a/drivers/gpu/nvgpu/clk/clk_prog.c +++ b/drivers/gpu/nvgpu/clk/clk_prog.c @@ -59,6 +59,7 @@ static int _clk_progs_pmudatainit(struct gk20a *g, } pset->slave_entry_count = pprogs->slave_entry_count; pset->vf_entry_count = pprogs->vf_entry_count; + pset->vf_sec_entry_count = pprogs->vf_sec_entry_count; done: return status; @@ -121,6 +122,7 @@ int clk_prog_sw_setup(struct gk20a *g) status = devinit_get_clk_prog_table(g, pclkprogobjs); if (status) { + nvgpu_err(g, "Error parsing the clk prog Vbios tables"); goto done; } @@ -130,7 +132,6 @@ int clk_prog_sw_setup(struct gk20a *g) goto done; } - done: nvgpu_log_info(g, " done status %x", status); return status; @@ -155,11 +156,273 @@ int clk_prog_pmu_setup(struct gk20a *g) return status; } -static int devinit_get_clk_prog_table(struct gk20a *g, - struct clk_progs *pclkprogobjs) +static int devinit_get_clk_prog_table_35(struct gk20a *g, + struct clk_progs *pclkprogobjs, + u8 *clkprogs_tbl_ptr) +{ + int status = 0; + struct vbios_clock_programming_table_35_header header = { 0 }; + struct vbios_clock_programming_table_1x_entry prog = { 0 }; + struct vbios_clock_programming_table_1x_slave_entry slaveprog = { 0 }; + struct vbios_clock_programming_table_35_vf_entry vfprog = { 0 }; + struct vbios_clock_programming_table_35_vf_sec_entry vfsecprog = { 0 }; + u8 *entry = NULL; + u8 *slaveentry = NULL; + u8 *vfentry = NULL; + u8 *vfsecentry = NULL; + u32 i, j, k = 0; + struct clk_prog *pprog; + u8 prog_type; + u8 src_type; + u32 szfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D; + u32 hszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_35_HEADER_SIZE_0A; + u32 slaveszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_SIZE_03; + u32 vfszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_35_VF_ENTRY_SIZE_01; + u32 vfsecszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_35_VF_SEC_ENTRY_SIZE_02; + struct ctrl_clk_clk_prog_1x_master_vf_entry + vfentries[CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; + struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail + voltrailsecvfentries[ + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry + ratioslaveentries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; + struct ctrl_clk_clk_prog_1x_master_table_slave_entry + tableslaveentries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; + union { + struct boardobj board_obj; + struct clk_prog clkprog; + struct clk_prog_1x v1x; + struct clk_prog_35_master v35_master; + struct clk_prog_35_master_ratio v35_master_ratio; + struct clk_prog_35_master_table v35_master_table; + } prog_data; + + nvgpu_log_info(g, " "); + + if (clkprogs_tbl_ptr == NULL) { + status = -EINVAL; + goto done; + } + + memcpy(&header, clkprogs_tbl_ptr, hszfmt); + if (header.header_size < hszfmt) { + status = -EINVAL; + goto done; + } + hszfmt = header.header_size; + + if (header.entry_size < szfmt) { + status = -EINVAL; + goto done; + } + szfmt = header.entry_size; + + if (header.vf_entry_size < vfszfmt) { + status = -EINVAL; + goto done; + } + vfszfmt = header.vf_entry_size; + + if (header.slave_entry_size < slaveszfmt) { + status = -EINVAL; + goto done; + } + slaveszfmt = header.slave_entry_size; + + if (header.vf_entry_count > CTRL_CLK_CLK_DELTA_MAX_VOLT_RAILS) { + status = -EINVAL; + goto done; + } + + if (header.vf_sec_entry_size < vfsecszfmt) { + status = -EINVAL; + goto done; + } + vfsecszfmt = header.vf_sec_entry_size; + + pclkprogobjs->slave_entry_count = header.slave_entry_count; + pclkprogobjs->vf_entry_count = header.vf_entry_count; + pclkprogobjs->vf_sec_entry_count = header.vf_sec_entry_count; + + for (i = 0; i < header.entry_count; i++) { + memset(&prog_data, 0x0, (u32)sizeof(prog_data)); + + /* Read table entries*/ + entry = clkprogs_tbl_ptr + hszfmt + + (i * (szfmt + (header.slave_entry_count * slaveszfmt) + + (header.vf_entry_count * vfszfmt) + + (header.vf_sec_entry_count * vfsecszfmt))); + + memcpy(&prog, entry, szfmt); + memset(vfentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES); + memset(voltrailsecvfentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail) * + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES); + memset(ratioslaveentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES); + memset(tableslaveentries, 0xFF, + sizeof(struct ctrl_clk_clk_prog_1x_master_table_slave_entry) * + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES); + + prog_type = (u8)BIOS_GET_FIELD((prog.flags0), + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE); + nvgpu_log_info(g, "Prog_type (master, slave type): 0x%x", + prog_type); + if (prog_type == NV_VBIOS_CLOCK_PROGRAMMING_TABLE_35_ENTRY_FLAGS0_TYPE_DISABLED) { + nvgpu_log_info(g, "Skipped Entry"); + continue; + } + + src_type = (u8)BIOS_GET_FIELD(prog.flags0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE); + nvgpu_log_info(g, "source type: 0x%x", src_type); + switch (src_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL: + nvgpu_log_info(g, "Source type is PLL"); + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_PLL; + prog_data.v1x.source_data.pll.pll_idx = + (u8)BIOS_GET_FIELD(prog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX); + prog_data.v1x.source_data.pll.freq_step_size_mhz = + (u8)BIOS_GET_FIELD(prog.param1, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE); + nvgpu_log_info(g, "pll_index: 0x%x freq_step_size: %d", + prog_data.v1x.source_data.pll.pll_idx, + prog_data.v1x.source_data.pll.freq_step_size_mhz); + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_ONE_SOURCE: + nvgpu_log_info(g, "Source type is ONE_SOURCE"); + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE; + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_FLL: + nvgpu_log_info(g, "Source type is FLL"); + prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_FLL; + break; + + default: + nvgpu_err(g, "invalid source %d", prog_type); + status = -EINVAL; + break; + } + + if (status != 0) { + goto done; + } + prog_data.v1x.freq_max_mhz = (u16)prog.freq_max_mhz; + nvgpu_log_info(g, "Max freq: %d", prog_data.v1x.freq_max_mhz); + + slaveentry = entry + szfmt; + vfentry = entry + szfmt + header.slave_entry_count * slaveszfmt; + vfsecentry = entry + szfmt + + header.slave_entry_count * slaveszfmt + + header.vf_entry_count * vfszfmt; + + switch (prog_type) { + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + prog_data.v35_master.master.b_o_c_o_v_enabled = false; + for (j = 0; j < header.vf_entry_count; j++) { + memcpy(&vfprog, vfentry, vfszfmt); + + vfentries[j].vfe_idx = (u8)vfprog.vfe_idx; + vfentries[j].gain_vfe_idx = CTRL_BOARDOBJ_IDX_INVALID; + vfentry += vfszfmt; + + for (k = 0; k < header.vf_sec_entry_count; k++) { + memcpy(&vfsecprog, vfsecentry, vfsecszfmt); + + voltrailsecvfentries[j].sec_vf_entries[k].vfe_idx = (u8)vfsecprog.sec_vfe_idx; + if (prog_data.v1x.source == CTRL_CLK_PROG_1X_SOURCE_FLL) { + voltrailsecvfentries[j].sec_vf_entries[k].dvco_offset_vfe_idx = (u8)BIOS_GET_FIELD( + vfsecprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_35_SEC_VF_ENTRY_PARAM0_FLL_DVCO_OFFSET_VFE_IDX); + } else { + voltrailsecvfentries[j].sec_vf_entries[k].dvco_offset_vfe_idx = CTRL_BOARDOBJ_IDX_INVALID; + } + vfsecentry += vfsecszfmt; + nvgpu_log_info(g, "Sec_VF_entry %d: vfe_idx: 0x%x " + "dcvo_offset_vfe_idx: 0x%x", j, + voltrailsecvfentries[j].sec_vf_entries[k].vfe_idx, + voltrailsecvfentries[j].sec_vf_entries[k].dvco_offset_vfe_idx); + } + } + prog_data.v35_master.master.p_vf_entries = vfentries; + prog_data.v35_master.p_voltrail_sec_vf_entries = voltrailsecvfentries; + + for (j = 0; j < header.slave_entry_count; j++) { + memcpy(&slaveprog, slaveentry, slaveszfmt); + if (prog_type == NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO) { + ratioslaveentries[j].clk_dom_idx = + (u8)slaveprog.clk_dom_idx; + ratioslaveentries[j].ratio = (u8) + BIOS_GET_FIELD(slaveprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO); + } else { + tableslaveentries[j].clk_dom_idx = + (u8)slaveprog.clk_dom_idx; + tableslaveentries[j].freq_mhz = + (u16)BIOS_GET_FIELD(slaveprog.param0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ); + } + slaveentry += slaveszfmt; + } + + if (prog_type == NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO) { + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_35_MASTER_RATIO; + prog_data.v35_master_ratio.ratio.p_slave_entries = + ratioslaveentries; + } else { + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_35_MASTER_TABLE; + + prog_data.v35_master_table.table.p_slave_entries = + tableslaveentries; + } + break; + + case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SLAVE: + prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_35; + break; + + default: + nvgpu_err(g, "Wrong Prog entry type %d", prog_type); + status = -EINVAL; + break; + } + + if (status != 0) { + goto done; + } + pprog = construct_clk_prog(g, (void *)&prog_data); + if (pprog == NULL) { + nvgpu_err(g, + "error constructing clk_prog boardobj %d", i); + status = -EINVAL; + goto done; + } + + status = boardobjgrp_objinsert(&pclkprogobjs->super.super, + (struct boardobj *)(void *)pprog, i); + if (status != 0) { + nvgpu_err(g, "error adding clk_prog boardobj %d", i); + status = -EINVAL; + goto done; + } + } +done: + nvgpu_log_info(g, " done status %x", status); + return status; +} + +static int devinit_get_clk_prog_table_1x(struct gk20a *g, + struct clk_progs *pclkprogobjs, + u8 *clkprogs_tbl_ptr) { int status = 0; - u8 *clkprogs_tbl_ptr = NULL; struct vbios_clock_programming_table_1x_header header = { 0 }; struct vbios_clock_programming_table_1x_entry prog = { 0 }; struct vbios_clock_programming_table_1x_slave_entry slaveprog = { 0 }; @@ -170,7 +433,8 @@ static int devinit_get_clk_prog_table(struct gk20a *g, u32 i, j = 0; struct clk_prog *pprog; u8 prog_type; - u32 szfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D; + u8 src_type; + u32 szfmt; u32 hszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_SIZE_08; u32 slaveszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_SIZE_03; u32 vfszfmt = VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_SIZE_02; @@ -191,13 +455,6 @@ static int devinit_get_clk_prog_table(struct gk20a *g, nvgpu_log_info(g, " "); - clkprogs_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, - g->bios.clock_token, CLOCK_PROGRAMMING_TABLE); - if (clkprogs_tbl_ptr == NULL) { - status = -EINVAL; - goto done; - } - memcpy(&header, clkprogs_tbl_ptr, hszfmt); if (header.header_size < hszfmt) { status = -EINVAL; @@ -250,10 +507,12 @@ static int devinit_get_clk_prog_table(struct gk20a *g, memset(tableslaveentries, 0xFF, sizeof(struct ctrl_clk_clk_prog_1x_master_table_slave_entry) * CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES); - prog_type = (u8)BIOS_GET_FIELD(prog.flags0, + src_type = (u8)BIOS_GET_FIELD(prog.flags0, NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE); + prog_type = (u8)BIOS_GET_FIELD(prog.flags0, + NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE); - switch (prog_type) { + switch (src_type) { case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL: prog_data.v1x.source = CTRL_CLK_PROG_1X_SOURCE_PLL; prog_data.v1x.source_data.pll.pll_idx = @@ -275,14 +534,14 @@ static int devinit_get_clk_prog_table(struct gk20a *g, default: nvgpu_err(g, "invalid source %d", prog_type); status = -EINVAL; - goto done; + break; } + if (status != 0) { + goto done; + } prog_data.v1x.freq_max_mhz = (u16)prog.freq_max_mhz; - prog_type = (u8)BIOS_GET_FIELD(prog.flags0, - NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE); - vfentry = entry + szfmt + header.slave_entry_count * slaveszfmt; slaveentry = entry + szfmt; @@ -310,40 +569,31 @@ static int devinit_get_clk_prog_table(struct gk20a *g, for (j = 0; j < header.slave_entry_count; j++) { memcpy(&slaveprog, slaveentry, slaveszfmt); - switch (prog_type) { - case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + if (prog_type == NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO) { ratioslaveentries[j].clk_dom_idx = (u8)slaveprog.clk_dom_idx; ratioslaveentries[j].ratio = (u8) BIOS_GET_FIELD(slaveprog.param0, NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO); - break; - - case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + } else { tableslaveentries[j].clk_dom_idx = (u8)slaveprog.clk_dom_idx; tableslaveentries[j].freq_mhz = (u16)BIOS_GET_FIELD(slaveprog.param0, NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ); - break; } slaveentry += slaveszfmt; } - switch (prog_type) { - case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO: + if (prog_type == NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO) { prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO; prog_data.v1x_master_ratio.p_slave_entries = ratioslaveentries; - break; - - case NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE: + } else { prog_data.board_obj.type = CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE; prog_data.v1x_master_table.p_slave_entries = tableslaveentries; - break; - } break; @@ -354,10 +604,13 @@ static int devinit_get_clk_prog_table(struct gk20a *g, default: nvgpu_err(g, "source issue %d", prog_type); - status = -EINVAL; - goto done; + status = -EINVAL; + break; } + if (status != 0) { + goto done; + } pprog = construct_clk_prog(g, (void *)&prog_data); if (pprog == NULL) { nvgpu_err(g, @@ -367,8 +620,8 @@ static int devinit_get_clk_prog_table(struct gk20a *g, } status = boardobjgrp_objinsert(&pclkprogobjs->super.super, - (struct boardobj *)pprog, i); - if (status) { + (struct boardobj *)(void *)pprog, i); + if (status != 0) { nvgpu_err(g, "error adding clk_prog boardobj %d", i); status = -EINVAL; goto done; @@ -379,7 +632,43 @@ done: return status; } -static int _clk_prog_pmudatainit_super(struct gk20a *g, +static int devinit_get_clk_prog_table(struct gk20a *g, + struct clk_progs *pprogobjs) +{ + int status = 0; + u8 *clkprogs_tbl_ptr = NULL; + struct vbios_clock_programming_table_1x_header header = { 0 }; + nvgpu_log_info(g, " "); + + clkprogs_tbl_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, + g->bios.clock_token, CLOCK_PROGRAMMING_TABLE); + if (clkprogs_tbl_ptr == NULL) { + return -EINVAL; + } + memcpy(&header, clkprogs_tbl_ptr, + VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_SIZE_08); + + switch (header.version) { + case VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_VERSION: + status = devinit_get_clk_prog_table_1x(g, pprogobjs, + clkprogs_tbl_ptr); + break; + + case VBIOS_CLOCK_PROGRAMMING_TABLE_35_HEADER_VERSION: + status = devinit_get_clk_prog_table_35(g, pprogobjs, + clkprogs_tbl_ptr); + break; + + default: + nvgpu_err(g, "Invalid Clock Prog Table Header version\n"); + status = -EINVAL; + break; + } + + return status; + +} +static int clk_prog_pmudatainit_super(struct gk20a *g, struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) { @@ -391,7 +680,7 @@ static int _clk_prog_pmudatainit_super(struct gk20a *g, return status; } -static int _clk_prog_pmudatainit_1x(struct gk20a *g, +static int clk_prog_pmudatainit_1x(struct gk20a *g, struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) { @@ -401,14 +690,14 @@ static int _clk_prog_pmudatainit_1x(struct gk20a *g, nvgpu_log_info(g, " "); - status = _clk_prog_pmudatainit_super(g, board_obj_ptr, ppmudata); + status = clk_prog_pmudatainit_super(g, board_obj_ptr, ppmudata); if (status != 0) { return status; } - pclk_prog_1x = (struct clk_prog_1x *)board_obj_ptr; + pclk_prog_1x = (struct clk_prog_1x *)(void *)board_obj_ptr; - pset = (struct nv_pmu_clk_clk_prog_1x_boardobj_set *) + pset = (struct nv_pmu_clk_clk_prog_1x_boardobj_set *)(void *) ppmudata; pset->source = pclk_prog_1x->source; @@ -418,24 +707,24 @@ static int _clk_prog_pmudatainit_1x(struct gk20a *g, return status; } -static int _clk_prog_pmudatainit_1x_master(struct gk20a *g, +static int clk_prog_pmudatainit_1x_master(struct gk20a *g, struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) { int status = 0; struct clk_prog_1x_master *pclk_prog_1x_master; struct nv_pmu_clk_clk_prog_1x_master_boardobj_set *pset; - u32 vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + size_t vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * g->clk_pmu.clk_progobjs.vf_entry_count; nvgpu_log_info(g, " "); - status = _clk_prog_pmudatainit_1x(g, board_obj_ptr, ppmudata); + status = clk_prog_pmudatainit_1x(g, board_obj_ptr, ppmudata); pclk_prog_1x_master = - (struct clk_prog_1x_master *)board_obj_ptr; + (struct clk_prog_1x_master *)(void *)board_obj_ptr; - pset = (struct nv_pmu_clk_clk_prog_1x_master_boardobj_set *) + pset = (struct nv_pmu_clk_clk_prog_1x_master_boardobj_set *)(void *) ppmudata; memcpy(pset->vf_entries, pclk_prog_1x_master->p_vf_entries, vfsize); @@ -449,28 +738,56 @@ static int _clk_prog_pmudatainit_1x_master(struct gk20a *g, return status; } -static int _clk_prog_pmudatainit_1x_master_ratio(struct gk20a *g, +static int clk_prog_pmudatainit_35_master(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_35_master *pclk_prog_35_master; + struct nv_pmu_clk_clk_prog_35_master_boardobj_set *pset; + size_t voltrail_sec_vfsize = + sizeof(struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail) + * g->clk_pmu.clk_progobjs.vf_sec_entry_count; + + nvgpu_log_info(g, " "); + + status = clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); + + pclk_prog_35_master = + (struct clk_prog_35_master *)(void *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_35_master_boardobj_set *)(void *) + ppmudata; + + memcpy(pset->voltrail_sec_vf_entries, + pclk_prog_35_master->p_voltrail_sec_vf_entries, + voltrail_sec_vfsize); + + return status; +} + +static int clk_prog_pmudatainit_1x_master_ratio(struct gk20a *g, struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) { int status = 0; struct clk_prog_1x_master_ratio *pclk_prog_1x_master_ratio; struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set *pset; - u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * g->clk_pmu.clk_progobjs.slave_entry_count; nvgpu_log_info(g, " "); - status = _clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); + status = clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); if (status != 0) { return status; } pclk_prog_1x_master_ratio = - (struct clk_prog_1x_master_ratio *)board_obj_ptr; + (struct clk_prog_1x_master_ratio *)(void *)board_obj_ptr; pset = (struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set *) - ppmudata; + (void *)ppmudata; memcpy(pset->slave_entries, pclk_prog_1x_master_ratio->p_slave_entries, slavesize); @@ -478,34 +795,91 @@ static int _clk_prog_pmudatainit_1x_master_ratio(struct gk20a *g, return status; } -static int _clk_prog_pmudatainit_1x_master_table(struct gk20a *g, +static int clk_prog_pmudatainit_35_master_ratio(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_35_master_ratio *pclk_prog_35_master_ratio; + struct nv_pmu_clk_clk_prog_35_master_ratio_boardobj_set *pset; + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, " "); + + status = clk_prog_pmudatainit_35_master(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_prog_35_master_ratio = + (struct clk_prog_35_master_ratio *)(void *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_35_master_ratio_boardobj_set *) + (void *)ppmudata; + + memcpy(pset->ratio.slave_entries, + pclk_prog_35_master_ratio->ratio.p_slave_entries, slavesize); + + return status; +} + +static int clk_prog_pmudatainit_1x_master_table(struct gk20a *g, struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) { int status = 0; struct clk_prog_1x_master_table *pclk_prog_1x_master_table; struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set *pset; - u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * g->clk_pmu.clk_progobjs.slave_entry_count; nvgpu_log_info(g, " "); - status = _clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); + status = clk_prog_pmudatainit_1x_master(g, board_obj_ptr, ppmudata); if (status != 0) { return status; } pclk_prog_1x_master_table = - (struct clk_prog_1x_master_table *)board_obj_ptr; + (struct clk_prog_1x_master_table *)(void *)board_obj_ptr; pset = (struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set *) - ppmudata; + (void *)ppmudata; memcpy(pset->slave_entries, pclk_prog_1x_master_table->p_slave_entries, slavesize); return status; } +static int clk_prog_pmudatainit_35_master_table(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + struct clk_prog_35_master_table *pclk_prog_35_master_table; + struct nv_pmu_clk_clk_prog_35_master_table_boardobj_set *pset; + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, " "); + + status = clk_prog_pmudatainit_35_master(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pclk_prog_35_master_table = + (struct clk_prog_35_master_table *)(void *)board_obj_ptr; + + pset = (struct nv_pmu_clk_clk_prog_35_master_table_boardobj_set *) + (void *)ppmudata; + memcpy(pset->table.slave_entries, + pclk_prog_35_master_table->table.p_slave_entries, slavesize); + + return status; +} + static u32 _clk_prog_1x_master_rail_construct_vf_point(struct gk20a *g, struct clk_pmupstate *pclk, struct clk_prog_1x_master *p1xmaster, @@ -554,7 +928,7 @@ static int clk_prog_construct_super(struct gk20a *g, pclkprog = (struct clk_prog *)*ppboardobj; pclkprog->super.pmudatainit = - _clk_prog_pmudatainit_super; + clk_prog_pmudatainit_super; return status; } @@ -570,16 +944,45 @@ static int clk_prog_construct_1x(struct gk20a *g, int status = 0; nvgpu_log_info(g, " "); - ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X); + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_1X); status = clk_prog_construct_super(g, ppboardobj, size, pargs); if (status) { return -EINVAL; } - pclkprog = (struct clk_prog_1x *)*ppboardobj; + pclkprog = (struct clk_prog_1x *)(void *)*ppboardobj; pclkprog->super.super.pmudatainit = - _clk_prog_pmudatainit_1x; + clk_prog_pmudatainit_1x; + + pclkprog->source = ptmpprog->source; + pclkprog->freq_max_mhz = ptmpprog->freq_max_mhz; + pclkprog->source_data = ptmpprog->source_data; + + return status; +} + +static int clk_prog_construct_35(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_1x *pclkprog; + struct clk_prog_1x *ptmpprog = + (struct clk_prog_1x *)pargs; + int status = 0; + + nvgpu_log_info(g, " "); + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_35); + status = clk_prog_construct_super(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_1x *)(void *)*ppboardobj; + + pclkprog->super.super.pmudatainit = + clk_prog_pmudatainit_1x; pclkprog->source = ptmpprog->source; pclkprog->freq_max_mhz = ptmpprog->freq_max_mhz; @@ -597,22 +1000,22 @@ static int clk_prog_construct_1x_master(struct gk20a *g, struct clk_prog_1x_master *ptmpprog = (struct clk_prog_1x_master *)pargs; int status = 0; - u32 vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * + size_t vfsize = sizeof(struct ctrl_clk_clk_prog_1x_master_vf_entry) * g->clk_pmu.clk_progobjs.vf_entry_count; u8 railidx; nvgpu_log_info(g, " type - %x", BOARDOBJ_GET_TYPE(pargs)); - ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER); + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER); status = clk_prog_construct_1x(g, ppboardobj, size, pargs); if (status) { return -EINVAL; } - pclkprog = (struct clk_prog_1x_master *)*ppboardobj; + pclkprog = (struct clk_prog_1x_master *)(void *)*ppboardobj; pclkprog->super.super.super.pmudatainit = - _clk_prog_pmudatainit_1x_master; + clk_prog_pmudatainit_1x_master; pclkprog->vfflatten = vfflatten_prog_1x_master; @@ -645,6 +1048,47 @@ static int clk_prog_construct_1x_master(struct gk20a *g, return status; } +static int clk_prog_construct_35_master(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_35_master *pclkprog; + struct clk_prog_35_master *ptmpprog = + (struct clk_prog_35_master *)pargs; + int status = 0; + size_t voltrail_sec_vfsize = + sizeof(struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail) + * CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES; + + nvgpu_log_info(g, " type - %x", BOARDOBJ_GET_TYPE(pargs)); + + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_35_MASTER); + status = clk_prog_construct_1x_master(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_35_master *)(void *)*ppboardobj; + + pclkprog->super.super.super.pmudatainit = + clk_prog_pmudatainit_35_master; + + pclkprog->p_voltrail_sec_vf_entries = + (struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail *) + nvgpu_kzalloc(g, voltrail_sec_vfsize); + + memset(pclkprog->p_voltrail_sec_vf_entries, + CTRL_CLK_CLK_DOMAIN_INDEX_INVALID, voltrail_sec_vfsize); + + if ((memcpy(pclkprog->p_voltrail_sec_vf_entries, + ptmpprog->p_voltrail_sec_vf_entries, voltrail_sec_vfsize)) == NULL) { + status = -EINVAL; + } + + return status; +} + static int clk_prog_construct_1x_master_ratio(struct gk20a *g, struct boardobj **ppboardobj, u16 size, void *pargs) @@ -654,23 +1098,23 @@ static int clk_prog_construct_1x_master_ratio(struct gk20a *g, struct clk_prog_1x_master_ratio *ptmpprog = (struct clk_prog_1x_master_ratio *)pargs; int status = 0; - u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * g->clk_pmu.clk_progobjs.slave_entry_count; if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO) { return -EINVAL; } - ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO); + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO); status = clk_prog_construct_1x_master(g, ppboardobj, size, pargs); if (status) { return -EINVAL; } - pclkprog = (struct clk_prog_1x_master_ratio *)*ppboardobj; + pclkprog = (struct clk_prog_1x_master_ratio *)(void *)*ppboardobj; pclkprog->super.super.super.super.pmudatainit = - _clk_prog_pmudatainit_1x_master_ratio; + clk_prog_pmudatainit_1x_master_ratio; pclkprog->p_slave_entries = (struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *) @@ -687,6 +1131,51 @@ static int clk_prog_construct_1x_master_ratio(struct gk20a *g, return status; } +static int clk_prog_construct_35_master_ratio(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_35_master_ratio *pclkprog; + struct clk_prog_35_master_ratio *ptmpprog = + (struct clk_prog_35_master_ratio *)pargs; + int status = 0; + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_PROG_TYPE_35_MASTER_RATIO) { + return -EINVAL; + } + + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_35_MASTER_RATIO); + status = clk_prog_construct_35_master(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_35_master_ratio *)(void *)*ppboardobj; + + pclkprog->super.super.super.super.pmudatainit = + clk_prog_pmudatainit_35_master_ratio; + + pclkprog->ratio.p_slave_entries = + (struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *) + nvgpu_kzalloc(g, slavesize); + if (pclkprog->ratio.p_slave_entries == NULL) { + return -ENOMEM; + } + + memset(pclkprog->ratio.p_slave_entries, + CTRL_CLK_CLK_DOMAIN_INDEX_INVALID, slavesize); + + if ((memcpy(pclkprog->ratio.p_slave_entries, ptmpprog->ratio.p_slave_entries, + slavesize)) == NULL) { + status = -EINVAL; + } + + return status; +} + static int clk_prog_construct_1x_master_table(struct gk20a *g, struct boardobj **ppboardobj, u16 size, void *pargs) @@ -696,7 +1185,7 @@ static int clk_prog_construct_1x_master_table(struct gk20a *g, struct clk_prog_1x_master_table *ptmpprog = (struct clk_prog_1x_master_table *)pargs; int status = 0; - u32 slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry) * g->clk_pmu.clk_progobjs.slave_entry_count; nvgpu_log_info(g, "type - %x", BOARDOBJ_GET_TYPE(pargs)); @@ -705,16 +1194,16 @@ static int clk_prog_construct_1x_master_table(struct gk20a *g, return -EINVAL; } - ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE); + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE); status = clk_prog_construct_1x_master(g, ppboardobj, size, pargs); if (status) { return -EINVAL; } - pclkprog = (struct clk_prog_1x_master_table *)*ppboardobj; + pclkprog = (struct clk_prog_1x_master_table *)(void *)*ppboardobj; pclkprog->super.super.super.super.pmudatainit = - _clk_prog_pmudatainit_1x_master_table; + clk_prog_pmudatainit_1x_master_table; pclkprog->p_slave_entries = (struct ctrl_clk_clk_prog_1x_master_table_slave_entry *) @@ -738,6 +1227,60 @@ exit: return status; } +static int clk_prog_construct_35_master_table(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_prog_35_master_table *pclkprog; + struct clk_prog_35_master_table *ptmpprog = + (struct clk_prog_35_master_table *)pargs; + int status = 0; + size_t slavesize = sizeof(struct ctrl_clk_clk_prog_1x_master_table_slave_entry) * + g->clk_pmu.clk_progobjs.slave_entry_count; + + nvgpu_log_info(g, "type - %x", BOARDOBJ_GET_TYPE(pargs)); + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_PROG_TYPE_35_MASTER_TABLE) { + return -EINVAL; + } + + ptmpobj->type_mask |= (u32)BIT(CTRL_CLK_CLK_PROG_TYPE_35_MASTER_TABLE); + status = clk_prog_construct_35_master(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkprog = (struct clk_prog_35_master_table *)(void *)*ppboardobj; + + pclkprog->super.super.super.super.pmudatainit = + clk_prog_pmudatainit_35_master_table; + + pclkprog->table.p_slave_entries = + (struct ctrl_clk_clk_prog_1x_master_table_slave_entry *) + nvgpu_kzalloc(g, slavesize); + + if (pclkprog->table.p_slave_entries == NULL) { + status = -ENOMEM; + goto exit; + } + + memset(pclkprog->table.p_slave_entries, + CTRL_CLK_CLK_DOMAIN_INDEX_INVALID, slavesize); + + if ((memcpy(pclkprog->table.p_slave_entries, + ptmpprog->table.p_slave_entries,slavesize)) == NULL) { + status = -EINVAL; + } + +exit: + if (status != 0) { + status = (*ppboardobj)->destruct(*ppboardobj); + } + + return status; +} + static struct clk_prog *construct_clk_prog(struct gk20a *g, void *pargs) { struct boardobj *board_obj_ptr = NULL; @@ -760,6 +1303,20 @@ static struct clk_prog *construct_clk_prog(struct gk20a *g, void *pargs) sizeof(struct clk_prog_1x_master_ratio), pargs); break; + case CTRL_CLK_CLK_PROG_TYPE_35: + status = clk_prog_construct_35(g, &board_obj_ptr, + sizeof(struct clk_prog_1x), pargs); + break; + + case CTRL_CLK_CLK_PROG_TYPE_35_MASTER_TABLE: + status = clk_prog_construct_35_master_table(g, &board_obj_ptr, + sizeof(struct clk_prog_35_master_table), pargs); + break; + + case CTRL_CLK_CLK_PROG_TYPE_35_MASTER_RATIO: + status = clk_prog_construct_35_master_ratio(g, &board_obj_ptr, + sizeof(struct clk_prog_35_master_ratio), pargs); + break; default: return NULL; } diff --git a/drivers/gpu/nvgpu/clk/clk_prog.h b/drivers/gpu/nvgpu/clk/clk_prog.h index 206058fa2..aaa9ed632 100644 --- a/drivers/gpu/nvgpu/clk/clk_prog.h +++ b/drivers/gpu/nvgpu/clk/clk_prog.h @@ -57,7 +57,7 @@ struct clk_progs { struct boardobjgrp_e255 super; u8 slave_entry_count; u8 vf_entry_count; - + u8 vf_sec_entry_count; }; struct clk_prog { @@ -93,6 +93,42 @@ struct clk_prog_1x_master_table { struct ctrl_clk_clk_prog_1x_master_table_slave_entry *p_slave_entries; }; +struct clk_prog_3x_master { + bool b_o_c_o_v_enabled; + struct ctrl_clk_clk_prog_1x_master_vf_entry *p_vf_entries; + struct ctrl_clk_clk_delta deltas; + union ctrl_clk_clk_prog_1x_master_source_data source_data; + vf_flatten *vfflatten; + vf_lookup *vflookup; + get_fpoints *getfpoints; + get_slaveclk *getslaveclk; +}; + +struct clk_prog_3x_master_ratio { + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry *p_slave_entries; +}; + +struct clk_prog_3x_master_table { + struct ctrl_clk_clk_prog_1x_master_table_slave_entry *p_slave_entries; +}; + +struct clk_prog_35_master { + struct clk_prog_1x super; + struct clk_prog_3x_master master; + struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail + *p_voltrail_sec_vf_entries; +}; + +struct clk_prog_35_master_ratio { + struct clk_prog_35_master super; + struct clk_prog_3x_master_ratio ratio; +}; + +struct clk_prog_35_master_table { + struct clk_prog_35_master super; + struct clk_prog_3x_master_table table; +}; + #define CLK_CLK_PROG_GET(pclk, idx) \ ((struct clk_prog *)BOARDOBJGRP_OBJ_GET_BY_IDX( \ &pclk->clk_progobjs.super.super, (u8)(idx))) diff --git a/drivers/gpu/nvgpu/ctrl/ctrlclk.h b/drivers/gpu/nvgpu/ctrl/ctrlclk.h index 278e4c942..f15dbdc7b 100644 --- a/drivers/gpu/nvgpu/ctrl/ctrlclk.h +++ b/drivers/gpu/nvgpu/ctrl/ctrlclk.h @@ -60,10 +60,15 @@ #define CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID 0xFFU #define CTRL_CLK_CLK_DOMAIN_INDEX_INVALID 0xFF +#define CTRL_CLK_CLK_PROG_TYPE_3X 0x00U #define CTRL_CLK_CLK_PROG_TYPE_1X 0x01U #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER 0x02U #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_RATIO 0x03U #define CTRL_CLK_CLK_PROG_TYPE_1X_MASTER_TABLE 0x04U +#define CTRL_CLK_CLK_PROG_TYPE_35 0x05U +#define CTRL_CLK_CLK_PROG_TYPE_35_MASTER 0x06U +#define CTRL_CLK_CLK_PROG_TYPE_35_MASTER_RATIO 0x07U +#define CTRL_CLK_CLK_PROG_TYPE_35_MASTER_TABLE 0x08U #define CTRL_CLK_CLK_PROG_TYPE_UNKNOWN 255U /*! @@ -75,6 +80,7 @@ #define CTRL_CLK_PROG_1X_SOURCE_INVALID 255U #define CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES 4U +#define CTRL_CLK_CLK_PROG_35_MASTER_SEC_VF_ENTRY_VOLTRAIL_MAX 1U #define CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES 6U #define CTRL_CLK_CLK_VF_POINT_IDX_INVALID 255U @@ -110,6 +116,18 @@ struct ctrl_clk_clk_prog_1x_master_vf_entry { u8 vf_point_idx_last; }; +struct ctrl_clk_clk_prog_35_master_sec_vf_entry { + u8 vfe_idx; + u8 dvco_offset_vfe_idx; + u8 vf_point_idx_first; + u8 vf_point_idx_last; +}; + +struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail { + struct ctrl_clk_clk_prog_35_master_sec_vf_entry sec_vf_entries[ + CTRL_CLK_CLK_PROG_35_MASTER_SEC_VF_ENTRY_VOLTRAIL_MAX]; +}; + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry { u8 clk_dom_idx; u8 ratio; diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h index 7d729b6e2..4b7d08a18 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/bios.h +++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h @@ -73,7 +73,7 @@ struct bit_token { u16 data_ptr; } __packed; -#define BIOS_GET_FIELD(value, name) ((value & name##_MASK) >> name##_SHIFT) +#define BIOS_GET_FIELD(value, name) (((value) & (name##_MASK)) >> (name##_SHIFT)) struct fll_descriptor_header { u8 version; @@ -244,6 +244,7 @@ struct vbios_clocks_table_35_entry { #define NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM3_CLK_MONITOR_THRESHOLD_MAX_SHIFT 0x08 #define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_SIZE_08 0x08U +#define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_HEADER_VERSION 0x10U struct vbios_clock_programming_table_1x_header { u8 version; u8 header_size; @@ -255,6 +256,21 @@ struct vbios_clock_programming_table_1x_header { u8 vf_entry_count; } __packed; +#define VBIOS_CLOCK_PROGRAMMING_TABLE_35_HEADER_SIZE_0A 0x0AU +#define VBIOS_CLOCK_PROGRAMMING_TABLE_35_HEADER_VERSION 0x35U +struct vbios_clock_programming_table_35_header { + u8 version; + u8 header_size; + u8 entry_size; + u8 entry_count; + u8 slave_entry_size; + u8 slave_entry_count; + u8 vf_entry_size; + u8 vf_entry_count; + u8 vf_sec_entry_size; + u8 vf_sec_entry_count; +} __packed; + #define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_05 0x05U #define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_SIZE_0D 0x0DU struct vbios_clock_programming_table_1x_entry { @@ -266,28 +282,29 @@ struct vbios_clock_programming_table_1x_entry { u32 rsvd1; } __packed; -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASK 0xF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SHIFT 0 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO 0x00 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE 0x01 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SLAVE 0x02 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASK 0x0FU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SHIFT 0x00U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_RATIO 0x00U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_MASTER_TABLE 0x01U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_TYPE_SLAVE 0x02U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_35_ENTRY_FLAGS0_TYPE_DISABLED 0x0FU -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_MASK 0x70 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_SHIFT 4 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL 0x00 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_ONE_SOURCE 0x01 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_FLL 0x02 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_MASK 0x70U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_SHIFT 0x04U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_PLL 0x00U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_ONE_SOURCE 0x01U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_SOURCE_FLL 0x02U -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_MASK 0x80 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_SHIFT 7 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_FALSE 0x00 -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_TRUE 0x01 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_MASK 0x80U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_SHIFT 0x07U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_FALSE 0x00U +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_FLAGS0_OVOC_ENABLED_TRUE 0x01U -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_MASK 0xFF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_SHIFT 0 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_MASK 0xFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM0_PLL_PLL_INDEX_SHIFT 0x00U -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_MASK 0xFF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_SHIFT 0 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_MASK 0xFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_ENTRY_PARAM1_PLL_FREQ_STEP_SIZE_SHIFT 0x00U #define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_SIZE_03 0x03U struct vbios_clock_programming_table_1x_slave_entry { @@ -295,11 +312,11 @@ struct vbios_clock_programming_table_1x_slave_entry { u16 param0; } __packed; -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_MASK 0xFF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_SHIFT 0 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_MASK 0xFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_RATIO_RATIO_SHIFT 0x00U -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_MASK 0x3FFF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_SHIFT 0 +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_MASK 0x3FFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_SLAVE_ENTRY_PARAM0_MASTER_TABLE_FREQ_SHIFT 0x00U #define VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_SIZE_02 0x02U struct vbios_clock_programming_table_1x_vf_entry { @@ -307,8 +324,22 @@ struct vbios_clock_programming_table_1x_vf_entry { u8 param0; } __packed; -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_MASK 0xFF -#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_SHIFT 0 +#define VBIOS_CLOCK_PROGRAMMING_TABLE_35_VF_ENTRY_SIZE_01 0x01U +struct vbios_clock_programming_table_35_vf_entry { + u8 vfe_idx; +} __packed; + +#define VBIOS_CLOCK_PROGRAMMING_TABLE_35_VF_SEC_ENTRY_SIZE_02 0x02U +struct vbios_clock_programming_table_35_vf_sec_entry { + u8 sec_vfe_idx; + u8 param0; +} __packed; + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_MASK 0xFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_1X_VF_ENTRY_PARAM0_FLL_GAIN_VFE_IDX_SHIFT 0X00U + +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_35_SEC_VF_ENTRY_PARAM0_FLL_DVCO_OFFSET_VFE_IDX_MASK 0xFFU +#define NV_VBIOS_CLOCK_PROGRAMMING_TABLE_35_SEC_VF_ENTRY_PARAM0_FLL_DVCO_OFFSET_VFE_IDX_SHIFT 0X00U struct vbios_vfe_3x_header_struct { u8 version; diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h index 0fe4e6d87..a247e53d1 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h @@ -186,6 +186,7 @@ struct nv_pmu_clk_clk_prog_boardobjgrp_set_header { struct nv_pmu_boardobjgrp_e255 super; u8 slave_entry_count; u8 vf_entry_count; + u8 vf_sec_entry_count; }; struct nv_pmu_clk_clk_prog_boardobj_set { @@ -223,6 +224,45 @@ struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set { slave_entries[CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; }; +struct nv_pmu_clk_clk_prog_3x_master_boardobj_set { + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + bool b_o_c_o_v_enabled; + struct ctrl_clk_clk_prog_1x_master_vf_entry vf_entries[ + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; + struct ctrl_clk_clk_delta deltas; + union ctrl_clk_clk_prog_1x_master_source_data source_data; +}; + +struct nv_pmu_clk_clk_prog_3x_master_ratio_boardobj_set { + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + struct ctrl_clk_clk_prog_1x_master_ratio_slave_entry slave_entries[ + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; +}; + +struct nv_pmu_clk_clk_prog_3x_master_table_boardobj_set { + u8 rsvd; /* Stubbing for RM_PMU_BOARDOBJ_INTERFACE */ + struct ctrl_clk_clk_prog_1x_master_table_slave_entry slave_entries[ + CTRL_CLK_PROG_1X_MASTER_MAX_SLAVE_ENTRIES]; +}; + +struct nv_pmu_clk_clk_prog_35_master_boardobj_set { + struct nv_pmu_clk_clk_prog_1x_boardobj_set super; + struct nv_pmu_clk_clk_prog_3x_master_boardobj_set master; + struct ctrl_clk_clk_prog_35_master_sec_vf_entry_voltrail + voltrail_sec_vf_entries[ + CTRL_CLK_CLK_PROG_1X_MASTER_VF_ENTRY_MAX_ENTRIES]; +}; + +struct nv_pmu_clk_clk_prog_35_master_ratio_boardobj_set { + struct nv_pmu_clk_clk_prog_35_master_boardobj_set super; + struct nv_pmu_clk_clk_prog_3x_master_ratio_boardobj_set ratio; +}; + +struct nv_pmu_clk_clk_prog_35_master_table_boardobj_set { + struct nv_pmu_clk_clk_prog_35_master_boardobj_set super; + struct nv_pmu_clk_clk_prog_3x_master_table_boardobj_set table; +}; + union nv_pmu_clk_clk_prog_boardobj_set_union { struct nv_pmu_boardobj board_obj; struct nv_pmu_clk_clk_prog_boardobj_set super; @@ -230,6 +270,9 @@ union nv_pmu_clk_clk_prog_boardobj_set_union { struct nv_pmu_clk_clk_prog_1x_master_boardobj_set v1x_master; struct nv_pmu_clk_clk_prog_1x_master_ratio_boardobj_set v1x_master_ratio; struct nv_pmu_clk_clk_prog_1x_master_table_boardobj_set v1x_master_table; + struct nv_pmu_clk_clk_prog_35_master_boardobj_set v35_master; + struct nv_pmu_clk_clk_prog_35_master_ratio_boardobj_set v35_master_ratio; + struct nv_pmu_clk_clk_prog_35_master_table_boardobj_set v35_master_table; }; NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_prog);