Loading drivers/media/platform/msm/vpu/vpu_channel.c +13 −0 Original line number Diff line number Diff line Loading @@ -2440,6 +2440,19 @@ size_t vpu_hw_print_queues(char *buf, size_t buf_size) return vpu_hfi_print_queues(buf, buf_size); } int vpu_hw_write_csr_reg(u32 off, u32 val) { int rc; struct vpu_channel_hal *ch_hal = &g_vpu_ch_hal; if (VPU_IS_UP(ch_hal->mode)) rc = vpu_hfi_write_csr_reg(off, val); else rc = -EIO; /* firmware down */ return rc; } int vpu_hw_dump_csr_regs(char *buf, size_t buf_size) { int rc = 0; Loading drivers/media/platform/msm/vpu/vpu_channel.h +9 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,15 @@ void vpu_hw_debug_off(void); */ size_t vpu_hw_print_queues(char *buf, size_t buf_size); /** * vpu_hw_write_csr_reg() - write a value to a CSR register * @off: offset (from base) to write * @val: value to write * * Return: 0 on success, -ve on failure */ int vpu_hw_write_csr_reg(u32 off, u32 val); /** * vpu_hw_dump_csr_regs() - dump the contents of the VPU CSR registers into buf * @buf: debug buffer to write into Loading drivers/media/platform/msm/vpu/vpu_debug.c +35 −1 Original line number Diff line number Diff line Loading @@ -254,9 +254,43 @@ static ssize_t read_csr_regs(struct file *file, char __user *user_buf, return ret; } int write_csr_reg(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { int ret; int len; char buf[24]; char *sptr, *token; u32 reg_off; u32 reg_val; len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; sptr = buf; token = strsep(&sptr, ":"); if (!token) return -EINVAL; if (kstrtou32(token, 0, ®_off)) return -EINVAL; if (kstrtou32(sptr, 0, ®_val)) return -EINVAL; ret = vpu_hw_write_csr_reg(reg_off, reg_val); if (ret) return ret; return count; } static const struct file_operations csr_regs_ops = { .open = simple_open, .read = read_csr_regs, .write = write_csr_reg, }; static void debug_on(void) Loading Loading @@ -582,7 +616,7 @@ struct dentry *init_vpu_debugfs(struct vpu_dev_core *core) } /* create csr regs file */ attr = debugfs_create_file("csr_regs", S_IRUGO, root, NULL, attr = debugfs_create_file("csr_regs", RW_MODE, root, NULL, &csr_regs_ops); if (IS_ERR_OR_NULL(attr)) { pr_err("Failed to create csr regs attribute\n"); Loading drivers/media/platform/msm/vpu/vpu_hfi.c +69 −12 Original line number Diff line number Diff line Loading @@ -131,11 +131,6 @@ struct vpu_hfi_device { struct vpu_platform_resources *platform_resouce; }; struct addr_range { u32 start; u32 end; }; /* global */ static struct vpu_hfi_device g_hfi_device; Loading Loading @@ -1202,22 +1197,84 @@ size_t vpu_hfi_print_queues(char *buf, size_t buf_size) return strlcat(buf, "", buf_size); } static struct addr_range csr_skip_addrs[] = { struct addr_range { u32 start; u32 end; }; static struct addr_range restricted_csr_addrs[] = { /* start and end offsets of inaccessible address ranges */ { 0x0000, 0x000F }, { 0x0018, 0x001B }, { 0x0020, 0x0037 }, { 0x00C0, 0x00DF }, { 0x01A0, 0x01AF }, { 0x01A0, 0x0FFF }, }; /* registers which should not be written through debugfs * (may interfere with the normal operation of the driver * which makes use of these registers) */ static u32 no_write_csr_regs[] = { VPU_CSR_APPS_SGI_STS, VPU_CSR_APPS_SGI_CLR, VPU_CSR_FW_SGI_EN_SET, VPU_CSR_FW_SGI_EN_CLR, VPU_CSR_FW_SGI_FORCELEVEL, VPU_CSR_FW_SGI_STS, VPU_CSR_FW_SGI_CLR, VPU_CSR_FW_SGI_TRIG, VPU_CSR_SW_SCRATCH0_STS, VPU_CSR_SW_SCRATCH1_QTBL_INFO, VPU_CSR_SW_SCRATCH2_QTBL_ADDR, }; int vpu_hfi_write_csr_reg(u32 off, u32 val) { struct vpu_hfi_device *hdevice = &g_hfi_device; u32 v_base = (u32)(hdevice->reg_base); u32 p_base = (u32)(hdevice->platform_resouce->register_base_phy); u32 write_addr = v_base + off; u32 last_addr = v_base + VPU_CSR_LAST_REG; int i; if (write_addr > last_addr || write_addr < v_base) { pr_err("attempting to write outside of addr range\n"); return -EFAULT; } if (off % 4) { pr_err("addr must be 32-bit word-aligned\n"); return -EFAULT; } for (i = 0; i < ARRAY_SIZE(no_write_csr_regs); i++) { if (off == no_write_csr_regs[i]) { pr_err("not allowed write this reg through debugfs\n"); return -EFAULT; } } for (i = 0; i < ARRAY_SIZE(restricted_csr_addrs); i++) { if (off >= restricted_csr_addrs[i].start && off <= restricted_csr_addrs[i].end) { pr_err("attempting to write restricted addr range\n"); return -EFAULT; } } raw_hfi_reg_write(write_addr, val); pr_debug("wrote val: 0x%08x at addr: 0x%08x\n", val, p_base + off); return 0; } int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) { struct vpu_hfi_device *hdevice = &g_hfi_device; u32 v_base = (u32)(hdevice->reg_base); u32 p_base = (u32)(hdevice->platform_resouce->register_base_phy); u32 last_addr = v_base + csr_skip_addrs[ARRAY_SIZE(csr_skip_addrs) - 1].end; u32 last_addr = v_base + VPU_CSR_LAST_REG; u32 addr; char temp[32]; int i = 0, skip = 0, temp_size = 32; Loading @@ -1232,8 +1289,8 @@ int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) strlcat(buf, temp, buf_size); } if ((addr - v_base) >= csr_skip_addrs[i].start && (addr - v_base) <= csr_skip_addrs[i].end) { if ((addr - v_base) >= restricted_csr_addrs[i].start && (addr - v_base) <= restricted_csr_addrs[i].end) { skip = 1; snprintf(temp, temp_size, " xxxxxxxxxx"); strlcat(buf, temp, buf_size); Loading @@ -1244,7 +1301,7 @@ int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) } snprintf(temp, temp_size, " 0x%08x", readl_relaxed(addr + 0 * sizeof(u32))); raw_hfi_reg_read(addr)); strlcat(buf, temp, buf_size); } Loading drivers/media/platform/msm/vpu/vpu_hfi.h +8 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,14 @@ void vpu_hfi_set_pil_timeout(u32 pil_timeout); */ size_t vpu_hfi_print_queues(char *buf, size_t buf_size); /** * vpu_hfi_write_csr_reg() - write a value into a CSR register * @off: offset (from base) to write * @val: value to write * * Return: 0 on success, -ve on failure */ int vpu_hfi_write_csr_reg(u32 off, u32 val); /** * vpu_hfi_dump_csr_regs() - dump the contents of the VPU CSR registers Loading Loading
drivers/media/platform/msm/vpu/vpu_channel.c +13 −0 Original line number Diff line number Diff line Loading @@ -2440,6 +2440,19 @@ size_t vpu_hw_print_queues(char *buf, size_t buf_size) return vpu_hfi_print_queues(buf, buf_size); } int vpu_hw_write_csr_reg(u32 off, u32 val) { int rc; struct vpu_channel_hal *ch_hal = &g_vpu_ch_hal; if (VPU_IS_UP(ch_hal->mode)) rc = vpu_hfi_write_csr_reg(off, val); else rc = -EIO; /* firmware down */ return rc; } int vpu_hw_dump_csr_regs(char *buf, size_t buf_size) { int rc = 0; Loading
drivers/media/platform/msm/vpu/vpu_channel.h +9 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,15 @@ void vpu_hw_debug_off(void); */ size_t vpu_hw_print_queues(char *buf, size_t buf_size); /** * vpu_hw_write_csr_reg() - write a value to a CSR register * @off: offset (from base) to write * @val: value to write * * Return: 0 on success, -ve on failure */ int vpu_hw_write_csr_reg(u32 off, u32 val); /** * vpu_hw_dump_csr_regs() - dump the contents of the VPU CSR registers into buf * @buf: debug buffer to write into Loading
drivers/media/platform/msm/vpu/vpu_debug.c +35 −1 Original line number Diff line number Diff line Loading @@ -254,9 +254,43 @@ static ssize_t read_csr_regs(struct file *file, char __user *user_buf, return ret; } int write_csr_reg(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { int ret; int len; char buf[24]; char *sptr, *token; u32 reg_off; u32 reg_val; len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; sptr = buf; token = strsep(&sptr, ":"); if (!token) return -EINVAL; if (kstrtou32(token, 0, ®_off)) return -EINVAL; if (kstrtou32(sptr, 0, ®_val)) return -EINVAL; ret = vpu_hw_write_csr_reg(reg_off, reg_val); if (ret) return ret; return count; } static const struct file_operations csr_regs_ops = { .open = simple_open, .read = read_csr_regs, .write = write_csr_reg, }; static void debug_on(void) Loading Loading @@ -582,7 +616,7 @@ struct dentry *init_vpu_debugfs(struct vpu_dev_core *core) } /* create csr regs file */ attr = debugfs_create_file("csr_regs", S_IRUGO, root, NULL, attr = debugfs_create_file("csr_regs", RW_MODE, root, NULL, &csr_regs_ops); if (IS_ERR_OR_NULL(attr)) { pr_err("Failed to create csr regs attribute\n"); Loading
drivers/media/platform/msm/vpu/vpu_hfi.c +69 −12 Original line number Diff line number Diff line Loading @@ -131,11 +131,6 @@ struct vpu_hfi_device { struct vpu_platform_resources *platform_resouce; }; struct addr_range { u32 start; u32 end; }; /* global */ static struct vpu_hfi_device g_hfi_device; Loading Loading @@ -1202,22 +1197,84 @@ size_t vpu_hfi_print_queues(char *buf, size_t buf_size) return strlcat(buf, "", buf_size); } static struct addr_range csr_skip_addrs[] = { struct addr_range { u32 start; u32 end; }; static struct addr_range restricted_csr_addrs[] = { /* start and end offsets of inaccessible address ranges */ { 0x0000, 0x000F }, { 0x0018, 0x001B }, { 0x0020, 0x0037 }, { 0x00C0, 0x00DF }, { 0x01A0, 0x01AF }, { 0x01A0, 0x0FFF }, }; /* registers which should not be written through debugfs * (may interfere with the normal operation of the driver * which makes use of these registers) */ static u32 no_write_csr_regs[] = { VPU_CSR_APPS_SGI_STS, VPU_CSR_APPS_SGI_CLR, VPU_CSR_FW_SGI_EN_SET, VPU_CSR_FW_SGI_EN_CLR, VPU_CSR_FW_SGI_FORCELEVEL, VPU_CSR_FW_SGI_STS, VPU_CSR_FW_SGI_CLR, VPU_CSR_FW_SGI_TRIG, VPU_CSR_SW_SCRATCH0_STS, VPU_CSR_SW_SCRATCH1_QTBL_INFO, VPU_CSR_SW_SCRATCH2_QTBL_ADDR, }; int vpu_hfi_write_csr_reg(u32 off, u32 val) { struct vpu_hfi_device *hdevice = &g_hfi_device; u32 v_base = (u32)(hdevice->reg_base); u32 p_base = (u32)(hdevice->platform_resouce->register_base_phy); u32 write_addr = v_base + off; u32 last_addr = v_base + VPU_CSR_LAST_REG; int i; if (write_addr > last_addr || write_addr < v_base) { pr_err("attempting to write outside of addr range\n"); return -EFAULT; } if (off % 4) { pr_err("addr must be 32-bit word-aligned\n"); return -EFAULT; } for (i = 0; i < ARRAY_SIZE(no_write_csr_regs); i++) { if (off == no_write_csr_regs[i]) { pr_err("not allowed write this reg through debugfs\n"); return -EFAULT; } } for (i = 0; i < ARRAY_SIZE(restricted_csr_addrs); i++) { if (off >= restricted_csr_addrs[i].start && off <= restricted_csr_addrs[i].end) { pr_err("attempting to write restricted addr range\n"); return -EFAULT; } } raw_hfi_reg_write(write_addr, val); pr_debug("wrote val: 0x%08x at addr: 0x%08x\n", val, p_base + off); return 0; } int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) { struct vpu_hfi_device *hdevice = &g_hfi_device; u32 v_base = (u32)(hdevice->reg_base); u32 p_base = (u32)(hdevice->platform_resouce->register_base_phy); u32 last_addr = v_base + csr_skip_addrs[ARRAY_SIZE(csr_skip_addrs) - 1].end; u32 last_addr = v_base + VPU_CSR_LAST_REG; u32 addr; char temp[32]; int i = 0, skip = 0, temp_size = 32; Loading @@ -1232,8 +1289,8 @@ int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) strlcat(buf, temp, buf_size); } if ((addr - v_base) >= csr_skip_addrs[i].start && (addr - v_base) <= csr_skip_addrs[i].end) { if ((addr - v_base) >= restricted_csr_addrs[i].start && (addr - v_base) <= restricted_csr_addrs[i].end) { skip = 1; snprintf(temp, temp_size, " xxxxxxxxxx"); strlcat(buf, temp, buf_size); Loading @@ -1244,7 +1301,7 @@ int vpu_hfi_dump_csr_regs(char *buf, size_t buf_size) } snprintf(temp, temp_size, " 0x%08x", readl_relaxed(addr + 0 * sizeof(u32))); raw_hfi_reg_read(addr)); strlcat(buf, temp, buf_size); } Loading
drivers/media/platform/msm/vpu/vpu_hfi.h +8 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,14 @@ void vpu_hfi_set_pil_timeout(u32 pil_timeout); */ size_t vpu_hfi_print_queues(char *buf, size_t buf_size); /** * vpu_hfi_write_csr_reg() - write a value into a CSR register * @off: offset (from base) to write * @val: value to write * * Return: 0 on success, -ve on failure */ int vpu_hfi_write_csr_reg(u32 off, u32 val); /** * vpu_hfi_dump_csr_regs() - dump the contents of the VPU CSR registers Loading