int intel_scu_ipc_write_umip(u8 *data, int len, int offset) { int ret, offset_align; int len_align = 0; u32 dptr, sptr, cmd; u8 *buf = NULL; /* Cloverview don't need UMIP access through IPC */ if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_CLOVERVIEW) return -EINVAL; if (!intel_mip_base) return -ENODEV; if (offset + len > IPC_MIP_MAX_ADDR) return -EINVAL; intel_scu_ipc_lock(); offset_align = offset & (~0x3); len_align = (len + (offset - offset_align) + 3) & (~0x3); if (len != len_align) { buf = kzalloc(len_align, GFP_KERNEL); if (!buf) { pr_err("Alloc memory failed\n"); ret = -ENOMEM; goto fail; } ret = read_mip(buf, len_align, offset_align, 0); if (ret) goto fail; memcpy(buf + offset - offset_align, data, len); } else { buf = data; } dptr = offset_align; sptr = len_align / 4; cmd = IPC_CMD_UMIP_WR << 12 | IPCMSG_MIP_ACCESS; memcpy(intel_mip_base, buf, len_align); do { ret = intel_scu_ipc_raw_cmd(cmd, 0, NULL, 0, NULL, 0, dptr, sptr); if (ret == -EIO) msleep(20); } while (ret == -EIO); fail: if (buf && len_align != len) kfree(buf); intel_scu_ipc_unlock(); return ret; }
int intel_scu_ipc_read_mip(u8 *data, int len, int offset, int issigned) { int ret; intel_scu_ipc_lock(); ret = read_mip(data, len, offset, issigned); intel_scu_ipc_unlock(); return ret; }
int intel_scu_ipc_read_mip(u8 *data, int len, int offset, int issigned) { int ret; /* Only SMIP read for Cloverview is supported */ if ((intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_CLOVERVIEW) && (issigned != 1)) return -EINVAL; if (!intel_mip_base) return -ENODEV; if (offset + len > IPC_MIP_MAX_ADDR) return -EINVAL; intel_scu_ipc_lock(); ret = read_mip(data, len, offset, issigned); intel_scu_ipc_unlock(); return ret; }
int intel_scu_ipc_write_osnib(u8 *data, int len, int offset) { int i; int ret = 0; u32 posnibw, oshob_base; u8 osnib_data[OSNIB_SIZE]; u8 chksum = 0; void __iomem *oshob_addr, *osnibw_addr, *osnibr_addr; ret = intel_scu_ipc_command(IPCMSG_GET_HOBADDR, 0, NULL, 0, &oshob_base, 1); if (ret < 0) { pr_err("ipc_get_hobaddr failed!!\n"); goto exit; } pr_info("OSHOB addr values is %x\n", oshob_base); intel_scu_ipc_lock(); oshob_addr = ioremap_nocache(oshob_base, OSHOB_SIZE); if (!oshob_addr) { pr_err("ioremap failed!\n"); ret = -ENOMEM; goto exit; } /*Dump osnib data for generate chksum */ osnibr_addr = oshob_addr + OSNIB_OFFSET; for (i = 0; i < OSNIB_SIZE; i++) osnib_data[i] = readb(osnibr_addr + i); memcpy(osnib_data + offset, data, len); /* generate chksum */ for (i = 0; i < OSNIB_SIZE - 1; i++) chksum += osnib_data[i]; osnib_data[OSNIB_SIZE - 1] = ~chksum + 1; posnibw = readl(oshob_addr + POSNIBW_OFFSET); if (posnibw == 0) { /* workaround here for BZ 2914 */ posnibw = 0xFFFF3400; pr_err("ERR: posnibw from oshob is 0, manually set it here\n"); } pr_info("POSNIB: %x\n", posnibw); osnibw_addr = ioremap_nocache(posnibw, OSNIB_SIZE); if (!osnibw_addr) { pr_err("ioremap failed!\n"); ret = -ENOMEM; goto unmap_oshob_addr; } for (i = 0; i < OSNIB_SIZE; i++) writeb(*(osnib_data + i), (osnibw_addr + i)); ret = intel_scu_ipc_raw_cmd(IPCMSG_WRITE_OSNIB, 0, NULL, 0, NULL, 0, 0, 0xFFFFFFFF); if (ret < 0) pr_err("ipc_write_osnib failed!!\n"); iounmap(osnibw_addr); unmap_oshob_addr: iounmap(oshob_addr); exit: intel_scu_ipc_unlock(); return ret; }