u32 bsp_nvm_get_len(u32 itemid,u32* len) { u32 ret = NV_ERROR; struct nv_ref_data_info_stru ref_info = {0}; struct nv_file_list_info_stru file_info = {0}; nv_debug(NV_API_GETLEN,0,itemid,0,0); if(NULL == len) { nv_debug(NV_API_GETLEN,1,itemid,0,0); return BSP_ERR_NV_INVALID_PARAM; } /*check init state*/ if(false == nv_read_right(itemid)) { nv_debug(NV_API_GETLEN,3,itemid,0,0); return BSP_ERR_NV_MEM_INIT_FAIL; } ret = nv_search_byid(itemid,(u8*)NV_GLOBAL_CTRL_INFO_ADDR,&ref_info, &file_info); if(NV_OK == ret) { *len = ref_info.nv_len; return NV_OK; } return ret; }
u32 bsp_nvm_init(void) { u32 ret = NV_ERROR; struct nv_global_ddr_info_stru* ddr_info = (struct nv_global_ddr_info_stru*)NV_GLOBAL_INFO_ADDR; #ifdef BSP_CONFIG_HI3630 nv_printf("waiting for ap modem nv init ok .......\n"); BSP_SYNC_Wait(SYNC_MODULE_NV,0); #endif nv_debug(NV_FUN_NVM_INIT,0,0,0,0); if(ddr_info->ccore_init_state < NV_BOOT_INIT_OK) { nv_printf("[%s]:pre init fail,break here!\n",__FUNCTION__); nv_debug(NV_FUN_NVM_INIT,1,0,0,0); /*lint -save -e801*/ goto nv_init_fail; /*lint -restore*/ } g_nv_ctrl.shared_addr = (u32)NV_GLOBAL_INFO_ADDR; spin_lock_init(&g_nv_ctrl.spinlock); ret = nv_icc_chan_init(); if(ret) { nv_debug(NV_FUN_NVM_INIT,2,ret,0,0); /*lint -save -e801*/ goto nv_init_fail; /*lint -restore*/ } osl_sem_init(1,&g_nv_ctrl.rw_sem); osl_sem_init(0,&g_nv_ctrl.cc_sem); ret = bsp_nvm_read(NV_ID_MSP_FLASH_LESS_MID_THRED,(u8*)&g_nv_ctrl.mid_prio,sizeof(u32)); if(ret) { g_nv_ctrl.mid_prio = 20; nv_printf("read 0x%x error : 0x%x,use default count\n",NV_ID_MSP_FLASH_LESS_MID_THRED,ret); } ret = (u32)bsp_ipc_sem_create(IPC_SEM_NV_CRC); if(ret) { nv_debug(NV_FUN_KERNEL_INIT,3 ,ret ,0,0); /*lint -save -e801*/ goto nv_init_fail; /*lint -restore*/ } ddr_info->ccore_init_state = NV_INIT_OK; nv_printf("nv init ok !\n"); INIT_LIST_HEAD(&g_nv_ctrl.stList); return NV_OK; nv_init_fail: ddr_info->ccore_init_state = NV_INIT_FAIL; nv_printf("\n[%s]\n",__FUNCTION__); nv_help(NV_FUN_NVM_INIT); return ret; }
I2CDevPtr nvclock_i2c_probe_devices(nouveau_device *device, I2CBusPtr busses[], int num_busses) { int bus; I2CDevPtr dev; nv_debug(device, "probing I2C busses...\n"); /* Unlock the extended CRTC registers to get i2c working */ nvclock_i2c_lock_unlock(device, 0); /* On NV40 cards the i2c busses can be disabled */ if(device->card_type == NV_40) { volatile unsigned char *PCIO = (volatile unsigned char*)(device->mmio->getVirtualAddress() + 0x00601000); PCIO[0x3d4] = 0x49; PCIO[0x3d5] |= 0x4; /* Unlock the i2c busses */ } nvclock_i2c_probe_all_devices(busses, num_busses); for(bus = 0; bus < num_busses; bus++) { for(dev = busses[bus]->FirstDev; dev; dev = dev->NextDev) { nv_debug(dev->pI2CBus->card, "got response on bus:%s port:0x%x\n", busses[bus]->BusName, dev->SlaveAddr / 2); dev->arch = dev->pI2CBus->card->chipset; switch(dev->SlaveAddr / 2) { case 0x2d: if(w83l785r_detect(dev)) return dev; if(w83781d_detect(dev)) return dev; break; case 0x2e: if(f75375_detect(dev)) return dev; if(adt7473_detect(dev)) return dev; break; case 0x4c: if(lm99_detect(dev)) return dev; break; default: /* Unknown device */ break; } } } nvclock_i2c_lock_unlock(device, 1); return NULL; }
int nouveau_client_init(struct nouveau_client *client) { int ret; nv_debug(client, "init running\n"); ret = nouveau_handle_init(client->root); nv_debug(client, "init completed with %d\n", ret); return ret; }
static void nouveau_bios_shadow_pramin(struct nouveau_bios *bios) { struct nouveau_device *device = nv_device(bios); u64 addr = 0; u32 bar0 = 0; int i; if (device->card_type >= NV_50) { if (device->card_type >= NV_C0 && device->card_type < GM100) { if (nv_rd32(bios, 0x022500) & 0x00000001) return; } else if (device->card_type >= GM100) { if (nv_rd32(bios, 0x021c04) & 0x00000001) return; } addr = nv_rd32(bios, 0x619f04); if (!(addr & 0x00000008)) { nv_debug(bios, "... not enabled\n"); return; } if ( (addr & 0x00000003) != 1) { nv_debug(bios, "... not in vram\n"); return; } addr = (addr & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(bios, 0x001700) << 16; addr += 0xf0000; } bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16); } /* bail if no rom signature */ if (nv_rd08(bios, 0x700000) != 0x55 || nv_rd08(bios, 0x700001) != 0xaa) goto out; bios->size = nv_rd08(bios, 0x700002) * 512; if (!bios->size) goto out; bios->data = kmalloc(bios->size, GFP_KERNEL); if (bios->data) { for (i = 0; i < bios->size; i++) nv_wo08(bios, i, nv_rd08(bios, 0x700000 + i)); } out: if (device->card_type >= NV_50) nv_wr32(bios, 0x001700, bar0); }
int nouveau_therm_fan_ctor(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_gpio *gpio = nouveau_gpio(therm); struct nouveau_bios *bios = nouveau_bios(therm); struct dcb_gpio_func func; int ret; /* attempt to locate a drivable fan, and determine control method */ ret = gpio->find(gpio, 0, DCB_GPIO_FAN, 0xff, &func); if (ret == 0) { /* FIXME: is this really the place to perform such checks ? */ if (func.line != 16 && func.log[0] & DCB_GPIO_LOG_DIR_IN) { nv_debug(therm, "GPIO_FAN is in input mode\n"); ret = -EINVAL; } else { ret = nouveau_fanpwm_create(therm, &func); if (ret != 0) ret = nouveau_fantog_create(therm, &func); } } /* no controllable fan found, create a dummy fan module */ if (ret != 0) { ret = nouveau_fannil_create(therm); if (ret) return ret; } nv_info(therm, "FAN control: %s\n", priv->fan->type); /* read the current speed, it is useful when resuming */ priv->fan->percent = nouveau_therm_fan_get(therm); /* attempt to detect a tachometer connection */ ret = gpio->find(gpio, 0, DCB_GPIO_FAN_SENSE, 0xff, &priv->fan->tach); if (ret) priv->fan->tach.func = DCB_GPIO_UNUSED; /* initialise fan bump/slow update handling */ priv->fan->parent = therm; nouveau_alarm_init(&priv->fan->alarm, nouveau_fan_alarm); spin_lock_init(&priv->fan->lock); /* other random init... */ nouveau_therm_fan_set_defaults(therm); nvbios_perf_fan_parse(bios, &priv->fan->perf); if (!nvbios_fan_parse(bios, &priv->fan->bios)) { nv_debug(therm, "parsing the fan table failed\n"); if (nvbios_therm_fan_parse(bios, &priv->fan->bios)) nv_error(therm, "parsing both fan tables failed\n"); } nouveau_therm_fan_safety_checks(therm); return 0; }
int nouveau_client_fini(struct nouveau_client *client, bool suspend) { const char *name[2] = { "fini", "suspend" }; int ret; nv_debug(client, "%s running\n", name[suspend]); ret = nouveau_handle_fini(client->root, suspend); nv_debug(client, "%s completed with %d\n", name[suspend], ret); return ret; }
u32 bsp_nvm_flushEx(u32 off,u32 len,u32 itemid) { u32 ret = NV_ERROR; struct nv_icc_stru icc_req = {0}; struct nv_icc_stru icc_cnf = {0}; struct nv_global_ddr_info_stru* ddr_info = (struct nv_global_ddr_info_stru*)NV_GLOBAL_INFO_ADDR; nv_debug(NV_API_FLUSH,0,0,0,0); if(NV_INIT_OK != ddr_info->ccore_init_state) { nv_debug(NV_API_FLUSH,1,ddr_info->ccore_init_state,0,0); return BSP_ERR_NV_MEM_INIT_FAIL; } icc_req.msg_type = NV_ICC_REQ; icc_req.data_len = len; icc_req.data_off = off; icc_req.ret = 93; /*use to test ,no meaning*/ icc_req.itemid = itemid; icc_req.slice = bsp_get_slice_value(); ret = nv_icc_send((u8*)&icc_req,sizeof(icc_req)); if(ret) { nv_debug(NV_API_FLUSH,2,0,ret,0); return ret; } /*lint -save -e534*/ if(osl_sem_downtimeout(&g_nv_ctrl.cc_sem,NV_MAX_WAIT_TICK)) { nv_printf("down time out\n"); } /*lint -restore +e534*/ memcpy(&icc_cnf,g_nv_ctrl.nv_icc_buf,sizeof(icc_cnf)); if(icc_cnf.msg_type != NV_ICC_CNF) { nv_debug(NV_API_FLUSH,3,0,0,icc_cnf.msg_type); /*lint -save -e515 -e516*/ printf_nv("\n[%s]\n",__FUNCTION__); /*lint -restore*/ nv_help(NV_API_FLUSH); return BSP_ERR_NV_INVALID_PARAM; } return icc_cnf.ret; }
void nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec) { nv_debug(memx->ppwr, " DELAY = %d ns\n", nsec); memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec }); memx_out(memx); /* fuc can't handle multiple */ }
static void g84_therm_program_alarms(struct nvkm_therm *therm) { struct nvkm_therm_priv *priv = (void *)therm; struct nvbios_therm_sensor *sensor = &priv->bios_sensor; unsigned long flags; spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */ nv_wr32(therm, 0x20000, 0x000003ff); /* shutdown: The computer should be shutdown when reached */ nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis); nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp); /* THRS_1 : fan boost*/ nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp); /* THRS_2 : critical */ nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp); /* THRS_4 : down clock */ nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp); spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); nv_debug(therm, "Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n", sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis, sensor->thrs_down_clock.temp, sensor->thrs_down_clock.hysteresis, sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis, sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis); }
void nouveau_subdev_reset(struct nouveau_object *subdev) { nv_trace(subdev, "resetting...\n"); nv_ofuncs(subdev)->fini(subdev, false); nv_debug(subdev, "reset\n"); }
bool nouveau_identify(struct nouveau_device *device) { /* identify the chipset */ nv_debug(device, "identifying the chipset\n"); /* read boot0 and strapping information */ UInt32 boot0 = nv_rd32(device, 0x000000); UInt32 strap = nv_rd32(device, 0x101000); /* determine chipset and derive architecture from it */ if ((boot0 & 0x0f000000) > 0) { device->chipset = (boot0 & 0xff00000) >> 20; switch (device->chipset & ~0xf) { case 0x40: case 0x60: device->card_type = NV_40; break; case 0x50: case 0x80: case 0x90: case 0xa0: device->card_type = NV_50; break; case 0xc0: device->card_type = NV_C0; break; case 0xd0: device->card_type = NV_D0; break; case 0xe0: case 0xf0: case 0x100: device->card_type = NV_E0; break; default: break; } }
static int nouveau_voltgpio_init(struct nouveau_device *device) { struct nouveau_volt *volt = &device->volt; struct dcb_gpio_func func; int i; /* check we have gpio function info for each vid bit. on some * boards (ie. nvs295) the vid mask has more bits than there * are valid gpio functions... from traces, nvidia appear to * just touch the existing ones, so let's mask off the invalid * bits and continue with life */ for (i = 0; i < 8; i++) { if (volt->vid_mask & (1 << i)) { int ret = nouveau_gpio_find(device, 0, tags[i], 0xff, &func); if (ret) { if (ret != -ENOENT) return ret; nv_debug(device, "VID bit %d has no GPIO\n", i); volt->vid_mask &= ~(1 << i); } } } return 0; }
static int nvkm_ioctl_sclass(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_object *object = handle->object; union { struct nvif_ioctl_sclass_v0 v0; } *args = data; int ret; if (!nv_iclass(object, NV_PARENT_CLASS)) { nv_debug(object, "cannot have children (sclass)\n"); return -ENODEV; } nv_ioctl(object, "sclass size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nv_ioctl(object, "sclass vers %d count %d\n", args->v0.version, args->v0.count); if (size == args->v0.count * sizeof(args->v0.oclass[0])) { ret = nouveau_parent_lclass(object, args->v0.oclass, args->v0.count); if (ret >= 0) { args->v0.count = ret; ret = 0; } } else { ret = -EINVAL; } } return ret; }
int nouveau_bios_score(struct nouveau_device *device, const bool writeable) { if (device->bios.size < 3 || !device->bios.data || device->bios.data[0] != 0x55 || device->bios.data[1] != 0xAA) { nv_debug(device, "VBIOS signature not found\n"); return 0; } if (nvbios_checksum((u8*)device->bios.data, min_t(u32, device->bios.data[2] * 512, device->bios.size))) { nv_debug(device, "VBIOS checksum invalid\n"); /* if a ro image is somewhat bad, it's probably all rubbish */ return writeable ? 2 : 1; } nv_debug(device, "VBIOS appears to be valid\n"); return 3; }
static int gk20a_volt_vid_set(struct nvkm_volt *volt, u8 vid) { struct gk20a_volt_priv *priv = (void *)volt; nv_debug(volt, "set voltage as %duv\n", volt->vid[vid].uv); return regulator_set_voltage(priv->vdd, volt->vid[vid].uv, 1200000); }
void nvkm_hwsq_wr32(struct nvkm_hwsq *hwsq, u32 addr, u32 data) { nv_debug(hwsq->pbus, "R[%06x] = 0x%08x\n", addr, data); if (hwsq->data != data) { if ((data & 0xffff0000) != (hwsq->data & 0xffff0000)) { hwsq_cmd(hwsq, 5, (u8[]){ 0xe2, data, data >> 8, data >> 16, data >> 24 });
void nouveau_memx_wait(struct nouveau_memx *memx, u32 addr, u32 mask, u32 data, u32 nsec) { nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n", addr, mask, data, nsec); memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, ~mask, data, nsec }); memx_out(memx); /* fuc can't handle multiple */ }
static void nouveau_therm_update(struct nouveau_therm *therm, int mode) { struct nouveau_timer *ptimer = nouveau_timer(therm); struct nouveau_therm_priv *priv = (void *)therm; unsigned long flags; int duty; spin_lock_irqsave(&priv->lock, flags); nv_debug(therm, "FAN speed check\n"); if (mode < 0) mode = priv->mode; priv->mode = mode; switch (mode) { case NOUVEAU_THERM_CTRL_MANUAL: ptimer->alarm_cancel(ptimer, &priv->alarm); duty = nouveau_therm_fan_get(therm); if (duty < 0) duty = 100; break; case NOUVEAU_THERM_CTRL_AUTO: if (priv->fan->bios.nr_fan_trip) duty = nouveau_therm_update_trip(therm); else duty = nouveau_therm_update_linear(therm); break; case NOUVEAU_THERM_CTRL_NONE: default: ptimer->alarm_cancel(ptimer, &priv->alarm); goto done; } nv_debug(therm, "FAN target request: %d%%\n", duty); nouveau_therm_fan_set(therm, (mode != NOUVEAU_THERM_CTRL_AUTO), duty); done: if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO)) ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm); else if (!list_empty(&priv->alarm.head)) nv_debug(therm, "therm fan alarm list is not empty\n"); spin_unlock_irqrestore(&priv->lock, flags); }
static int nvkm_ioctl_path(struct nouveau_handle *parent, u32 type, u32 nr, u32 *path, void *data, u32 size, u8 owner, u8 *route, u64 *token) { struct nouveau_handle *handle = parent; struct nouveau_namedb *namedb; struct nouveau_object *object; int ret; while ((object = parent->object), nr--) { nv_ioctl(object, "path 0x%08x\n", path[nr]); if (!nv_iclass(object, NV_PARENT_CLASS)) { nv_debug(object, "cannot have children (path)\n"); return -EINVAL; } if (!(namedb = (void *)nv_pclass(object, NV_NAMEDB_CLASS)) || !(handle = nouveau_namedb_get(namedb, path[nr]))) { nv_debug(object, "handle 0x%08x not found\n", path[nr]); return -ENOENT; } nouveau_namedb_put(handle); parent = handle; } if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != handle->route) { nv_ioctl(object, "object route != owner\n"); return -EACCES; } *route = handle->route; *token = handle->token; if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) { if (nvkm_ioctl_v0[type].version == 0) { ret = nvkm_ioctl_v0[type].func(handle, data, size); } } return ret; }
int nouveau_volt_create(struct nouveau_device *device) { struct nouveau_volt *volt = &device->volt; struct nvbios_volt_entry ivid; struct nvbios_volt info; u8 ver, hdr, cnt, len; u16 data; int ret = -EUNKNOWN, i; volt->get = nouveau_volt_get; data = nvbios_volt_parse(device, &ver, &hdr, &cnt, &len, &info); if (data && info.vidmask && info.base && info.step) { for (i = 0; i < info.vidmask + 1; i++) { if (info.base >= info.min && info.base <= info.max) { volt->vid[volt->vid_nr].uv = info.base; volt->vid[volt->vid_nr].vid = i; volt->vid_nr++; } info.base += info.step; } volt->vid_mask = info.vidmask; } else if (data && info.vidmask) { for (i = 0; i < cnt; i++) { data = nvbios_volt_entry_parse(device, i, &ver, &hdr, &ivid); if (data) { volt->vid[volt->vid_nr].uv = ivid.voltage; volt->vid[volt->vid_nr].vid = ivid.vid; volt->vid_nr++; } } volt->vid_mask = info.vidmask; } if (volt->vid_nr) { for (i = 0; i < volt->vid_nr; i++) { nv_debug(device, "VID %02x: %duv\n", volt->vid[i].vid, volt->vid[i].uv); } /*XXX: this is an assumption.. there probably exists boards * out there with i2c-connected voltage controllers too.. */ ret = nouveau_voltgpio_init(device); if (ret == 0) { volt->vid_get = nouveau_voltgpio_get; } } return ret; }
static void nouveau_therm_update(struct nouveau_therm *therm, int mode) { struct nouveau_timer *ptimer = nouveau_timer(therm); struct nouveau_therm_priv *priv = (void *)therm; unsigned long flags; bool immd = true; bool poll = true; int duty = -1; spin_lock_irqsave(&priv->lock, flags); if (mode < 0) mode = priv->mode; priv->mode = mode; switch (mode) { case NOUVEAU_THERM_CTRL_MANUAL: ptimer->alarm_cancel(ptimer, &priv->alarm); duty = nouveau_therm_fan_get(therm); if (duty < 0) duty = 100; poll = false; break; case NOUVEAU_THERM_CTRL_AUTO: switch(priv->fan->bios.fan_mode) { case NVBIOS_THERM_FAN_TRIP: duty = nouveau_therm_update_trip(therm); break; case NVBIOS_THERM_FAN_LINEAR: duty = nouveau_therm_update_linear(therm); break; case NVBIOS_THERM_FAN_OTHER: if (priv->cstate) duty = priv->cstate; poll = false; break; } immd = false; break; case NOUVEAU_THERM_CTRL_NONE: default: ptimer->alarm_cancel(ptimer, &priv->alarm); poll = false; } if (list_empty(&priv->alarm.head) && poll) ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm); spin_unlock_irqrestore(&priv->lock, flags); if (duty >= 0) { nv_debug(therm, "FAN target request: %d%%\n", duty); nouveau_therm_fan_set(therm, immd, duty); } }
int nouveau_therm_cstate(struct nouveau_therm *ptherm, int fan, int dir) { struct nouveau_therm_priv *priv = (void *)ptherm; if (!dir || (dir < 0 && fan < priv->cstate) || (dir > 0 && fan > priv->cstate)) { nv_debug(ptherm, "default fan speed -> %d%%\n", fan); priv->cstate = fan; nouveau_therm_update(ptherm, -1); } return 0; }
bool mxms_checksum(struct nouveau_mxm *mxm) { u16 size = mxms_headerlen(mxm) + mxms_structlen(mxm); u8 *mxms = mxms_data(mxm), sum = 0; while (size--) sum += *mxms++; if (sum) { nv_debug(mxm, "checksum invalid\n"); return false; } return true; }
static int gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { struct gk20a_volt_priv *priv; struct nvkm_volt *volt; struct nouveau_platform_device *plat; int i, ret, uv; ret = nvkm_volt_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; volt = &priv->base; plat = nv_device_to_platform(nv_device(parent)); uv = regulator_get_voltage(plat->gpu->vdd); nv_info(priv, "The default voltage is %duV\n", uv); priv->vdd = plat->gpu->vdd; priv->base.vid_get = gk20a_volt_vid_get; priv->base.vid_set = gk20a_volt_vid_set; priv->base.set_id = gk20a_volt_set_id; volt->vid_nr = ARRAY_SIZE(gk20a_cvb_coef); nv_debug(priv, "%s - vid_nr = %d\n", __func__, volt->vid_nr); for (i = 0; i < volt->vid_nr; i++) { volt->vid[i].vid = i; volt->vid[i].uv = gk20a_volt_calc_voltage(&gk20a_cvb_coef[i], plat->gpu_speedo); nv_debug(priv, "%2d: vid=%d, uv=%d\n", i, volt->vid[i].vid, volt->vid[i].uv); } return 0; }
bool mxms_foreach(struct nouveau_mxm *mxm, u8 types, bool (*exec)(struct nouveau_mxm *, u8 *, void *), void *info) { u8 *mxms = mxms_data(mxm); u8 *desc = mxms + mxms_headerlen(mxm); u8 *fini = desc + mxms_structlen(mxm) - 1; while (desc < fini) { u8 type = desc[0] & 0x0f; u8 headerlen = 0; u8 recordlen = 0; u8 entries = 0; switch (type) { case 0: /* Output Device Structure */ if (mxms_version(mxm) >= 0x0300) headerlen = 8; else headerlen = 6; break; case 1: /* System Cooling Capability Structure */ case 2: /* Thermal Structure */ case 3: /* Input Power Structure */ headerlen = 4; break; case 4: /* GPIO Device Structure */ headerlen = 4; recordlen = 2; entries = (ROM32(desc[0]) & 0x01f00000) >> 20; break; case 5: /* Vendor Specific Structure */ headerlen = 8; break; case 6: /* Backlight Control Structure */ if (mxms_version(mxm) >= 0x0300) { headerlen = 4; recordlen = 8; entries = (desc[1] & 0xf0) >> 4; } else { headerlen = 8; } break; case 7: /* Fan Control Structure */ headerlen = 8; recordlen = 4; entries = desc[1] & 0x07; break; default: nv_debug(mxm, "unknown descriptor type %d\n", type); return false; }
bool mxms_valid(struct nouveau_mxm *mxm) { u8 *mxms = mxms_data(mxm); if (*(u32 *)mxms != 0x5f4d584d) { nv_debug(mxm, "signature invalid\n"); return false; } if (!mxms_version(mxm) || !mxms_checksum(mxm)) return false; return true; }
static int nouveau_volt_set(struct nouveau_volt *volt, u32 uv) { if (volt->vid_set) { int i, ret = -EINVAL; for (i = 0; i < volt->vid_nr; i++) { if (volt->vid[i].uv == uv) { ret = volt->vid_set(volt, volt->vid[i].vid); nv_debug(volt, "set %duv: %d\n", uv, ret); break; } } return ret; } return -ENODEV; }
static void nouveau_bios_shadow_pramin(struct nouveau_device *device) { u32 bar0 = 0; int i; nv_debug(device, "shadowing bios from PRAMIN\n"); if (device->card_type >= NV_50) { u64 addr = (u64)(nv_rd32(device, 0x619f04) & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(device, 0x001700) << 16; addr += 0xf0000; } bar0 = nv_mask(device, 0x001700, 0xffffffff, (u32)(addr >> 16)); }
void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; struct nvbios_therm_sensor *sensor = &priv->bios_sensor; nv_debug(therm, "programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n", sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis, sensor->thrs_down_clock.temp, sensor->thrs_down_clock.hysteresis, sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis, sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis); alarm_timer_callback(&priv->sensor.therm_poll_alarm); }