diff options
Diffstat (limited to 'drivers/soc/mediatek')
-rw-r--r-- | drivers/soc/mediatek/mtk-cmdq-helper.c | 158 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-mutex.c | 42 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-socinfo.c | 14 |
3 files changed, 174 insertions, 40 deletions
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 0b2e5690da..046522664d 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -12,6 +12,8 @@ #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 0 @@ -56,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); @@ -106,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, @@ -129,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); @@ -300,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} }; @@ -316,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} }; @@ -381,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 = {}; @@ -393,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_ABSOLUTE; - inst.value = addr >> - cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan); + 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) { @@ -427,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"); diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index 73c256d395..01b129caf1 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -496,6 +496,40 @@ 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_TCC0] = MT8195_MUTEX_MOD_MDP_TCC0, + [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 +769,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 +1130,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 }, diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index 42572e8c15..74672a9d6d 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -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) |