blob: 92112eb16c11048e28230a2926dfb46e3163aada [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/pm_runtime.h>
#include "iris_firmware.h"
#include "iris_core.h"
#include "iris_hfi_common.h"
#include "iris_vpu_common.h"
u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries)
{
switch (hfi_primaries) {
case HFI_PRIMARIES_RESERVED:
return V4L2_COLORSPACE_DEFAULT;
case HFI_PRIMARIES_BT709:
return V4L2_COLORSPACE_REC709;
case HFI_PRIMARIES_BT470_SYSTEM_M:
return V4L2_COLORSPACE_470_SYSTEM_M;
case HFI_PRIMARIES_BT470_SYSTEM_BG:
return V4L2_COLORSPACE_470_SYSTEM_BG;
case HFI_PRIMARIES_BT601_525:
return V4L2_COLORSPACE_SMPTE170M;
case HFI_PRIMARIES_SMPTE_ST240M:
return V4L2_COLORSPACE_SMPTE240M;
case HFI_PRIMARIES_BT2020:
return V4L2_COLORSPACE_BT2020;
case V4L2_COLORSPACE_DCI_P3:
return HFI_PRIMARIES_SMPTE_RP431_2;
default:
return V4L2_COLORSPACE_DEFAULT;
}
}
u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics)
{
switch (hfi_characterstics) {
case HFI_TRANSFER_RESERVED:
return V4L2_XFER_FUNC_DEFAULT;
case HFI_TRANSFER_BT709:
return V4L2_XFER_FUNC_709;
case HFI_TRANSFER_SMPTE_ST240M:
return V4L2_XFER_FUNC_SMPTE240M;
case HFI_TRANSFER_SRGB_SYCC:
return V4L2_XFER_FUNC_SRGB;
case HFI_TRANSFER_SMPTE_ST2084_PQ:
return V4L2_XFER_FUNC_SMPTE2084;
default:
return V4L2_XFER_FUNC_DEFAULT;
}
}
u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients)
{
switch (hfi_coefficients) {
case HFI_MATRIX_COEFF_RESERVED:
return V4L2_YCBCR_ENC_DEFAULT;
case HFI_MATRIX_COEFF_BT709:
return V4L2_YCBCR_ENC_709;
case HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625:
return V4L2_YCBCR_ENC_XV601;
case HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625:
return V4L2_YCBCR_ENC_601;
case HFI_MATRIX_COEFF_SMPTE_ST240:
return V4L2_YCBCR_ENC_SMPTE240M;
case HFI_MATRIX_COEFF_BT2020_NON_CONSTANT:
return V4L2_YCBCR_ENC_BT2020;
case HFI_MATRIX_COEFF_BT2020_CONSTANT:
return V4L2_YCBCR_ENC_BT2020_CONST_LUM;
default:
return V4L2_YCBCR_ENC_DEFAULT;
}
}
int iris_hfi_core_init(struct iris_core *core)
{
const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops;
int ret;
ret = hfi_ops->sys_init(core);
if (ret)
return ret;
ret = hfi_ops->sys_image_version(core);
if (ret)
return ret;
return hfi_ops->sys_interframe_powercollapse(core);
}
irqreturn_t iris_hfi_isr(int irq, void *data)
{
disable_irq_nosync(irq);
return IRQ_WAKE_THREAD;
}
irqreturn_t iris_hfi_isr_handler(int irq, void *data)
{
struct iris_core *core = data;
if (!core)
return IRQ_NONE;
mutex_lock(&core->lock);
pm_runtime_mark_last_busy(core->dev);
iris_vpu_clear_interrupt(core);
mutex_unlock(&core->lock);
core->hfi_response_ops->hfi_response_handler(core);
if (!iris_vpu_watchdog(core, core->intr_status))
enable_irq(irq);
return IRQ_HANDLED;
}
int iris_hfi_pm_suspend(struct iris_core *core)
{
int ret;
ret = iris_vpu_prepare_pc(core);
if (ret) {
pm_runtime_mark_last_busy(core->dev);
ret = -EAGAIN;
goto error;
}
ret = iris_set_hw_state(core, false);
if (ret)
goto error;
iris_vpu_power_off(core);
return 0;
error:
dev_err(core->dev, "failed to suspend\n");
return ret;
}
int iris_hfi_pm_resume(struct iris_core *core)
{
const struct iris_hfi_command_ops *ops = core->hfi_ops;
int ret;
ret = iris_vpu_power_on(core);
if (ret)
goto error;
ret = iris_set_hw_state(core, true);
if (ret)
goto err_power_off;
ret = iris_vpu_boot_firmware(core);
if (ret)
goto err_suspend_hw;
ret = ops->sys_interframe_powercollapse(core);
if (ret)
goto err_suspend_hw;
return 0;
err_suspend_hw:
iris_set_hw_state(core, false);
err_power_off:
iris_vpu_power_off(core);
error:
dev_err(core->dev, "failed to resume\n");
return -EBUSY;
}