Merge commit '624ca942fb32d32a3769b7f7bf56511cf9bb2685'

* commit '624ca942fb32d32a3769b7f7bf56511cf9bb2685':
  drm/rockchip: vop2: enable vp0 dclk for deassert hdmi1/edp1 mux in rk3588
  misc: rockchip: pcie-rkep: Support ioctl PCIE_EP_DMA_XFER_BLOCK
  PCI: rockchip: dw: Export DMA transmission interface
  PCI: rockchip: dw: Support dma_debug for DMA debug
  arm64: dts: rockchip: rk3566 evb: add edp panel phy size config
  arm64: dts: rockchip: rk3288 evb: add edp panel phy size config
  arm64: dts: rockchip: rk3399 evb: add edp panel phy size config
  arm64: dts: rockchip: rk3588 evb: fix edp panel phy size config
  ASoC: rockchip: multi-dais: Fix error path handle
  arm64: dts: rockchip: rk3562 evb: add mipi panel phy size config
  arm64: dts: rockchip: rk3568 evb: add mipi panel phy size config
  arm64: dts: rockchip: rk3588 evb: add mipi panel phy size config
  media: rockchip: isp: remove param run double

Change-Id: I36c59067e59a4ac7987704d96fade104b844a8af
This commit is contained in:
Tao Huang
2023-10-24 11:36:54 +08:00
31 changed files with 277 additions and 56 deletions

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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 = <MIPI_DSI_FMT_RGB888>;

View File

@@ -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>;

View File

@@ -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 = <MIPI_DSI_FMT_RGB888>;
@@ -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 = <MIPI_DSI_FMT_RGB888>;

View File

@@ -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 = <MIPI_DSI_FMT_RGB888>;
@@ -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 = <MIPI_DSI_FMT_RGB888>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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>;

View File

@@ -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);
}

View File

@@ -130,11 +130,6 @@ static int rkisp_params_vb2_queue_setup(struct vb2_queue *vq,
INIT_LIST_HEAD(&params_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);

View File

@@ -19,10 +19,15 @@
#include <linux/mutex.h>
#include <linux/ctype.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <uapi/linux/rk-pcie-ep.h>
#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);

View File

@@ -3,8 +3,6 @@
* Copyright (c) 2022 Rockchip Electronics Co., Ltd.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h>
#include <linux/ktime.h>
#include <linux/module.h>
@@ -14,8 +12,9 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}