mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2025-09-26 19:04:54 +00:00
1959 lines
56 KiB
C
1959 lines
56 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2021 MediaTek Inc.
|
|
* Author: Chris-YC Chen <chris-yc.chen@mediatek.com>
|
|
*/
|
|
|
|
#include <linux/component.h>
|
|
#include <linux/dma-mapping.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <cmdq-util.h>
|
|
|
|
#include "mtk-mml-rdma-golden.h"
|
|
#include "mtk-mml-buf.h"
|
|
#include "mtk-mml-color.h"
|
|
#include "mtk-mml-core.h"
|
|
#include "mtk-mml-driver.h"
|
|
#include "tile_driver.h"
|
|
#include "mtk-mml-tile.h"
|
|
#include "tile_mdp_func.h"
|
|
#include "mtk-mml-mmp.h"
|
|
|
|
#ifdef CONFIG_MTK_SMI_EXT
|
|
#include "smi_public.h"
|
|
#endif
|
|
|
|
#define RDMA_EN 0x000
|
|
#define RDMA_UFBDC_DCM_EN 0x004
|
|
#define RDMA_RESET 0x008
|
|
#define RDMA_INTERRUPT_ENABLE 0x010
|
|
#define RDMA_INTERRUPT_STATUS 0x018
|
|
#define RDMA_CON 0x020
|
|
#define RDMA_SHADOW_CTRL 0x024
|
|
#define RDMA_GMCIF_CON 0x028
|
|
#define RDMA_SRC_CON 0x030
|
|
#define RDMA_COMP_CON 0x038
|
|
#define RDMA_PVRIC_CRYUVAL_0 0x040
|
|
#define RDMA_PVRIC_CRYUVAL_1 0x048
|
|
#define RDMA_PVRIC_CRCH0123VAL_0 0x050
|
|
#define RDMA_PVRIC_CRCH0123VAL_1 0x058
|
|
#define RDMA_MF_BKGD_SIZE_IN_BYTE 0x060
|
|
#define RDMA_MF_BKGD_SIZE_IN_PXL 0x068
|
|
#define RDMA_MF_SRC_SIZE 0x070
|
|
#define RDMA_MF_CLIP_SIZE 0x078
|
|
#define RDMA_MF_OFFSET_1 0x080
|
|
#define RDMA_SF_BKGD_SIZE_IN_BYTE 0x090
|
|
#define RDMA_MF_BKGD_H_SIZE_IN_PXL 0x098
|
|
#define RDMA_VC1_RANGE 0x0f0
|
|
#define RDMA_SRC_OFFSET_0 0x118
|
|
#define RDMA_SRC_OFFSET_1 0x120
|
|
#define RDMA_SRC_OFFSET_2 0x128
|
|
#define RDMA_SRC_OFFSET_WP 0x148
|
|
#define RDMA_SRC_OFFSET_HP 0x150
|
|
#define RDMA_TRANSFORM_0 0x200
|
|
#define RDMA_DMABUF_CON_0 0x240
|
|
#define RDMA_URGENT_TH_CON_0 0x244
|
|
#define RDMA_ULTRA_TH_CON_0 0x248
|
|
#define RDMA_PREULTRA_TH_CON_0 0x250
|
|
#define RDMA_DMABUF_CON_1 0x254
|
|
#define RDMA_URGENT_TH_CON_1 0x258
|
|
#define RDMA_ULTRA_TH_CON_1 0x260
|
|
#define RDMA_PREULTRA_TH_CON_1 0x264
|
|
#define RDMA_DMABUF_CON_2 0x268
|
|
#define RDMA_URGENT_TH_CON_2 0x270
|
|
#define RDMA_ULTRA_TH_CON_2 0x274
|
|
#define RDMA_PREULTRA_TH_CON_2 0x278
|
|
#define RDMA_DMABUF_CON_3 0x280
|
|
#define RDMA_URGENT_TH_CON_3 0x284
|
|
#define RDMA_ULTRA_TH_CON_3 0x288
|
|
#define RDMA_PREULTRA_TH_CON_3 0x290
|
|
#define RDMA_DITHER_CON 0x2a0
|
|
#define RDMA_RESV_DUMMY_0 0x2a8
|
|
#define RDMA_UNCOMP_MON 0x2c0
|
|
#define RDMA_COMP_MON 0x2c8
|
|
#define RDMA_CHKS_EXTR 0x300
|
|
#define RDMA_CHKS_INTW 0x308
|
|
#define RDMA_CHKS_INTR 0x310
|
|
#define RDMA_CHKS_ROTO 0x318
|
|
#define RDMA_CHKS_SRIY 0x320
|
|
#define RDMA_CHKS_SRIU 0x328
|
|
#define RDMA_CHKS_SRIV 0x330
|
|
#define RDMA_CHKS_SROY 0x338
|
|
#define RDMA_CHKS_SROU 0x340
|
|
#define RDMA_CHKS_SROV 0x348
|
|
#define RDMA_CHKS_VUPI 0x350
|
|
#define RDMA_CHKS_VUPO 0x358
|
|
#define RDMA_DEBUG_CON 0x380
|
|
#define RDMA_MON_STA_0 0x400
|
|
#define RDMA_MON_STA_1 0x408
|
|
#define RDMA_MON_STA_2 0x410
|
|
#define RDMA_MON_STA_3 0x418
|
|
#define RDMA_MON_STA_4 0x420
|
|
#define RDMA_MON_STA_5 0x428
|
|
#define RDMA_MON_STA_6 0x430
|
|
#define RDMA_MON_STA_7 0x438
|
|
#define RDMA_MON_STA_8 0x440
|
|
#define RDMA_MON_STA_9 0x448
|
|
#define RDMA_MON_STA_10 0x450
|
|
#define RDMA_MON_STA_11 0x458
|
|
#define RDMA_MON_STA_12 0x460
|
|
#define RDMA_MON_STA_13 0x468
|
|
#define RDMA_MON_STA_14 0x470
|
|
#define RDMA_MON_STA_15 0x478
|
|
#define RDMA_MON_STA_16 0x480
|
|
#define RDMA_MON_STA_17 0x488
|
|
#define RDMA_MON_STA_18 0x490
|
|
#define RDMA_MON_STA_19 0x498
|
|
#define RDMA_MON_STA_20 0x4a0
|
|
#define RDMA_MON_STA_21 0x4a8
|
|
#define RDMA_MON_STA_22 0x4b0
|
|
#define RDMA_MON_STA_23 0x4b8
|
|
#define RDMA_MON_STA_24 0x4c0
|
|
#define RDMA_MON_STA_25 0x4c8
|
|
#define RDMA_MON_STA_26 0x4d0
|
|
#define RDMA_MON_STA_27 0x4d8
|
|
#define RDMA_MON_STA_28 0x4e0
|
|
#define RDMA_SRC_BASE_0 0xf00
|
|
#define RDMA_SRC_BASE_1 0xf08
|
|
#define RDMA_SRC_BASE_2 0xf10
|
|
#define RDMA_UFO_DEC_LENGTH_BASE_Y 0xf20
|
|
#define RDMA_UFO_DEC_LENGTH_BASE_C 0xf28
|
|
#define RDMA_SRC_BASE_0_MSB 0xf30
|
|
#define RDMA_SRC_BASE_1_MSB 0xf34
|
|
#define RDMA_SRC_BASE_2_MSB 0xf38
|
|
#define RDMA_UFO_DEC_LENGTH_BASE_Y_MSB 0xf3c
|
|
#define RDMA_UFO_DEC_LENGTH_BASE_C_MSB 0xf40
|
|
#define RDMA_SRC_OFFSET_0_MSB 0xf44
|
|
#define RDMA_SRC_OFFSET_1_MSB 0xf48
|
|
#define RDMA_SRC_OFFSET_2_MSB 0xf4c
|
|
#define RDMA_AFBC_PAYLOAD_OST 0xf50
|
|
|
|
enum cpr_reg_idx {
|
|
/* CMDQ_CPR_PREBUILT_REG_CNT = 20 */
|
|
CPR_RDMA_SRC_OFFSET_0 = 0,
|
|
CPR_RDMA_SRC_OFFSET_1,
|
|
CPR_RDMA_SRC_OFFSET_2,
|
|
CPR_RDMA_SRC_OFFSET_WP,
|
|
CPR_RDMA_SRC_OFFSET_HP,
|
|
CPR_RDMA_TRANSFORM_0,
|
|
CPR_RDMA_SRC_BASE_0,
|
|
CPR_RDMA_SRC_BASE_1,
|
|
CPR_RDMA_SRC_BASE_2,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_Y,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_C,
|
|
CPR_RDMA_SRC_BASE_0_MSB,
|
|
CPR_RDMA_SRC_BASE_1_MSB,
|
|
CPR_RDMA_SRC_BASE_2_MSB,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_Y_MSB,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_C_MSB,
|
|
CPR_RDMA_SRC_OFFSET_0_MSB,
|
|
CPR_RDMA_SRC_OFFSET_1_MSB,
|
|
CPR_RDMA_SRC_OFFSET_2_MSB,
|
|
CPR_RDMA_AFBC_PAYLOAD_OST,
|
|
/* CMDQ_CPR_PREBUILT_EXT_REG_CNT = 30 */
|
|
CPR_RDMA_CON,
|
|
CPR_RDMA_GMCIF_CON,
|
|
CPR_RDMA_SRC_CON,
|
|
CPR_RDMA_COMP_CON,
|
|
CPR_RDMA_MF_BKGD_SIZE_IN_BYTE,
|
|
CPR_RDMA_MF_BKGD_SIZE_IN_PXL,
|
|
CPR_RDMA_MF_SRC_SIZE,
|
|
CPR_RDMA_MF_CLIP_SIZE,
|
|
CPR_RDMA_MF_OFFSET_1,
|
|
CPR_RDMA_SF_BKGD_SIZE_IN_BYTE,
|
|
CPR_RDMA_MF_BKGD_H_SIZE_IN_PXL,
|
|
CPR_RDMA_DMABUF_CON_0,
|
|
CPR_RDMA_URGENT_TH_CON_0,
|
|
CPR_RDMA_ULTRA_TH_CON_0,
|
|
CPR_RDMA_PREULTRA_TH_CON_0,
|
|
CPR_RDMA_DMABUF_CON_1,
|
|
CPR_RDMA_URGENT_TH_CON_1,
|
|
CPR_RDMA_ULTRA_TH_CON_1,
|
|
CPR_RDMA_PREULTRA_TH_CON_1,
|
|
CPR_RDMA_DMABUF_CON_2,
|
|
CPR_RDMA_URGENT_TH_CON_2,
|
|
CPR_RDMA_ULTRA_TH_CON_2,
|
|
CPR_RDMA_PREULTRA_TH_CON_2,
|
|
CPR_RDMA_DMABUF_CON_3,
|
|
CPR_RDMA_URGENT_TH_CON_3,
|
|
CPR_RDMA_ULTRA_TH_CON_3,
|
|
CPR_RDMA_PREULTRA_TH_CON_3,
|
|
CPR_RDMA_DITHER_CON,
|
|
|
|
CPR_RDMA_COUNT, /* 50 */
|
|
};
|
|
|
|
#define RDMA_CPR_PREBUILT(mod, pipe, index) \
|
|
((index) < CMDQ_CPR_PREBUILT_REG_CNT ? \
|
|
CMDQ_CPR_PREBUILT(mod, pipe, index) : \
|
|
CMDQ_CPR_PREBUILT_EXT(mod, pipe, (index) - CMDQ_CPR_PREBUILT_REG_CNT))
|
|
|
|
static const dma_addr_t reg_idx_to_ofst[CPR_RDMA_COUNT] = {
|
|
[CPR_RDMA_SRC_OFFSET_0] = RDMA_SRC_OFFSET_0,
|
|
[CPR_RDMA_SRC_OFFSET_1] = RDMA_SRC_OFFSET_1,
|
|
[CPR_RDMA_SRC_OFFSET_2] = RDMA_SRC_OFFSET_2,
|
|
[CPR_RDMA_SRC_OFFSET_WP] = RDMA_SRC_OFFSET_WP,
|
|
[CPR_RDMA_SRC_OFFSET_HP] = RDMA_SRC_OFFSET_HP,
|
|
[CPR_RDMA_TRANSFORM_0] = RDMA_TRANSFORM_0,
|
|
[CPR_RDMA_SRC_BASE_0] = RDMA_SRC_BASE_0,
|
|
[CPR_RDMA_SRC_BASE_1] = RDMA_SRC_BASE_1,
|
|
[CPR_RDMA_SRC_BASE_2] = RDMA_SRC_BASE_2,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_Y] = RDMA_UFO_DEC_LENGTH_BASE_Y,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_C] = RDMA_UFO_DEC_LENGTH_BASE_C,
|
|
[CPR_RDMA_SRC_BASE_0_MSB] = RDMA_SRC_BASE_0_MSB,
|
|
[CPR_RDMA_SRC_BASE_1_MSB] = RDMA_SRC_BASE_1_MSB,
|
|
[CPR_RDMA_SRC_BASE_2_MSB] = RDMA_SRC_BASE_2_MSB,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_Y_MSB] = RDMA_UFO_DEC_LENGTH_BASE_Y_MSB,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_C_MSB] = RDMA_UFO_DEC_LENGTH_BASE_C_MSB,
|
|
[CPR_RDMA_SRC_OFFSET_0_MSB] = RDMA_SRC_OFFSET_0_MSB,
|
|
[CPR_RDMA_SRC_OFFSET_1_MSB] = RDMA_SRC_OFFSET_1_MSB,
|
|
[CPR_RDMA_SRC_OFFSET_2_MSB] = RDMA_SRC_OFFSET_2_MSB,
|
|
[CPR_RDMA_AFBC_PAYLOAD_OST] = RDMA_AFBC_PAYLOAD_OST,
|
|
|
|
[CPR_RDMA_CON] = RDMA_CON,
|
|
[CPR_RDMA_GMCIF_CON] = RDMA_GMCIF_CON,
|
|
[CPR_RDMA_SRC_CON] = RDMA_SRC_CON,
|
|
[CPR_RDMA_COMP_CON] = RDMA_COMP_CON,
|
|
[CPR_RDMA_MF_BKGD_SIZE_IN_BYTE] = RDMA_MF_BKGD_SIZE_IN_BYTE,
|
|
[CPR_RDMA_MF_BKGD_SIZE_IN_PXL] = RDMA_MF_BKGD_SIZE_IN_PXL,
|
|
[CPR_RDMA_MF_SRC_SIZE] = RDMA_MF_SRC_SIZE,
|
|
[CPR_RDMA_MF_CLIP_SIZE] = RDMA_MF_CLIP_SIZE,
|
|
[CPR_RDMA_MF_OFFSET_1] = RDMA_MF_OFFSET_1,
|
|
[CPR_RDMA_SF_BKGD_SIZE_IN_BYTE] = RDMA_SF_BKGD_SIZE_IN_BYTE,
|
|
[CPR_RDMA_MF_BKGD_H_SIZE_IN_PXL] = RDMA_MF_BKGD_H_SIZE_IN_PXL,
|
|
[CPR_RDMA_DMABUF_CON_0] = RDMA_DMABUF_CON_0,
|
|
[CPR_RDMA_URGENT_TH_CON_0] = RDMA_URGENT_TH_CON_0,
|
|
[CPR_RDMA_ULTRA_TH_CON_0] = RDMA_ULTRA_TH_CON_0,
|
|
[CPR_RDMA_PREULTRA_TH_CON_0] = RDMA_PREULTRA_TH_CON_0,
|
|
[CPR_RDMA_DMABUF_CON_1] = RDMA_DMABUF_CON_1,
|
|
[CPR_RDMA_URGENT_TH_CON_1] = RDMA_URGENT_TH_CON_1,
|
|
[CPR_RDMA_ULTRA_TH_CON_1] = RDMA_ULTRA_TH_CON_1,
|
|
[CPR_RDMA_PREULTRA_TH_CON_1] = RDMA_PREULTRA_TH_CON_1,
|
|
[CPR_RDMA_DMABUF_CON_2] = RDMA_DMABUF_CON_2,
|
|
[CPR_RDMA_URGENT_TH_CON_2] = RDMA_URGENT_TH_CON_2,
|
|
[CPR_RDMA_ULTRA_TH_CON_2] = RDMA_ULTRA_TH_CON_2,
|
|
[CPR_RDMA_PREULTRA_TH_CON_2] = RDMA_PREULTRA_TH_CON_2,
|
|
[CPR_RDMA_DMABUF_CON_3] = RDMA_DMABUF_CON_3,
|
|
[CPR_RDMA_URGENT_TH_CON_3] = RDMA_URGENT_TH_CON_3,
|
|
[CPR_RDMA_ULTRA_TH_CON_3] = RDMA_ULTRA_TH_CON_3,
|
|
[CPR_RDMA_PREULTRA_TH_CON_3] = RDMA_PREULTRA_TH_CON_3,
|
|
[CPR_RDMA_DITHER_CON] = RDMA_DITHER_CON,
|
|
};
|
|
|
|
static const enum cpr_reg_idx lsb_to_msb[CPR_RDMA_COUNT] = {
|
|
[CPR_RDMA_SRC_OFFSET_0] = CPR_RDMA_SRC_OFFSET_0_MSB,
|
|
[CPR_RDMA_SRC_OFFSET_1] = CPR_RDMA_SRC_OFFSET_1_MSB,
|
|
[CPR_RDMA_SRC_OFFSET_2] = CPR_RDMA_SRC_OFFSET_2_MSB,
|
|
[CPR_RDMA_SRC_BASE_0] = CPR_RDMA_SRC_BASE_0_MSB,
|
|
[CPR_RDMA_SRC_BASE_1] = CPR_RDMA_SRC_BASE_1_MSB,
|
|
[CPR_RDMA_SRC_BASE_2] = CPR_RDMA_SRC_BASE_2_MSB,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_Y] = CPR_RDMA_UFO_DEC_LENGTH_BASE_Y_MSB,
|
|
[CPR_RDMA_UFO_DEC_LENGTH_BASE_C] = CPR_RDMA_UFO_DEC_LENGTH_BASE_C_MSB,
|
|
};
|
|
|
|
static const enum cpr_reg_idx rdma_dmabuf[] = {
|
|
CPR_RDMA_DMABUF_CON_0,
|
|
CPR_RDMA_DMABUF_CON_1,
|
|
CPR_RDMA_DMABUF_CON_2,
|
|
CPR_RDMA_DMABUF_CON_3,
|
|
};
|
|
|
|
static const enum cpr_reg_idx rdma_urgent_th[] = {
|
|
CPR_RDMA_URGENT_TH_CON_0,
|
|
CPR_RDMA_URGENT_TH_CON_1,
|
|
CPR_RDMA_URGENT_TH_CON_2,
|
|
CPR_RDMA_URGENT_TH_CON_3,
|
|
};
|
|
|
|
static const enum cpr_reg_idx rdma_ultra_th[] = {
|
|
CPR_RDMA_ULTRA_TH_CON_0,
|
|
CPR_RDMA_ULTRA_TH_CON_1,
|
|
CPR_RDMA_ULTRA_TH_CON_2,
|
|
CPR_RDMA_ULTRA_TH_CON_3,
|
|
};
|
|
|
|
static const enum cpr_reg_idx rdma_preultra_th[] = {
|
|
CPR_RDMA_PREULTRA_TH_CON_0,
|
|
CPR_RDMA_PREULTRA_TH_CON_1,
|
|
CPR_RDMA_PREULTRA_TH_CON_2,
|
|
CPR_RDMA_PREULTRA_TH_CON_3,
|
|
};
|
|
|
|
/* SMI offset */
|
|
#define SMI_LARB_NON_SEC_CON 0x380
|
|
|
|
enum rdma_label {
|
|
RDMA_LABEL_BASE_0 = 0,
|
|
RDMA_LABEL_BASE_0_MSB,
|
|
RDMA_LABEL_BASE_1,
|
|
RDMA_LABEL_BASE_1_MSB,
|
|
RDMA_LABEL_BASE_2,
|
|
RDMA_LABEL_BASE_2_MSB,
|
|
RDMA_LABEL_UFO_DEC_BASE_Y,
|
|
RDMA_LABEL_UFO_DEC_BASE_Y_MSB,
|
|
RDMA_LABEL_UFO_DEC_BASE_C,
|
|
RDMA_LABEL_UFO_DEC_BASE_C_MSB,
|
|
RDMA_LABEL_TOTAL
|
|
};
|
|
|
|
static s32 rdma_write(struct cmdq_pkt *pkt, phys_addr_t base_pa, u8 hw_pipe,
|
|
enum cpr_reg_idx idx, u32 value, bool write_sec)
|
|
{
|
|
if (write_sec) {
|
|
return cmdq_pkt_assign_command(pkt,
|
|
RDMA_CPR_PREBUILT(CMDQ_PREBUILT_MML, hw_pipe, idx), value);
|
|
}
|
|
/* else */
|
|
return cmdq_pkt_write(pkt, NULL,
|
|
base_pa + reg_idx_to_ofst[idx], value, U32_MAX);
|
|
}
|
|
|
|
static s32 rdma_write_ofst(struct cmdq_pkt *pkt, phys_addr_t base_pa, u8 hw_pipe,
|
|
enum cpr_reg_idx lsb_idx, u64 value, bool write_sec)
|
|
{
|
|
enum cpr_reg_idx msb_idx;
|
|
s32 ret;
|
|
|
|
if (unlikely(lsb_idx < 0))
|
|
return -EFAULT;
|
|
|
|
msb_idx = lsb_to_msb[lsb_idx];
|
|
|
|
ret = rdma_write(pkt, base_pa, hw_pipe,
|
|
lsb_idx, value & GENMASK_ULL(31, 0), write_sec);
|
|
if (ret)
|
|
return ret;
|
|
ret = rdma_write(pkt, base_pa, hw_pipe,
|
|
msb_idx, value >> 32, write_sec);
|
|
return ret;
|
|
}
|
|
|
|
static s32 rdma_write_reuse(struct cmdq_pkt *pkt, phys_addr_t base_pa, u8 hw_pipe,
|
|
enum cpr_reg_idx idx, u32 value,
|
|
struct mml_task_reuse *reuse,
|
|
struct mml_pipe_cache *cache,
|
|
u16 *label_idx, bool write_sec)
|
|
{
|
|
if (write_sec) {
|
|
return mml_assign(pkt,
|
|
RDMA_CPR_PREBUILT(CMDQ_PREBUILT_MML, hw_pipe, idx), value,
|
|
reuse, cache, label_idx);
|
|
}
|
|
/* else */
|
|
return mml_write(pkt,
|
|
base_pa + reg_idx_to_ofst[idx], value, U32_MAX,
|
|
reuse, cache, label_idx);
|
|
}
|
|
|
|
static s32 rdma_write_addr(struct cmdq_pkt *pkt, phys_addr_t base_pa, u8 hw_pipe,
|
|
enum cpr_reg_idx lsb_idx, u64 value,
|
|
struct mml_task_reuse *reuse,
|
|
struct mml_pipe_cache *cache,
|
|
u16 *label_idx, bool write_sec)
|
|
{
|
|
enum cpr_reg_idx msb_idx;
|
|
s32 ret;
|
|
|
|
if (unlikely(lsb_idx < 0))
|
|
return -EFAULT;
|
|
|
|
msb_idx = lsb_to_msb[lsb_idx];
|
|
|
|
ret = rdma_write_reuse(pkt, base_pa, hw_pipe,
|
|
lsb_idx, value & GENMASK_ULL(31, 0),
|
|
reuse, cache, label_idx, write_sec);
|
|
if (ret)
|
|
return ret;
|
|
ret = rdma_write_reuse(pkt, base_pa, hw_pipe,
|
|
msb_idx, value >> 32,
|
|
reuse, cache, label_idx + 1, write_sec);
|
|
return ret;
|
|
}
|
|
|
|
static void rdma_update_addr(struct mml_task_reuse *reuse,
|
|
u16 label_lsb, u16 label_msb, u64 value)
|
|
{
|
|
mml_update(reuse, label_lsb, value & GENMASK_ULL(31, 0));
|
|
mml_update(reuse, label_msb, value >> 32);
|
|
}
|
|
|
|
enum rdma_golden_fmt {
|
|
GOLDEN_FMT_ARGB,
|
|
GOLDEN_FMT_RGB,
|
|
GOLDEN_FMT_YUV420,
|
|
GOLDEN_FMT_TOTAL
|
|
};
|
|
|
|
struct rdma_data {
|
|
u32 tile_width;
|
|
u8 rb_swap; /* version for rb channel swap behavior */
|
|
bool write_sec_reg;
|
|
|
|
/* threshold golden setting for racing mode */
|
|
struct rdma_golden golden[GOLDEN_FMT_TOTAL];
|
|
};
|
|
|
|
static const struct rdma_data mt6893_rdma_data = {
|
|
.tile_width = 640,
|
|
.rb_swap = 1,
|
|
};
|
|
|
|
static const struct rdma_data mt6983_rdma_data = {
|
|
.tile_width = 1696,
|
|
.rb_swap = 1,
|
|
.write_sec_reg = true,
|
|
.golden = {
|
|
[GOLDEN_FMT_ARGB] = {
|
|
.cnt = ARRAY_SIZE(th_argb_mt6983),
|
|
.settings = th_argb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_RGB] = {
|
|
.cnt = ARRAY_SIZE(th_rgb_mt6983),
|
|
.settings = th_rgb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_YUV420] = {
|
|
.cnt = ARRAY_SIZE(th_yuv420_mt6983),
|
|
.settings = th_yuv420_mt6983,
|
|
},
|
|
},
|
|
};
|
|
|
|
static const struct rdma_data mt6879_rdma_data = {
|
|
.tile_width = 1440,
|
|
.rb_swap = 1,
|
|
.write_sec_reg = true,
|
|
};
|
|
|
|
static const struct rdma_data mt6895_rdma0_data = {
|
|
.tile_width = 1344,
|
|
.rb_swap = 1,
|
|
.write_sec_reg = true,
|
|
.golden = {
|
|
[GOLDEN_FMT_ARGB] = {
|
|
.cnt = ARRAY_SIZE(th_argb_mt6983),
|
|
.settings = th_argb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_RGB] = {
|
|
.cnt = ARRAY_SIZE(th_rgb_mt6983),
|
|
.settings = th_rgb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_YUV420] = {
|
|
.cnt = ARRAY_SIZE(th_yuv420_mt6983),
|
|
.settings = th_yuv420_mt6983,
|
|
},
|
|
},
|
|
};
|
|
|
|
static const struct rdma_data mt6895_rdma1_data = {
|
|
.tile_width = 896,
|
|
.rb_swap = 1,
|
|
.write_sec_reg = true,
|
|
.golden = {
|
|
[GOLDEN_FMT_ARGB] = {
|
|
.cnt = ARRAY_SIZE(th_argb_mt6983),
|
|
.settings = th_argb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_RGB] = {
|
|
.cnt = ARRAY_SIZE(th_rgb_mt6983),
|
|
.settings = th_rgb_mt6983,
|
|
},
|
|
[GOLDEN_FMT_YUV420] = {
|
|
.cnt = ARRAY_SIZE(th_yuv420_mt6983),
|
|
.settings = th_yuv420_mt6983,
|
|
},
|
|
},
|
|
};
|
|
|
|
struct mml_comp_rdma {
|
|
struct mml_comp comp;
|
|
const struct rdma_data *data;
|
|
struct device *dev; /* for dmabuf to iova */
|
|
|
|
u16 event_eof;
|
|
|
|
/* smi register to config sram/dram mode */
|
|
phys_addr_t smi_larb_con;
|
|
|
|
u32 sram_cnt;
|
|
u64 sram_pa;
|
|
struct mutex sram_mutex;
|
|
};
|
|
|
|
struct rdma_frame_data {
|
|
u8 enable_ufo;
|
|
u8 hw_fmt;
|
|
u8 swap;
|
|
u8 blk;
|
|
u8 lb_2b_mode;
|
|
u8 field;
|
|
u8 blk_10bit;
|
|
u8 blk_tile;
|
|
u8 color_tran;
|
|
u8 matrix_sel;
|
|
u32 bits_per_pixel_y;
|
|
u32 bits_per_pixel_uv;
|
|
u32 hor_shift_uv;
|
|
u32 ver_shift_uv;
|
|
u32 vdo_blk_shift_w;
|
|
u32 vdo_blk_height;
|
|
u32 vdo_blk_shift_h;
|
|
u32 pixel_acc; /* pixel accumulation */
|
|
u32 datasize; /* qos data size in bytes */
|
|
u16 crop_off_l; /* crop offset left */
|
|
u16 crop_off_t; /* crop offset top */
|
|
|
|
/* array of indices to one of entry in cache entry list,
|
|
* use in reuse command
|
|
*/
|
|
u16 labels[RDMA_LABEL_TOTAL];
|
|
};
|
|
|
|
#define rdma_frm_data(i) ((struct rdma_frame_data *)(i->data))
|
|
|
|
static inline struct mml_comp_rdma *comp_to_rdma(struct mml_comp *comp)
|
|
{
|
|
return container_of(comp, struct mml_comp_rdma, comp);
|
|
}
|
|
|
|
static s32 rdma_config_read(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg)
|
|
{
|
|
ccfg->data = kzalloc(sizeof(struct rdma_frame_data), GFP_KERNEL);
|
|
return 0;
|
|
}
|
|
|
|
static s32 rdma_buf_map(struct mml_comp *comp, struct mml_task *task,
|
|
const struct mml_path_node *node)
|
|
{
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
s32 ret = 0;
|
|
|
|
mml_trace_ex_begin("%s", __func__);
|
|
|
|
if (unlikely(task->config->info.mode == MML_MODE_SRAM_READ)) {
|
|
mutex_lock(&rdma->sram_mutex);
|
|
if (!rdma->sram_cnt)
|
|
rdma->sram_pa = (u64)mml_sram_get(task->config->mml);
|
|
rdma->sram_cnt++;
|
|
mutex_unlock(&rdma->sram_mutex);
|
|
|
|
mml_msg("%s comp %u sram pa %#llx",
|
|
__func__, comp->id, rdma->sram_pa);
|
|
} else {
|
|
/* get iova */
|
|
ret = mml_buf_iova_get(rdma->dev, &task->buf.src);
|
|
if (ret < 0)
|
|
mml_err("%s iova fail %d", __func__, ret);
|
|
|
|
mml_msg("%s comp %u iova %#11llx (%u) %#11llx (%u) %#11llx (%u)",
|
|
__func__, comp->id,
|
|
task->buf.src.dma[0].iova,
|
|
task->buf.src.size[0],
|
|
task->buf.src.dma[1].iova,
|
|
task->buf.src.size[1],
|
|
task->buf.src.dma[2].iova,
|
|
task->buf.src.size[2]);
|
|
|
|
mml_mmp(buf_map, MMPROFILE_FLAG_PULSE,
|
|
((u64)task->job.jobid << 16) | comp->id,
|
|
(unsigned long)task->buf.src.dma[0].iova);
|
|
}
|
|
|
|
mml_trace_ex_end();
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void rdma_buf_unmap(struct mml_comp *comp, struct mml_task *task,
|
|
const struct mml_path_node *node)
|
|
{
|
|
struct mml_comp_rdma *rdma;
|
|
|
|
if (unlikely(task->config->info.mode == MML_MODE_SRAM_READ)) {
|
|
rdma = comp_to_rdma(comp);
|
|
|
|
mutex_lock(&rdma->sram_mutex);
|
|
rdma->sram_cnt--;
|
|
if (rdma->sram_cnt == 0)
|
|
mml_sram_put(task->config->mml);
|
|
mutex_unlock(&rdma->sram_mutex);
|
|
}
|
|
}
|
|
|
|
static s32 rdma_tile_prepare(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg,
|
|
struct tile_func_block *func,
|
|
union mml_tile_data *data)
|
|
{
|
|
struct mml_frame_config *cfg = task->config;
|
|
struct mml_frame_data *src = &cfg->info.src;
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
|
|
data->rdma.src_fmt = src->format;
|
|
data->rdma.blk_shift_w = MML_FMT_BLOCK(src->format) ? 4 : 0;
|
|
data->rdma.blk_shift_h = MML_FMT_BLOCK(src->format) ? 5 : 0;
|
|
data->rdma.max_width = rdma->data->tile_width;
|
|
|
|
/* RDMA support crop capability */
|
|
func->type = TILE_TYPE_RDMA | TILE_TYPE_CROP_EN;
|
|
func->init_func = tile_rdma_init;
|
|
func->for_func = tile_rdma_for;
|
|
func->back_func = tile_rdma_back;
|
|
func->data = data;
|
|
func->enable_flag = true;
|
|
|
|
func->full_size_x_in = src->width;
|
|
func->full_size_y_in = src->height;
|
|
func->full_size_x_out = src->width;
|
|
func->full_size_y_out = src->height;
|
|
|
|
if (cfg->info.dest_cnt == 1 ||
|
|
!memcmp(&cfg->info.dest[0].crop,
|
|
&cfg->info.dest[1].crop,
|
|
sizeof(struct mml_crop))) {
|
|
struct mml_frame_dest *dest = &cfg->info.dest[0];
|
|
u32 in_crop_w, in_crop_h;
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
|
|
data->rdma.crop = dest->crop.r;
|
|
|
|
in_crop_w = dest->crop.r.width;
|
|
in_crop_h = dest->crop.r.height;
|
|
if (in_crop_w + dest->crop.r.left > src->width)
|
|
in_crop_w = src->width - dest->crop.r.left;
|
|
if (in_crop_h + dest->crop.r.top > src->height)
|
|
in_crop_h = src->height - dest->crop.r.top;
|
|
|
|
if (dest->crop.r.width != src->width ||
|
|
dest->crop.r.height != src->height) {
|
|
func->full_size_x_out = in_crop_w;
|
|
func->full_size_y_out = in_crop_h;
|
|
}
|
|
|
|
rdma_frm->crop_off_l = data->rdma.crop.left;
|
|
rdma_frm->crop_off_t = data->rdma.crop.top;
|
|
} else {
|
|
data->rdma.crop.left = 0;
|
|
data->rdma.crop.top = 0;
|
|
data->rdma.crop.width = src->width;
|
|
data->rdma.crop.height = src->height;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const struct mml_comp_tile_ops rdma_tile_ops = {
|
|
.prepare = rdma_tile_prepare,
|
|
};
|
|
|
|
static u32 rdma_get_label_count(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg)
|
|
{
|
|
return RDMA_LABEL_TOTAL;
|
|
}
|
|
|
|
static void rdma_color_fmt(struct mml_frame_config *cfg,
|
|
struct rdma_frame_data *rdma_frm)
|
|
{
|
|
u32 fmt = cfg->info.src.format;
|
|
u16 profile_in = cfg->info.src.profile;
|
|
|
|
rdma_frm->color_tran = 0;
|
|
rdma_frm->matrix_sel = 15;
|
|
|
|
rdma_frm->enable_ufo = MML_FMT_UFO(fmt);
|
|
rdma_frm->hw_fmt = MML_FMT_HW_FORMAT(fmt);
|
|
rdma_frm->swap = MML_FMT_SWAP(fmt);
|
|
rdma_frm->blk = MML_FMT_BLOCK(fmt);
|
|
rdma_frm->lb_2b_mode = rdma_frm->blk ? 0 : 1;
|
|
rdma_frm->field = MML_FMT_INTERLACED(fmt);
|
|
rdma_frm->blk_10bit = MML_FMT_10BIT_PACKED(fmt);
|
|
rdma_frm->blk_tile = MML_FMT_10BIT_TILE(fmt);
|
|
|
|
switch (fmt) {
|
|
case MML_FMT_GREY:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_RGB565:
|
|
case MML_FMT_BGR565:
|
|
rdma_frm->bits_per_pixel_y = 16;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
rdma_frm->color_tran = 1;
|
|
break;
|
|
case MML_FMT_RGB888:
|
|
case MML_FMT_BGR888:
|
|
rdma_frm->bits_per_pixel_y = 24;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
rdma_frm->color_tran = 1;
|
|
break;
|
|
case MML_FMT_RGBA8888:
|
|
case MML_FMT_BGRA8888:
|
|
case MML_FMT_ARGB8888:
|
|
case MML_FMT_ABGR8888:
|
|
case MML_FMT_RGBA1010102:
|
|
case MML_FMT_BGRA1010102:
|
|
case MML_FMT_RGBA8888_AFBC:
|
|
case MML_FMT_BGRA8888_AFBC:
|
|
case MML_FMT_RGBA1010102_AFBC:
|
|
case MML_FMT_BGRA1010102_AFBC:
|
|
rdma_frm->bits_per_pixel_y = 32;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
rdma_frm->color_tran = 1;
|
|
break;
|
|
case MML_FMT_UYVY:
|
|
case MML_FMT_VYUY:
|
|
case MML_FMT_YUYV:
|
|
case MML_FMT_YVYU:
|
|
rdma_frm->bits_per_pixel_y = 16;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_I420:
|
|
case MML_FMT_YV12:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 8;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_I422:
|
|
case MML_FMT_YV16:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 8;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_I444:
|
|
case MML_FMT_YV24:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 8;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_NV12:
|
|
case MML_FMT_NV21:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 16;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_YUV420_AFBC:
|
|
case MML_FMT_YVU420_AFBC:
|
|
rdma_frm->bits_per_pixel_y = 12;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_BLK_UFO:
|
|
case MML_FMT_BLK_UFO_AUO:
|
|
case MML_FMT_BLK:
|
|
rdma_frm->vdo_blk_shift_w = 4;
|
|
rdma_frm->vdo_blk_height = 32;
|
|
rdma_frm->vdo_blk_shift_h = 5;
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 16;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_NV16:
|
|
case MML_FMT_NV61:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 16;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_NV24:
|
|
case MML_FMT_NV42:
|
|
rdma_frm->bits_per_pixel_y = 8;
|
|
rdma_frm->bits_per_pixel_uv = 16;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_NV12_10L:
|
|
case MML_FMT_NV21_10L:
|
|
rdma_frm->bits_per_pixel_y = 16;
|
|
rdma_frm->bits_per_pixel_uv = 32;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_YUV4441010102:
|
|
rdma_frm->bits_per_pixel_y = 32;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 0;
|
|
rdma_frm->ver_shift_uv = 0;
|
|
break;
|
|
case MML_FMT_NV12_10P:
|
|
case MML_FMT_NV21_10P:
|
|
rdma_frm->bits_per_pixel_y = 10;
|
|
rdma_frm->bits_per_pixel_uv = 20;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_YUV420_10P_AFBC:
|
|
case MML_FMT_YVU420_10P_AFBC:
|
|
rdma_frm->bits_per_pixel_y = 16;
|
|
rdma_frm->bits_per_pixel_uv = 0;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
case MML_FMT_BLK_10H:
|
|
case MML_FMT_BLK_10V:
|
|
case MML_FMT_BLK_10HJ:
|
|
case MML_FMT_BLK_10VJ:
|
|
case MML_FMT_BLK_UFO_10H:
|
|
case MML_FMT_BLK_UFO_10V:
|
|
case MML_FMT_BLK_UFO_10HJ:
|
|
case MML_FMT_BLK_UFO_10VJ:
|
|
rdma_frm->vdo_blk_shift_w = 4;
|
|
rdma_frm->vdo_blk_height = 32;
|
|
rdma_frm->vdo_blk_shift_h = 5;
|
|
rdma_frm->bits_per_pixel_y = 10;
|
|
rdma_frm->bits_per_pixel_uv = 20;
|
|
rdma_frm->hor_shift_uv = 1;
|
|
rdma_frm->ver_shift_uv = 1;
|
|
break;
|
|
default:
|
|
mml_err("[rdma] not support format %x", fmt);
|
|
break;
|
|
}
|
|
|
|
if (profile_in == MML_YCBCR_PROFILE_BT2020 ||
|
|
profile_in == MML_YCBCR_PROFILE_FULL_BT709 ||
|
|
profile_in == MML_YCBCR_PROFILE_FULL_BT2020)
|
|
profile_in = MML_YCBCR_PROFILE_BT709;
|
|
|
|
if (rdma_frm->color_tran) {
|
|
if (profile_in == MML_YCBCR_PROFILE_BT601)
|
|
rdma_frm->matrix_sel = 2;
|
|
else if (profile_in == MML_YCBCR_PROFILE_BT709)
|
|
rdma_frm->matrix_sel = 3;
|
|
else if (profile_in == MML_YCBCR_PROFILE_FULL_BT601)
|
|
rdma_frm->matrix_sel = 0;
|
|
else
|
|
mml_err("[rdma] unknown color conversion %x",
|
|
profile_in);
|
|
}
|
|
}
|
|
|
|
s32 check_setting(struct mml_file_buf *src_buf, struct mml_frame_data *src)
|
|
{
|
|
s32 plane = MML_FMT_PLANE(src->format);
|
|
/* block format error check */
|
|
if (MML_FMT_BLOCK(src->format)) {
|
|
if ((src->width & 0x0f) || (src->height & 0x1f)) {
|
|
mml_err("invalid blk, width %u, height %u",
|
|
src->width, src->height);
|
|
mml_err("alignment width 16x, height 32x");
|
|
return -1;
|
|
}
|
|
|
|
/* 16-byte error */
|
|
if ((src_buf->dma[0].iova & 0x0f) ||
|
|
(plane > 1 && (src_buf->dma[1].iova & 0x0f)) ||
|
|
(plane > 2 && (src_buf->dma[2].iova & 0x0f))) {
|
|
mml_err("invalid block format setting, buffer %#11llx %#11llx %#11llx",
|
|
src_buf->dma[0].iova, src_buf->dma[1].iova,
|
|
src_buf->dma[2].iova);
|
|
mml_err("buffer should be 16 align");
|
|
return -1;
|
|
}
|
|
/* 128-byte warning for performance */
|
|
if ((src_buf->dma[0].iova & 0x7f) ||
|
|
(plane > 1 && (src_buf->dma[1].iova & 0x7f)) ||
|
|
(plane > 2 && (src_buf->dma[2].iova & 0x7f))) {
|
|
mml_log("warning: block format setting, buffer %#11llx %#11llx %#11llx",
|
|
src_buf->dma[0].iova, src_buf->dma[1].iova,
|
|
src_buf->dma[2].iova);
|
|
}
|
|
}
|
|
|
|
if ((MML_FMT_PLANE(src->format) > 1) && src->uv_stride <= 0) {
|
|
src->uv_stride = mml_color_get_min_uv_stride(src->format,
|
|
src->width);
|
|
}
|
|
if ((plane == 1 && !src_buf->dma[0].iova) ||
|
|
(plane == 2 && (!src_buf->dma[1].iova || !src_buf->dma[0].iova)) ||
|
|
(plane == 3 && (!src_buf->dma[2].iova || !src_buf->dma[1].iova ||
|
|
!src_buf->dma[0].iova))) {
|
|
mml_err("buffer plane number error, format = %#x, plane = %d",
|
|
src->format, plane);
|
|
return -1;
|
|
}
|
|
|
|
if (MML_FMT_H_SUBSAMPLE(src->format))
|
|
src->width &= ~1;
|
|
|
|
if (MML_FMT_V_SUBSAMPLE(src->format))
|
|
src->height &= ~1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void calc_ufo(struct mml_file_buf *src_buf, struct mml_frame_data *src,
|
|
u64 *ufo_dec_length_y, u64 *ufo_dec_length_c,
|
|
u32 *u4pic_size_bs, u32 *u4pic_size_y_bs)
|
|
{
|
|
u32 u4pic_size_y = src->width * src->height;
|
|
u32 u4ufo_len_size_y =
|
|
((((u4pic_size_y + 255) >> 8) + 63 + (16*8)) >> 6) << 6;
|
|
u32 u4pic_size_c_bs;
|
|
|
|
if (MML_FMT_10BIT_PACKED(src->format)) {
|
|
if (MML_FMT_10BIT_JUMP(src->format)) {
|
|
*u4pic_size_y_bs =
|
|
(((u4pic_size_y * 5 >> 2) + 511) >> 9) << 9;
|
|
*u4pic_size_bs =
|
|
((*u4pic_size_y_bs + u4ufo_len_size_y + 4095) >>
|
|
12) << 12;
|
|
u4pic_size_c_bs =
|
|
(((u4pic_size_y * 5 >> 3) + 63) >> 6) << 6;
|
|
} else {
|
|
*u4pic_size_y_bs =
|
|
(((u4pic_size_y * 5 >> 2) + 4095) >> 12) << 12;
|
|
u4pic_size_c_bs = u4pic_size_y * 5 >> 3;
|
|
*u4pic_size_bs =
|
|
((*u4pic_size_y_bs + u4pic_size_c_bs + 511) >>
|
|
9) << 9;
|
|
}
|
|
} else {
|
|
if (MML_FMT_AUO(src->format)) {
|
|
u4ufo_len_size_y = u4ufo_len_size_y << 1;
|
|
*u4pic_size_y_bs = ((u4pic_size_y + 511) >> 9) << 9;
|
|
*u4pic_size_bs =
|
|
((*u4pic_size_y_bs + u4ufo_len_size_y + 4095) >>
|
|
12) << 12;
|
|
u4pic_size_c_bs =
|
|
(((u4pic_size_y >> 1) + 63) >> 6) << 6;
|
|
} else {
|
|
*u4pic_size_y_bs = ((u4pic_size_y + 4095) >> 12) << 12;
|
|
u4pic_size_c_bs = u4pic_size_y >> 1;
|
|
*u4pic_size_bs =
|
|
((*u4pic_size_y_bs + u4pic_size_c_bs + 511) >>
|
|
9) << 9;
|
|
}
|
|
}
|
|
|
|
if (MML_FMT_10BIT_JUMP(src->format) || MML_FMT_AUO(src->format)) {
|
|
/* Y YL C CL*/
|
|
*ufo_dec_length_y = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
*u4pic_size_y_bs;
|
|
*ufo_dec_length_c = src_buf->dma[1].iova + src->plane_offset[1] +
|
|
u4pic_size_c_bs;
|
|
} else {
|
|
/* Y C YL CL */
|
|
*ufo_dec_length_y = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
*u4pic_size_bs;
|
|
*ufo_dec_length_c = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
*u4pic_size_bs + u4ufo_len_size_y;
|
|
}
|
|
}
|
|
|
|
static void rdma_cpr_trigger(struct cmdq_pkt *pkt, const u8 hw_pipe,
|
|
const bool secure)
|
|
{
|
|
cmdq_pkt_wfe(pkt, CMDQ_TOKEN_PREBUILT_MML_LOCK);
|
|
cmdq_pkt_assign_command(pkt, CMDQ_CPR_PREBUILT_PIPE(CMDQ_PREBUILT_MML),
|
|
hw_pipe + (secure << 1));
|
|
cmdq_pkt_set_event(pkt, CMDQ_TOKEN_PREBUILT_MML_WAIT);
|
|
cmdq_pkt_wfe(pkt, CMDQ_TOKEN_PREBUILT_MML_SET);
|
|
cmdq_pkt_set_event(pkt, CMDQ_TOKEN_PREBUILT_MML_LOCK);
|
|
}
|
|
|
|
static void rdma_reset_threshold(struct mml_comp_rdma *rdma,
|
|
struct cmdq_pkt *pkt, const phys_addr_t base_pa, const u8 hw_pipe,
|
|
const bool write_sec)
|
|
{
|
|
u32 i;
|
|
|
|
/* clear threshold for all plane */
|
|
for (i = 0; i < ARRAY_SIZE(rdma_dmabuf); i++) {
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_dmabuf[i],
|
|
0x3000000, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_urgent_th[i],
|
|
0, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_ultra_th[i],
|
|
0, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_preultra_th[i],
|
|
0, write_sec);
|
|
}
|
|
}
|
|
|
|
static void rdma_select_threshold_hrt(struct mml_comp_rdma *rdma,
|
|
struct cmdq_pkt *pkt, const phys_addr_t base_pa, const u8 hw_pipe,
|
|
const bool write_sec, u32 format, u32 width, u32 height)
|
|
{
|
|
const struct rdma_golden *golden;
|
|
const struct golden_setting *golden_set;
|
|
u32 pixel = width * height;
|
|
u32 idx, i;
|
|
|
|
if (MML_FMT_PLANE(format) == 1) {
|
|
if (MML_FMT_BITS_PER_PIXEL(format) >= 32)
|
|
golden = &rdma->data->golden[GOLDEN_FMT_ARGB];
|
|
else
|
|
golden = &rdma->data->golden[GOLDEN_FMT_RGB];
|
|
} else {
|
|
golden = &rdma->data->golden[GOLDEN_FMT_YUV420];
|
|
}
|
|
|
|
for (idx = 0; idx < golden->cnt - 1; idx++)
|
|
if (golden->settings[idx].pixel > pixel)
|
|
break;
|
|
golden_set = &golden->settings[idx];
|
|
|
|
/* config threshold for all plane */
|
|
for (i = 0; i < ARRAY_SIZE(rdma_dmabuf); i++) {
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_dmabuf[i],
|
|
3 << 24 | 32, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_urgent_th[i],
|
|
golden_set->plane[i].urgent, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_ultra_th[i],
|
|
golden_set->plane[i].ultra, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, rdma_preultra_th[i],
|
|
golden_set->plane[i].preultra, write_sec);
|
|
}
|
|
}
|
|
|
|
static s32 rdma_config_frame(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg)
|
|
{
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
struct mml_frame_config *cfg = task->config;
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
struct mml_file_buf *src_buf = &task->buf.src;
|
|
struct mml_frame_data *src = &cfg->info.src;
|
|
struct cmdq_pkt *pkt = task->pkts[ccfg->pipe];
|
|
struct mml_task_reuse *reuse = &task->reuse[ccfg->pipe];
|
|
struct mml_pipe_cache *cache = &cfg->cache[ccfg->pipe];
|
|
|
|
const phys_addr_t base_pa = comp->base_pa;
|
|
const u8 hw_pipe = cfg->path[ccfg->pipe]->hw_pipe;
|
|
const bool write_sec = mml_slt ? false : rdma->data->write_sec_reg;
|
|
const u32 dst_fmt = cfg->info.dest[ccfg->node->out_idx].data.format;
|
|
u8 simple_mode = 1;
|
|
u8 filter_mode;
|
|
u8 loose = 0;
|
|
u8 bit_number = 0;
|
|
u8 ufo_auo = 0;
|
|
u8 ufo_jump = 0;
|
|
u8 afbc = 0;
|
|
u8 afbc_y2r = 0;
|
|
u8 hyfbc = 0;
|
|
u8 ufbdc = 0;
|
|
u8 ufbdc_sec_mode = 0;
|
|
u8 output_10bit = 0;
|
|
u32 width_in_pxl = 0;
|
|
u32 height_in_pxl = 0;
|
|
u64 iova[3];
|
|
u64 ufo_dec_length_y = 0;
|
|
u64 ufo_dec_length_c = 0;
|
|
u32 u4pic_size_bs = 0;
|
|
u32 u4pic_size_y_bs = 0;
|
|
u32 gmcif_con;
|
|
u8 in_swap;
|
|
|
|
mml_msg("use config %p rdma %p", cfg, rdma);
|
|
|
|
if (!write_sec) {
|
|
/* Enable engine */
|
|
cmdq_pkt_write(pkt, NULL, base_pa + RDMA_EN, 0x1, 0x00000001);
|
|
/* Enable shadow */
|
|
cmdq_pkt_write(pkt, NULL, base_pa + RDMA_SHADOW_CTRL, 0x1, U32_MAX);
|
|
}
|
|
|
|
rdma_color_fmt(cfg, rdma_frm);
|
|
|
|
if (MML_FMT_V_SUBSAMPLE(src->format) &&
|
|
!MML_FMT_V_SUBSAMPLE(cfg->info.dest[0].data.format) &&
|
|
!MML_FMT_BLOCK(src->format))
|
|
/* 420 to 422 interpolation solution */
|
|
filter_mode = 2;
|
|
else
|
|
/* config.enRDMACrop ? 3 : 2 */
|
|
/* RSZ uses YUV422, RDMA could use V filter unless cropping */
|
|
filter_mode = 3;
|
|
|
|
if (cfg->alpharot)
|
|
rdma_frm->color_tran = 0;
|
|
else if (MML_FMT_10BIT(src->format))
|
|
rdma_frm->color_tran = 1;
|
|
|
|
/* Enable dither on output, not input */
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_DITHER_CON, 0x0, write_sec);
|
|
|
|
gmcif_con = BIT(0) | /* COMMAND_DIV */
|
|
GENMASK(6, 4) | /* READ_REQUEST_TYPE */
|
|
GENMASK(9, 8) | /* WRITE_REQUEST_TYPE */
|
|
BIT(16); /* PRE_ULTRA_EN */
|
|
/* racing case also enable urgent/ultra to not blocking disp */
|
|
if (unlikely(mml_racing_urgent)) {
|
|
gmcif_con ^= BIT(16) | BIT(15); /* URGENT_EN: always */
|
|
rdma_reset_threshold(rdma, pkt, base_pa, hw_pipe, write_sec);
|
|
} else if (cfg->info.mode == MML_MODE_RACING) {
|
|
gmcif_con |= BIT(12) | /* ULTRA_EN */
|
|
BIT(14); /* URGENT_EN */
|
|
rdma_select_threshold_hrt(rdma, pkt, base_pa, hw_pipe,
|
|
write_sec, src->format, src->width, src->height);
|
|
} else {
|
|
rdma_reset_threshold(rdma, pkt, base_pa, hw_pipe, write_sec);
|
|
}
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_GMCIF_CON,
|
|
gmcif_con, write_sec);
|
|
|
|
if (MML_FMT_IS_ARGB(src->format) &&
|
|
cfg->info.dest[0].pq_config.en_hdr &&
|
|
!cfg->info.dest[0].pq_config.en_dre &&
|
|
!cfg->info.dest[0].pq_config.en_sharp)
|
|
rdma_frm->color_tran = 0;
|
|
|
|
if (MML_FMT_10BIT_LOOSE(src->format))
|
|
loose = 1;
|
|
if (MML_FMT_10BIT(src->format))
|
|
bit_number = 1;
|
|
|
|
in_swap = rdma_frm->swap;
|
|
|
|
if (MML_FMT_COMPRESS(dst_fmt) &&
|
|
MML_FMT_10BIT(dst_fmt)) {
|
|
if (rdma->data->rb_swap == 1) {
|
|
if (cfg->alpharot) {
|
|
if ((MML_FMT_COMPRESS(src->format) &&
|
|
MML_FMT_SWAP(dst_fmt)) ||
|
|
(!MML_FMT_COMPRESS(src->format) &&
|
|
!MML_FMT_SWAP(dst_fmt)))
|
|
in_swap = in_swap ? 0 : 1;
|
|
} else {
|
|
if (MML_FMT_IS_RGB(src->format) &&
|
|
!MML_FMT_SWAP(dst_fmt))
|
|
in_swap = in_swap ? 0 : 1;
|
|
}
|
|
} else if (rdma->data->rb_swap == 2) {
|
|
if (MML_FMT_IS_RGB(src->format) &&
|
|
!MML_FMT_SWAP(dst_fmt))
|
|
in_swap = in_swap ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_CON,
|
|
(rdma_frm->hw_fmt << 0) +
|
|
(filter_mode << 9) +
|
|
(loose << 11) +
|
|
(rdma_frm->field << 12) +
|
|
(in_swap << 14) +
|
|
(rdma_frm->blk << 15) +
|
|
(1 << 17) + /* UNIFORM_CONFIG */
|
|
(bit_number << 18) +
|
|
(rdma_frm->blk_tile << 23) +
|
|
(0 << 24) + /* RING_BUF_READ */
|
|
(cfg->alpharot << 25),
|
|
write_sec);
|
|
|
|
if (rdma_frm->blk_10bit)
|
|
ufo_jump = MML_FMT_10BIT_JUMP(src->format);
|
|
else
|
|
ufo_auo = MML_FMT_AUO(src->format);
|
|
|
|
if (MML_FMT_COMPRESS(src->format)) {
|
|
afbc = 1;
|
|
if (MML_FMT_IS_ARGB(src->format))
|
|
afbc_y2r = 1;
|
|
ufbdc = 1;
|
|
if (MML_FMT_IS_YUV(src->format)) {
|
|
width_in_pxl = ((src->width + 15) >> 4) << 4;
|
|
height_in_pxl = ((src->height + 15) >> 4) << 4;
|
|
} else {
|
|
width_in_pxl = ((src->width + 31) >> 5) << 5;
|
|
height_in_pxl = ((src->height + 7) >> 3) << 3;
|
|
}
|
|
if (src->secure)
|
|
ufbdc_sec_mode = 1;
|
|
} else if (rdma_frm->enable_ufo && rdma_frm->blk_10bit) {
|
|
width_in_pxl = (src->y_stride << 2) / 5;
|
|
}
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_BKGD_SIZE_IN_PXL,
|
|
width_in_pxl, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_BKGD_H_SIZE_IN_PXL,
|
|
height_in_pxl, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_AFBC_PAYLOAD_OST,
|
|
0, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_COMP_CON,
|
|
(rdma_frm->enable_ufo << 31) +
|
|
(ufo_auo << 29) +
|
|
(ufo_jump << 28) +
|
|
(1 << 26) + /* UFO_DATA_IN_NOT_REV */
|
|
(1 << 25) + /* UFO_DATA_OUT_NOT_REV */
|
|
(0 << 24) + /* ufo_dcp */
|
|
(0 << 23) + /* ufo_dcp_10bit */
|
|
(afbc << 22) +
|
|
(afbc_y2r << 21) +
|
|
(0 << 20) + /* pvric_en */
|
|
(1 << 19) + /* SHORT_BURST */
|
|
(ufbdc_sec_mode << 18) +
|
|
(12 << 14) + /* UFBDC_HG_DISABLE */
|
|
(hyfbc << 13) +
|
|
(ufbdc << 12) +
|
|
(1 << 11), /* payload_ost */
|
|
write_sec);
|
|
|
|
if (rdma_frm->enable_ufo) {
|
|
calc_ufo(src_buf, src, &ufo_dec_length_y, &ufo_dec_length_c,
|
|
&u4pic_size_bs, &u4pic_size_y_bs);
|
|
|
|
rdma_write_addr(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_Y,
|
|
ufo_dec_length_y,
|
|
reuse, cache,
|
|
&rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_Y],
|
|
write_sec);
|
|
|
|
rdma_write_addr(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_C,
|
|
ufo_dec_length_c,
|
|
reuse, cache,
|
|
&rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_C],
|
|
write_sec);
|
|
} else {
|
|
rdma_write_ofst(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_Y, 0, write_sec);
|
|
rdma_write_ofst(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_UFO_DEC_LENGTH_BASE_C, 0, write_sec);
|
|
}
|
|
|
|
if (MML_FMT_10BIT(src->format) ||
|
|
MML_FMT_10BIT(cfg->info.dest[0].data.format))
|
|
output_10bit = 1;
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_CON,
|
|
(rdma_frm->lb_2b_mode << 12) +
|
|
(output_10bit << 5) +
|
|
(simple_mode << 4),
|
|
write_sec);
|
|
|
|
/* Write frame base address */
|
|
if (unlikely(cfg->info.mode == MML_MODE_SRAM_READ)) {
|
|
iova[0] = rdma->sram_pa + src->plane_offset[0];
|
|
iova[1] = rdma->sram_pa + src->plane_offset[1];
|
|
iova[2] = rdma->sram_pa + src->plane_offset[2];
|
|
|
|
cmdq_pkt_write(pkt, NULL, rdma->smi_larb_con,
|
|
GENMASK(19, 16), GENMASK(19, 16));
|
|
|
|
} else if (rdma_frm->enable_ufo) {
|
|
if (MML_FMT_10BIT_JUMP(src->format) ||
|
|
MML_FMT_AUO(src->format)) {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
u4pic_size_bs;
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
} else {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
u4pic_size_y_bs;
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
}
|
|
} else {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[1].iova + src->plane_offset[1];
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
}
|
|
|
|
mml_msg("%s src %#011llx %#011llx %#011llx",
|
|
__func__, iova[0], iova[1], iova[2]);
|
|
|
|
if (!mml_slt) {
|
|
rdma_write_addr(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_SRC_BASE_0,
|
|
iova[0],
|
|
reuse, cache,
|
|
&rdma_frm->labels[RDMA_LABEL_BASE_0],
|
|
write_sec);
|
|
rdma_write_addr(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_SRC_BASE_1,
|
|
iova[1],
|
|
reuse, cache,
|
|
&rdma_frm->labels[RDMA_LABEL_BASE_1],
|
|
write_sec);
|
|
rdma_write_addr(pkt, base_pa, hw_pipe,
|
|
CPR_RDMA_SRC_BASE_2,
|
|
iova[2],
|
|
reuse, cache,
|
|
&rdma_frm->labels[RDMA_LABEL_BASE_2],
|
|
write_sec);
|
|
}
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_BKGD_SIZE_IN_BYTE,
|
|
src->y_stride, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_SF_BKGD_SIZE_IN_BYTE,
|
|
src->uv_stride, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_TRANSFORM_0,
|
|
(rdma_frm->matrix_sel << 23) +
|
|
(rdma_frm->color_tran << 16),
|
|
write_sec);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static s32 rdma_config_tile(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg, u32 idx)
|
|
{
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
struct mml_frame_config *cfg = task->config;
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
struct mml_frame_data *src = &cfg->info.src;
|
|
struct cmdq_pkt *pkt = task->pkts[ccfg->pipe];
|
|
u32 plane;
|
|
|
|
const phys_addr_t base_pa = comp->base_pa;
|
|
const u8 hw_pipe = cfg->path[ccfg->pipe]->hw_pipe;
|
|
const bool write_sec = mml_slt ? false : rdma->data->write_sec_reg;
|
|
|
|
struct mml_tile_engine *tile = config_get_tile(cfg, ccfg, idx);
|
|
|
|
u64 src_offset_0;
|
|
u64 src_offset_1;
|
|
u64 src_offset_2;
|
|
u32 src_offset_wp = 0;
|
|
u32 src_offset_hp = 0;
|
|
u32 mf_src_w;
|
|
u32 mf_src_h;
|
|
u32 mf_clip_w;
|
|
u32 mf_clip_h;
|
|
u32 mf_offset_w_1;
|
|
u32 mf_offset_h_1;
|
|
|
|
/* Following data retrieve from tile calc result */
|
|
u64 in_xs = tile->in.xs;
|
|
const u32 in_xe = tile->in.xe;
|
|
u64 in_ys = tile->in.ys;
|
|
const u32 in_ye = tile->in.ye;
|
|
const u32 out_xs = tile->out.xs;
|
|
const u32 out_xe = tile->out.xe;
|
|
const u64 out_ys = tile->out.ys;
|
|
const u32 out_ye = tile->out.ye;
|
|
const u32 crop_ofst_x = tile->luma.x;
|
|
const u32 crop_ofst_y = tile->luma.y;
|
|
|
|
if (rdma_frm->blk) {
|
|
/* Alignment X left in block boundary */
|
|
in_xs = ((in_xs >> rdma_frm->vdo_blk_shift_w) <<
|
|
rdma_frm->vdo_blk_shift_w);
|
|
/* Alignment Y top in block boundary */
|
|
in_ys = ((in_ys >> rdma_frm->vdo_blk_shift_h) <<
|
|
rdma_frm->vdo_blk_shift_h);
|
|
}
|
|
|
|
if (MML_FMT_COMPRESS(src->format)) {
|
|
src_offset_wp = in_xs;
|
|
src_offset_hp = in_ys;
|
|
}
|
|
|
|
if (!rdma_frm->blk) {
|
|
/* Set Y pixel offset */
|
|
src_offset_0 = (in_xs * rdma_frm->bits_per_pixel_y >> 3) +
|
|
in_ys * src->y_stride;
|
|
|
|
/* Set U pixel offset */
|
|
src_offset_1 = ((in_xs >> rdma_frm->hor_shift_uv) *
|
|
rdma_frm->bits_per_pixel_uv >> 3) +
|
|
(in_ys >> rdma_frm->ver_shift_uv) *
|
|
src->uv_stride;
|
|
|
|
/* Set V pixel offset */
|
|
src_offset_2 = ((in_xs >> rdma_frm->hor_shift_uv) *
|
|
rdma_frm->bits_per_pixel_uv >> 3) +
|
|
(in_ys >> rdma_frm->ver_shift_uv) *
|
|
src->uv_stride;
|
|
|
|
/* Set source size */
|
|
mf_src_w = in_xe - in_xs + 1;
|
|
mf_src_h = in_ye - in_ys + 1;
|
|
|
|
/* Set target size */
|
|
mf_clip_w = out_xe - out_xs + 1;
|
|
mf_clip_h = out_ye - out_ys + 1;
|
|
|
|
/* Set crop offset */
|
|
mf_offset_w_1 = crop_ofst_x;
|
|
mf_offset_h_1 = crop_ofst_y;
|
|
} else {
|
|
/* Set Y pixel offset */
|
|
src_offset_0 = (in_xs *
|
|
(rdma_frm->vdo_blk_height << rdma_frm->field) *
|
|
rdma_frm->bits_per_pixel_y >> 3) +
|
|
(out_ys >> rdma_frm->vdo_blk_shift_h) *
|
|
src->y_stride;
|
|
|
|
/* Set 10bit UFO mode */
|
|
if (MML_FMT_10BIT_PACKED(src->format) && rdma_frm->enable_ufo)
|
|
src_offset_wp = (src_offset_0 << 2) / 5;
|
|
|
|
/* Set U pixel offset */
|
|
src_offset_1 = ((in_xs >> rdma_frm->hor_shift_uv) *
|
|
((rdma_frm->vdo_blk_height >>
|
|
rdma_frm->ver_shift_uv) << rdma_frm->field) *
|
|
rdma_frm->bits_per_pixel_uv >> 3) +
|
|
(out_ys >> rdma_frm->vdo_blk_shift_h) *
|
|
src->uv_stride;
|
|
|
|
/* Set V pixel offset */
|
|
src_offset_2 = ((in_xs >> rdma_frm->hor_shift_uv) *
|
|
((rdma_frm->vdo_blk_height >>
|
|
rdma_frm->ver_shift_uv) << rdma_frm->field) *
|
|
rdma_frm->bits_per_pixel_uv >> 3) +
|
|
(out_ys >> rdma_frm->vdo_blk_shift_h) *
|
|
src->uv_stride;
|
|
|
|
/* Set source size */
|
|
mf_src_w = in_xe - in_xs + 1;
|
|
mf_src_h = (in_ye - in_ys + 1) << rdma_frm->field;
|
|
|
|
/* Set target size */
|
|
mf_clip_w = out_xe - out_xs + 1;
|
|
mf_clip_h = (out_ye - out_ys + 1) << rdma_frm->field;
|
|
|
|
/* Set crop offset */
|
|
mf_offset_w_1 = out_xs + rdma_frm->crop_off_l - in_xs;
|
|
mf_offset_h_1 = (out_ys + rdma_frm->crop_off_t - in_ys) << rdma_frm->field;
|
|
}
|
|
|
|
rdma_write_ofst(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_OFFSET_0,
|
|
src_offset_0, write_sec);
|
|
rdma_write_ofst(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_OFFSET_1,
|
|
src_offset_1, write_sec);
|
|
rdma_write_ofst(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_OFFSET_2,
|
|
src_offset_2, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_OFFSET_WP,
|
|
src_offset_wp, write_sec);
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_SRC_OFFSET_HP,
|
|
src_offset_hp, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_SRC_SIZE,
|
|
(mf_src_h << 16) + mf_src_w, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_CLIP_SIZE,
|
|
(mf_clip_h << 16) + mf_clip_w, write_sec);
|
|
|
|
rdma_write(pkt, base_pa, hw_pipe, CPR_RDMA_MF_OFFSET_1,
|
|
(mf_offset_h_1 << 16) + mf_offset_w_1, write_sec);
|
|
|
|
/* qos accumulate tile pixel */
|
|
rdma_frm->pixel_acc += mf_src_w * mf_src_h;
|
|
|
|
/* calculate qos for later use */
|
|
plane = MML_FMT_PLANE(src->format);
|
|
rdma_frm->datasize += mml_color_get_min_y_size(src->format,
|
|
mf_src_w, mf_src_h);
|
|
if (plane > 1)
|
|
rdma_frm->datasize += mml_color_get_min_uv_size(src->format,
|
|
mf_src_w, mf_src_h);
|
|
if (plane > 2)
|
|
rdma_frm->datasize += mml_color_get_min_uv_size(src->format,
|
|
mf_src_w, mf_src_h);
|
|
|
|
if (write_sec)
|
|
rdma_cpr_trigger(pkt, hw_pipe, src->secure);
|
|
return 0;
|
|
}
|
|
|
|
static s32 rdma_wait(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg, u32 idx)
|
|
{
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
struct cmdq_pkt *pkt = task->pkts[ccfg->pipe];
|
|
|
|
/* wait rdma frame done */
|
|
cmdq_pkt_wfe(pkt, rdma->event_eof);
|
|
return 0;
|
|
}
|
|
|
|
static s32 rdma_post(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg)
|
|
{
|
|
struct mml_frame_config *cfg = task->config;
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
struct mml_pipe_cache *cache = &task->config->cache[ccfg->pipe];
|
|
|
|
/* ufo case */
|
|
if (MML_FMT_UFO(cfg->info.src.format))
|
|
rdma_frm->datasize = (u32)div_u64((u64)rdma_frm->datasize * 7, 10);
|
|
|
|
/* Data size add to task and pixel,
|
|
* it is ok for rdma to directly assign and accumulate in wrot.
|
|
*/
|
|
cache->total_datasize = rdma_frm->datasize;
|
|
cache->max_pixel = rdma_frm->pixel_acc;
|
|
|
|
mml_msg("%s task %p pipe %hhu data %u pixel %u",
|
|
__func__, task, ccfg->pipe, rdma_frm->datasize, rdma_frm->pixel_acc);
|
|
|
|
/* for sram test rollback smi config */
|
|
if (unlikely(cfg->info.mode == MML_MODE_SRAM_READ)) {
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
|
|
cmdq_pkt_write(task->pkts[ccfg->pipe], NULL, rdma->smi_larb_con,
|
|
0, GENMASK(19, 16));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static s32 rdma_reconfig_frame(struct mml_comp *comp, struct mml_task *task,
|
|
struct mml_comp_config *ccfg)
|
|
{
|
|
struct mml_frame_config *cfg = task->config;
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
struct mml_file_buf *src_buf = &task->buf.src;
|
|
struct mml_frame_data *src = &cfg->info.src;
|
|
struct mml_task_reuse *reuse = &task->reuse[ccfg->pipe];
|
|
|
|
u64 iova[3];
|
|
u64 ufo_dec_length_y = 0;
|
|
u64 ufo_dec_length_c = 0;
|
|
u32 u4pic_size_bs = 0;
|
|
u32 u4pic_size_y_bs = 0;
|
|
|
|
if (unlikely(cfg->info.mode == MML_MODE_SRAM_READ)) {
|
|
/* no need update addr for sram case */
|
|
return 0;
|
|
}
|
|
|
|
if (rdma_frm->enable_ufo) {
|
|
calc_ufo(src_buf, src, &ufo_dec_length_y, &ufo_dec_length_c,
|
|
&u4pic_size_bs, &u4pic_size_y_bs);
|
|
|
|
rdma_update_addr(reuse,
|
|
rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_Y],
|
|
rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_Y_MSB],
|
|
ufo_dec_length_y);
|
|
rdma_update_addr(reuse,
|
|
rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_C],
|
|
rdma_frm->labels[RDMA_LABEL_UFO_DEC_BASE_C_MSB],
|
|
ufo_dec_length_c);
|
|
}
|
|
|
|
/* Write frame base address */
|
|
if (rdma_frm->enable_ufo) {
|
|
if (MML_FMT_10BIT_JUMP(src->format) ||
|
|
MML_FMT_AUO(src->format)) {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
u4pic_size_bs;
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
} else {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[0].iova + src->plane_offset[0] +
|
|
u4pic_size_y_bs;
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
}
|
|
} else {
|
|
iova[0] = src_buf->dma[0].iova + src->plane_offset[0];
|
|
iova[1] = src_buf->dma[1].iova + src->plane_offset[1];
|
|
iova[2] = src_buf->dma[2].iova + src->plane_offset[2];
|
|
}
|
|
|
|
rdma_update_addr(reuse,
|
|
rdma_frm->labels[RDMA_LABEL_BASE_0],
|
|
rdma_frm->labels[RDMA_LABEL_BASE_0_MSB],
|
|
iova[0]);
|
|
rdma_update_addr(reuse,
|
|
rdma_frm->labels[RDMA_LABEL_BASE_1],
|
|
rdma_frm->labels[RDMA_LABEL_BASE_1_MSB],
|
|
iova[1]);
|
|
rdma_update_addr(reuse,
|
|
rdma_frm->labels[RDMA_LABEL_BASE_2],
|
|
rdma_frm->labels[RDMA_LABEL_BASE_2_MSB],
|
|
iova[2]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct mml_comp_config_ops rdma_cfg_ops = {
|
|
.prepare = rdma_config_read,
|
|
.buf_map = rdma_buf_map,
|
|
.buf_unmap = rdma_buf_unmap,
|
|
.get_label_count = rdma_get_label_count,
|
|
.frame = rdma_config_frame,
|
|
.tile = rdma_config_tile,
|
|
.wait = rdma_wait,
|
|
.post = rdma_post,
|
|
.reframe = rdma_reconfig_frame,
|
|
};
|
|
|
|
u32 rdma_datasize_get(struct mml_task *task, struct mml_comp_config *ccfg)
|
|
{
|
|
struct rdma_frame_data *rdma_frm = rdma_frm_data(ccfg);
|
|
|
|
return rdma_frm->datasize;
|
|
}
|
|
|
|
u32 rdma_format_get(struct mml_task *task, struct mml_comp_config *ccfg)
|
|
{
|
|
return task->config->info.src.format;
|
|
}
|
|
|
|
static const struct mml_comp_hw_ops rdma_hw_ops = {
|
|
.pw_enable = &mml_comp_pw_enable,
|
|
.pw_disable = &mml_comp_pw_disable,
|
|
.clk_enable = &mml_comp_clk_enable,
|
|
.clk_disable = &mml_comp_clk_disable,
|
|
.qos_datasize_get = &rdma_datasize_get,
|
|
.qos_format_get = &rdma_format_get,
|
|
.qos_set = &mml_comp_qos_set,
|
|
.qos_clear = &mml_comp_qos_clear,
|
|
};
|
|
|
|
static const char *rdma_state(u32 state)
|
|
{
|
|
switch (state) {
|
|
case 0x1:
|
|
return "idle";
|
|
case 0x2:
|
|
return "wait sof";
|
|
case 0x4:
|
|
return "reg update";
|
|
case 0x8:
|
|
return "clear0";
|
|
case 0x10:
|
|
return "clear1";
|
|
case 0x20:
|
|
return "int0";
|
|
case 0x40:
|
|
return "int1";
|
|
case 0x80:
|
|
return "data running";
|
|
case 0x100:
|
|
return "wait done";
|
|
case 0x200:
|
|
return "warm reset";
|
|
case 0x400:
|
|
return "wait reset";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
static void rdma_debug_dump(struct mml_comp *comp)
|
|
{
|
|
struct mml_comp_rdma *rdma = comp_to_rdma(comp);
|
|
void __iomem *base = comp->base;
|
|
u32 value[30];
|
|
u32 mon[29];
|
|
u32 state, greq;
|
|
u32 i;
|
|
|
|
mml_err("rdma component %u dump:", comp->id);
|
|
|
|
if (rdma->data->write_sec_reg)
|
|
cmdq_util_prebuilt_dump(0, CMDQ_TOKEN_PREBUILT_MML_WAIT);
|
|
else {
|
|
u32 shadow_ctrl;
|
|
|
|
/* Enable shadow read working */
|
|
shadow_ctrl = readl(base + RDMA_SHADOW_CTRL);
|
|
shadow_ctrl |= 0x4;
|
|
writel(shadow_ctrl, base + RDMA_SHADOW_CTRL);
|
|
}
|
|
|
|
value[0] = readl(base + RDMA_EN);
|
|
value[1] = readl(base + RDMA_RESET);
|
|
value[2] = readl(base + RDMA_SRC_CON);
|
|
value[3] = readl(base + RDMA_COMP_CON);
|
|
/* for afbc case enable more debug info */
|
|
if (value[3] & BIT(22)) {
|
|
u32 debug_con = readl(base + RDMA_DEBUG_CON);
|
|
|
|
debug_con |= 0xe000;
|
|
writel(debug_con, base + RDMA_DEBUG_CON);
|
|
}
|
|
|
|
value[4] = readl(base + RDMA_MF_BKGD_SIZE_IN_BYTE);
|
|
value[5] = readl(base + RDMA_MF_BKGD_SIZE_IN_PXL);
|
|
value[6] = readl(base + RDMA_MF_SRC_SIZE);
|
|
value[7] = readl(base + RDMA_MF_CLIP_SIZE);
|
|
value[8] = readl(base + RDMA_MF_OFFSET_1);
|
|
value[9] = readl(base + RDMA_SF_BKGD_SIZE_IN_BYTE);
|
|
value[10] = readl(base + RDMA_MF_BKGD_H_SIZE_IN_PXL);
|
|
if (!rdma->data->write_sec_reg) {
|
|
value[11] = readl(base + RDMA_SRC_OFFSET_0_MSB);
|
|
value[12] = readl(base + RDMA_SRC_OFFSET_0);
|
|
value[13] = readl(base + RDMA_SRC_OFFSET_1_MSB);
|
|
value[14] = readl(base + RDMA_SRC_OFFSET_1);
|
|
value[15] = readl(base + RDMA_SRC_OFFSET_2_MSB);
|
|
value[16] = readl(base + RDMA_SRC_OFFSET_2);
|
|
value[17] = readl(base + RDMA_SRC_OFFSET_WP);
|
|
value[18] = readl(base + RDMA_SRC_OFFSET_HP);
|
|
value[19] = readl(base + RDMA_SRC_BASE_0_MSB);
|
|
value[20] = readl(base + RDMA_SRC_BASE_0);
|
|
value[21] = readl(base + RDMA_SRC_BASE_1_MSB);
|
|
value[22] = readl(base + RDMA_SRC_BASE_1);
|
|
value[23] = readl(base + RDMA_SRC_BASE_2_MSB);
|
|
value[24] = readl(base + RDMA_SRC_BASE_2);
|
|
value[25] = readl(base + RDMA_UFO_DEC_LENGTH_BASE_Y_MSB);
|
|
value[26] = readl(base + RDMA_UFO_DEC_LENGTH_BASE_Y);
|
|
value[27] = readl(base + RDMA_UFO_DEC_LENGTH_BASE_C_MSB);
|
|
value[28] = readl(base + RDMA_UFO_DEC_LENGTH_BASE_C);
|
|
value[29] = readl(base + RDMA_AFBC_PAYLOAD_OST);
|
|
}
|
|
|
|
/* mon sta from 0 ~ 28 */
|
|
for (i = 0; i < ARRAY_SIZE(mon); i++)
|
|
mon[i] = readl(base + RDMA_MON_STA_0 + i * 8);
|
|
|
|
mml_err("RDMA_EN %#010x RDMA_RESET %#010x RDMA_SRC_CON %#010x RDMA_COMP_CON %#010x",
|
|
value[0], value[1], value[2], value[3]);
|
|
mml_err("RDMA_MF_BKGD_SIZE_IN_BYTE %#010x RDMA_MF_BKGD_SIZE_IN_PXL %#010x",
|
|
value[4], value[5]);
|
|
mml_err("RDMA_MF_SRC_SIZE %#010x RDMA_MF_CLIP_SIZE %#010x RDMA_MF_OFFSET_1 %#010x",
|
|
value[6], value[7], value[8]);
|
|
mml_err("RDMA_SF_BKGD_SIZE_IN_BYTE %#010x RDMA_MF_BKGD_H_SIZE_IN_PXL %#010x",
|
|
value[9], value[10]);
|
|
if (!rdma->data->write_sec_reg) {
|
|
mml_err("RDMA_SRC OFFSET_0_MSB %#010x OFFSET_0 %#010x",
|
|
value[11], value[12]);
|
|
mml_err("RDMA_SRC OFFSET_1_MSB %#010x OFFSET_1 %#010x",
|
|
value[13], value[14]);
|
|
mml_err("RDMA_SRC OFFSET_2_MSB %#010x OFFSET_2 %#010x",
|
|
value[15], value[16]);
|
|
mml_err("RDMA_SRC_OFFSET_WP %#010x RDMA_SRC_OFFSET_HP %#010x",
|
|
value[17], value[18]);
|
|
mml_err("RDMA_SRC BASE_0_MSB %#010x BASE_0 %#010x",
|
|
value[19], value[20]);
|
|
mml_err("RDMA_SRC BASE_1_MSB %#010x BASE_1 %#010x",
|
|
value[21], value[22]);
|
|
mml_err("RDMA_SRC BASE_2_MSB %#010x BASE_2 %#010x",
|
|
value[23], value[24]);
|
|
mml_err("RDMA_UFO_DEC_LENGTH BASE_Y_MSB %#010x BASE_Y %#010x",
|
|
value[25], value[26]);
|
|
mml_err("RDMA_UFO_DEC_LENGTH BASE_C_MSB %#010x BASE_C %#010x",
|
|
value[27], value[28]);
|
|
mml_err("RDMA_AFBC_PAYLOAD_OST %#010x",
|
|
value[29]);
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_SIZE(mon) / 3; i++) {
|
|
mml_err("RDMA_MON_STA_%-2u %#010x RDMA_MON_STA_%-2u %#010x RDMA_MON_STA_%-2u %#010x",
|
|
i * 3, mon[i * 3],
|
|
i * 3 + 1, mon[i * 3 + 1],
|
|
i * 3 + 2, mon[i * 3 + 2]);
|
|
}
|
|
mml_err("RDMA_MON_STA_27 %#010x RDMA_MON_STA_28 %#010x",
|
|
mon[27], mon[28]);
|
|
|
|
/* parse state */
|
|
mml_err("RDMA ack:%u req:%d ufo:%u",
|
|
(mon[0] >> 11) & 0x1, (mon[0] >> 10) & 0x1,
|
|
(mon[0] >> 25) & 0x1);
|
|
state = (mon[1] >> 8) & 0x7ff;
|
|
greq = (mon[0] >> 21) & 0x1;
|
|
mml_err("RDMA state: %#x (%s)", state, rdma_state(state));
|
|
mml_err("RDMA horz_cnt %u vert_cnt %u",
|
|
mon[26] & 0xffff, (mon[26] >> 16) & 0xffff);
|
|
mml_err("RDMA greq:%u => suggest to ask SMI help:%u", greq, greq);
|
|
}
|
|
|
|
static const struct mml_comp_debug_ops rdma_debug_ops = {
|
|
.dump = &rdma_debug_dump,
|
|
};
|
|
|
|
static int mml_bind(struct device *dev, struct device *master, void *data)
|
|
{
|
|
struct mml_comp_rdma *rdma = dev_get_drvdata(dev);
|
|
s32 ret;
|
|
|
|
ret = mml_register_comp(master, &rdma->comp);
|
|
if (ret)
|
|
dev_err(dev, "Failed to register mml component %s: %d\n",
|
|
dev->of_node->full_name, ret);
|
|
return ret;
|
|
}
|
|
|
|
static void mml_unbind(struct device *dev, struct device *master, void *data)
|
|
{
|
|
struct mml_comp_rdma *rdma = dev_get_drvdata(dev);
|
|
|
|
mml_unregister_comp(master, &rdma->comp);
|
|
}
|
|
|
|
static const struct component_ops mml_comp_ops = {
|
|
.bind = mml_bind,
|
|
.unbind = mml_unbind,
|
|
};
|
|
|
|
static struct mml_comp_rdma *dbg_probed_components[4];
|
|
static int dbg_probed_count;
|
|
|
|
static int probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
struct mml_comp_rdma *priv;
|
|
s32 ret;
|
|
|
|
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
|
if (!priv)
|
|
return -ENOMEM;
|
|
|
|
platform_set_drvdata(pdev, priv);
|
|
priv->data = of_device_get_match_data(dev);
|
|
priv->dev = dev;
|
|
|
|
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(34));
|
|
if (ret)
|
|
dev_err(dev, "fail to config rdma dma mask %d\n", ret);
|
|
|
|
ret = mml_comp_init(pdev, &priv->comp);
|
|
if (ret) {
|
|
dev_err(dev, "Failed to init mml component: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
/* init larb for smi and mtcmos */
|
|
ret = mml_comp_init_larb(&priv->comp, dev);
|
|
if (ret) {
|
|
if (ret == -EPROBE_DEFER)
|
|
return ret;
|
|
dev_err(dev, "fail to init component %u larb ret %d",
|
|
priv->comp.id, ret);
|
|
}
|
|
|
|
/* store smi larb con register for later use */
|
|
priv->smi_larb_con = priv->comp.larb_base +
|
|
SMI_LARB_NON_SEC_CON + priv->comp.larb_port * 4;
|
|
mutex_init(&priv->sram_mutex);
|
|
mml_log("comp(rdma) %u smi larb con %#lx", priv->comp.id, priv->smi_larb_con);
|
|
|
|
if (of_property_read_u16(dev->of_node, "event_frame_done",
|
|
&priv->event_eof))
|
|
dev_err(dev, "read event frame_done fail\n");
|
|
|
|
/* assign ops */
|
|
priv->comp.tile_ops = &rdma_tile_ops;
|
|
priv->comp.config_ops = &rdma_cfg_ops;
|
|
priv->comp.hw_ops = &rdma_hw_ops;
|
|
priv->comp.debug_ops = &rdma_debug_ops;
|
|
|
|
dbg_probed_components[dbg_probed_count++] = priv;
|
|
|
|
ret = component_add(dev, &mml_comp_ops);
|
|
if (ret)
|
|
dev_err(dev, "Failed to add component: %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int remove(struct platform_device *pdev)
|
|
{
|
|
component_del(&pdev->dev, &mml_comp_ops);
|
|
return 0;
|
|
}
|
|
|
|
const struct of_device_id mml_rdma_driver_dt_match[] = {
|
|
{
|
|
.compatible = "mediatek,mt6983-mml_rdma",
|
|
.data = &mt6983_rdma_data,
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6893-mml_rdma",
|
|
.data = &mt6893_rdma_data
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6879-mml_rdma",
|
|
.data = &mt6879_rdma_data
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6895-mml_rdma0",
|
|
.data = &mt6895_rdma0_data
|
|
},
|
|
{
|
|
.compatible = "mediatek,mt6895-mml_rdma1",
|
|
.data = &mt6895_rdma1_data
|
|
},
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, mml_rdma_driver_dt_match);
|
|
|
|
struct platform_driver mml_rdma_driver = {
|
|
.probe = probe,
|
|
.remove = remove,
|
|
.driver = {
|
|
.name = "mediatek-mml-rdma",
|
|
.owner = THIS_MODULE,
|
|
.of_match_table = mml_rdma_driver_dt_match,
|
|
},
|
|
};
|
|
|
|
//module_platform_driver(mml_rdma_driver);
|
|
|
|
static s32 dbg_case;
|
|
static s32 dbg_set(const char *val, const struct kernel_param *kp)
|
|
{
|
|
s32 result;
|
|
|
|
result = kstrtos32(val, 0, &dbg_case);
|
|
mml_log("%s: debug_case=%d", __func__, dbg_case);
|
|
|
|
switch (dbg_case) {
|
|
case 0:
|
|
mml_log("use read to dump component status");
|
|
break;
|
|
default:
|
|
mml_err("invalid debug_case: %d", dbg_case);
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static s32 dbg_get(char *buf, const struct kernel_param *kp)
|
|
{
|
|
s32 length = 0;
|
|
u32 i;
|
|
|
|
switch (dbg_case) {
|
|
case 0:
|
|
length += snprintf(buf + length, PAGE_SIZE - length,
|
|
"[%d] probed count: %d\n", dbg_case, dbg_probed_count);
|
|
for (i = 0; i < dbg_probed_count; i++) {
|
|
struct mml_comp *comp = &dbg_probed_components[i]->comp;
|
|
|
|
length += snprintf(buf + length, PAGE_SIZE - length,
|
|
" - [%d] mml comp_id: %d.%d @%llx name: %s bound: %d\n", i,
|
|
comp->id, comp->sub_idx, comp->base_pa,
|
|
comp->name ? comp->name : "(null)", comp->bound);
|
|
length += snprintf(buf + length, PAGE_SIZE - length,
|
|
" - larb_port: %d @%llx pw: %d clk: %d\n",
|
|
comp->larb_port, comp->larb_base,
|
|
comp->pw_cnt, comp->clk_cnt);
|
|
}
|
|
break;
|
|
default:
|
|
mml_err("not support read for debug_case: %d", dbg_case);
|
|
break;
|
|
}
|
|
buf[length] = '\0';
|
|
|
|
return length;
|
|
}
|
|
|
|
static const struct kernel_param_ops dbg_param_ops = {
|
|
.set = dbg_set,
|
|
.get = dbg_get,
|
|
};
|
|
module_param_cb(rdma_debug, &dbg_param_ops, NULL, 0644);
|
|
MODULE_PARM_DESC(rdma_debug, "mml rdma debug case");
|
|
|
|
MODULE_AUTHOR("Dennis-YC Hsieh <dennis-yc.hsieh@mediatek.com>");
|
|
MODULE_DESCRIPTION("MediaTek SoC display MML RDMA driver");
|
|
MODULE_LICENSE("GPL v2");
|