Merge commit '8b15ae280af3fb565e89bf7e7746f47766bb00a4'

* commit '8b15ae280af3fb565e89bf7e7746f47766bb00a4':
  video: rockchip: mpp: optimize iommu faul handle for ccu flow
  media: rockchip: isp: fix rockit set_fmt stuck
  pwm: rockchip: rename pwm-rockchip.h to pwm-rockchip-irq-callbacks.h
  media: i2c: sc223a fix dvp image error
  media: i2c: sc223a add dvp configuration
  video: rockchip: mpp: rkvenc2: fix irq proc
  ARM: dts: rockchip: rv1126: add pwm irq configs
  PCI: rockchip: dw: Support DMA linked list mode
  PCI: rockchip: dw: Adding DMA linked list mode definition
  video: rockchip: rga3: fix import failure does not return error code
  media: rockchip: isp: fix power_cnt if error
  drm: bridge: dw-hdmi: fix incorrect I2CM configuration
  Revert "drm: bridge: dw-hdmi: Fixed ddc error caused by plug out hdmi when reading edid"
  arm64: configs: rockchip_defconfig: Enable CONFIG_MFD_RK806_I2C
  arm64: dts: rockchip: rk3528: add pwm irq configs
  arm64: dts: rockchip: rk3328: add pwm irq configs
  arm64: dts: rockchip: rk1808: add pwm irq configs

Change-Id: I4ce6137b655a57fa97b9d2ae14b49b1ecf27db1d
This commit is contained in:
Tao Huang
2023-12-01 20:58:48 +08:00
24 changed files with 803 additions and 358 deletions

View File

@@ -957,6 +957,7 @@
pwm0: pwm@ff430000 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff430000 0x10>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm0m0_pins>;
@@ -968,6 +969,7 @@
pwm1: pwm@ff430010 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff430010 0x10>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm1m0_pins>;
@@ -979,6 +981,7 @@
pwm2: pwm@ff430020 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff430020 0x10>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm2m0_pins>;
@@ -990,6 +993,8 @@
pwm3: pwm@ff430030 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff430030 0x10>;
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm3m0_pins>;
@@ -1001,6 +1006,7 @@
pwm4: pwm@ff440000 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff440000 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm4m0_pins>;
@@ -1012,6 +1018,7 @@
pwm5: pwm@ff440010 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff440010 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm5m0_pins>;
@@ -1023,6 +1030,7 @@
pwm6: pwm@ff440020 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff440020 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm6m0_pins>;
@@ -1034,6 +1042,8 @@
pwm7: pwm@ff440030 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff440030 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm7m0_pins>;
@@ -1269,6 +1279,7 @@
pwm8: pwm@ff550000 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff550000 0x10>;
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm8m0_pins>;
@@ -1280,6 +1291,7 @@
pwm9: pwm@ff550010 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff550010 0x10>;
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm9m0_pins>;
@@ -1291,6 +1303,7 @@
pwm10: pwm@ff550020 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff550020 0x10>;
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm10m0_pins>;
@@ -1302,6 +1315,8 @@
pwm11: pwm@ff550030 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff550030 0x10>;
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm11m0_pins>;

View File

@@ -808,6 +808,7 @@
pwm0: pwm@ff3d0000 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d0000 0x0 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm0_pin>;
@@ -819,6 +820,7 @@
pwm1: pwm@ff3d0010 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d0010 0x0 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm1_pin>;
@@ -830,6 +832,7 @@
pwm2: pwm@ff3d0020 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d0020 0x0 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm2_pin>;
@@ -841,6 +844,8 @@
pwm3: pwm@ff3d0030 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d0030 0x0 0x10>;
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm3_pin>;
@@ -852,6 +857,7 @@
pwm4: pwm@ff3d8000 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d8000 0x0 0x10>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm4_pin>;
@@ -863,6 +869,7 @@
pwm5: pwm@ff3d8010 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d8010 0x0 0x10>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm5_pin>;
@@ -874,6 +881,7 @@
pwm6: pwm@ff3d8020 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d8020 0x0 0x10>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm6_pin>;
@@ -885,6 +893,8 @@
pwm7: pwm@ff3d8030 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff3d8030 0x0 0x10>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm7_pin>;
@@ -1213,6 +1223,7 @@
pwm8: pwm@ff5d0000 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff5d0000 0x0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm8_pin>;
@@ -1224,6 +1235,7 @@
pwm9: pwm@fff5d0010 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff5d0010 0x0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm9_pin>;
@@ -1235,6 +1247,7 @@
pwm10: pwm@ff5d0020 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff5d0020 0x0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm10_pin>;
@@ -1246,6 +1259,8 @@
pwm11: pwm@ff5d0030 {
compatible = "rockchip,rk1808-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xff5d0030 0x0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm11_pin>;

View File

@@ -684,6 +684,7 @@
pwm0: pwm@ff1b0000 {
compatible = "rockchip,rk3328-pwm";
reg = <0x0 0xff1b0000 0x0 0x10>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@@ -695,6 +696,7 @@
pwm1: pwm@ff1b0010 {
compatible = "rockchip,rk3328-pwm";
reg = <0x0 0xff1b0010 0x0 0x10>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";
@@ -706,6 +708,7 @@
pwm2: pwm@ff1b0020 {
compatible = "rockchip,rk3328-pwm";
reg = <0x0 0xff1b0020 0x0 0x10>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>;
clock-names = "pwm", "pclk";
pinctrl-names = "active";

View File

@@ -1803,6 +1803,7 @@
pwm0: pwm@ffa90000 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa90000 0x0 0x10>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm0m0_pins>;
@@ -1814,6 +1815,7 @@
pwm1: pwm@ffa90010 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa90010 0x0 0x10>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm1m0_pins>;
@@ -1825,6 +1827,7 @@
pwm2: pwm@ffa90020 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa90020 0x0 0x10>;
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm2m0_pins>;
@@ -1849,6 +1852,7 @@
pwm4: pwm@ffa98000 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa98000 0x0 0x10>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm4m0_pins>;
@@ -1860,6 +1864,7 @@
pwm5: pwm@ffa98010 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa98010 0x0 0x10>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm5m0_pins>;
@@ -1871,6 +1876,7 @@
pwm6: pwm@ffa98020 {
compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xffa98020 0x0 0x10>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm6m0_pins>;

View File

@@ -558,6 +558,7 @@ CONFIG_DW_WATCHDOG=y
CONFIG_MFD_RK618=y
CONFIG_MFD_RK628=y
CONFIG_MFD_RK630_I2C=y
CONFIG_MFD_RK806_I2C=y
CONFIG_MFD_RK806_SPI=y
CONFIG_MFD_RK808=y
CONFIG_MFD_RKX110_X120=y

View File

@@ -426,14 +426,18 @@ static void repo_hpd_event(struct work_struct *p_work)
if (hdmi->bridge.dev) {
bool change;
void *data = hdmi->plat_data->phy_data;
change = drm_helper_hpd_irq_event(hdmi->bridge.dev);
if (change && hdmi->cec_adap &&
hdmi->cec_adap->devnode.registered)
cec_queue_pin_hpd_event(hdmi->cec_adap,
hdmi->hpd_state,
ktime_get());
if (change) {
if (hdmi->plat_data->set_ddc_io)
hdmi->plat_data->set_ddc_io(data, hdmi->hpd_state);
if (hdmi->cec_adap->devnode.registered)
cec_queue_pin_hpd_event(hdmi->cec_adap,
hdmi->hpd_state,
ktime_get());
}
drm_bridge_hpd_notify(&hdmi->bridge, status);
}
}
@@ -539,10 +543,12 @@ static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
HDMI_IH_MUTE_I2CM_STAT0);
/* set SDA high level holding time */
hdmi_writeb(hdmi, 0x48, HDMI_I2CM_SDA_HOLD);
dw_hdmi_i2c_set_divs(hdmi);
/* Only configure when we use the internal I2C controller */
if (hdmi->i2c) {
/* set SDA high level holding time */
hdmi_writeb(hdmi, 0x48, HDMI_I2CM_SDA_HOLD);
dw_hdmi_i2c_set_divs(hdmi);
}
}
static bool dw_hdmi_i2c_unwedge(struct dw_hdmi *hdmi)
@@ -647,11 +653,7 @@ static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi,
while (retry > 0) {
if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
void *data = hdmi->plat_data->phy_data;
dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc read\n");
if (hdmi->plat_data->set_ddc_io)
hdmi->plat_data->set_ddc_io(data, false);
return -EPERM;
}
@@ -730,11 +732,7 @@ static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi,
while (retry > 0) {
if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
void *data = hdmi->plat_data->phy_data;
dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc write\n");
if (hdmi->plat_data->set_ddc_io)
hdmi->plat_data->set_ddc_io(data, false);
return -EPERM;
}
@@ -779,7 +777,6 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
struct dw_hdmi_i2c *i2c = hdmi->i2c;
u8 addr = msgs[0].addr;
void *data = hdmi->plat_data->phy_data;
int i, ret = 0;
if (addr == DDC_CI_ADDR)
@@ -804,9 +801,6 @@ static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
mutex_lock(&i2c->lock);
if (hdmi->plat_data->set_ddc_io)
hdmi->plat_data->set_ddc_io(data, true);
hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
udelay(100);
@@ -4112,7 +4106,6 @@ static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_state)
{
struct dw_hdmi *hdmi = bridge->driver_private;
void *data = hdmi->plat_data->phy_data;
mutex_lock(&hdmi->mutex);
hdmi->disabled = true;
@@ -4123,11 +4116,6 @@ static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
if (hdmi->plat_data->dclk_set)
hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, false, 0);
mutex_unlock(&hdmi->mutex);
mutex_lock(&hdmi->i2c->lock);
if (hdmi->plat_data->set_ddc_io)
hdmi->plat_data->set_ddc_io(data, false);
mutex_unlock(&hdmi->i2c->lock);
}
static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -4457,8 +4445,7 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
* Even if we are using a separate i2c adapter doing this doesn't
* hurt.
*/
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
dw_hdmi_i2c_init(hdmi);
if (hdmi->phy.ops->setup_hpd)
hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
@@ -5414,8 +5401,7 @@ void dw_hdmi_resume(struct dw_hdmi *hdmi)
pinctrl_pm_select_default_state(hdmi->dev);
mutex_lock(&hdmi->mutex);
dw_hdmi_reg_initial(hdmi);
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
dw_hdmi_i2c_init(hdmi);
if (hdmi->irq)
enable_irq(hdmi->irq);
/*

View File

@@ -40,6 +40,8 @@
#define PIXEL_RATE_WITH_405M_10BIT (SC223A_LINK_FREQ_405 * 2 * \
SC223A_LANES / SC223A_BITS_PER_SAMPLE)
/* 79.2Mhz */
#define SC223A_PIXEL_RATE (79200000)
#define SC223A_XVCLK_FREQ 24000000
#define CHIP_ID 0xcb3e
@@ -93,10 +95,12 @@
#define SC223A_REG_VALUE_16BIT 2
#define SC223A_REG_VALUE_24BIT 3
#define RKMODULE_CAMERA_MODULE_MODE "rockchip,camera_mode"
#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
#define SC223A_NAME "sc223a"
#define CAMERA_MIPI_MODE "mipi_mode"
#define CAMERA_DVP_MODE "dvp_mode"
static const char * const sc223a_supply_names[] = {
"avdd", /* Analog power */
"dovdd", /* Digital I/O power */
@@ -105,6 +109,17 @@ static const char * const sc223a_supply_names[] = {
#define SC223A_NUM_SUPPLIES ARRAY_SIZE(sc223a_supply_names)
enum sc223a_support_mode_id {
SC223A_MIPI_1920X1080 = 0,
SC223A_DVP_1920X1080,
SC223A_MODE_ID_MAX = SC223A_DVP_1920X1080,
};
enum sc223a_mode_id {
SC223A_MIPI_MODE = 0,
SC223A_DVP_MODE,
};
struct regval {
u16 addr;
u8 val;
@@ -121,6 +136,7 @@ struct sc223a_mode {
const struct regval *reg_list;
u32 hdr_mode;
u32 vc[PAD_MAX];
u8 mode_id;
};
struct sc223a {
@@ -152,6 +168,7 @@ struct sc223a {
const char *module_facing;
const char *module_name;
const char *len_name;
const char *mode;
u32 cur_vts;
bool has_init_exp;
bool is_thunderboot;
@@ -353,8 +370,223 @@ static const struct regval sc223a_linear_10_1920x1080_30fps_regs[] = {
{REG_NULL, 0x00},
};
/*
* Xclk 24Mhz
* Pclk 79.2Mhz
* max_framerate 30fps
* 1920x1080
* dvp 10bit, 2lane
*/
static const struct regval sc223a_linear_10_1920x1080_dvp_30fps_regs[] = {
{0x0100, 0x00},
{0x36e9, 0x80},
{0x37f9, 0x80},
{0x3001, 0xff},
{0x3002, 0xf0},
{0x300a, 0x24},
{0x3018, 0x0f},
{0x301a, 0xf8},
{0x301c, 0x94},
{0x301f, 0x40},
{0x303f, 0x81},
{0x30b8, 0x44},
{0x3200, 0x00},
{0x3201, 0x00},
{0x3202, 0x00},
{0x3203, 0x00},
{0x3204, 0x07},
{0x3205, 0x87},
{0x3206, 0x04},
{0x3207, 0x3f},
{0x3208, 0x07},
{0x3209, 0x80},
{0x320a, 0x04},
{0x320b, 0x38},
{0x320c, 0x09},
{0x320d, 0x60},
{0x320e, 0x04},
{0x320f, 0x65},
{0x3210, 0x00},
{0x3211, 0x04},
{0x3212, 0x00},
{0x3213, 0x04},
{0x3227, 0x03},
{0x3250, 0x00},
{0x3253, 0x0c},
{0x3281, 0x80},
{0x3301, 0x06},
{0x3302, 0x12},
{0x3306, 0x84},
{0x3309, 0x60},
{0x330a, 0x00},
{0x330b, 0xe0},
{0x330d, 0x20},
{0x3314, 0x15},
{0x331e, 0x41},
{0x331f, 0x51},
{0x3320, 0x0a},
{0x3326, 0x0e},
{0x3333, 0x10},
{0x3334, 0x40},
{0x335d, 0x60},
{0x335e, 0x06},
{0x335f, 0x08},
{0x3364, 0x56},
{0x337a, 0x06},
{0x337b, 0x0e},
{0x337c, 0x02},
{0x337d, 0x0a},
{0x3390, 0x03},
{0x3391, 0x0f},
{0x3392, 0x1f},
{0x3393, 0x06},
{0x3394, 0x06},
{0x3395, 0x06},
{0x3396, 0x48},
{0x3397, 0x4b},
{0x3398, 0x5f},
{0x3399, 0x06},
{0x339a, 0x06},
{0x339b, 0x9c},
{0x339c, 0x9c},
{0x33a2, 0x04},
{0x33a3, 0x0a},
{0x33ad, 0x1c},
{0x33af, 0x40},
{0x33b1, 0x80},
{0x33b3, 0x20},
{0x349f, 0x02},
{0x34a6, 0x48},
{0x34a7, 0x4b},
{0x34a8, 0x20},
{0x34a9, 0x20},
{0x34f8, 0x5f},
{0x34f9, 0x10},
{0x3616, 0xac},
{0x3630, 0xc0},
{0x3631, 0x86},
{0x3632, 0x26},
{0x3633, 0x32},
{0x3637, 0x29},
{0x363a, 0x84},
{0x363b, 0x04},
{0x363c, 0x08},
{0x3641, 0x3a},
{0x364f, 0x39},
{0x3670, 0xce},
{0x3674, 0xc0},
{0x3675, 0xc0},
{0x3676, 0xc0},
{0x3677, 0x86},
{0x3678, 0x8b},
{0x3679, 0x8c},
{0x367c, 0x4b},
{0x367d, 0x5f},
{0x367e, 0x4b},
{0x367f, 0x5f},
{0x3690, 0x62},
{0x3691, 0x63},
{0x3692, 0x63},
{0x3699, 0x86},
{0x369a, 0x92},
{0x369b, 0xa4},
{0x369c, 0x48},
{0x369d, 0x4b},
{0x36a2, 0x4b},
{0x36a3, 0x4f},
{0x36ea, 0x09},
{0x36eb, 0x0c},
{0x36ec, 0x1c},
{0x36ed, 0x28},
{0x370f, 0x01},
{0x3721, 0x6c},
{0x3722, 0x09},
{0x3724, 0x41},
{0x3725, 0xc4},
{0x37b0, 0x09},
{0x37b1, 0x09},
{0x37b2, 0x09},
{0x37b3, 0x48},
{0x37b4, 0x5f},
{0x37fa, 0x09},
{0x37fb, 0x32},
{0x37fc, 0x10},
{0x37fd, 0x37},
{0x3900, 0x19},
{0x3901, 0x02},
{0x3905, 0xb8},
{0x391b, 0x82},
{0x391c, 0x00},
{0x391f, 0x04},
{0x3928, 0xc1},
{0x3933, 0x81},
{0x3934, 0x4c},
{0x393f, 0xff},
{0x3940, 0x73},
{0x3942, 0x01},
{0x3943, 0x4d},
{0x3946, 0x20},
{0x3957, 0x86},
{0x3e01, 0x8c},
{0x3e02, 0x00},
{0x3e28, 0xc4},
{0x440e, 0x02},
{0x4501, 0xc0},
{0x4509, 0x14},
{0x450d, 0x11},
{0x4518, 0x00},
{0x451b, 0x0a},
{0x4603, 0x09},
{0x4819, 0x07},
{0x481b, 0x04},
{0x481d, 0x0e},
{0x3000, 0xff},
{0x481f, 0x03},
{0x4821, 0x09},
{0x4823, 0x04},
{0x4825, 0x03},
{0x4827, 0x03},
{0x4829, 0x06},
{0x501c, 0x00},
{0x501d, 0x60},
{0x501e, 0x00},
{0x501f, 0x40},
{0x5799, 0x06},
{0x5ae0, 0xfe},
{0x5ae1, 0x40},
{0x5ae2, 0x38},
{0x5ae3, 0x30},
{0x5ae4, 0x28},
{0x5ae5, 0x38},
{0x5ae6, 0x30},
{0x5ae7, 0x28},
{0x5ae8, 0x3f},
{0x5ae9, 0x34},
{0x5aea, 0x2c},
{0x5aeb, 0x3f},
{0x5aec, 0x34},
{0x5aed, 0x2c},
{0x5aee, 0xfe},
{0x5aef, 0x40},
{0x5af4, 0x38},
{0x5af5, 0x30},
{0x5af6, 0x28},
{0x5af7, 0x38},
{0x5af8, 0x30},
{0x5af9, 0x28},
{0x5afa, 0x3f},
{0x5afb, 0x34},
{0x5afc, 0x2c},
{0x5afd, 0x3f},
{0x5afe, 0x34},
{0x5aff, 0x2c},
{0x36e9, 0x53},
{0x37f9, 0x53},
{REG_NULL, 0x00},
};
static const struct sc223a_mode supported_modes[] = {
{
[SC223A_MIPI_1920X1080] = {
.width = 1920,
.height = 1080,
.max_fps = {
@@ -367,11 +599,28 @@ static const struct sc223a_mode supported_modes[] = {
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
.reg_list = sc223a_linear_10_1920x1080_30fps_regs,
.hdr_mode = NO_HDR,
.mode_id = SC223A_MIPI_MODE,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
}
},
[SC223A_DVP_1920X1080] = {
.width = 1920,
.height = 1080,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x0080,
.hts_def = 0x0960,
.vts_def = 0x0465,
.bus_fmt = MEDIA_BUS_FMT_SBGGR8_1X8,
.reg_list = sc223a_linear_10_1920x1080_dvp_30fps_regs,
.hdr_mode = NO_HDR,
.mode_id = SC223A_DVP_MODE,
.vc[PAD0] = 0,
},
};
static const s64 link_freq_menu_items[] = {
static const __maybe_unused s64 link_freq_menu_items[] = {
SC223A_LINK_FREQ_405
};
@@ -694,17 +943,25 @@ static int sc223a_g_mbus_config(struct v4l2_subdev *sd,
struct sc223a *sc223a = to_sc223a(sd);
const struct sc223a_mode *mode = sc223a->cur_mode;
u32 val = 1 << (SC223A_LANES - 1) |
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
u32 val;
if (mode->hdr_mode != NO_HDR)
val |= V4L2_MBUS_CSI2_CHANNEL_1;
if (mode->hdr_mode == HDR_X3)
val |= V4L2_MBUS_CSI2_CHANNEL_2;
if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
val = 1 << (SC223A_LANES - 1) |
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
if (mode->hdr_mode != NO_HDR)
val |= V4L2_MBUS_CSI2_CHANNEL_1;
if (mode->hdr_mode == HDR_X3)
val |= V4L2_MBUS_CSI2_CHANNEL_2;
config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
config->type = V4L2_MBUS_PARALLEL;
config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_VSYNC_ACTIVE_LOW |
V4L2_MBUS_PCLK_SAMPLE_RISING;
}
return 0;
}
@@ -724,6 +981,7 @@ static long sc223a_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
struct sc223a *sc223a = to_sc223a(sd);
struct rkmodule_hdr_cfg *hdr;
u32 i, h, w;
u8 mode;
long ret = 0;
u32 stream = 0;
@@ -740,9 +998,11 @@ static long sc223a_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
hdr = (struct rkmodule_hdr_cfg *)arg;
w = sc223a->cur_mode->width;
h = sc223a->cur_mode->height;
mode = sc223a->cur_mode->mode_id;
for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
if (w == supported_modes[i].width &&
h == supported_modes[i].height &&
mode == supported_modes[i].mode_id &&
supported_modes[i].hdr_mode == hdr->hdr_mode) {
sc223a->cur_mode = &supported_modes[i];
break;
@@ -889,6 +1149,7 @@ static int __sc223a_start_stream(struct sc223a *sc223a)
}
}
}
return sc223a_write_reg(sc223a->client, SC223A_REG_CTRL_MODE,
SC223A_REG_VALUE_08BIT, SC223A_MODE_STREAMING);
}
@@ -1293,13 +1554,18 @@ static int sc223a_initialize_controls(struct sc223a *sc223a)
return ret;
handler->lock = &sc223a->mutex;
ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
0, 0, link_freq_menu_items);
if (ctrl)
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
0, 0, link_freq_menu_items);
if (ctrl)
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
0, PIXEL_RATE_WITH_405M_10BIT, 1, PIXEL_RATE_WITH_405M_10BIT);
} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
0, SC223A_PIXEL_RATE, 1, SC223A_PIXEL_RATE);
}
v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
0, PIXEL_RATE_WITH_405M_10BIT, 1, PIXEL_RATE_WITH_405M_10BIT);
h_blank = mode->hts_def - mode->width;
sc223a->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
@@ -1412,6 +1678,8 @@ static int sc223a_probe(struct i2c_client *client,
&sc223a->module_name);
ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
&sc223a->len_name);
ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_MODE,
&sc223a->mode);
if (ret) {
dev_err(dev, "could not get module information!\n");
return -EINVAL;
@@ -1420,14 +1688,18 @@ static int sc223a_probe(struct i2c_client *client,
sc223a->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
sc223a->client = client;
for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
if (hdr_mode == supported_modes[i].hdr_mode) {
sc223a->cur_mode = &supported_modes[i];
break;
if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
if (hdr_mode == supported_modes[i].hdr_mode) {
sc223a->cur_mode = &supported_modes[i];
break;
}
}
if (i == ARRAY_SIZE(supported_modes))
sc223a->cur_mode = &supported_modes[SC223A_MIPI_1920X1080];
} else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
sc223a->cur_mode = &supported_modes[SC223A_DVP_1920X1080];
}
if (i == ARRAY_SIZE(supported_modes))
sc223a->cur_mode = &supported_modes[0];
sc223a->xvclk = devm_clk_get(dev, "xvclk");
if (IS_ERR(sc223a->xvclk)) {

View File

@@ -280,16 +280,19 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p,
if (prepare) {
ret = __isp_pipeline_prepare(p, me);
if (ret < 0)
return ret;
goto err;
}
ret = __isp_pipeline_s_isp_clk(p);
if (ret < 0)
return ret;
goto err;
if (dev->isp_inp & (INP_CSI | INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF))
rkisp_csi_config_patch(dev);
return 0;
err:
atomic_dec(&p->power_cnt);
return ret;
}
static int rkisp_pipeline_close(struct rkisp_pipeline *p)

View File

@@ -310,8 +310,9 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg,
int width, int height, int wrap_line)
{
struct rkisp_stream *stream = NULL;
struct rkisp_buffer *isp_buf;
struct rkisp_buffer *isp_buf, *buf_temp;
int offset, i, ret;
unsigned long lock_flags = 0;
stream = rkisp_rockit_get_stream(input_rockit_cfg);
@@ -331,16 +332,18 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg,
if (stream->ispdev->cap_dev.wrap_line && stream->id == RKISP_STREAM_MP)
rkisp_dvbm_init(stream);
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
if (stream->curr_buf) {
list_add_tail(&stream->curr_buf->queue, &stream->buf_queue);
if (stream->curr_buf == stream->next_buf)
stream->next_buf = NULL;
stream->curr_buf = NULL;
}
if (stream->next_buf) {
list_add_tail(&stream->next_buf->queue, &stream->buf_queue);
stream->next_buf = NULL;
}
list_for_each_entry(isp_buf, &stream->buf_queue, queue) {
list_for_each_entry_safe(isp_buf, buf_temp, &stream->buf_queue, queue) {
if (stream->out_isp_fmt.mplanes == 1) {
for (i = 0; i < stream->out_isp_fmt.cplanes - 1; i++) {
height = stream->out_fmt.height;
@@ -352,6 +355,7 @@ int rkisp_rockit_config_stream(struct rockit_cfg *input_rockit_cfg,
}
}
}
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
return 0;
}

View File

@@ -56,6 +56,8 @@ static DEFINE_MUTEX(rkep_mutex);
#define PCIE_DMA_WR_SAR_PTR_HI 0x210
#define PCIE_DMA_WR_DAR_PTR_LO 0x214
#define PCIE_DMA_WR_DAR_PTR_HI 0x218
#define PCIE_DMA_WR_LL_PTR_LO 0x21c
#define PCIE_DMA_WR_LL_PTR_HI 0x220
#define PCIE_DMA_WR_WEILO 0x18
#define PCIE_DMA_WR_WEIHI 0x1c
#define PCIE_DMA_WR_DOORBELL 0x10
@@ -63,6 +65,7 @@ static DEFINE_MUTEX(rkep_mutex);
#define PCIE_DMA_WR_INT_MASK 0x54
#define PCIE_DMA_WR_INT_CLEAR 0x58
#define PCIE_DMA_WR_ERR_STATUS 0x5c
#define PCIE_DMA_WR_LL_ERR_EN 0x90
#define PCIE_DMA_RD_ENB 0x2c
#define PCIE_DMA_RD_CTRL_LO 0x300
@@ -72,6 +75,8 @@ static DEFINE_MUTEX(rkep_mutex);
#define PCIE_DMA_RD_SAR_PTR_HI 0x310
#define PCIE_DMA_RD_DAR_PTR_LO 0x314
#define PCIE_DMA_RD_DAR_PTR_HI 0x318
#define PCIE_DMA_RD_LL_PTR_LO 0x31c
#define PCIE_DMA_RD_LL_PTR_HI 0x320
#define PCIE_DMA_RD_WEILO 0x38
#define PCIE_DMA_RD_WEIHI 0x3c
#define PCIE_DMA_RD_DOORBELL 0x30
@@ -80,6 +85,7 @@ static DEFINE_MUTEX(rkep_mutex);
#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_RD_LL_ERR_EN 0xc4
#define PCIE_DMA_CHANEL_MAX_NUM 2
@@ -133,9 +139,9 @@ static int rkep_ep_dma_xfer(struct pcie_rkep *pcie_rkep, struct pcie_ep_dma_bloc
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);
ret = pcie_dw_wired_dma_tobus_block(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);
ret = pcie_dw_wired_dma_frombus_block(pcie_rkep->dma_obj, dma->chn, dma->block.local_paddr, dma->block.bus_paddr, dma->block.size);
return ret;
}
@@ -660,41 +666,69 @@ 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;
unsigned int ctr_off = PCIE_DMA_OFFSET + 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);
if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
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);
} else {
dev_err(&pdev->dev, "phys_descs=0x%llx\n", table->phys_descs);
}
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));
if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
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, 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, 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, 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, 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, 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, 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, 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_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, 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, ctr_off + PCIE_DMA_RD_CTRL_HI));
dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_LL_PTR_LO = %x\n", ctr_off + PCIE_DMA_RD_LL_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_LO));
dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_RD_LL_PTR_HI = %x\n", ctr_off + PCIE_DMA_RD_LL_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_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_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));
if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
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, 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, 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, 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, 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, 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, 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, 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));
} 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, 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, ctr_off + PCIE_DMA_WR_CTRL_HI));
dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_LL_PTR_LO = %x\n", ctr_off + PCIE_DMA_WR_LL_PTR_LO, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_LO));
dev_err(&pdev->dev, "reg[0x%x] PCIE_DMA_WR_LL_PTR_HI = %x\n", ctr_off + PCIE_DMA_WR_LL_PTR_HI, pcie_rkep_readl_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_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));
}
}
}
@@ -703,24 +737,39 @@ static void pcie_rkep_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cu
struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev);
struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_XFERSIZE,
cur->ctx_reg.xfersize);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_LO,
cur->ctx_reg.sarptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_HI,
cur->ctx_reg.sarptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_LO,
cur->ctx_reg.darptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_HI,
cur->ctx_reg.darptrhi);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
cur->start.asdword);
if (cur->dma_mode == RK_PCIE_DMA_BLOCK) {
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_XFERSIZE,
cur->ctx_reg.xfersize);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_LO,
cur->ctx_reg.sarptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_SAR_PTR_HI,
cur->ctx_reg.sarptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_LO,
cur->ctx_reg.darptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_DAR_PTR_HI,
cur->ctx_reg.darptrhi);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
cur->start.asdword);
} else {
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_LO,
lower_32_bits(cur->phys_descs));
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_RD_LL_PTR_HI,
upper_32_bits(cur->phys_descs));
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL,
cur->start.asdword);
}
// pcie_rkep_dma_debug(obj, cur);
}
@@ -729,26 +778,41 @@ static void pcie_rkep_start_dma_wr(struct dma_trx_obj *obj, struct dma_table *cu
struct pci_dev *pdev = container_of(obj->dev, struct pci_dev, dev);
struct pcie_rkep *pcie_rkep = pci_get_drvdata(pdev);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_XFERSIZE,
cur->ctx_reg.xfersize);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_LO,
cur->ctx_reg.sarptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_HI,
cur->ctx_reg.sarptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_LO,
cur->ctx_reg.darptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_HI,
cur->ctx_reg.darptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_WEILO,
cur->weilo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
cur->start.asdword);
if (cur->dma_mode == RK_PCIE_DMA_BLOCK) {
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_XFERSIZE,
cur->ctx_reg.xfersize);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_LO,
cur->ctx_reg.sarptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_SAR_PTR_HI,
cur->ctx_reg.sarptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_LO,
cur->ctx_reg.darptrlo);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_DAR_PTR_HI,
cur->ctx_reg.darptrhi);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_WEILO,
cur->weilo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
cur->start.asdword);
} else {
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB,
cur->enb.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_LO,
cur->ctx_reg.ctrllo.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_CTRL_HI,
cur->ctx_reg.ctrlhi.asdword);
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_LO,
lower_32_bits(cur->phys_descs));
pcie_rkep_writel_dbi(pcie_rkep, ctr_off + PCIE_DMA_WR_LL_PTR_HI,
upper_32_bits(cur->phys_descs));
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL,
cur->start.asdword);
}
// pcie_rkep_dma_debug(obj, cur);
}
@@ -767,26 +831,36 @@ static void pcie_rkep_start_dma_dwc(struct dma_trx_obj *obj, struct dma_table *t
static void pcie_rkep_config_dma_dwc(struct dma_table *table)
{
table->enb.enb = 0x1;
table->ctx_reg.ctrllo.lie = 0x1;
table->ctx_reg.ctrllo.rie = 0x0;
table->ctx_reg.ctrllo.td = 0x1;
table->ctx_reg.ctrlhi.asdword = 0x0;
table->ctx_reg.xfersize = table->buf_size;
if (table->dir == DMA_FROM_BUS) {
table->ctx_reg.sarptrlo = (u32)(table->bus & 0xffffffff);
table->ctx_reg.sarptrhi = (u32)(table->bus >> 32);
table->ctx_reg.darptrlo = (u32)(table->local & 0xffffffff);
table->ctx_reg.darptrhi = (u32)(table->local >> 32);
} else if (table->dir == DMA_TO_BUS) {
table->ctx_reg.sarptrlo = (u32)(table->local & 0xffffffff);
table->ctx_reg.sarptrhi = (u32)(table->local >> 32);
table->ctx_reg.darptrlo = (u32)(table->bus & 0xffffffff);
table->ctx_reg.darptrhi = (u32)(table->bus >> 32);
if (table->dma_mode == RK_PCIE_DMA_BLOCK) {
table->enb.enb = 0x1;
table->ctx_reg.ctrllo.lie = 0x1;
table->ctx_reg.ctrllo.rie = 0x0;
table->ctx_reg.ctrllo.td = 0x1;
table->ctx_reg.ctrlhi.asdword = 0x0;
table->ctx_reg.xfersize = table->buf_size;
if (table->dir == DMA_FROM_BUS) {
table->ctx_reg.sarptrlo = (u32)(table->bus & 0xffffffff);
table->ctx_reg.sarptrhi = (u32)(table->bus >> 32);
table->ctx_reg.darptrlo = (u32)(table->local & 0xffffffff);
table->ctx_reg.darptrhi = (u32)(table->local >> 32);
} else if (table->dir == DMA_TO_BUS) {
table->ctx_reg.sarptrlo = (u32)(table->local & 0xffffffff);
table->ctx_reg.sarptrhi = (u32)(table->local >> 32);
table->ctx_reg.darptrlo = (u32)(table->bus & 0xffffffff);
table->ctx_reg.darptrhi = (u32)(table->bus >> 32);
}
table->weilo.weight0 = 0x0;
table->start.stop = 0x0;
table->start.chnl = table->chn;
} else {
table->enb.enb = 0x1;
table->ctx_reg.ctrllo.lie = 0x1;
table->ctx_reg.ctrllo.rie = 0x0;
table->ctx_reg.ctrllo.ccs = 1;
table->ctx_reg.ctrllo.llen = 1;
table->ctx_reg.ctrlhi.asdword = 0x0;
table->start.chnl = table->chn;
}
table->weilo.weight0 = 0x0;
table->start.stop = 0x0;
table->start.chnl = table->chn;
}
static int pcie_rkep_get_dma_status(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir)
@@ -812,7 +886,7 @@ static int pcie_rkep_get_dma_status(struct dma_trx_obj *obj, u8 chn, enum dma_di
}
if (status.abortsta & BIT(chn)) {
dev_err(&pdev->dev, "%s, write abort\n", __func__);
dev_err(&pdev->dev, "%s, write abort %x\n", __func__, status.asdword);
clears.abortclr = BIT(chn);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_CLEAR,
clears.asdword);
@@ -1130,6 +1204,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
if (pcie_rkep->dma_obj) {
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
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;
@@ -1137,6 +1212,10 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id)
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);
/* Enable linked list err en */
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_WR_LL_ERR_EN, 0xffffffff);
pcie_rkep_writel_dbi(pcie_rkep, PCIE_DMA_OFFSET + PCIE_DMA_RD_LL_ERR_EN, 0xffffffff);
}
}

View File

@@ -46,13 +46,14 @@ static unsigned int test_dev;
module_param(test_dev, uint, 0644);
MODULE_PARM_DESC(test_dev, "Choose dma_obj device,(default 0)");
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)");
static bool is_wired;
module_param_named(is_wired, is_wired, bool, 0644);
MODULE_PARM_DESC(is_wired, "Transfer is triggered by wired DMA(default false)");
#define PCIE_DW_MISC_DMATEST_DEV_MAX 8
#define PCIE_DMA_CHANEL_MAX_NUM 2
#define PCIE_DMA_LL_MAX_NUM 1024 /* Unrestricted, tentative value */
struct pcie_dw_dmatest_dev {
struct dma_trx_obj *obj;
@@ -113,11 +114,11 @@ static int rk_pcie_dma_wait_for_finished(struct dma_trx_obj *obj, struct dma_tab
return ret;
}
static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
u64 local_paddr, u64 bus_paddr, u32 size)
static int rk_pcie_local_dma_frombus_block(struct dma_trx_obj *obj, u32 chn,
u64 local_paddr, u64 bus_paddr, u32 size)
{
struct pcie_dw_dmatest_dev *dmatest_dev = (struct pcie_dw_dmatest_dev *)obj->priv;
struct dma_table *table;
struct dma_trx_obj *obj = dmatest_dev->obj;
int ret;
if (chn >= PCIE_DMA_CHANEL_MAX_NUM)
@@ -154,11 +155,11 @@ static int rk_pcie_ep_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 c
return ret;
}
static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
u64 bus_paddr, u64 local_paddr, u32 size)
int rk_pcie_local_dma_tobus_block(struct dma_trx_obj *obj, u32 chn,
u64 bus_paddr, u64 local_paddr, u32 size)
{
struct pcie_dw_dmatest_dev *dmatest_dev = (struct pcie_dw_dmatest_dev *)obj->priv;
struct dma_table *table;
struct dma_trx_obj *obj = dmatest_dev->obj;
int ret;
if (chn >= PCIE_DMA_CHANEL_MAX_NUM)
@@ -195,18 +196,6 @@ static int rk_pcie_ep_dma_tobus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn
return ret;
}
static int rk_pcie_rc_dma_frombus(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
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,
u64 bus_paddr, u64 local_paddr, u32 size)
{
return rk_pcie_ep_dma_frombus(dmatest_dev, chn, bus_paddr, local_paddr, size);
}
static int rk_pcie_dma_interrupt_handler_call_back(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir)
{
struct pcie_dw_dmatest_dev *dmatest_dev = (struct pcie_dw_dmatest_dev *)obj->priv;
@@ -257,20 +246,16 @@ 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,
int pcie_dw_wired_dma_frombus_block(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);
return rk_pcie_local_dma_tobus_block(obj, chn, local_paddr, bus_paddr, size);
}
int pcie_dw_rc_dma_tobus(struct dma_trx_obj *obj, u32 chn,
int pcie_dw_wired_dma_tobus_block(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);
return rk_pcie_local_dma_frombus_block(obj, chn, bus_paddr, local_paddr, size);
}
static int dma_test(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
@@ -295,19 +280,19 @@ static int dma_test(struct pcie_dw_dmatest_dev *dmatest_dev, u32 chn,
start_time = ktime_get();
for (i = 0; i < loop; i++) {
if (rd_en) {
if (is_rc)
rk_pcie_rc_dma_frombus(dmatest_dev, chn, local_paddr, bus_paddr, size);
if (is_wired)
pcie_dw_wired_dma_frombus_block(dmatest_dev->obj, chn, local_paddr, bus_paddr, size);
else
rk_pcie_ep_dma_frombus(dmatest_dev, chn, local_paddr, bus_paddr, size);
rk_pcie_local_dma_frombus_block(dmatest_dev->obj, chn, local_paddr, bus_paddr, size);
dma_sync_single_for_cpu(obj->dev, local_paddr, size, DMA_FROM_DEVICE);
}
if (wr_en) {
dma_sync_single_for_device(obj->dev, local_paddr, size, DMA_TO_DEVICE);
if (is_rc)
rk_pcie_rc_dma_tobus(dmatest_dev, chn, bus_paddr, local_paddr, size);
if (is_wired)
pcie_dw_wired_dma_tobus_block(dmatest_dev->obj, chn, bus_paddr, local_paddr, size);
else
rk_pcie_ep_dma_tobus(dmatest_dev, chn, bus_paddr, local_paddr, size);
rk_pcie_local_dma_tobus_block(dmatest_dev->obj, chn, bus_paddr, local_paddr, size);
}
}
end_time = ktime_get();
@@ -363,19 +348,17 @@ static int pcie_dw_dmatest(const char *val, const struct kernel_param *kp)
if (!s_dmatest_dev[0].obj) {
pr_err("dmatest dev not exits\n");
kfree(tmp);
return -1;
}
strncpy(tmp, val, 8);
if (!strncmp(tmp, "run", 3)) {
if (!strncmp(tmp, "run", 3))
dma_run();
} else if (!strncmp(tmp, "show", 4)) {
else if (!strncmp(tmp, "show", 4))
pcie_dw_dmatest_show();
} else {
else
pr_info("input error\n");
}
return 0;
}

View File

@@ -11,8 +11,8 @@ 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);
int pcie_dw_wired_dma_frombus_block(struct dma_trx_obj *obj, u32 chn, u64 local_paddr, u64 bus_paddr, u32 size);
int pcie_dw_wired_dma_tobus_block(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)
{
@@ -21,12 +21,12 @@ static inline struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, b
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)
static inline int pcie_dw_wired_dma_frombus_block(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)
static inline int pcie_dw_wired_dma_tobus_block(struct dma_trx_obj *obj, u32 chn, u64 bus_paddr, u64 local_paddr, u32 size)
{
return -1;
}

View File

@@ -20,11 +20,31 @@
#define PCIE_DMA_DATA_FREE_ACK_TABLE_OFFSET 0x10
#define PCIE_DMA_DATA_READ_REMOTE_TABLE_OFFSET 0x18
/* DMA linked list register filed */
#define PCIE_DWC_DMA_CB BIT(0)
#define PCIE_DWC_DMA_TCB BIT(1)
#define PCIE_DWC_DMA_LLP BIT(2)
#define PCIE_DWC_DMA_LIE BIT(3)
#define PCIE_DWC_DMA_RIE BIT(4)
#define PCIE_DWC_DMA_CCS BIT(8)
#define PCIE_DWC_DMA_LLE BIT(9)
#define SET_LL_32(ll, value) \
writel(value, ll)
#define SET_LL_64(ll, value) \
writeq(value, ll)
enum dma_dir {
DMA_FROM_BUS,
DMA_TO_BUS,
};
enum dma_mode {
RK_PCIE_DMA_BLOCK,
RK_PCIE_DMA_LL,
};
/**
* The Channel Control Register for read and write.
*/
@@ -155,8 +175,40 @@ struct dma_table {
phys_addr_t local;
phys_addr_t bus;
size_t buf_size;
u32 dma_mode;
};
struct rk_edma_lli {
u32 control;
u32 transfer_size;
union {
u64 reg;
struct {
u32 lsb;
u32 msb;
};
} sar;
union {
u64 reg;
struct {
u32 lsb;
u32 msb;
};
} dar;
} __packed;
struct rk_edma_llp {
u32 control;
u32 reserved;
union {
u64 reg;
struct {
u32 lsb;
u32 msb;
};
} llp;
} __packed;
struct dma_trx_obj {
struct device *dev;
int loop_count;

View File

@@ -3,8 +3,8 @@
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
#ifndef _PWM_ROCKCHIP_H_
#define _PWM_ROCKCHIP_H_
#ifndef _PWM_ROCKCHIP_IRQ_CALLBACKS_H_
#define _PWM_ROCKCHIP_IRQ_CALLBACKS_H_
#include <linux/pwm.h>

View File

@@ -19,7 +19,7 @@
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/time.h>
#include "pwm-rockchip.h"
#include "pwm-rockchip-irq-callbacks.h"
#define PWM_MAX_CHANNEL_NUM 4

View File

@@ -490,7 +490,6 @@ struct mpp_taskqueue {
u32 core_id_max;
u32 core_count;
unsigned long dev_active_flags;
u32 iommu_fault;
};
struct mpp_reset_group {

View File

@@ -1531,6 +1531,7 @@ static int rkvdec2_core_probe(struct platform_device *pdev)
if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_SOFT) {
mpp->dev_ops->task_worker = rkvdec2_soft_ccu_worker;
irq_proc = rkvdec2_soft_ccu_irq;
mpp->fault_handler = rkvdec2_soft_ccu_iommu_fault_handle;
} else if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_HARD) {
if (mpp->core_id == 0 && mpp->task_capacity > 1) {
dec->link_dec->task_capacity = mpp->task_capacity;
@@ -1540,8 +1541,8 @@ static int rkvdec2_core_probe(struct platform_device *pdev)
}
mpp->dev_ops->task_worker = rkvdec2_hard_ccu_worker;
irq_proc = rkvdec2_hard_ccu_irq;
mpp->fault_handler = rkvdec2_hard_ccu_iommu_fault_handle;
}
mpp->fault_handler = rkvdec2_ccu_iommu_fault_handle;
kthread_init_work(&mpp->work, mpp->dev_ops->task_worker);
/* get irq request */

View File

@@ -219,12 +219,7 @@ struct rkvdec2_dev {
u32 task_index;
/* mmu info */
void __iomem *mmu_base;
u32 fault_iova;
u32 mmu_fault;
u32 mmu0_st;
u32 mmu1_st;
u32 mmu0_pta;
u32 mmu1_pta;
};
int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session,

View File

@@ -1555,7 +1555,7 @@ static int rkvdec2_soft_ccu_reset(struct mpp_taskqueue *queue,
if (mpp->disable)
continue;
dev_info(mpp->dev, "resetting...\n");
dev_info(mpp->dev, "resetting for err %#x\n", mpp->irq_status);
disable_hardirq(mpp->irq);
/* foce idle, disconnect core and ccu */
@@ -1618,61 +1618,104 @@ void *rkvdec2_ccu_alloc_task(struct mpp_session *session,
return &task->mpp_task;
}
static void rkvdec2_ccu_check_pagefault_info(struct mpp_dev *mpp)
static struct mpp_dev *rkvdec2_ccu_dev_match_by_iommu(struct mpp_taskqueue *queue,
struct device *iommu_dev)
{
u32 i = 0;
struct mpp_dev *mpp = NULL;
struct rkvdec2_dev *dec = NULL;
u32 mmu[2] = {0, 0x40};
u32 i;
for (i = 0; i < mpp->queue->core_count; i++) {
struct mpp_dev *core = mpp->queue->cores[i];
struct rkvdec2_dev *dec = to_rkvdec2_dev(core);
void __iomem *mmu_base = dec->mmu_base;
u32 mmu0_st;
u32 mmu1_st;
u32 mmu0_pta;
u32 mmu1_pta;
for (i = 0; i < queue->core_count; i++) {
struct mpp_dev *core = queue->cores[i];
if (!mmu_base)
return;
#define FAULT_STATUS 0x7e2
rkvdec2_ccu_power_on(mpp->queue, dec->ccu);
mmu0_st = readl(mmu_base + 0x4);
mmu1_st = readl(mmu_base + 0x44);
mmu0_pta = readl(mmu_base + 0xc);
mmu1_pta = readl(mmu_base + 0x4c);
dec->mmu0_st = mmu0_st;
dec->mmu1_st = mmu1_st;
dec->mmu0_pta = mmu0_pta;
dec->mmu1_pta = mmu1_pta;
pr_err("core %d mmu0 %08x %08x mm1 %08x %08x\n",
core->core_id, mmu0_st, mmu0_pta, mmu1_st, mmu1_pta);
if ((mmu0_st & FAULT_STATUS) || (mmu1_st & FAULT_STATUS) ||
mmu0_pta || mmu1_pta) {
dec->fault_iova = readl(dec->link_dec->reg_base + 0x4);
dec->mmu_fault = 1;
pr_err("core %d fault iova %08x\n", core->core_id, dec->fault_iova);
rockchip_iommu_mask_irq(core->dev);
} else {
dec->mmu_fault = 0;
dec->fault_iova = 0;
if (&core->iommu_info->pdev->dev == iommu_dev) {
mpp = core;
dec = to_rkvdec2_dev(mpp);
}
}
if (!dec || !dec->mmu_base)
goto out;
/* there are two iommus */
for (i = 0; i < 2; i++) {
u32 status = readl(dec->mmu_base + mmu[i] + 0x4);
u32 iova = readl(dec->mmu_base + mmu[i] + 0xc);
u32 is_write = (status & BIT(5)) ? 1 : 0;
if (status && iova)
dev_err(iommu_dev, "core %d pagfault at iova %#08x type %s status %#x\n",
mpp->core_id, iova, is_write ? "write" : "read", status);
}
out:
return mpp;
}
int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg)
int rkvdec2_soft_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg)
{
struct mpp_dev *mpp = (struct mpp_dev *)arg;
struct mpp_taskqueue *queue = mpp->queue;
struct mpp_task *mpp_task;
mpp_debug_enter();
rkvdec2_ccu_check_pagefault_info(mpp);
mpp = rkvdec2_ccu_dev_match_by_iommu(queue, iommu_dev);
if (!mpp) {
dev_err(iommu_dev, "iommu fault, but no dev match\n");
return 0;
}
mpp_task = mpp->cur_task;
if (mpp_task)
mpp_task_dump_mem_region(mpp, mpp_task);
mpp->queue->iommu_fault = 1;
/*
* Mask iommu irq, in order for iommu not repeatedly trigger pagefault.
* Until the pagefault task finish by hw timeout.
*/
rockchip_iommu_mask_irq(mpp->dev);
atomic_inc(&mpp->queue->reset_request);
kthread_queue_work(&mpp->queue->worker, &mpp->work);
mpp_debug_leave();
return 0;
}
int rkvdec2_hard_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg)
{
struct mpp_dev *mpp = (struct mpp_dev *)arg;
struct mpp_taskqueue *queue = mpp->queue;
struct mpp_task *mpp_task = NULL, *n;
struct rkvdec2_dev *dec;
u32 err_task_iova;
mpp_debug_enter();
mpp = rkvdec2_ccu_dev_match_by_iommu(queue, iommu_dev);
if (!mpp) {
dev_err(iommu_dev, "iommu fault, but no dev match\n");
return 0;
}
dec = to_rkvdec2_dev(mpp);
err_task_iova = readl(dec->link_dec->reg_base + 0x4);
dev_err(mpp->dev, "core %d err task iova %#08x\n", mpp->core_id, err_task_iova);
rockchip_iommu_mask_irq(mpp->dev);
list_for_each_entry_safe(mpp_task, n, &queue->running_list, queue_link) {
struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
if ((u32)task->table->iova == err_task_iova) {
mpp_task_dump_mem_region(mpp, mpp_task);
set_bit(TASK_STATE_ABORT, &mpp_task->state);
break;
}
}
atomic_inc(&mpp->queue->reset_request);
kthread_queue_work(&mpp->queue->worker, &mpp->work);
@@ -2041,7 +2084,7 @@ static int rkvdec2_hard_ccu_dequeue(struct mpp_taskqueue *queue,
ccu_decoded_num = readl(ccu->reg_base + RKVDEC_CCU_DEC_NUM_BASE);
ccu_total_dec_num = readl(ccu->reg_base + RKVDEC_CCU_TOTAL_NUM_BASE);
mpp_debug(DEBUG_IRQ_CHECK,
"session %d task %d w:h[%d %d] err %d irq_status %08x timeout=%u abort=%u iova %08x next %08x ccu[%d %d]\n",
"session %d task %d w:h[%d %d] err %d irq_status %#x timeout=%u abort=%u iova %08x next %08x ccu[%d %d]\n",
mpp_task->session->index, mpp_task->task_index, task->width,
task->height, !!(irq_status & RKVDEC_INT_ERROR_MASK), irq_status,
timeout_flag, abort_flag, (u32)task->table->iova,
@@ -2055,7 +2098,7 @@ static int rkvdec2_hard_ccu_dequeue(struct mpp_taskqueue *queue,
cancel_delayed_work(&mpp_task->timeout_work);
mpp_task->hw_cycles = tb_reg[hw->tb_reg_cycle];
mpp_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz);
task->irq_status = irq_status;
task->irq_status = irq_status ? irq_status : RKVDEC_ERROR_STA;
if (irq_status)
rkvdec2_hard_ccu_finish(hw, task);
@@ -2081,7 +2124,7 @@ static int rkvdec2_hard_ccu_dequeue(struct mpp_taskqueue *queue,
/* Wake up the GET thread */
wake_up(&mpp_task->wait);
if ((irq_status & RKVDEC_INT_ERROR_MASK) || timeout_flag) {
pr_err("session %d task %d irq_status %08x timeout=%u abort=%u\n",
pr_err("session %d task %d irq_status %#x timeout=%u abort=%u\n",
mpp_task->session->index, mpp_task->task_index,
irq_status, timeout_flag, abort_flag);
atomic_inc(&queue->reset_request);
@@ -2339,51 +2382,6 @@ done:
return 0;
}
static void rkvdec2_hard_ccu_handle_pagefault_task(struct rkvdec2_dev *dec,
struct mpp_task *mpp_task)
{
struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
mpp_dbg_ccu("session %d task %d w:h[%d %d] pagefault mmu0[%08x %08x] mmu1[%08x %08x] fault_iova %08x\n",
mpp_task->session->index, mpp_task->task_index,
task->width, task->height, dec->mmu0_st, dec->mmu0_pta,
dec->mmu1_st, dec->mmu1_pta, dec->fault_iova);
set_bit(TASK_STATE_HANDLE, &mpp_task->state);
task->irq_status |= BIT(4);
cancel_delayed_work(&mpp_task->timeout_work);
rkvdec2_hard_ccu_finish(dec->link_dec->info, task);
set_bit(TASK_STATE_FINISH, &mpp_task->state);
set_bit(TASK_STATE_DONE, &mpp_task->state);
list_move_tail(&task->table->link, &dec->ccu->unused_list);
list_del_init(&mpp_task->queue_link);
/* Wake up the GET thread */
wake_up(&mpp_task->wait);
kref_put(&mpp_task->ref, mpp_free_task);
dec->mmu_fault = 0;
dec->fault_iova = 0;
}
static void rkvdec2_hard_ccu_pagefault_proc(struct mpp_taskqueue *queue)
{
struct mpp_task *loop = NULL, *n;
list_for_each_entry_safe(loop, n, &queue->running_list, queue_link) {
struct rkvdec2_task *task = to_rkvdec2_task(loop);
u32 iova = (u32)task->table->iova;
u32 i;
for (i = 0; i < queue->core_count; i++) {
struct mpp_dev *core = queue->cores[i];
struct rkvdec2_dev *dec = to_rkvdec2_dev(core);
if (!dec->mmu_fault || dec->fault_iova != iova)
continue;
rkvdec2_hard_ccu_handle_pagefault_task(dec, loop);
}
}
}
static void rkvdec2_hard_ccu_resend_tasks(struct mpp_dev *mpp, struct mpp_taskqueue *queue)
{
struct rkvdec2_task *task_pre = NULL;
@@ -2463,11 +2461,6 @@ void rkvdec2_hard_ccu_worker(struct kthread_work *work_s)
/* reset process */
rkvdec2_hard_ccu_reset(queue, dec->ccu);
atomic_set(&queue->reset_request, 0);
/* if iommu pagefault, find the fault task and drop it */
if (queue->iommu_fault) {
rkvdec2_hard_ccu_pagefault_proc(queue);
queue->iommu_fault = 0;
}
/* relink running task iova in list, and resend them to hw */
if (!list_empty(&queue->running_list))

View File

@@ -221,9 +221,9 @@ void rkvdec2_link_session_deinit(struct mpp_session *session);
int rkvdec2_attach_ccu(struct device *dev, struct rkvdec2_dev *dec);
int rkvdec2_ccu_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec);
void *rkvdec2_ccu_alloc_task(struct mpp_session *session, struct mpp_task_msgs *msgs);
int rkvdec2_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg);
int rkvdec2_soft_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg);
irqreturn_t rkvdec2_soft_ccu_irq(int irq, void *param);
void rkvdec2_soft_ccu_worker(struct kthread_work *work_s);
@@ -231,5 +231,8 @@ int rkvdec2_ccu_alloc_table(struct rkvdec2_dev *dec,
struct rkvdec_link_dev *link_dec);
irqreturn_t rkvdec2_hard_ccu_irq(int irq, void *param);
void rkvdec2_hard_ccu_worker(struct kthread_work *work_s);
int rkvdec2_hard_ccu_iommu_fault_handle(struct iommu_domain *iommu,
struct device *iommu_dev,
unsigned long iova, int status, void *arg);
#endif

View File

@@ -130,6 +130,11 @@ struct rkvenc_hw_info {
#define INT_STA_RBUS_ERR_STA BIT(7)
#define INT_STA_WDG_STA BIT(8)
#define INT_STA_ERROR (INT_STA_BRSP_OTSD_STA | \
INT_STA_WBUS_ERR_STA | \
INT_STA_RBUS_ERR_STA | \
INT_STA_WDG_STA)
#define DCHS_REG_OFFSET (0x304)
#define DCHS_CLASS_OFFSET (33)
#define DCHS_TXE (0x10)
@@ -1266,9 +1271,9 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
return 0;
}
static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task)
static void rkvenc2_read_slice_len(struct mpp_dev *mpp, struct rkvenc_task *task,
u32 last)
{
u32 last = mpp_read_relaxed(mpp, 0x002c) & INT_STA_ENC_DONE_STA;
u32 sli_num = mpp_read_relaxed(mpp, RKVENC2_REG_SLICE_NUM_BASE);
union rkvenc2_slice_len_info slice_info;
u32 task_id = task->mpp_task.task_id;
@@ -1308,46 +1313,41 @@ static int rkvenc_irq(struct mpp_dev *mpp)
struct rkvenc_hw_info *hw = enc->hw_info;
struct mpp_task *mpp_task = NULL;
struct rkvenc_task *task = NULL;
u32 int_clear = 1;
u32 irq_mask = 0;
u32 irq_status;
int ret = IRQ_NONE;
mpp_debug_enter();
mpp->irq_status = mpp_read(mpp, hw->int_sta_base);
if (!mpp->irq_status)
irq_status = mpp_read(mpp, hw->int_sta_base);
mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
dev_name(mpp->dev), irq_status);
if (!irq_status)
return ret;
/* clear int first */
mpp_write(mpp, hw->int_clr_base, irq_status);
if (mpp->cur_task) {
mpp_task = mpp->cur_task;
task = to_rkvenc_task(mpp_task);
}
if (mpp->irq_status & INT_STA_ENC_DONE_STA) {
if (task) {
if (task->task_split)
rkvenc2_read_slice_len(mpp, task);
/* 1. read slice number and slice length */
if (task && task->task_split &&
(irq_status & (INT_STA_SLC_DONE_STA | INT_STA_ENC_DONE_STA))) {
mpp_time_part_diff(mpp_task);
rkvenc2_read_slice_len(mpp, task, irq_status & INT_STA_ENC_DONE_STA);
wake_up(&mpp_task->wait);
}
wake_up(&mpp_task->wait);
}
/* 2. process slice irq */
if (irq_status & INT_STA_SLC_DONE_STA)
ret = IRQ_HANDLED;
irq_mask = INT_STA_ENC_DONE_STA;
ret = IRQ_WAKE_THREAD;
if (enc->bs_overflow) {
mpp->irq_status |= INT_STA_BSF_OFLW_STA;
enc->bs_overflow = 0;
}
} else if (mpp->irq_status & INT_STA_SLC_DONE_STA) {
if (task && task->task_split) {
mpp_time_part_diff(mpp_task);
rkvenc2_read_slice_len(mpp, task);
wake_up(&mpp_task->wait);
}
irq_mask = INT_STA_ENC_DONE_STA;
int_clear = 0;
} else if (mpp->irq_status & INT_STA_BSF_OFLW_STA) {
/* 3. process bitstream overflow */
if (irq_status & INT_STA_BSF_OFLW_STA) {
u32 bs_rd = mpp_read(mpp, RKVENC2_REG_ADR_BSBR);
u32 bs_wr = mpp_read(mpp, RKVENC2_REG_ST_BSB);
u32 bs_top = mpp_read(mpp, RKVENC2_REG_ADR_BSBT);
@@ -1359,28 +1359,33 @@ static int rkvenc_irq(struct mpp_dev *mpp)
bs_wr += 128;
if (bs_wr >= bs_top)
bs_wr = bs_bot;
/* clear int first */
mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
/* update write addr for enc continue */
mpp_write(mpp, RKVENC2_REG_ADR_BSBS, bs_wr);
enc->bs_overflow = 1;
irq_mask = 0;
int_clear = 0;
ret = IRQ_HANDLED;
} else {
dev_err(mpp->dev, "found error status %08x\n", mpp->irq_status);
irq_mask = mpp->irq_status;
ret = IRQ_HANDLED;
}
/* 4. process frame irq */
if (irq_status & INT_STA_ENC_DONE_STA) {
mpp->irq_status = irq_status;
if (enc->bs_overflow) {
mpp->irq_status |= INT_STA_BSF_OFLW_STA;
enc->bs_overflow = 0;
}
ret = IRQ_WAKE_THREAD;
}
if (irq_mask)
mpp_write(mpp, hw->int_mask_base, irq_mask);
/* 5. process error irq */
if (irq_status & INT_STA_ERROR) {
mpp->irq_status = irq_status;
if (int_clear) {
mpp_write(mpp, hw->int_clr_base, mpp->irq_status);
udelay(5);
mpp_write(mpp, hw->int_sta_base, 0);
dev_err(mpp->dev, "found error status %08x\n", irq_status);
ret = IRQ_WAKE_THREAD;
}
mpp_debug_leave();
@@ -1388,6 +1393,11 @@ static int rkvenc_irq(struct mpp_dev *mpp)
return ret;
}
static int vepu540c_irq(struct mpp_dev *mpp)
{
return rkvenc_irq(mpp);
}
static int rkvenc_isr(struct mpp_dev *mpp)
{
struct rkvenc_task *task;
@@ -1416,9 +1426,6 @@ static int rkvenc_isr(struct mpp_dev *mpp)
rkvenc2_update_dchs(enc, task);
mpp_debug(DEBUG_IRQ_STATUS, "%s irq_status: %08x\n",
dev_name(mpp->dev), task->irq_status);
if (task->irq_status & enc->hw_info->err_mask) {
atomic_inc(&mpp->reset_request);
@@ -2162,6 +2169,20 @@ static struct mpp_dev_ops rkvenc_ccu_dev_ops = {
.dump_session = rkvenc_dump_session,
};
static struct mpp_dev_ops vepu540c_dev_ops_v2 = {
.wait_result = rkvenc2_wait_result,
.alloc_task = rkvenc_alloc_task,
.run = rkvenc_run,
.irq = vepu540c_irq,
.isr = rkvenc_isr,
.finish = rkvenc_finish,
.result = rkvenc_result,
.free_task = rkvenc_free_task,
.ioctl = rkvenc_control,
.init_session = rkvenc_init_session,
.free_session = rkvenc_free_session,
.dump_session = rkvenc_dump_session,
};
static const struct mpp_dev_var rkvenc_v2_data = {
.device_type = MPP_DEVICE_RKVENC,
@@ -2176,7 +2197,7 @@ static const struct mpp_dev_var rkvenc_540c_data = {
.hw_info = &rkvenc_540c_hw_info.hw,
.trans_info = trans_rkvenc_540c,
.hw_ops = &rkvenc_hw_ops,
.dev_ops = &rkvenc_dev_ops_v2,
.dev_ops = &vepu540c_dev_ops_v2,
};
static const struct mpp_dev_var rkvenc_ccu_data = {

View File

@@ -56,8 +56,8 @@ void rga_mm_dump_info(struct rga_mm *session);
int rga_mm_map_job_info(struct rga_job *job);
void rga_mm_unmap_job_info(struct rga_job *job);
uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
struct rga_session *session);
int rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
struct rga_session *session);
int rga_mm_release_buffer(uint32_t handle);
int rga_mm_session_release_buffer(struct rga_session *session);

View File

@@ -650,7 +650,7 @@ static long rga_ioctl_import_buffer(unsigned long arg, struct rga_session *sessi
}
ret = rga_mm_import_buffer(&external_buffer[i], session);
if (ret == 0) {
if (ret <= 0) {
pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = %s(0x%x)\n",
i, (unsigned long)external_buffer[i].memory,
rga_get_memory_type_str(external_buffer[i].type),

View File

@@ -455,6 +455,7 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer,
phys_addr = sg_phys(buffer->sgt->sgl);
if (phys_addr == 0) {
pr_err("%s get physical address error!", __func__);
ret = -EFAULT;
goto unmap_buffer;
}
@@ -571,6 +572,7 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer,
phys_addr = sg_phys(sgt->sgl);
if (phys_addr == 0) {
pr_err("%s get physical address error!", __func__);
ret = -EFAULT;
goto free_sgt;
}
@@ -621,8 +623,9 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer,
if (mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS)
break;
pr_err("Current %s[%d] cannot support virtual address!\n",
pr_err("Current %s[%d] cannot support physically discontinuous virtual address!\n",
rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu);
ret = -EOPNOTSUPP;
goto free_dma_buffer;
}
@@ -2044,8 +2047,18 @@ void rga_mm_unmap_job_info(struct rga_job *job)
}
}
uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
struct rga_session *session)
/*
* rga_mm_import_buffer - Importing external buffer into the RGA driver
*
* @external_buffer: [in] Parameters of external buffer
* @session: [in] Session of the current process
*
* returns:
* if return value > 0, the buffer import is successful and is the generated
* buffer-handle, negative error code on failure.
*/
int rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
struct rga_session *session)
{
int ret = 0, new_id;
struct rga_mm *mm;
@@ -2054,7 +2067,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
mm = rga_drvdata->mm;
if (mm == NULL) {
pr_err("rga mm is null!\n");
return 0;
return -EFAULT;
}
mutex_lock(&mm->lock);
@@ -2080,7 +2093,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
pr_err("%s alloc internal_buffer error!\n", __func__);
mutex_unlock(&mm->lock);
return 0;
return -ENOMEM;
}
ret = rga_mm_map_buffer(external_buffer, internal_buffer, NULL, true);
@@ -2099,6 +2112,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
idr_preload_end();
if (new_id < 0) {
pr_err("internal_buffer alloc id failed!\n");
ret = new_id;
goto FREE_INTERNAL_BUFFER;
}
@@ -2117,7 +2131,7 @@ FREE_INTERNAL_BUFFER:
mutex_unlock(&mm->lock);
kfree(internal_buffer);
return 0;
return ret;
}
int rga_mm_release_buffer(uint32_t handle)