Commit d1734cfc authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'mtk-soc-for-v6.10' of...

Merge tag 'mtk-soc-for-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux into soc/drivers

MediaTek driver updates for v6.10

This adds a much needed cleanup for the MediaTek CMDQ helper driver and
also some more helper functions which will be used in drivers using the
MediaTek Global Command Engine (GCE) HW.

Also adds support for MT8188's VPPSYS mutex for MDP3 support, a new SoC
in the mtk-socinfo driver and changes the marketing name for the pre
existing MT8188 SoC.

* tag 'mtk-soc-for-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux:
  soc: mediatek: mtk-socinfo: Correct the marketing name for MT8188GV
  soc: mediatek: mtk-socinfo: Add entry for MT8395AV/ZA Genio 1200
  soc: mediatek: mtk-mutex: Add support for MT8188 VPPSYS
  soc: mediatek: socinfo: Advertise about unknown MediaTek SoC
  soc: mediatek: cmdq: Don't log an error when gce-client-reg is not found
  soc: mediatek: mtk-cmdq: Add cmdq_pkt_acquire_event() function
  soc: mediatek: mtk-cmdq: Add cmdq_pkt_poll_addr() function
  soc: mediatek: mtk-cmdq: Add cmdq_pkt_mem_move() function
  soc: mediatek: mtk-cmdq: Add specific purpose register definitions for GCE
  soc: mediatek: cmdq: Refine cmdq_pkt_create() and cmdq_pkt_destroy()
  soc: mediatek: cmdq: Remove cmdq_pkt_flush_async() helper function
  soc: mediatek: cmdq: Add cmdq_pkt_eoc() helper function
  soc: mediatek: cmdq: Add cmdq_pkt_jump_rel() helper function
  soc: mediatek: cmdq: Rename cmdq_pkt_jump() to cmdq_pkt_jump_abs()
  soc: mediatek: cmdq: Add parameter shift_pa to cmdq_pkt_jump()
  soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE

Link: https://lore.kernel.org/r/20240429140245.238210-2-angelogioacchino.delregno@collabora.comSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 75c0675f 8a87e1d2
......@@ -12,9 +12,12 @@
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
#define CMDQ_POLL_ENABLE_MASK BIT(0)
/* dedicate the last GPR_R15 to assign the register address to be poll */
#define CMDQ_POLL_ADDR_GPR (15)
#define CMDQ_EOC_IRQ_EN BIT(0)
#define CMDQ_REG_TYPE 1
#define CMDQ_JUMP_RELATIVE 1
#define CMDQ_JUMP_RELATIVE 0
#define CMDQ_JUMP_ABSOLUTE 1
struct cmdq_instruction {
union {
......@@ -55,7 +58,7 @@ int cmdq_dev_get_client_reg(struct device *dev,
"mediatek,gce-client-reg",
3, idx, &spec);
if (err < 0) {
dev_err(dev,
dev_warn(dev,
"error %d can't parse gce-client-reg property (%d)",
err, idx);
......@@ -105,22 +108,16 @@ void cmdq_mbox_destroy(struct cmdq_client *client)
}
EXPORT_SYMBOL(cmdq_mbox_destroy);
struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
{
struct cmdq_pkt *pkt;
struct device *dev;
dma_addr_t dma_addr;
pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
if (!pkt)
return ERR_PTR(-ENOMEM);
pkt->va_base = kzalloc(size, GFP_KERNEL);
if (!pkt->va_base) {
kfree(pkt);
return ERR_PTR(-ENOMEM);
}
if (!pkt->va_base)
return -ENOMEM;
pkt->buf_size = size;
pkt->cl = (void *)client;
dev = client->chan->mbox->dev;
dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
......@@ -128,24 +125,20 @@ struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
if (dma_mapping_error(dev, dma_addr)) {
dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
kfree(pkt->va_base);
kfree(pkt);
return ERR_PTR(-ENOMEM);
return -ENOMEM;
}
pkt->pa_base = dma_addr;
return pkt;
return 0;
}
EXPORT_SYMBOL(cmdq_pkt_create);
void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt)
{
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
DMA_TO_DEVICE);
kfree(pkt->va_base);
kfree(pkt);
}
EXPORT_SYMBOL(cmdq_pkt_destroy);
......@@ -299,6 +292,32 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
}
EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr)
{
const u16 high_addr_reg_idx = CMDQ_THR_SPR_IDX0;
const u16 value_reg_idx = CMDQ_THR_SPR_IDX1;
int ret;
/* read the value of src_addr into high_addr_reg_idx */
ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(src_addr));
if (ret < 0)
return ret;
ret = cmdq_pkt_read_s(pkt, high_addr_reg_idx, CMDQ_ADDR_LOW(src_addr), value_reg_idx);
if (ret < 0)
return ret;
/* write the value of value_reg_idx into dst_addr */
ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(dst_addr));
if (ret < 0)
return ret;
ret = cmdq_pkt_write_s(pkt, high_addr_reg_idx, CMDQ_ADDR_LOW(dst_addr), value_reg_idx);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(cmdq_pkt_mem_move);
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
{
struct cmdq_instruction inst = { {0} };
......@@ -315,6 +334,21 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
}
EXPORT_SYMBOL(cmdq_pkt_wfe);
int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event)
{
struct cmdq_instruction inst = {};
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
inst.op = CMDQ_CODE_WFE;
inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE | CMDQ_WFE_WAIT;
inst.event = event;
return cmdq_pkt_append_command(pkt, inst);
}
EXPORT_SYMBOL(cmdq_pkt_acquire_event);
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
{
struct cmdq_instruction inst = { {0} };
......@@ -380,6 +414,53 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
}
EXPORT_SYMBOL(cmdq_pkt_poll_mask);
int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
{
struct cmdq_instruction inst = { {0} };
u8 use_mask = 0;
int ret;
/*
* Append an MASK instruction to set the mask for following POLL instruction
* which enables use_mask bit.
*/
if (mask != GENMASK(31, 0)) {
inst.op = CMDQ_CODE_MASK;
inst.mask = ~mask;
ret = cmdq_pkt_append_command(pkt, inst);
if (ret < 0)
return ret;
use_mask = CMDQ_POLL_ENABLE_MASK;
}
/*
* POLL is an legacy operation in GCE and it does not support SPR and CMDQ_CODE_LOGIC,
* so it can not use cmdq_pkt_assign to keep polling register address to SPR.
* If user wants to poll a register address which doesn't have a subsys id,
* user needs to use GPR and CMDQ_CODE_MASK to move polling register address to GPR.
*/
inst.op = CMDQ_CODE_MASK;
inst.dst_t = CMDQ_REG_TYPE;
inst.sop = CMDQ_POLL_ADDR_GPR;
inst.value = addr;
ret = cmdq_pkt_append_command(pkt, inst);
if (ret < 0)
return ret;
/* Append POLL instruction to poll the register address assign to GPR previously. */
inst.op = CMDQ_CODE_POLL;
inst.dst_t = CMDQ_REG_TYPE;
inst.sop = CMDQ_POLL_ADDR_GPR;
inst.offset = use_mask;
inst.value = value;
ret = cmdq_pkt_append_command(pkt, inst);
if (ret < 0)
return ret;
return 0;
}
EXPORT_SYMBOL(cmdq_pkt_poll_addr);
int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
{
struct cmdq_instruction inst = {};
......@@ -392,17 +473,36 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
}
EXPORT_SYMBOL(cmdq_pkt_assign);
int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
{
struct cmdq_instruction inst = {};
inst.op = CMDQ_CODE_JUMP;
inst.offset = CMDQ_JUMP_RELATIVE;
inst.value = addr >>
cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
inst.offset = CMDQ_JUMP_ABSOLUTE;
inst.value = addr >> shift_pa;
return cmdq_pkt_append_command(pkt, inst);
}
EXPORT_SYMBOL(cmdq_pkt_jump_abs);
int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
{
struct cmdq_instruction inst = { {0} };
inst.op = CMDQ_CODE_JUMP;
inst.value = (u32)offset >> shift_pa;
return cmdq_pkt_append_command(pkt, inst);
}
EXPORT_SYMBOL(cmdq_pkt_jump_rel);
int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
{
struct cmdq_instruction inst = { {0} };
inst.op = CMDQ_CODE_EOC;
inst.value = CMDQ_EOC_IRQ_EN;
return cmdq_pkt_append_command(pkt, inst);
}
EXPORT_SYMBOL(cmdq_pkt_jump);
EXPORT_SYMBOL(cmdq_pkt_eoc);
int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
......@@ -426,19 +526,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
}
EXPORT_SYMBOL(cmdq_pkt_finalize);
int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
{
int err;
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
err = mbox_send_message(client->chan, pkt);
if (err < 0)
return err;
/* We can send next packet immediately, so just call txdone. */
mbox_client_txdone(client->chan, 0);
return 0;
}
EXPORT_SYMBOL(cmdq_pkt_flush_async);
MODULE_LICENSE("GPL v2");
......@@ -496,6 +496,39 @@ static const unsigned int mt8188_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_MERGE5] = MT8188_MUTEX_MOD_DISP1_VPP_MERGE4,
};
static const unsigned int mt8188_mdp_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
[MUTEX_MOD_IDX_MDP_RDMA0] = MT8195_MUTEX_MOD_MDP_RDMA0,
[MUTEX_MOD_IDX_MDP_RDMA2] = MT8195_MUTEX_MOD_MDP_RDMA2,
[MUTEX_MOD_IDX_MDP_RDMA3] = MT8195_MUTEX_MOD_MDP_RDMA3,
[MUTEX_MOD_IDX_MDP_FG0] = MT8195_MUTEX_MOD_MDP_FG0,
[MUTEX_MOD_IDX_MDP_FG2] = MT8195_MUTEX_MOD_MDP_FG2,
[MUTEX_MOD_IDX_MDP_FG3] = MT8195_MUTEX_MOD_MDP_FG3,
[MUTEX_MOD_IDX_MDP_HDR0] = MT8195_MUTEX_MOD_MDP_HDR0,
[MUTEX_MOD_IDX_MDP_HDR2] = MT8195_MUTEX_MOD_MDP_HDR2,
[MUTEX_MOD_IDX_MDP_HDR3] = MT8195_MUTEX_MOD_MDP_HDR3,
[MUTEX_MOD_IDX_MDP_AAL0] = MT8195_MUTEX_MOD_MDP_AAL0,
[MUTEX_MOD_IDX_MDP_AAL2] = MT8195_MUTEX_MOD_MDP_AAL2,
[MUTEX_MOD_IDX_MDP_AAL3] = MT8195_MUTEX_MOD_MDP_AAL3,
[MUTEX_MOD_IDX_MDP_RSZ0] = MT8195_MUTEX_MOD_MDP_RSZ0,
[MUTEX_MOD_IDX_MDP_RSZ2] = MT8195_MUTEX_MOD_MDP_RSZ2,
[MUTEX_MOD_IDX_MDP_RSZ3] = MT8195_MUTEX_MOD_MDP_RSZ3,
[MUTEX_MOD_IDX_MDP_MERGE2] = MT8195_MUTEX_MOD_MDP_MERGE2,
[MUTEX_MOD_IDX_MDP_MERGE3] = MT8195_MUTEX_MOD_MDP_MERGE3,
[MUTEX_MOD_IDX_MDP_TDSHP0] = MT8195_MUTEX_MOD_MDP_TDSHP0,
[MUTEX_MOD_IDX_MDP_TDSHP2] = MT8195_MUTEX_MOD_MDP_TDSHP2,
[MUTEX_MOD_IDX_MDP_TDSHP3] = MT8195_MUTEX_MOD_MDP_TDSHP3,
[MUTEX_MOD_IDX_MDP_COLOR0] = MT8195_MUTEX_MOD_MDP_COLOR0,
[MUTEX_MOD_IDX_MDP_COLOR2] = MT8195_MUTEX_MOD_MDP_COLOR2,
[MUTEX_MOD_IDX_MDP_COLOR3] = MT8195_MUTEX_MOD_MDP_COLOR3,
[MUTEX_MOD_IDX_MDP_OVL0] = MT8195_MUTEX_MOD_MDP_OVL0,
[MUTEX_MOD_IDX_MDP_PAD0] = MT8195_MUTEX_MOD_MDP_PAD0,
[MUTEX_MOD_IDX_MDP_PAD2] = MT8195_MUTEX_MOD_MDP_PAD2,
[MUTEX_MOD_IDX_MDP_PAD3] = MT8195_MUTEX_MOD_MDP_PAD3,
[MUTEX_MOD_IDX_MDP_WROT0] = MT8195_MUTEX_MOD_MDP_WROT0,
[MUTEX_MOD_IDX_MDP_WROT2] = MT8195_MUTEX_MOD_MDP_WROT2,
[MUTEX_MOD_IDX_MDP_WROT3] = MT8195_MUTEX_MOD_MDP_WROT3,
};
static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
......@@ -735,6 +768,13 @@ static const struct mtk_mutex_data mt8188_mutex_driver_data = {
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
};
static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = {
.mutex_sof = mt8188_mutex_sof,
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
.mutex_table_mod = mt8188_mdp_mutex_table_mod,
};
static const struct mtk_mutex_data mt8192_mutex_driver_data = {
.mutex_mod = mt8192_mutex_mod,
.mutex_sof = mt8183_mutex_sof,
......@@ -1089,6 +1129,7 @@ static const struct of_device_id mutex_driver_dt_match[] = {
{ .compatible = "mediatek,mt8186-disp-mutex", .data = &mt8186_mutex_driver_data },
{ .compatible = "mediatek,mt8186-mdp3-mutex", .data = &mt8186_mdp_mutex_driver_data },
{ .compatible = "mediatek,mt8188-disp-mutex", .data = &mt8188_mutex_driver_data },
{ .compatible = "mediatek,mt8188-vpp-mutex", .data = &mt8188_vpp_mutex_driver_data },
{ .compatible = "mediatek,mt8192-disp-mutex", .data = &mt8192_mutex_driver_data },
{ .compatible = "mediatek,mt8195-disp-mutex", .data = &mt8195_mutex_driver_data },
{ .compatible = "mediatek,mt8195-vpp-mutex", .data = &mt8195_vpp_mutex_driver_data },
......
......@@ -48,14 +48,15 @@ static struct socinfo_data socinfo_data_table[] = {
MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000940),
MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010),
MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011),
MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 838", 0x81880000, 0x00000010),
MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 838", 0x81880000, 0x00000011),
MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080),
MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0),
MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED),
MTK_SOCINFO_ENTRY("MT8395", "MT8395AV/ZA", "Genio 1200", 0x83950100, CELL_NOT_USED),
};
static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
......@@ -144,7 +145,14 @@ static int mtk_socinfo_get_socinfo_data(struct mtk_socinfo *mtk_socinfop)
}
}
return match_socinfo_index >= 0 ? match_socinfo_index : -ENOENT;
if (match_socinfo_index < 0) {
dev_warn(mtk_socinfop->dev,
"Unknown MediaTek SoC with ID 0x%08x 0x%08x\n",
cell_data[0], cell_data[1]);
return -ENOENT;
}
return match_socinfo_index;
}
static int mtk_socinfo_probe(struct platform_device *pdev)
......
......@@ -14,6 +14,15 @@
#define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0)))
#define CMDQ_ADDR_LOW(addr) ((u16)(addr) | BIT(1))
/*
* Every cmdq thread has its own SPRs (Specific Purpose Registers),
* so there are 4 * N (threads) SPRs in GCE that shares the same indexes below.
*/
#define CMDQ_THR_SPR_IDX0 (0)
#define CMDQ_THR_SPR_IDX1 (1)
#define CMDQ_THR_SPR_IDX2 (2)
#define CMDQ_THR_SPR_IDX3 (3)
struct cmdq_pkt;
struct cmdq_client_reg {
......@@ -62,17 +71,19 @@ void cmdq_mbox_destroy(struct cmdq_client *client);
/**
* cmdq_pkt_create() - create a CMDQ packet
* @client: the CMDQ mailbox client
* @pkt: the CMDQ packet
* @size: required CMDQ buffer size
*
* Return: CMDQ packet pointer
* Return: 0 for success; else the error code is returned
*/
struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size);
/**
* cmdq_pkt_destroy() - destroy the CMDQ packet
* @client: the CMDQ mailbox client
* @pkt: the CMDQ packet
*/
void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt);
/**
* cmdq_pkt_write() - append write command to the CMDQ packet
......@@ -173,6 +184,18 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
u16 addr_low, u32 value, u32 mask);
/**
* cmdq_pkt_mem_move() - append memory move command to the CMDQ packet
* @pkt: the CMDQ packet
* @src_addr: source address
* @dst_addr: destination address
*
* Appends a CMDQ command to copy the value found in `src_addr` to `dst_addr`.
*
* Return: 0 for success; else the error code is returned
*/
int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr);
/**
* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
* @pkt: the CMDQ packet
......@@ -183,6 +206,21 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
*/
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
/**
* cmdq_pkt_acquire_event() - append acquire event command to the CMDQ packet
* @pkt: the CMDQ packet
* @event: the desired event to be acquired
*
* User can use cmdq_pkt_acquire_event() as `mutex_lock` and cmdq_pkt_clear_event()
* as `mutex_unlock` to protect some `critical section` instructions between them.
* cmdq_pkt_acquire_event() would wait for event to be cleared.
* After event is cleared by cmdq_pkt_clear_event in other GCE threads,
* cmdq_pkt_acquire_event() would set event and keep executing next instruction.
*
* Return: 0 for success; else the error code is returned
*/
int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event);
/**
* cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
* @pkt: the CMDQ packet
......@@ -248,36 +286,76 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
/**
* cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
* to execute an instruction that change current thread PC to
* a physical address which should contains more instruction.
* cmdq_pkt_poll_addr() - Append blocking POLL command to CMDQ packet
* @pkt: the CMDQ packet
* @addr: the hardware register address
* @value: the specified target register value
* @mask: the specified target register mask
*
* Appends a polling (POLL) command to the CMDQ packet and asks the GCE
* to execute an instruction that checks for the specified `value` (with
* or without `mask`) to appear in the specified hardware register `addr`.
* All GCE threads will be blocked by this instruction.
*
* Return: 0 for success or negative error code
*/
int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask);
/**
* cmdq_pkt_jump_abs() - Append jump command to the CMDQ packet, ask GCE
* to execute an instruction that change current thread
* PC to a absolute physical address which should
* contains more instruction.
* @pkt: the CMDQ packet
* @addr: physical address of target instruction buffer
* @addr: absolute physical address of target instruction buffer
* @shift_pa: shift bits of physical address in CMDQ instruction. This value
* is got by cmdq_get_shift_pa().
*
* Return: 0 for success; else the error code is returned
*/
int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
/* This wrapper has to be removed after all users migrated to jump_abs */
static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
{
return cmdq_pkt_jump_abs(pkt, addr, shift_pa);
}
/**
* cmdq_pkt_finalize() - Append EOC and jump command to pkt.
* cmdq_pkt_jump_rel() - Append jump command to the CMDQ packet, ask GCE
* to execute an instruction that change current thread
* PC to a physical address with relative offset. The
* target address should contains more instruction.
* @pkt: the CMDQ packet
* @offset: relative offset of target instruction buffer from current PC.
* @shift_pa: shift bits of physical address in CMDQ instruction. This value
* is got by cmdq_get_shift_pa().
*
* Return: 0 for success; else the error code is returned
*/
int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa);
/**
* cmdq_pkt_eoc() - Append EOC and ask GCE to generate an IRQ at end of execution
* @pkt: The CMDQ packet
*
* Appends an End Of Code (EOC) command to the CMDQ packet and asks the GCE
* to generate an interrupt at the end of the execution of all commands in
* the pipeline.
* The EOC command is usually appended to the end of the pipeline to notify
* that all commands are done.
*
* Return: 0 for success or negative error number
*/
int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
/**
* cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
* packet and call back at the end of done packet
* cmdq_pkt_finalize() - Append EOC and jump command to pkt.
* @pkt: the CMDQ packet
*
* Return: 0 for success; else the error code is returned
*
* Trigger CMDQ to asynchronously execute the CMDQ packet and call back
* at the end of done packet. Note that this is an ASYNC function. When the
* function returned, it may or may not be finished.
*/
int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
#else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
......@@ -294,12 +372,12 @@ static inline struct cmdq_client *cmdq_mbox_create(struct device *dev, int index
static inline void cmdq_mbox_destroy(struct cmdq_client *client) { }
static inline struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
static inline int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
{
return ERR_PTR(-EINVAL);
return -EINVAL;
}
static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
static inline void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt) { }
static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
{
......@@ -374,17 +452,32 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
return -EINVAL;
}
static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
static inline int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
{
return -EINVAL;
}
static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
static inline int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
{
return -EINVAL;
}
static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
{
return -EINVAL;
}
static inline int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
{
return -EINVAL;
}
static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
{
return -EINVAL;
}
static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
return -EINVAL;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment