static void venus_assign_register_offsets(struct venus_core *core)
{
- if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
- core->vbif_base = core->base + VBIF_BASE;
+ if (IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core)) {
core->cpu_base = core->base + CPU_BASE_V6;
core->cpu_cs_base = core->base + CPU_CS_BASE_V6;
core->cpu_ic_base = core->base + CPU_IC_BASE_V6;
core->wrapper_base = core->base + WRAPPER_BASE_V6;
core->wrapper_tz_base = core->base + WRAPPER_TZ_BASE_V6;
- core->aon_base = core->base + AON_BASE_V6;
+ if (IS_AR50_LITE(core)) {
+ core->vbif_base = NULL;
+ core->aon_base = NULL;
+ } else {
+ core->vbif_base = core->base + VBIF_BASE;
+ core->aon_base = core->base + AON_BASE_V6;
+ }
} else {
core->vbif_base = core->base + VBIF_BASE;
core->cpu_base = core->base + CPU_BASE;
if (ret)
goto err_firmware_deinit;
+ ret = venus_firmware_cfg(core);
+ if (ret)
+ goto err_venus_shutdown;
+
ret = hfi_core_resume(core, true);
if (ret)
goto err_venus_shutdown;
#define IS_IRIS2(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2)
#define IS_IRIS2_1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2_1)
+static inline bool is_lite(struct venus_core *core)
+{
+ return IS_AR50_LITE(core);
+}
+
#define ctrl_to_inst(ctrl) \
container_of((ctrl)->handler, struct venus_inst, ctrl_handler)
return 0;
}
+int venus_firmware_cfg(struct venus_core *core)
+{
+ void __iomem *cpu_cs_base = core->cpu_cs_base;
+
+ if (IS_AR50_LITE(core))
+ writel(CPU_CS_VCICMD_ARP_OFF, cpu_cs_base + CPU_CS_VCICMD);
+
+ return 0;
+}
+
int venus_boot(struct venus_core *core)
{
struct device *dev = core->dev;
int venus_firmware_init(struct venus_core *core);
void venus_firmware_deinit(struct venus_core *core);
int venus_firmware_check(struct venus_core *core);
+int venus_firmware_cfg(struct venus_core *core);
int venus_boot(struct venus_core *core);
int venus_shutdown(struct venus_core *core);
int venus_set_hw_state(struct venus_core *core, bool suspend);
if (ret)
return ret;
- inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
+ inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(inst->core,
+ version,
+ codec,
session_type);
- inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
+ inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(inst->core,
+ version,
+ codec,
session_type);
- inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec,
+ inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(inst->core,
+ version,
+ codec,
session_type);
return 0;
return ret;
if (plat->capabilities)
- caps = plat->capabilities(&entries);
+ caps = plat->capabilities(core, &entries);
if (!caps || !entries || !count)
return -EINVAL;
}
unsigned long
-hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_vpp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
return 0;
if (plat->codec_vpp_freq)
- freq = plat->codec_vpp_freq(session_type, codec);
+ freq = plat->codec_vpp_freq(core, session_type, codec);
return freq;
}
unsigned long
-hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_vsp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
return 0;
if (plat->codec_vpp_freq)
- freq = plat->codec_vsp_freq(session_type, codec);
+ freq = plat->codec_vsp_freq(core, session_type, codec);
return freq;
}
unsigned long
-hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_lp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
return 0;
if (plat->codec_lp_freq)
- freq = plat->codec_lp_freq(session_type, codec);
+ freq = plat->codec_lp_freq(core, session_type, codec);
return freq;
}
int
-hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count)
{
const struct hfi_platform *plat;
return -EINVAL;
if (plat->codecs)
- plat->codecs(enc_codecs, dec_codecs, count);
+ plat->codecs(core, enc_codecs, dec_codecs, count);
if (IS_IRIS2_1(core)) {
*enc_codecs &= ~HFI_VIDEO_CODEC_VP8;
};
struct hfi_platform {
- unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec);
- unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec);
- unsigned long (*codec_lp_freq)(u32 session_type, u32 codec);
- void (*codecs)(u32 *enc_codecs, u32 *dec_codecs, u32 *count);
- const struct hfi_plat_caps *(*capabilities)(unsigned int *entries);
+ unsigned long (*codec_vpp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ unsigned long (*codec_vsp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ unsigned long (*codec_lp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ void (*codecs)(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count);
+ const struct hfi_plat_caps *(*capabilities)(struct venus_core *core,
+ unsigned int *entries);
int (*bufreq)(struct hfi_plat_buffers_params *params, u32 session_type,
u32 buftype, struct hfi_buffer_requirements *bufreq);
};
extern const struct hfi_platform hfi_plat_v6;
const struct hfi_platform *hfi_platform_get(enum hfi_version version);
-unsigned long hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-unsigned long hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-int hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs,
- u32 *count);
+unsigned long hfi_platform_get_codec_vpp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+unsigned long hfi_platform_get_codec_vsp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+unsigned long hfi_platform_get_codec_lp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+int hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count);
#endif
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
+#include "core.h"
#include "hfi_platform.h"
static const struct hfi_plat_caps caps[] = {
.num_fmts = 4,
} };
-static const struct hfi_plat_caps *get_capabilities(unsigned int *entries)
+static const struct hfi_plat_caps *get_capabilities(struct venus_core *core,
+ unsigned int *entries)
{
+ if (is_lite(core))
+ return NULL;
+
*entries = ARRAY_SIZE(caps);
return caps;
}
-static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+static void get_codecs(struct venus_core *core,
+ u32 *enc_codecs, u32 *dec_codecs, u32 *count)
{
+ if (is_lite(core))
+ return;
+
*enc_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
HFI_VIDEO_CODEC_VP8;
*dec_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
};
static const struct hfi_platform_codec_freq_data *
-get_codec_freq_data(u32 session_type, u32 pixfmt)
+get_codec_freq_data(struct venus_core *core, u32 session_type, u32 pixfmt)
{
const struct hfi_platform_codec_freq_data *data = codec_freq_data;
unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
const struct hfi_platform_codec_freq_data *found = NULL;
+ if (is_lite(core))
+ return NULL;
+
for (i = 0; i < data_size; i++) {
if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
found = &data[i];
return found;
}
-static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vpp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vpp_freq;
return 0;
}
-static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vsp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vsp_freq;
return 0;
}
-static unsigned long codec_lp_freq(u32 session_type, u32 codec)
+static unsigned long codec_lp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->low_power_freq;
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
+#include "core.h"
#include "hfi_platform.h"
static const struct hfi_plat_caps caps[] = {
.num_fmts = 4,
} };
-static const struct hfi_plat_caps *get_capabilities(unsigned int *entries)
+static const struct hfi_plat_caps *get_capabilities(struct venus_core *core,
+ unsigned int *entries)
{
+ if (is_lite(core))
+ return NULL;
+
*entries = ARRAY_SIZE(caps);
return caps;
}
-static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+static void get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count)
{
+ if (is_lite(core))
+ return;
+
*enc_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
HFI_VIDEO_CODEC_VP8;
*dec_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
};
static const struct hfi_platform_codec_freq_data *
-get_codec_freq_data(u32 session_type, u32 pixfmt)
+get_codec_freq_data(struct venus_core *core, u32 session_type, u32 pixfmt)
{
const struct hfi_platform_codec_freq_data *data = codec_freq_data;
unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
const struct hfi_platform_codec_freq_data *found = NULL;
+ if (is_lite(core))
+ return NULL;
+
for (i = 0; i < data_size; i++) {
if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
found = &data[i];
return found;
}
-static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vpp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vpp_freq;
return 0;
}
-static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vsp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vsp_freq;
return 0;
}
-static unsigned long codec_lp_freq(u32 session_type, u32 codec)
+static unsigned long codec_lp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->low_power_freq;
void __iomem *cpu_ic_base = hdev->core->cpu_ic_base;
u32 clear_bit;
- if (IS_V6(hdev->core))
+ if (IS_V6(hdev->core) || (IS_V4(hdev->core) && is_lite(hdev->core)))
clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT_V6);
else
clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT);
if (count >= max_tries)
ret = -ETIMEDOUT;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) {
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core)) {
writel(0x1, cpu_cs_base + CPU_CS_H2XSOFTINTEN_V6);
- writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
+
+ if (!IS_AR50_LITE(hdev->core))
+ writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
}
return ret;
u32 mask_val;
int ret;
+ if (IS_AR50_LITE(hdev->core))
+ return 0;
+
if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) {
writel(0x3, cpu_cs_base + CPU_CS_X2RPMH_V6);
wrapper_base = hdev->core->wrapper_base;
status = readl(wrapper_base + WRAPPER_INTR_STATUS);
- if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
+
+ if (IS_AR50_LITE(core)) {
+ if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
+ status & WRAPPER_INTR_STATUS_A2HWD_MASK_V4_LITE ||
+ status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
+ hdev->irq_status = status;
+ } else if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
status & WRAPPER_INTR_STATUS_A2HWD_MASK_V6 ||
status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
hdev->irq_status = status;
}
writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR);
- if (!(IS_IRIS2(core) || IS_IRIS2_1(core)))
+ if (!(IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core)))
writel(status, wrapper_base + WRAPPER_INTR_CLEAR);
return IRQ_WAKE_THREAD;
void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core))
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core))
cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6);
else
cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core))
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core))
cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6);
else
cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
/* Venus cpu */
#define CPU_CS_SCIACMDARG3 0x58
+#define CPU_CS_VCICMD 0x20
+#define CPU_CS_VCICMD_ARP_OFF BIT(0)
+
#define SFR_ADDR 0x5c
#define MMAP_ADDR 0x60
#define UC_REGION_ADDR 0x64
#define WRAPPER_INTR_MASK_A2HCPU_MASK 0x4
#define WRAPPER_INTR_MASK_A2HCPU_SHIFT 0x2
+#define WRAPPER_INTR_STATUS_A2HWD_MASK_V4_LITE 0x10
#define WRAPPER_INTR_STATUS_A2HWD_MASK_V6 0x8
#define WRAPPER_INTR_MASK_A2HWD_BASK_V6 0x8
dev_pm_opp_put(opp);
for (i = 0; i < res->clks_num; i++) {
- if (IS_V6(core)) {
+ if (IS_V6(core) || (IS_V4(core) && is_lite(core))) {
ret = clk_set_rate(core->clks[i], freq);
if (ret)
goto err;