diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-04 21:05:48 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-04 21:05:48 +0300 |
commit | 228dfe98a313f6b6bff5da8b2c5e650e297ebf1a (patch) | |
tree | 501dc44c2453743eb2298fe23d6cdd0b5e91b2c2 /drivers/misc/habanalabs/common/decoder.c | |
parent | 798cd57cd5f871452461746032cf6ee50b0fd69a (diff) | |
parent | b5276c924497705ca927ad85a763c37f2de98349 (diff) | |
download | linux-228dfe98a313f6b6bff5da8b2c5e650e297ebf1a.tar.xz |
Merge tag 'char-misc-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char / misc driver updates from Greg KH:
"Here is the large set of char and misc and other driver subsystem
changes for 6.0-rc1.
Highlights include:
- large set of IIO driver updates, additions, and cleanups
- new habanalabs device support added (loads of register maps much
like GPUs have)
- soundwire driver updates
- phy driver updates
- slimbus driver updates
- tiny virt driver fixes and updates
- misc driver fixes and updates
- interconnect driver updates
- hwtracing driver updates
- fpga driver updates
- extcon driver updates
- firmware driver updates
- counter driver update
- mhi driver fixes and updates
- binder driver fixes and updates
- speakup driver fixes
All of these have been in linux-next for a while without any reported
problems"
* tag 'char-misc-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (634 commits)
drivers: lkdtm: fix clang -Wformat warning
char: remove VR41XX related char driver
misc: Mark MICROCODE_MINOR unused
spmi: trace: fix stack-out-of-bound access in SPMI tracing functions
dt-bindings: iio: adc: Add compatible for MT8188
iio: light: isl29028: Fix the warning in isl29028_remove()
iio: accel: sca3300: Extend the trigger buffer from 16 to 32 bytes
iio: fix iio_format_avail_range() printing for none IIO_VAL_INT
iio: adc: max1027: unlock on error path in max1027_read_single_value()
iio: proximity: sx9324: add empty line in front of bullet list
iio: magnetometer: hmc5843: Remove duplicate 'the'
iio: magn: yas530: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
iio: magnetometer: ak8974: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
iio: light: veml6030: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
iio: light: vcnl4035: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
iio: light: vcnl4000: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr() macros
iio: light: tsl2591: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr()
iio: light: tsl2583: Use DEFINE_RUNTIME_DEV_PM_OPS and pm_ptr()
iio: light: isl29028: Use DEFINE_RUNTIME_DEV_PM_OPS() and pm_ptr()
iio: light: gp2ap002: Switch to DEFINE_RUNTIME_DEV_PM_OPS and pm_ptr()
...
Diffstat (limited to 'drivers/misc/habanalabs/common/decoder.c')
-rw-r--r-- | drivers/misc/habanalabs/common/decoder.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/misc/habanalabs/common/decoder.c b/drivers/misc/habanalabs/common/decoder.c new file mode 100644 index 000000000000..2aab14d74b53 --- /dev/null +++ b/drivers/misc/habanalabs/common/decoder.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2022 HabanaLabs, Ltd. + * All Rights Reserved. + */ + +#include "habanalabs.h" + +#define VCMD_CONTROL_OFFSET 0x40 /* SWREG16 */ +#define VCMD_IRQ_STATUS_OFFSET 0x44 /* SWREG17 */ + +#define VCMD_IRQ_STATUS_ENDCMD_MASK 0x1 +#define VCMD_IRQ_STATUS_BUSERR_MASK 0x2 +#define VCMD_IRQ_STATUS_TIMEOUT_MASK 0x4 +#define VCMD_IRQ_STATUS_CMDERR_MASK 0x8 +#define VCMD_IRQ_STATUS_ABORT_MASK 0x10 +#define VCMD_IRQ_STATUS_RESET_MASK 0x20 + +static void dec_print_abnrm_intr_source(struct hl_device *hdev, u32 irq_status) +{ + const char *format = "abnormal interrupt source:%s%s%s%s%s%s\n"; + char *intr_source[6] = {"Unknown", "", "", "", "", ""}; + int i = 0; + + if (!irq_status) + return; + + if (irq_status & VCMD_IRQ_STATUS_ENDCMD_MASK) + intr_source[i++] = " ENDCMD"; + if (irq_status & VCMD_IRQ_STATUS_BUSERR_MASK) + intr_source[i++] = " BUSERR"; + if (irq_status & VCMD_IRQ_STATUS_TIMEOUT_MASK) + intr_source[i++] = " TIMEOUT"; + if (irq_status & VCMD_IRQ_STATUS_CMDERR_MASK) + intr_source[i++] = " CMDERR"; + if (irq_status & VCMD_IRQ_STATUS_ABORT_MASK) + intr_source[i++] = " ABORT"; + if (irq_status & VCMD_IRQ_STATUS_RESET_MASK) + intr_source[i++] = " RESET"; + + dev_err(hdev->dev, format, intr_source[0], intr_source[1], + intr_source[2], intr_source[3], intr_source[4], intr_source[5]); +} + +static void dec_error_intr_work(struct hl_device *hdev, u32 base_addr, u32 core_id) +{ + bool reset_required = false; + u32 irq_status; + + irq_status = RREG32(base_addr + VCMD_IRQ_STATUS_OFFSET); + + dev_err(hdev->dev, "Decoder abnormal interrupt %#x, core %d\n", irq_status, core_id); + + dec_print_abnrm_intr_source(hdev, irq_status); + + if (irq_status & VCMD_IRQ_STATUS_TIMEOUT_MASK) + reset_required = true; + + /* Clear the interrupt */ + WREG32(base_addr + VCMD_IRQ_STATUS_OFFSET, irq_status); + + /* Flush the interrupt clear */ + RREG32(base_addr + VCMD_IRQ_STATUS_OFFSET); + + if (reset_required) + hl_device_reset(hdev, HL_DRV_RESET_HARD); +} + +static void dec_completion_abnrm(struct work_struct *work) +{ + struct hl_dec *dec = container_of(work, struct hl_dec, completion_abnrm_work); + struct hl_device *hdev = dec->hdev; + + dec_error_intr_work(hdev, dec->base_addr, dec->core_id); +} + +void hl_dec_fini(struct hl_device *hdev) +{ + kfree(hdev->dec); +} + +int hl_dec_init(struct hl_device *hdev) +{ + struct asic_fixed_properties *prop = &hdev->asic_prop; + struct hl_dec *dec; + int rc, j; + + /* if max core is 0, nothing to do*/ + if (!prop->max_dec) + return 0; + + hdev->dec = kcalloc(prop->max_dec, sizeof(struct hl_dec), GFP_KERNEL); + if (!hdev->dec) + return -ENOMEM; + + for (j = 0 ; j < prop->max_dec ; j++) { + dec = hdev->dec + j; + + dec->hdev = hdev; + INIT_WORK(&dec->completion_abnrm_work, dec_completion_abnrm); + dec->core_id = j; + dec->base_addr = hdev->asic_funcs->get_dec_base_addr(hdev, j); + if (!dec->base_addr) { + dev_err(hdev->dev, "Invalid base address of decoder %d\n", j); + rc = -EINVAL; + goto err_dec_fini; + } + } + + return 0; + +err_dec_fini: + hl_dec_fini(hdev); + + return rc; +} + +void hl_dec_ctx_fini(struct hl_ctx *ctx) +{ + struct hl_device *hdev = ctx->hdev; + struct asic_fixed_properties *prop = &hdev->asic_prop; + struct hl_dec *dec; + int j; + + for (j = 0 ; j < prop->max_dec ; j++) { + if (!!(prop->decoder_enabled_mask & BIT(j))) { + dec = hdev->dec + j; + /* Stop the decoder */ + WREG32(dec->base_addr + VCMD_CONTROL_OFFSET, 0); + } + } +} |