diff --git a/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi b/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi index e8e3890a3b2b..f0eea2fae7c3 100644 --- a/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi +++ b/arch/arm/boot/dts/rk3288-evb-android-rk808-edp.dtsi @@ -15,6 +15,8 @@ backlight = <&backlight>; enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>; prepare-delay-ms = <120>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index c53849c03a66..35637a5a6772 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -148,6 +148,8 @@ pinctrl-names = "default"; pinctrl-0 = <&lcd_cs>; prepare-delay-ms = <120>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts index 844a91ec8c83..34a9b6648443 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android-avb.dts @@ -39,6 +39,8 @@ prepare-delay-ms = <20>; reset-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts index 72aa97affa99..bb53e270a2f5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-android.dts @@ -36,6 +36,8 @@ reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; prepare-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts index b4b3a003dd33..bc82021e125e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-linux.dts @@ -46,6 +46,8 @@ reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; prepare-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts index 18ef511c8f63..75091223a3ab 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind-lpddr4-v13-android-avb.dts @@ -50,6 +50,8 @@ prepare-delay-ms = <20>; reset-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi index 5304f0f52e7c..ab2a79b4edad 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dtsi @@ -70,6 +70,8 @@ enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; prepare-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts index c0abcf7050cf..0dbe011b02d7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts @@ -73,6 +73,8 @@ enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; prepare-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts index 54066eeb9826..5beab0fd8424 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-lp4-linux.dts @@ -70,6 +70,8 @@ enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; prepare-delay-ms = <20>; enable-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts index 4800dbfd298d..0277a1811aa1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-lp4-v11-linux.dts @@ -136,6 +136,8 @@ prepare-delay-ms = <20>; enable-delay-ms = <20>; reset-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts index 004ccbc3d8d6..dbcc4417fc96 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10-linux.dts @@ -136,6 +136,8 @@ prepare-delay-ms = <20>; enable-delay-ms = <20>; reset-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts index 8eb9ac1ae383..80663f087174 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v10.dts @@ -124,6 +124,8 @@ prepare-delay-ms = <20>; enable-delay-ms = <20>; reset-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts index 1b0f4ffbc2f8..a1204d2f3a40 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11-linux.dts @@ -136,6 +136,8 @@ prepare-delay-ms = <20>; enable-delay-ms = <20>; reset-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts index 2b14880203ea..32194fe32ef5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-evb-v11.dts @@ -126,6 +126,8 @@ prepare-delay-ms = <20>; enable-delay-ms = <20>; reset-delay-ms = <20>; + width-mm = <120>; + height-mm = <160>; display-timings { native-mode = <&timing0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi index 1e5aa02153b4..c9f16a7ce88e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562-evb.dtsi @@ -163,6 +163,8 @@ prepare-delay-ms = <60>; unprepare-delay-ms = <60>; disable-delay-ms = <60>; + width-mm = <68>; + height-mm = <121>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts b/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts index d9db92b4640b..d441e555a42b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-edp.dts @@ -15,6 +15,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi index 876ea5711a81..f7394b4f2fc2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi @@ -403,6 +403,8 @@ prepare-delay-ms = <60>; unprepare-delay-ms = <60>; disable-delay-ms = <60>; + width-mm = <68>; + height-mm = <121>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; @@ -735,6 +737,8 @@ prepare-delay-ms = <60>; unprepare-delay-ms = <60>; disable-delay-ms = <60>; + width-mm = <68>; + height-mm = <121>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi index bdc9effca194..170105ead88c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi @@ -275,6 +275,8 @@ prepare-delay-ms = <10>; unprepare-delay-ms = <10>; disable-delay-ms = <60>; + width-mm = <68>; + height-mm = <121>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; @@ -607,6 +609,8 @@ prepare-delay-ms = <10>; unprepare-delay-ms = <10>; disable-delay-ms = <10>; + width-mm = <68>; + height-mm = <121>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts index a889cc3250f8..9ea50364c627 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb2-lp4-v10-edp.dts @@ -18,8 +18,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; - width-mm = <129>; - height-mm = <171>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts index 964efd902861..9d27fbfc65c3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts @@ -18,8 +18,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; - width-mm = <129>; - height-mm = <171>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts index 3890e1d26247..a5ee38a637ec 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts @@ -18,8 +18,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; - width-mm = <129>; - height-mm = <171>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi index 68f17eec6956..8c1d0f37b8a3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-lp4x.dtsi @@ -142,8 +142,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; - width-mm = <129>; - height-mm = <171>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi index 4e0cc72ff2ac..982461d2f4d8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb8-lp4x.dtsi @@ -106,8 +106,8 @@ enable-delay-ms = <120>; unprepare-delay-ms = <120>; disable-delay-ms = <120>; - width-mm = <129>; - height-mm = <171>; + width-mm = <120>; + height-mm = <160>; panel-timing { clock-frequency = <200000000>; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 5fa26a513174..252aba42b33b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -8162,6 +8162,30 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_sta vop2_cfg_done(crtc); vop2_wait_for_fs_by_done_bit_status(vp); } + + /* + * In RK3588 VOP, HDMI1/eDP1 MUX1 module's reset signal should be released + * when PD_VOP turn on. If this reset signal is not be released, the HDMI1 + * or eDP1 output interface can't work normally. + * However, If the deassert signal want to transfer to HDMI1/eDP1 MUX1 and + * take effect, it need the video port0 dclk's source clk work a few moment. + * In some cases, the video port0 dclk's source clk is disabled(now only the + * hdmi0/1 phy pll as the dclk source parent will appear) after PD_VOP turn + * on, for example, vidoe port0 dclk source select hdmi phy pll. To fix + * this issue, enable video port0 dclk for a few monent when active a video + * port which attach to eDP1/HDMI1. + */ + if (vop2->version == VOP_VERSION_RK3588) { + if (vp->id != 0 && (vp->output_if & (VOP_OUTPUT_IF_eDP1 | VOP_OUTPUT_IF_HDMI1))) { + struct vop2_video_port *vp0 = &vop2->vps[0]; + + clk_prepare_enable(vp0->dclk); + if (!clk_get_rate(vp0->dclk)) + clk_set_rate(vp0->dclk, 148500000); + udelay(20); + clk_disable_unprepare(vp0->dclk); + } + } out: vop2_unlock(vop2); } diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index cbfcf581424d..ae795152fb2e 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -130,11 +130,6 @@ static int rkisp_params_vb2_queue_setup(struct vb2_queue *vq, INIT_LIST_HEAD(¶ms_vdev->params); - if (params_vdev->first_cfg_params) { - params_vdev->first_cfg_params = false; - return 0; - } - params_vdev->first_params = true; return 0; @@ -246,10 +241,6 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq) params_vdev->cur_buf = NULL; } - if (dev->is_pre_on) { - params_vdev->first_cfg_params = true; - return; - } rkisp_params_disable_isp(params_vdev); /* clean module params */ params_vdev->ops->clear_first_param(params_vdev); diff --git a/drivers/misc/rockchip/pcie-rkep.c b/drivers/misc/rockchip/pcie-rkep.c index b39b9f4156af..8ad5a9b55272 100644 --- a/drivers/misc/rockchip/pcie-rkep.c +++ b/drivers/misc/rockchip/pcie-rkep.c @@ -19,10 +19,15 @@ #include #include #include +#include + #include #include "../../pci/controller/rockchip-pcie-dma.h" #include "../../pci/controller/dwc/pcie-dw-dmatest.h" +#if IS_MODULE(CONFIG_PCIE_FUNC_RKEP) && IS_ENABLED(CONFIG_PCIE_DW_DMATEST) +#include "../../pci/controller/dwc/pcie-dw-dmatest.c" +#endif #define DRV_NAME "pcie-rkep" @@ -56,6 +61,7 @@ static DEFINE_MUTEX(rkep_mutex); #define PCIE_DMA_WR_INT_STATUS 0x4c #define PCIE_DMA_WR_INT_MASK 0x54 #define PCIE_DMA_WR_INT_CLEAR 0x58 +#define PCIE_DMA_WR_ERR_STATUS 0x5c #define PCIE_DMA_RD_ENB 0x2c #define PCIE_DMA_RD_CTRL_LO 0x300 @@ -71,6 +77,8 @@ static DEFINE_MUTEX(rkep_mutex); #define PCIE_DMA_RD_INT_STATUS 0xa0 #define PCIE_DMA_RD_INT_MASK 0xa8 #define PCIE_DMA_RD_INT_CLEAR 0xac +#define PCIE_DMA_RD_ERR_STATUS_LOW 0xb8 +#define PCIE_DMA_RD_ERR_STATUS_HIGH 0xbc #define PCIE_DMA_CHANEL_MAX_NUM 2 @@ -103,6 +111,18 @@ struct pcie_rkep { struct fasync_struct *async; }; +static int rkep_ep_dma_xfer(struct pcie_rkep *pcie_rkep, struct pcie_ep_dma_block_req *dma) +{ + int ret; + + if (dma->wr) + ret = pcie_dw_rc_dma_tobus(pcie_rkep->dma_obj, dma->chn, dma->block.bus_paddr, dma->block.local_paddr, dma->block.size); + else + ret = pcie_dw_rc_dma_frombus(pcie_rkep->dma_obj, dma->chn, dma->block.local_paddr, dma->block.bus_paddr, dma->block.size); + + return ret; +} + static int pcie_rkep_fasync(int fd, struct file *file, int mode) { struct miscdevice *miscdev = file->private_data; @@ -245,6 +265,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a struct miscdevice *miscdev = file->private_data; struct pcie_rkep *pcie_rkep = container_of(miscdev, struct pcie_rkep, dev); struct pcie_ep_dma_cache_cfg cfg; + struct pcie_ep_dma_block_req dma; void __user *uarg = (void __user *)args; int ret; u64 addr; @@ -265,7 +286,8 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a case PCIE_DMA_CACHE_INVALIDE: ret = copy_from_user(&cfg, uarg, sizeof(cfg)); if (ret) { - dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n"); + dev_err(&pcie_rkep->pdev->dev, + "failed to get invalid cfg copy from userspace\n"); return -EFAULT; } dma_sync_single_for_cpu(&pcie_rkep->pdev->dev, cfg.addr, cfg.size, DMA_FROM_DEVICE); @@ -273,12 +295,24 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a case PCIE_DMA_CACHE_FLUSH: ret = copy_from_user(&cfg, uarg, sizeof(cfg)); if (ret) { - dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n"); + dev_err(&pcie_rkep->pdev->dev, + "failed to get flush cfg copy from userspace\n"); return -EFAULT; } dma_sync_single_for_device(&pcie_rkep->pdev->dev, cfg.addr, cfg.size, DMA_TO_DEVICE); break; + case PCIE_EP_DMA_XFER_BLOCK: + ret = copy_from_user(&dma, uarg, sizeof(dma)); + if (ret) { + dev_err(&pcie_rkep->pdev->dev, "failed to get dma_data copy from userspace\n"); + return -EFAULT; + } + ret = rkep_ep_dma_xfer(pcie_rkep, &dma); + if (ret) { + dev_err(&pcie_rkep->pdev->dev, "failed to transfer dma, ret=%d\n", ret); + return -EFAULT; + } default: break; } @@ -308,6 +342,48 @@ static inline u32 pcie_rkep_readl_dbi(struct pcie_rkep *pcie_rkep, u32 reg) return readl(pcie_rkep->bar4 + reg); } +static void pcie_rkep_dma_debug(struct dma_trx_obj *obj, struct dma_table *table) +{ + struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev); + struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev); + unsigned int ctr_off = table->chn * 0x200; + + dev_err(&pdev->dev, "chnl=%x\n", table->start.chnl); + dev_err(&pdev->dev, "%s\n", table->dir == DMA_FROM_BUS ? "udma read" : "udma write"); + dev_err(&pdev->dev, "src=0x%x %x\n", table->ctx_reg.sarptrhi, table->ctx_reg.sarptrlo); + dev_err(&pdev->dev, "dst=0x%x %x\n", table->ctx_reg.darptrhi, table->ctx_reg.darptrlo); + dev_err(&pdev->dev, "xfersize=%x\n", table->ctx_reg.xfersize); + + if (table->dir == DMA_FROM_BUS) { + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_INT_MASK = %x\n", PCIE_DMA_RD_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ENB = %x\n", PCIE_DMA_RD_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_LO = %x\n", ctr_off + PCIE_DMA_RD_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_CTRL_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_CTRL_HI = %x\n", ctr_off + PCIE_DMA_RD_CTRL_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_CTRL_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_XFERSIZE = %x\n", ctr_off + PCIE_DMA_RD_XFERSIZE, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_XFERSIZE)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_SAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_SAR_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_SAR_PTR_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_SAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_SAR_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_SAR_PTR_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_DAR_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_DAR_PTR_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_DAR_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_RD_DAR_PTR_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_DOORBELL = %x\n", PCIE_DMA_RD_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_INT_STATUS = %x\n", PCIE_DMA_RD_INT_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_STATUS)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_LOW = %x\n", PCIE_DMA_RD_ERR_STATUS_LOW, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_LOW)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_ERR_STATUS_HIGH = %x\n", PCIE_DMA_RD_ERR_STATUS_HIGH, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ERR_STATUS_HIGH)); + } else { + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_MASK = %x\n", PCIE_DMA_WR_INT_MASK, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ENB = %x\n", PCIE_DMA_WR_ENB, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_LO = %x\n", ctr_off + PCIE_DMA_WR_CTRL_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_CTRL_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_CTRL_HI = %x\n", ctr_off + PCIE_DMA_WR_CTRL_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_CTRL_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_XFERSIZE = %x\n", ctr_off + PCIE_DMA_WR_XFERSIZE, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_XFERSIZE)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_SAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_SAR_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_SAR_PTR_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_SAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_SAR_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_SAR_PTR_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DAR_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_DAR_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_DAR_PTR_LO)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DAR_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_DAR_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + ctr_off + PCIE_DMA_WR_DAR_PTR_HI)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_DOORBELL = %x\n", PCIE_DMA_WR_DOORBELL, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_INT_STATUS = %x\n", PCIE_DMA_WR_INT_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS)); + dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_ERR_STATUS = %x\n", PCIE_DMA_WR_ERR_STATUS, pcie_rkep_readl_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ERR_STATUS)); + } +} + static void pcie_rkep_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off) { struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev); @@ -331,6 +407,7 @@ static void pcie_rkep_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cu cur->ctx_reg.darptrhi); pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL, cur->start.asdword); + // pcie_rkep_dma_debug(obj, cur); } static void pcie_rkep_start_dma_wr(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off) @@ -358,6 +435,7 @@ static void pcie_rkep_start_dma_wr(struct dma_trx_obj *obj, struct dma_table *cu cur->weilo.asdword); pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL, cur->start.asdword); + // pcie_rkep_dma_debug(obj, cur); } static void pcie_rkep_start_dma_dwc(struct dma_trx_obj *obj, struct dma_table *table) @@ -637,7 +715,7 @@ static int rkep_loadfile(struct device *dev, char *path, void __iomem *bar, int dev_info(dev, "%s file %s size %lld to %p\n", __func__, path, size, bar + pos); offset = 0; - kernel_read(p_file, bar + pos, size, &offset); + kernel_read(p_file, (void *)bar + pos, (size_t)size, (loff_t *)&offset); dev_info(dev, "kernel_read size %lld from %s to %p\n", size, path, bar + pos); @@ -674,6 +752,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct pcie_rkep *pcie_rkep; u8 *name; u16 val; + bool dmatest_irq = false; pcie_rkep = devm_kzalloc(&pdev->dev, sizeof(*pcie_rkep), GFP_KERNEL); if (!pcie_rkep) @@ -742,7 +821,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto err_register_irq; - pcie_rkep->dma_obj = pcie_dw_dmatest_register(&pdev->dev, true); + pcie_rkep->dma_obj = pcie_dw_dmatest_register(&pdev->dev, dmatest_irq); if (IS_ERR(pcie_rkep->dma_obj)) { dev_err(&pcie_rkep->pdev->dev, "failed to prepare dmatest\n"); ret = -EINVAL; @@ -753,14 +832,23 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id) pcie_rkep->dma_obj->start_dma_func = pcie_rkep_start_dma_dwc; pcie_rkep->dma_obj->config_dma_func = pcie_rkep_config_dma_dwc; pcie_rkep->dma_obj->get_dma_status = pcie_rkep_get_dma_status; + pcie_rkep->dma_obj->dma_debug = pcie_rkep_dma_debug; + if (!dmatest_irq) { + pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, 0xffffffff); + pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, 0xffffffff); + } } + + #if IS_ENABLED(CONFIG_PCIE_FUNC_RKEP_USERPAGES) pcie_rkep->user_pages = alloc_contig_pages(RKEP_USER_MEM_SIZE >> PAGE_SHIFT, GFP_KERNEL, 0, NULL); if (!pcie_rkep->user_pages) { dev_err(&pcie_rkep->pdev->dev, "failed to allocate contiguous pages\n"); ret = -EINVAL; + if (pcie_rkep->dma_obj) + pcie_dw_dmatest_unregister(pcie_rkep->dma_obj); goto err_register_obj; } dev_err(&pdev->dev, "successfully allocate continuouse buffer for userspace\n"); @@ -811,6 +899,9 @@ static void pcie_rkep_remove(struct pci_dev *pdev) struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev); int i; + if (pcie_rkep->dma_obj) + pcie_dw_dmatest_unregister(pcie_rkep->dma_obj); + device_remove_file(&pdev->dev, &dev_attr_rkep); #if IS_ENABLED(CONFIG_PCIE_FUNC_RKEP_USERPAGES) free_contig_range(page_to_pfn(pcie_rkep->user_pages), RKEP_USER_MEM_SIZE >> PAGE_SHIFT); diff --git a/drivers/pci/controller/dwc/pcie-dw-dmatest.c b/drivers/pci/controller/dwc/pcie-dw-dmatest.c index 4b0d4d3e01c8..f9c445a39e58 100644 --- a/drivers/pci/controller/dwc/pcie-dw-dmatest.c +++ b/drivers/pci/controller/dwc/pcie-dw-dmatest.c @@ -3,8 +3,6 @@ * Copyright (c) 2022 Rockchip Electronics Co., Ltd. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -14,8 +12,9 @@ #include #include #include +#include +#include -#include "pcie-designware.h" #include "pcie-dw-dmatest.h" #include "../rockchip-pcie-dma.h" @@ -35,12 +34,12 @@ static unsigned int rw_test = 3; module_param(rw_test, uint, 0644); MODULE_PARM_DESC(rw_test, "Read/Write test, 1-read 2-write 3-both(default 3)"); -static unsigned int bus_addr = 0x3c000000; -module_param(bus_addr, uint, 0644); +static unsigned long bus_addr = 0x3c000000; +module_param(bus_addr, ulong, 0644); MODULE_PARM_DESC(bus_addr, "Dmatest chn0 bus_addr(remote), chn1 add offset 0x100000, (default 0x3c000000)"); -static unsigned int local_addr = 0x3c000000; -module_param(local_addr, uint, 0644); +static unsigned long local_addr = 0x3c000000; +module_param(local_addr, ulong, 0644); MODULE_PARM_DESC(local_addr, "Dmatest chn0 local_addr(local), chn1 add offset 0x100000, (default 0x3c000000)"); static unsigned int test_dev; @@ -51,7 +50,7 @@ static bool is_rc = true; module_param_named(is_rc, is_rc, bool, 0644); MODULE_PARM_DESC(is_rc, "Test port is rc(default true)"); -#define PCIE_DW_MISC_DMATEST_DEV_MAX 5 +#define PCIE_DW_MISC_DMATEST_DEV_MAX 8 #define PCIE_DMA_CHANEL_MAX_NUM 2 @@ -64,6 +63,9 @@ struct pcie_dw_dmatest_dev { struct mutex rd_lock[PCIE_DMA_CHANEL_MAX_NUM]; /* Corresponding to each read DMA channel */ struct mutex wr_lock[PCIE_DMA_CHANEL_MAX_NUM]; /* Corresponding to each write DMA channel */ + + struct dma_table rd_tbl_buf[PCIE_DMA_CHANEL_MAX_NUM]; + struct dma_table wr_tbl_buf[PCIE_DMA_CHANEL_MAX_NUM]; }; static struct pcie_dw_dmatest_dev s_dmatest_dev[PCIE_DW_MISC_DMATEST_DEV_MAX]; @@ -83,19 +85,36 @@ static void pcie_dw_dmatest_show(void) dev_info(s_dmatest_dev[test_dev].obj->dev, " is current test_dev\n"); } -static int rk_pcie_dma_wait_for_finised(struct dma_trx_obj *obj, struct dma_table *table) +static int rk_pcie_dma_wait_for_finished(struct dma_trx_obj *obj, struct dma_table *table) { - int ret; + int ret = 0, timeout_us, i; - do { + timeout_us = table->buf_size / 100 + 1000; /* 100MB/s for redundant calculate */ + + for (i = 0; i < timeout_us; i++) { ret = obj->get_dma_status(obj, table->chn, table->dir); - } while (!ret); + if (ret == 1) { + ret = 0; + break; + } else if (ret < 0) { + ret = -EFAULT; + break; + } + udelay(1); + } + + if (i >= timeout_us || ret) { + dev_err(obj->dev, "%s timeout\n", __func__); + if (obj->dma_debug) + obj->dma_debug(obj, table); + return -EFAULT; + } return ret; } static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn, - u32 local_paddr, u32 bus_paddr, u32 size) + u64 local_paddr, u64 bus_paddr, u32 size) { struct dma_table *table; struct dma_trx_obj *obj = dmatest_dev->obj; @@ -104,11 +123,11 @@ static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 c if (chn >= PCIE_DMA_CHANEL_MAX_NUM) return -1; - table = kzalloc(sizeof(struct dma_table), GFP_KERNEL); - if (!table) - return -ENOMEM; - mutex_lock(&dmatest_dev->rd_lock[chn]); + + table = &dmatest_dev->rd_tbl_buf[chn]; + memset(table, 0, sizeof(struct dma_table)); + if (dmatest_dev->irq_en) reinit_completion(&dmatest_dev->rd_done[chn]); @@ -128,17 +147,15 @@ static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 c else if (ret == 0) dev_err(obj->dev, "%s timed out\n", __func__); } else { - ret = rk_pcie_dma_wait_for_finised(obj, table); + ret = rk_pcie_dma_wait_for_finished(obj, table); } mutex_unlock(&dmatest_dev->rd_lock[chn]); - kfree(table); - return ret; } static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn, - u32 bus_paddr, u32 local_paddr, u32 size) + u64 bus_paddr, u64 local_paddr, u32 size) { struct dma_table *table; struct dma_trx_obj *obj = dmatest_dev->obj; @@ -147,11 +164,11 @@ static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn if (chn >= PCIE_DMA_CHANEL_MAX_NUM) return -1; - table = kzalloc(sizeof(struct dma_table), GFP_KERNEL); - if (!table) - return -ENOMEM; - mutex_lock(&dmatest_dev->wr_lock[chn]); + + table = &dmatest_dev->wr_tbl_buf[chn]; + memset(table, 0, sizeof(struct dma_table)); + if (dmatest_dev->irq_en) reinit_completion(&dmatest_dev->wr_done[chn]); @@ -171,23 +188,21 @@ static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn else if (ret == 0) dev_err(obj->dev, "%s timed out\n", __func__); } else { - ret = rk_pcie_dma_wait_for_finised(obj, table); + ret = rk_pcie_dma_wait_for_finished(obj, table); } mutex_unlock(&dmatest_dev->wr_lock[chn]); - kfree(table); - return ret; } static int rk_pcie_rc_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn, - u32 local_paddr, u32 bus_paddr, u32 size) + u64 local_paddr, u64 bus_paddr, u32 size) { return rk_pcie_ep_dma_tobus(dmatest_dev, chn, local_paddr, bus_paddr, size); } static int rk_pcie_rc_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn, - u32 bus_paddr, u32 local_paddr, u32 size) + u64 bus_paddr, u64 local_paddr, u32 size) { return rk_pcie_ep_dma_frombus(dmatest_dev, chn, bus_paddr, local_paddr, size); } @@ -237,8 +252,29 @@ struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en) return obj; } +void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj) +{ + cur_dmatest_dev = 0; +} + +int pcie_dw_rc_dma_frombus(struct dma_trx_obj *obj, u32 chn, + u64 local_paddr, u64 bus_paddr, u32 size) +{ + struct pcie_dw_dmatest_dev *dmatest_dev = obj->priv; + + return rk_pcie_ep_dma_tobus(dmatest_dev, chn, local_paddr, bus_paddr, size); +} + +int pcie_dw_rc_dma_tobus(struct dma_trx_obj *obj, u32 chn, + u64 bus_paddr, u64 local_paddr, u32 size) +{ + struct pcie_dw_dmatest_dev *dmatest_dev = obj->priv; + + return rk_pcie_ep_dma_frombus(dmatest_dev, chn, bus_paddr, local_paddr, size); +} + static int dma_test(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn, - u32 bus_paddr, u32 local_paddr, u32 size, u32 loop, u8 rd_en, u8 wr_en) + u64 bus_paddr, u64 local_paddr, u32 size, u32 loop, u8 rd_en, u8 wr_en) { ktime_t start_time; ktime_t end_time; diff --git a/drivers/pci/controller/dwc/pcie-dw-dmatest.h b/drivers/pci/controller/dwc/pcie-dw-dmatest.h index cfed7aa22914..68fa1b1efc60 100644 --- a/drivers/pci/controller/dwc/pcie-dw-dmatest.h +++ b/drivers/pci/controller/dwc/pcie-dw-dmatest.h @@ -10,11 +10,26 @@ struct device; #if IS_ENABLED(CONFIG_PCIE_DW_DMATEST) struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en); +void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj); +int pcie_dw_rc_dma_frombus(struct dma_trx_obj *obj, u32 chn, u64 local_paddr, u64 bus_paddr, u32 size); +int pcie_dw_rc_dma_tobus(struct dma_trx_obj *obj, u32 chn, u64 bus_paddr, u64 local_paddr, u32 size); #else static inline struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en) { return NULL; } + +static inline void pcie_dw_dmatest_unregister(struct dma_trx_obj *obj) { } + +static inline int pcie_dw_rc_dma_frombus(struct dma_trx_obj *obj, u32 chn, u64 local_paddr, u64 bus_paddr, u32 size) +{ + return -1; +} + +static inline int pcie_dw_rc_dma_tobus(struct dma_trx_obj *obj, u32 chn, u64 bus_paddr, u64 local_paddr, u32 size) +{ + return -1; +} #endif #endif diff --git a/drivers/pci/controller/rockchip-pcie-dma.h b/drivers/pci/controller/rockchip-pcie-dma.h index e9da2d0e16ac..4a184fcaf122 100644 --- a/drivers/pci/controller/rockchip-pcie-dma.h +++ b/drivers/pci/controller/rockchip-pcie-dma.h @@ -192,6 +192,7 @@ struct dma_trx_obj { void (*config_dma_func)(struct dma_table *table); int (*get_dma_status)(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir); int (*cb)(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir); + void (*dma_debug)(struct dma_trx_obj *obj, struct dma_table *table); ktime_t begin; ktime_t end; u64 cache_time_total; diff --git a/include/uapi/linux/rk-pcie-ep.h b/include/uapi/linux/rk-pcie-ep.h index b6e3ac04ac2b..c5c42507f7b5 100644 --- a/include/uapi/linux/rk-pcie-ep.h +++ b/include/uapi/linux/rk-pcie-ep.h @@ -40,6 +40,21 @@ struct pcie_ep_dma_cache_cfg { __u32 size; }; +struct pcie_ep_dma_block { + __u64 bus_paddr; + __u64 local_paddr; + __u32 size; +}; + +struct pcie_ep_dma_block_req { + __u16 vir_id; /* Default 0 */ + __u8 chn; + __u8 wr; + __u32 flag; +#define PCIE_EP_DMA_BLOCK_FLAG_COHERENT BIT(0) /* Cache coherent, 1-need, 0-None */ + struct pcie_ep_dma_block block; +}; + #define PCIE_EP_OBJ_INFO_MAGIC 0x524B4550 enum pcie_ep_obj_irq_type { @@ -89,5 +104,6 @@ struct pcie_ep_obj_info { #define PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER _IOW(PCIE_BASE, 4, int) #define PCIE_EP_GET_USER_INFO _IOR(PCIE_BASE, 5, struct pcie_ep_user_data) #define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, enum pcie_ep_mmap_resource) +#define PCIE_EP_DMA_XFER_BLOCK _IOW(PCIE_BASE, 32, struct pcie_ep_dma_block_req) #endif diff --git a/sound/soc/rockchip/rockchip_multi_dais_pcm.c b/sound/soc/rockchip/rockchip_multi_dais_pcm.c index 17e12bac7b11..d0173bfd54aa 100644 --- a/sound/soc/rockchip/rockchip_multi_dais_pcm.c +++ b/sound/soc/rockchip/rockchip_multi_dais_pcm.c @@ -617,7 +617,7 @@ static int dmaengine_mpcm_set_runtime_hwparams(struct snd_pcm_substream *substre int ret; chan = to_chan(pcm, substream); - if (!chan) + if (!chan || !dma_dev) return -EINVAL; memset(&hw, 0, sizeof(hw)); @@ -721,6 +721,7 @@ static int dmaengine_mpcm_new(struct snd_soc_component *component, struct snd_so { struct dmaengine_mpcm *pcm = soc_component_to_mpcm(component); struct snd_pcm_substream *substream; + struct device *dma_dev; size_t prealloc_buffer_size; size_t max_buffer_size; unsigned int i; @@ -733,9 +734,15 @@ static int dmaengine_mpcm_new(struct snd_soc_component *component, struct snd_so if (!substream) continue; + dma_dev = dmaengine_dma_dev(pcm, substream); + if (!dma_dev) { + dev_err(component->dev, "No chan found, should assign 'rockchip,no-dmaengine' in DT\n"); + return -EINVAL; + } + snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_IRAM, - dmaengine_dma_dev(pcm, substream), + dma_dev, prealloc_buffer_size, max_buffer_size); }