mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
Merge commit '2688d7f9259151ac782d92bece2458eb998aa829'
* commit '2688d7f9259151ac782d92bece2458eb998aa829': media: i2c: add ar2020 sensor driver watchdog: dw_wdt: fix array out-of-bounds in theory mfd: rkx110_x120: add irq support drm/rockchip: vop2: fix overlapping_copy Change-Id: I50059e725ec7b7efc4e0437e85f9622ba9c97fb9 Conflicts: drivers/media/i2c/Kconfig drivers/media/i2c/Makefile
This commit is contained in:
@@ -11602,6 +11602,7 @@ static int vop2_win_init(struct vop2 *vop2)
|
||||
struct vop2_win *win;
|
||||
struct vop2_layer *layer;
|
||||
char name[DRM_PROP_NAME_LEN];
|
||||
char area_name[DRM_PROP_NAME_LEN];
|
||||
unsigned int num_wins = 0;
|
||||
uint8_t plane_id = 0;
|
||||
unsigned int i, j;
|
||||
@@ -11677,8 +11678,8 @@ static int vop2_win_init(struct vop2 *vop2)
|
||||
area->phys_id = win->phys_id;
|
||||
area->area_id = j + 1;
|
||||
area->plane_id = plane_id++;
|
||||
snprintf(name, min(sizeof(name), strlen(win->name)), "%s", win->name);
|
||||
snprintf(name, sizeof(name), "%s%d", name, area->area_id);
|
||||
snprintf(area_name, min(sizeof(area_name), strlen(win->name)), "%s", win->name);
|
||||
snprintf(name, sizeof(name), "%s%d", area_name, area->area_id);
|
||||
area->name = devm_kstrdup(vop2->dev, name, GFP_KERNEL);
|
||||
num_wins++;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,20 @@ config VIDEO_AR0822
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ar0822.
|
||||
|
||||
config VIDEO_AR2020
|
||||
tristate "Onsemi AR2020 sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Onsemi
|
||||
AR2020 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ar2020.
|
||||
|
||||
config VIDEO_BF3925
|
||||
tristate "BYD BF3925 sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
|
||||
@@ -22,6 +22,7 @@ obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
|
||||
obj-$(CONFIG_VIDEO_AR0230) += ar0230.o
|
||||
obj-$(CONFIG_VIDEO_AR0521) += ar0521.o
|
||||
obj-$(CONFIG_VIDEO_AR0822) += ar0822.o
|
||||
obj-$(CONFIG_VIDEO_AR2020) += ar2020.o
|
||||
obj-$(CONFIG_VIDEO_AW36518) += aw36518.o
|
||||
obj-$(CONFIG_VIDEO_AW8601) += aw8601.o
|
||||
obj-$(CONFIG_VIDEO_BF3925) += bf3925.o
|
||||
|
||||
5413
drivers/media/i2c/ar2020.c
Normal file
5413
drivers/media/i2c/ar2020.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -101,7 +101,33 @@
|
||||
#define SER_RKLINK_AUDIO_RECOVER LINK_REG(0x0034)
|
||||
#define SER_RKLINK_AUDIO_FM_STATUS LINK_REG(0x0038)
|
||||
#define SER_RKLINK_FIFO_STATUS LINK_REG(0x003C)
|
||||
#define CH1_CMD_FIFO_UNDERRUN BIT(24)
|
||||
#define CH0_CMD_FIFO_UNDERRUN BIT(23)
|
||||
#define DATA1_FIFO_UNDERRUN BIT(22)
|
||||
#define DATA0_FIFO_UNDERRUN BIT(21)
|
||||
#define AUDIO_FIFO_UNDERRUN BIT(20)
|
||||
#define LVDS1_FIFO_UNDERRUN BIT(19)
|
||||
#define LVDS0_FIFO_UNDERRUN BIT(18)
|
||||
#define DSI_CH1_FIFO_UNDERRUN BIT(17)
|
||||
#define DSI_CH0_FIFO_UNDERRUN BIT(16)
|
||||
#define CH1_CMD_FIFO_OVERFLOW BIT(8)
|
||||
#define CH0_CMD_FIFO_OVERFLOW BIT(7)
|
||||
#define DATA0_FIFO_OVERFLOW BIT(6)
|
||||
#define DATA1_FIFO_OVERFLOW BIT(5)
|
||||
#define AUDIO_FIFO_OVERFLOW BIT(4)
|
||||
#define LVDS1_FIFO_OVERFLOW BIT(3)
|
||||
#define LVDS0_FIFO_OVERFLOW BIT(2)
|
||||
#define DSI_CH1_FIFO_OVERFLOW BIT(1)
|
||||
#define DSI_CH0_FIFO_OVERFLOW BIT(0)
|
||||
#define SER_RKLINK_SOURCE_IRQ_EN LINK_REG(0x0040)
|
||||
#define TRAIN_DONE_IRQ_FLAG BIT(19)
|
||||
#define FIFO_UNDERRUN_IRQ_FLAG BIT(18)
|
||||
#define FIFO_OVERFLOW_IRQ_FLAG BIT(17)
|
||||
#define AUDIO_FM_IRQ_OUTPUT_FLAG BIT(16)
|
||||
#define TRAIN_DONE_IRQ_OUTPUT_EN BIT(3)
|
||||
#define FIFO_UNDERRUN_IRQ_OUTPUT_EN BIT(2)
|
||||
#define FIFO_OVERFLOW_IRQ_OUTPUT_EN BIT(1)
|
||||
#define AUDIO_FM_IRQ_OUTPUT_EN BIT(0)
|
||||
|
||||
#define SER_RKLINK_TRAIN_CTRL LINK_REG(0x0044)
|
||||
#define SER_RKLINK_I2C_CFG LINK_REG(0x00C0)
|
||||
@@ -144,7 +170,9 @@
|
||||
#define PCS_REG24(id) PCS_REG(id, 0x24)
|
||||
#define PCS_REG28(id) PCS_REG(id, 0x28)
|
||||
#define PCS_REG30(id) PCS_REG(id, 0x30)
|
||||
#define PCS_INT_STARTUP(x) HIWORD_UPDATE(x, GENMASK(15, 0), 0)
|
||||
#define PCS_REG34(id) PCS_REG(id, 0x34)
|
||||
#define PCS_INT_REMOTE_MODE(x) HIWORD_UPDATE(x, GENMASK(15, 0), 0)
|
||||
#define PCS_REG40(id) PCS_REG(id, 0x40)
|
||||
|
||||
#define PMA_REG(id, x) ((x) + RKX110_SER_PMA0_BASE + (id) * RKX110_SER_PMA_OFFSET)
|
||||
@@ -195,6 +223,15 @@
|
||||
#define PMA_CLK_8X_DIV_MASK HIWORD_MASK(7, 1)
|
||||
#define PMA_CLK_8X_DIV(x) HIWORD_UPDATE(x, GENMASK(7, 1), 1)
|
||||
|
||||
#define SER_PMA_IRQ_EN(id) PMA_REG(id, 0xF0)
|
||||
#define FORCE_INITIAL_IRQ_EN HIWORD_UPDATE(1, BIT(3), 3)
|
||||
#define RTERM_ONCE_TIMEOUT_IRQ_EN HIWORD_UPDATE(1, BIT(1), 1)
|
||||
#define PLL_LOCK_TIMEOUT_IRQ_EN HIWORD_UPDATE(1, BIT(0), 0)
|
||||
#define SER_PMA_IRQ_STATUS(id) PMA_REG(id, 0xF4)
|
||||
#define FORCE_INITIAL_PULSE_STATUS BIT(3)
|
||||
#define RTERM_ONCE_TIMEOUT_STATUS BIT(1)
|
||||
#define PLL_LOCK_TIMEOUT_STATUS BIT(0)
|
||||
|
||||
enum {
|
||||
SER_LINK_CH_ID0 = 0,
|
||||
SER_LINK_CH_ID1,
|
||||
@@ -750,3 +787,346 @@ void rkx110_ser_pma_enable(struct rk_serdes *serdes, bool enable, u8 pma_id, u8
|
||||
|
||||
serdes->i2c_update_bits(client, SER_GRF_SOC_CON7, mask, val);
|
||||
}
|
||||
|
||||
static void rkx110_linktx_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_LINK_EN);
|
||||
|
||||
serdes->i2c_write_reg(client, SER_RKLINK_SOURCE_IRQ_EN, TRAIN_DONE_IRQ_OUTPUT_EN |
|
||||
FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
|
||||
}
|
||||
|
||||
static void rkx110_linktx_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_LINK_DIS);
|
||||
serdes->i2c_read_reg(client, SER_RKLINK_SOURCE_IRQ_EN, &val);
|
||||
val &= ~(SER_RKLINK_SOURCE_IRQ_EN | TRAIN_DONE_IRQ_OUTPUT_EN |
|
||||
FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
|
||||
serdes->i2c_write_reg(client, SER_RKLINK_SOURCE_IRQ_EN, val);
|
||||
}
|
||||
|
||||
static void rkx110_linktx_fifo_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, SER_RKLINK_FIFO_STATUS, &value);
|
||||
dev_err(serdes->dev, "ser rklink fifo status:0x%x\n", value);
|
||||
|
||||
if (value & CH1_CMD_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx ch1 cmd fifo underrun\n");
|
||||
if (value & CH0_CMD_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx ch0 cmd fifo underrun\n");
|
||||
if (value & DATA1_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx data1 fifo underrun\n");
|
||||
if (value & DATA0_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx data0 fifo underrun\n");
|
||||
if (value & AUDIO_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx audio fifo underrun\n");
|
||||
if (value & LVDS1_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx lvds1 fifo underrun\n");
|
||||
if (value & LVDS0_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx lvds0 fifo underrun\n");
|
||||
if (value & DSI_CH1_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx dsi ch1 fifo underrun\n");
|
||||
if (value & DSI_CH0_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linktx dsi ch0 fifo underrun\n");
|
||||
if (value & CH1_CMD_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx ch1 cmd fifo overflow\n");
|
||||
if (value & CH0_CMD_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx ch0 cmd fifo overflow\n");
|
||||
if (value & DATA1_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx data1 fifo overflow\n");
|
||||
if (value & DATA0_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx data0 fifo overflow\n");
|
||||
if (value & AUDIO_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx audio fifo overflow\n");
|
||||
if (value & LVDS1_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx lvds1 fifo overflow\n");
|
||||
if (value & LVDS0_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx lvds0 fifo overflow\n");
|
||||
if (value & DSI_CH1_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx dsi ch1 fifo overflow\n");
|
||||
if (value & DSI_CH0_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linktx dsi ch0 fifo overflow\n");
|
||||
|
||||
/* clear fifo status */
|
||||
serdes->i2c_write_reg(client, SER_RKLINK_FIFO_STATUS, value);
|
||||
}
|
||||
|
||||
static void rkx110_linktx_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 flag, value;
|
||||
int i = 0;
|
||||
|
||||
serdes->i2c_read_reg(client, SER_RKLINK_SOURCE_IRQ_EN, &flag);
|
||||
flag &= TRAIN_DONE_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG |
|
||||
AUDIO_FM_IRQ_OUTPUT_FLAG;
|
||||
dev_info(serdes->dev, "linktx irq flag:0x%08x\n", flag);
|
||||
while (flag) {
|
||||
switch (flag & BIT(i)) {
|
||||
case TRAIN_DONE_IRQ_FLAG:
|
||||
serdes->i2c_read_reg(client, SER_RKLINK_TRAIN_CTRL, &value);
|
||||
dev_info(serdes->dev, "linktx train done, status:0x%08x\n", value);
|
||||
/* write any thing to train ctrl will clear the train done irq flag */
|
||||
serdes->i2c_write_reg(client, SER_RKLINK_TRAIN_CTRL, value);
|
||||
break;
|
||||
case FIFO_UNDERRUN_IRQ_FLAG:
|
||||
case FIFO_OVERFLOW_IRQ_FLAG:
|
||||
flag &= ~(FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG);
|
||||
rkx110_linktx_fifo_handler(serdes, dev_id);
|
||||
break;
|
||||
case AUDIO_FM_IRQ_OUTPUT_FLAG:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flag &= ~BIT(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void rkx110_pcs_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val;
|
||||
|
||||
val = pcs_id ? SER_IRQ_PCS1_EN : SER_IRQ_PCS0_EN;
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, PCS_REG30(pcs_id), PCS_INT_STARTUP(0xffff));
|
||||
serdes->i2c_write_reg(client, PCS_REG34(pcs_id), PCS_INT_REMOTE_MODE(0xffff));
|
||||
}
|
||||
|
||||
static void rkx110_pcs_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val;
|
||||
|
||||
val = pcs_id ? SER_IRQ_PCS1_DIS : SER_IRQ_PCS0_DIS;
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, PCS_REG30(pcs_id), PCS_INT_STARTUP(0));
|
||||
serdes->i2c_write_reg(client, PCS_REG34(pcs_id), PCS_INT_REMOTE_MODE(0));
|
||||
}
|
||||
|
||||
static void rkx110_pcs_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, PCS_REG24(pcs_id), &value);
|
||||
dev_info(serdes->dev, "ser pcs%d startup fatal status:0x%08x\n", pcs_id, value);
|
||||
|
||||
serdes->i2c_read_reg(client, PCS_REG28(pcs_id), &value);
|
||||
dev_info(serdes->dev, "ser pcs%d remote mode fatal status:0x%08x\n", pcs_id, value);
|
||||
|
||||
/* clear startup fatal status */
|
||||
serdes->i2c_write_reg(client, PCS_REG1C(pcs_id), 0xffffffff);
|
||||
serdes->i2c_write_reg(client, PCS_REG1C(pcs_id), 0xffff0000);
|
||||
|
||||
/* clear remote fatal status */
|
||||
serdes->i2c_write_reg(client, PCS_REG14(pcs_id), 0xffffffff);
|
||||
serdes->i2c_write_reg(client, PCS_REG14(pcs_id), 0xffff0000);
|
||||
}
|
||||
|
||||
static void rkx110_pma_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val;
|
||||
|
||||
val = pcs_id ? SER_IRQ_PMA_ADAPT1_EN : SER_IRQ_PMA_ADAPT0_EN;
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, SER_PMA_IRQ_EN(pcs_id), FORCE_INITIAL_IRQ_EN |
|
||||
RTERM_ONCE_TIMEOUT_IRQ_EN | PLL_LOCK_TIMEOUT_IRQ_EN);
|
||||
}
|
||||
|
||||
static void rkx110_pma_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val;
|
||||
|
||||
val = pcs_id ? SER_IRQ_PMA_ADAPT1_DIS : SER_IRQ_PMA_ADAPT0_DIS;
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, SER_PMA_IRQ_EN(pcs_id), 0);
|
||||
}
|
||||
|
||||
static void rkx110_pma_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, SER_PMA_IRQ_STATUS(pcs_id), &value);
|
||||
dev_info(serdes->dev, "ser pma%d irq status:0x%08x\n", pcs_id, value);
|
||||
|
||||
if (value & FORCE_INITIAL_PULSE_STATUS)
|
||||
dev_info(serdes->dev, "ser pma trig force initial pulse status\n");
|
||||
else if (value & RTERM_ONCE_TIMEOUT_STATUS)
|
||||
dev_info(serdes->dev, "ser pma trig rterm once timeout status\n");
|
||||
else if (value & PLL_LOCK_TIMEOUT_STATUS)
|
||||
dev_info(serdes->dev, "ser pma trig pll lock timeout status\n");
|
||||
|
||||
/* clear pma irq status */
|
||||
serdes->i2c_write_reg(client, SER_PMA_IRQ_STATUS(pcs_id), value);
|
||||
}
|
||||
|
||||
static void rkx110_remote_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
if (serdes->stream_type == STREAM_DISPLAY) {
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_REMOTE_EN);
|
||||
rkx120_irq_enable(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void rkx110_remote_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
if (serdes->stream_type == STREAM_DISPLAY) {
|
||||
serdes->i2c_write_reg(client, SER_GRF_IRQ_EN, SER_IRQ_REMOTE_DIS);
|
||||
rkx120_irq_disable(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void rkx110_remote_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
if (serdes->stream_type == STREAM_DISPLAY)
|
||||
rkx120_irq_handler(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
|
||||
void rkx110_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
/* enable pcs irq */
|
||||
rkx110_pcs_irq_enable(serdes, 0, dev_id);
|
||||
|
||||
/* enable dsirx irq */
|
||||
|
||||
/* enable gpio irq */
|
||||
|
||||
/* enable csihost irq */
|
||||
|
||||
/* enable pma_adapt irq */
|
||||
rkx110_pma_irq_enable(serdes, 0, dev_id);
|
||||
|
||||
/* enable efuse irq */
|
||||
|
||||
/* enable vicap irq */
|
||||
|
||||
/* enable remote irq */
|
||||
rkx110_remote_irq_enable(serdes, dev_id);
|
||||
|
||||
/* enable ext irq */
|
||||
|
||||
/* enable link irq */
|
||||
rkx110_linktx_irq_enable(serdes, dev_id);
|
||||
}
|
||||
|
||||
void rkx110_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
/* disable pcs irq */
|
||||
rkx110_pcs_irq_disable(serdes, 0, dev_id);
|
||||
|
||||
/* disable dsirx irq */
|
||||
|
||||
/* disable gpio irq */
|
||||
|
||||
/* disable csihost irq */
|
||||
|
||||
/* disable pma_adapt irq */
|
||||
rkx110_pma_irq_disable(serdes, 0, dev_id);
|
||||
|
||||
/* disable efuse irq */
|
||||
|
||||
/* disable vicap irq */
|
||||
|
||||
/* disable remote irq and other lane irq*/
|
||||
rkx110_remote_irq_disable(serdes, dev_id);
|
||||
|
||||
/* disable ext irq */
|
||||
|
||||
/* disable link irq */
|
||||
rkx110_linktx_irq_disable(serdes, dev_id);
|
||||
}
|
||||
|
||||
int rkx110_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 status, mask;
|
||||
u32 i = 0;
|
||||
|
||||
serdes->i2c_read_reg(client, SER_GRF_IRQ_EN, &mask);
|
||||
serdes->i2c_read_reg(client, SER_GRF_IRQ_STATUS, &status);
|
||||
dev_info(serdes->dev, "dev%d get the ser irq status:0x%08x\n", dev_id, status);
|
||||
|
||||
status &= mask;
|
||||
|
||||
while (status) {
|
||||
switch (status & BIT(i)) {
|
||||
case SER_IRQ_PCS0:
|
||||
rkx110_pcs_irq_handler(serdes, 0, dev_id);
|
||||
break;
|
||||
case SER_IRQ_PCS1:
|
||||
rkx110_pcs_irq_handler(serdes, 1, dev_id);
|
||||
break;
|
||||
case SER_IRQ_DSIRX0:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_DSIRX1:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_GPIO0:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_GPIO1:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_CSIHOST0:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_CSIHOST1:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_PMA_ADAPT0:
|
||||
rkx110_pma_irq_handler(serdes, 0, dev_id);
|
||||
break;
|
||||
case SER_IRQ_PMA_ADAPT1:
|
||||
rkx110_pma_irq_handler(serdes, 1, dev_id);
|
||||
break;
|
||||
case SER_IRQ_EFUSE:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_VICAP:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_REMOTE:
|
||||
rkx110_remote_irq_handler(serdes, dev_id);
|
||||
break;
|
||||
case SER_IRQ_EXT:
|
||||
/* TBD */
|
||||
break;
|
||||
case SER_IRQ_LINK:
|
||||
rkx110_linktx_irq_handler(serdes, dev_id);
|
||||
break;
|
||||
case SER_IRQ_OTHER_LANE:
|
||||
/* TBD */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
status &= ~BIT(i);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -357,6 +357,8 @@ enum {
|
||||
#define SER_GRF_SOC_CON5 GRF_REG(0x114)
|
||||
#define SER_GRF_SOC_CON6 GRF_REG(0x118)
|
||||
#define SER_GRF_SOC_CON7 GRF_REG(0x11C)
|
||||
#define SER_GRF_IRQ_EN GRF_REG(0x140)
|
||||
#define SER_GRF_IRQ_STATUS GRF_REG(0x150)
|
||||
#define SER_GRF_SOC_STATUS0 GRF_REG(0x160)
|
||||
|
||||
enum {
|
||||
@@ -467,6 +469,71 @@ enum {
|
||||
PMA0_DISABLE = HIWORD_UPDATE(0, BIT(8), 8),
|
||||
|
||||
/* SER_GRF_IRQ_EN */
|
||||
SER_IRQ_OTHER_LANE_EN = HIWORD_UPDATE(1, BIT(15), 15),
|
||||
SER_IRQ_OTHER_LANE_DIS = HIWORD_UPDATE(0, BIT(15), 15),
|
||||
|
||||
SER_IRQ_LINK_EN = HIWORD_UPDATE(1, BIT(14), 14),
|
||||
SER_IRQ_LINK_DIS = HIWORD_UPDATE(0, BIT(14), 14),
|
||||
|
||||
SER_IRQ_EXT_EN = HIWORD_UPDATE(1, BIT(13), 13),
|
||||
SER_IRQ_EXT_DIS = HIWORD_UPDATE(0, BIT(13), 13),
|
||||
|
||||
SER_IRQ_REMOTE_EN = HIWORD_UPDATE(1, BIT(12), 12),
|
||||
SER_IRQ_REMOTE_DIS = HIWORD_UPDATE(0, BIT(12), 12),
|
||||
|
||||
SER_IRQ_VICAP_EN = HIWORD_UPDATE(1, BIT(11), 11),
|
||||
SER_IRQ_VICAP_DIS = HIWORD_UPDATE(0, BIT(11), 11),
|
||||
|
||||
SER_IRQ_EFUSE_EN = HIWORD_UPDATE(1, BIT(10), 10),
|
||||
SER_IRQ_EFUSE_DIS = HIWORD_UPDATE(0, BIT(10), 10),
|
||||
|
||||
SER_IRQ_PMA_ADAPT1_EN = HIWORD_UPDATE(1, BIT(9), 9),
|
||||
SER_IRQ_PMA_ADAPT1_DIS = HIWORD_UPDATE(0, BIT(9), 9),
|
||||
|
||||
SER_IRQ_PMA_ADAPT0_EN = HIWORD_UPDATE(1, BIT(8), 8),
|
||||
SER_IRQ_PMA_ADAPT0_DIS = HIWORD_UPDATE(0, BIT(8), 8),
|
||||
|
||||
SER_IRQ_CSIHOST1_EN = HIWORD_UPDATE(1, BIT(7), 7),
|
||||
SER_IRQ_CSIHOST1_DIS = HIWORD_UPDATE(0, BIT(7), 7),
|
||||
|
||||
SER_IRQ_CSIHOST0_EN = HIWORD_UPDATE(1, BIT(6), 6),
|
||||
SER_IRQ_CSIHOST0_DIS = HIWORD_UPDATE(0, BIT(6), 6),
|
||||
|
||||
SER_IRQ_GPIO1_EN = HIWORD_UPDATE(1, BIT(5), 5),
|
||||
SER_IRQ_GPIO1_DIS = HIWORD_UPDATE(0, BIT(5), 5),
|
||||
|
||||
SER_IRQ_GPIO0_EN = HIWORD_UPDATE(1, BIT(4), 4),
|
||||
SER_IRQ_GPIO0_DIS = HIWORD_UPDATE(0, BIT(4), 4),
|
||||
|
||||
SER_IRQ_DSIRX1_EN = HIWORD_UPDATE(1, BIT(3), 3),
|
||||
SER_IRQ_DSIRX1_DIS = HIWORD_UPDATE(0, BIT(3), 3),
|
||||
|
||||
SER_IRQ_DSIRX0_EN = HIWORD_UPDATE(1, BIT(2), 2),
|
||||
SER_IRQ_DSIRX0_DIS = HIWORD_UPDATE(0, BIT(2), 2),
|
||||
|
||||
SER_IRQ_PCS1_EN = HIWORD_UPDATE(1, BIT(1), 1),
|
||||
SER_IRQ_PCS1_DIS = HIWORD_UPDATE(0, BIT(1), 1),
|
||||
|
||||
SER_IRQ_PCS0_EN = HIWORD_UPDATE(1, BIT(0), 0),
|
||||
SER_IRQ_PCS0_DIS = HIWORD_UPDATE(0, BIT(0), 0),
|
||||
|
||||
/* SER_GRF_IRQ_STATUS */
|
||||
SER_IRQ_OTHER_LANE = BIT(15),
|
||||
SER_IRQ_LINK = BIT(14),
|
||||
SER_IRQ_EXT = BIT(13),
|
||||
SER_IRQ_REMOTE = BIT(12),
|
||||
SER_IRQ_VICAP = BIT(11),
|
||||
SER_IRQ_EFUSE = BIT(10),
|
||||
SER_IRQ_PMA_ADAPT1 = BIT(9),
|
||||
SER_IRQ_PMA_ADAPT0 = BIT(8),
|
||||
SER_IRQ_CSIHOST1 = BIT(7),
|
||||
SER_IRQ_CSIHOST0 = BIT(6),
|
||||
SER_IRQ_GPIO1 = BIT(5),
|
||||
SER_IRQ_GPIO0 = BIT(4),
|
||||
SER_IRQ_DSIRX1 = BIT(3),
|
||||
SER_IRQ_DSIRX0 = BIT(2),
|
||||
SER_IRQ_PCS1 = BIT(1),
|
||||
SER_IRQ_PCS0 = BIT(0),
|
||||
|
||||
/* SER_GRF_SOC_STATUS0 */
|
||||
SER_PCS1_READY = BIT(21),
|
||||
|
||||
@@ -262,7 +262,9 @@ struct rk_serdes {
|
||||
struct regulator *supply;
|
||||
struct gpio_desc *reset;
|
||||
struct gpio_desc *enable;
|
||||
struct gpio_desc *irq_gpio;
|
||||
|
||||
int irq;
|
||||
/*
|
||||
* Control by I2C-Debug
|
||||
*/
|
||||
@@ -364,4 +366,10 @@ void rkx110_linktx_passthrough_cfg(struct rk_serdes *serdes, u32 client_id, u32
|
||||
bool is_rx);
|
||||
void rkx120_linkrx_passthrough_cfg(struct rk_serdes *serdes, u32 client_id, u32 func_id,
|
||||
bool is_rx);
|
||||
void rkx110_irq_enable(struct rk_serdes *serdes, u8 dev_id);
|
||||
void rkx110_irq_disable(struct rk_serdes *serdes, u8 dev_id);
|
||||
int rkx110_irq_handler(struct rk_serdes *serdes, u8 dev_id);
|
||||
void rkx120_irq_enable(struct rk_serdes *serdes, u8 dev_id);
|
||||
void rkx120_irq_disable(struct rk_serdes *serdes, u8 dev_id);
|
||||
int rkx120_irq_handler(struct rk_serdes *serdes, u8 dev_id);
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mfd/core.h>
|
||||
@@ -652,6 +653,25 @@ static int rk_serdes_passthrough_init(struct rk_serdes *serdes)
|
||||
kfree(configs);
|
||||
}
|
||||
|
||||
/* config irq passthrough */
|
||||
if (serdes->stream_type == STREAM_DISPLAY) {
|
||||
rkx110_linktx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
|
||||
false);
|
||||
rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
|
||||
true);
|
||||
if (serdes->remote_nr == 2)
|
||||
rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE1,
|
||||
RK_SERDES_PASSTHROUGH_IRQ, true);
|
||||
} else {
|
||||
rkx120_linkrx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
|
||||
false);
|
||||
rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
|
||||
true);
|
||||
if (serdes->remote_nr == 2)
|
||||
rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE1,
|
||||
RK_SERDES_PASSTHROUGH_IRQ, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -953,9 +973,66 @@ static int rk_serdes_pinctrl_init(struct rk_serdes *serdes)
|
||||
kfree(configs);
|
||||
}
|
||||
|
||||
/* config irq pinctrl */
|
||||
if (serdes->stream_type == STREAM_DISPLAY) {
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX110,
|
||||
RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC2);
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX120,
|
||||
RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC0);
|
||||
if (serdes->remote_nr == 2)
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX120,
|
||||
RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC0);
|
||||
} else {
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX110,
|
||||
RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC0);
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX120,
|
||||
RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC2);
|
||||
if (serdes->remote_nr == 2)
|
||||
serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX110,
|
||||
RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
|
||||
RK_SERDES_PIN_CONFIG_MUX_FUNC2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_serdes_irq_enable(struct rk_serdes *serdes)
|
||||
{
|
||||
if (serdes->stream_type == STREAM_DISPLAY)
|
||||
rkx110_irq_enable(serdes, DEVICE_LOCAL);
|
||||
else
|
||||
rkx120_irq_enable(serdes, DEVICE_LOCAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__maybe_unused static int rk_serdes_irq_disable(struct rk_serdes *serdes)
|
||||
{
|
||||
if (serdes->stream_type == STREAM_DISPLAY)
|
||||
rkx110_irq_disable(serdes, DEVICE_LOCAL);
|
||||
else
|
||||
rkx120_irq_disable(serdes, DEVICE_LOCAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rk_serdes_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct rk_serdes *serdes = arg;
|
||||
|
||||
if (serdes->stream_type == STREAM_DISPLAY)
|
||||
rkx110_irq_handler(serdes, DEVICE_LOCAL);
|
||||
else
|
||||
rkx120_irq_handler(serdes, DEVICE_LOCAL);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
@@ -1014,6 +1091,30 @@ static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_devic
|
||||
return ret;
|
||||
}
|
||||
|
||||
serdes->irq_gpio = devm_gpiod_get_optional(dev, "irq", GPIOD_IN);
|
||||
if (IS_ERR(serdes->irq_gpio)) {
|
||||
ret = PTR_ERR(serdes->irq_gpio);
|
||||
dev_err(dev, "failed to request irq GPIO: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (serdes->irq_gpio) {
|
||||
serdes->irq = gpiod_to_irq(serdes->irq_gpio);
|
||||
if (serdes->irq < 0)
|
||||
return dev_err_probe(dev, serdes->irq, "failed to get irq\n");
|
||||
|
||||
irq_set_status_flags(serdes->irq, IRQ_NOAUTOEN);
|
||||
ret = devm_request_threaded_irq(dev, serdes->irq, NULL,
|
||||
rk_serdes_irq_handler,
|
||||
IRQF_TRIGGER_LOW |
|
||||
IRQF_ONESHOT, "serdes-irq", serdes);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request serdes interrupt\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_warn(dev, "no support serdes irq function\n");
|
||||
}
|
||||
|
||||
disp_np = of_get_child_by_name(dev->of_node, "serdes-panel");
|
||||
if (disp_np) {
|
||||
serdes->stream_type = STREAM_DISPLAY;
|
||||
@@ -1062,6 +1163,9 @@ static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_devic
|
||||
rk_serdes_set_rate(serdes, RATE_4GBPS_83M);
|
||||
rk_serdes_pinctrl_init(serdes);
|
||||
rk_serdes_passthrough_init(serdes);
|
||||
rk_serdes_irq_enable(serdes);
|
||||
enable_irq(serdes->irq);
|
||||
|
||||
out:
|
||||
rk_serdes_debugfs_init(serdes);
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#define LANE0_DATA_WIDTH_16BIT UPDATE(1, 13, 12)
|
||||
#define LANE0_DATA_WIDTH_24BIT UPDATE(2, 13, 12)
|
||||
#define LANE0_DATA_WIDTH_32BIT UPDATE(3, 13, 12)
|
||||
#define LANE1_PKT_LOSE_NUM_CLR BIT(9)
|
||||
#define LANE0_PKT_LOSE_NUM_CLR BIT(8)
|
||||
#define LANE0_EN BIT(4)
|
||||
#define LANE1_EN BIT(5)
|
||||
#define DES_EN BIT(0)
|
||||
@@ -115,6 +117,42 @@
|
||||
#define E2_FIRST_FRAME_DEL BIT(6)
|
||||
#define E1_FIRST_FRAME_DEL BIT(5)
|
||||
#define E0_FIRST_FRAME_DEL BIT(4)
|
||||
#define RKLINK_DES_FIFO_STATUS LINK_REG(0x0084)
|
||||
#define AUDIO_FIFO_UNDERRUN BIT(29)
|
||||
#define AUDIO_ORDER_UNDERRUN BIT(28)
|
||||
#define VIDEO_DATA_FIFO_UNDERRUN BIT(27)
|
||||
#define VIDEO_ORDER_UNDERRUN BIT(26)
|
||||
#define CMD_FIFO_UNDERRUN BIT(25)
|
||||
#define E1_ORDER_MIS BIT(15)
|
||||
#define E0_ORDER_MIS BIT(14)
|
||||
#define AUDIO_FIFO_OVERFLOW BIT(13)
|
||||
#define AUDIO_ORDER_OVERFLOW BIT(12)
|
||||
#define VIDEO_DATA_FIFO_OVERFLOW GENMASK(11, 8)
|
||||
#define VIDEO_ORDER_OVERFLOW GENMASK(7, 4)
|
||||
#define CMD_FIFO_OVERFLOW GENMASK(3, 0)
|
||||
#define RKLINK_DES_SINK_IRQ_EN LINK_REG(0x0088)
|
||||
#define COMP_NOT_ENOUGH_IRQ_FLAG BIT(26)
|
||||
#define VIDEO_FM_IRQ_FLAG BIT(25)
|
||||
#define AUDIO_FM_IRQ_FLAG BIT(24)
|
||||
#define ORDER_MIS_IRQ_FLAG BIT(23)
|
||||
#define FIFO_UNDERRUN_IRQ_FLAG BIT(22)
|
||||
#define FIFO_OVERFLOW_IRQ_FLAG BIT(21)
|
||||
#define PKT_LOSE_IRQ_FLAG BIT(20)
|
||||
#define LAST_ERROR_IRQ_FLAG BIT(19)
|
||||
#define ECC2BIT_ERROR_IRQ_FLAG BIT(18)
|
||||
#define ECC1BIT_ERROR_IRQ_FLAG BIT(17)
|
||||
#define CRC_ERROR_IRQ_FLAG BIT(16)
|
||||
#define COMP_NOT_ENOUGH_IRQ_OUTPUT_EN BIT(10)
|
||||
#define VIDEO_FM_IRQ_OUTPUT_EN BIT(9)
|
||||
#define AUDIO_FM_IRQ_OUTPUT_EN BIT(8)
|
||||
#define ORDER_MIS_IRQ_OUTPUT_EN BIT(7)
|
||||
#define FIFO_UNDERRUN_IRQ_OUTPUT_EN BIT(6)
|
||||
#define FIFO_OVERFLOW_IRQ_OUTPUT_EN BIT(5)
|
||||
#define PKT_LOSE_IRQ_OUTPUT_EN BIT(4)
|
||||
#define LAST_ERROR_IRQ_OUTPUT_EN BIT(3)
|
||||
#define ECC2BIT_ERROR_IRQ_OUTPUT_EN BIT(2)
|
||||
#define ECC1BIT_ERROR_IRQ_OUTPUT_EN BIT(1)
|
||||
#define CRC_ERROR_IRQ_OUTPUT_EN BIT(0)
|
||||
|
||||
#define DES_RKLINK_STOP_CFG LINK_REG(0x009C)
|
||||
#define STOP_AUDIO BIT(4)
|
||||
@@ -147,6 +185,7 @@
|
||||
#define PCS_REG24(id) PCS_REG(id, 0x24)
|
||||
#define PCS_REG28(id) PCS_REG(id, 0x28)
|
||||
#define PCS_REG30(id) PCS_REG(id, 0x30)
|
||||
#define DES_PCS_INI_EN(x) HIWORD_UPDATE(x, GENMASK(15, 0), 0)
|
||||
#define PCS_REG34(id) PCS_REG(id, 0x34)
|
||||
#define PCS_REG40(id) PCS_REG(id, 0x40)
|
||||
|
||||
@@ -226,6 +265,19 @@
|
||||
#define DES_PMA_LOAD0E(id) PMA_REG(id, 0x48)
|
||||
#define DES_PMA_REG100(id) PMA_REG(id, 0x100)
|
||||
|
||||
#define DES_PMA_IRQ_EN(id) PMA_REG(id, 0xF0)
|
||||
#define FORCE_INITIAL_IRQ_EN HIWORD_UPDATE(1, BIT(6), 6)
|
||||
#define RX_RDY_NEG_IRQ_EN HIWORD_UPDATE(1, BIT(5), 5)
|
||||
#define RX_LOS_IRQ_EN HIWORD_UPDATE(1, BIT(4), 4)
|
||||
#define RX_RDY_TIMEOUT_IRQ_EN HIWORD_UPDATE(1, BIT(2), 2)
|
||||
#define PLL_LOCK_TIMEOUT_IRQ_EN HIWORD_UPDATE(1, BIT(0), 0)
|
||||
#define DES_PMA_IRQ_STATUS(id) PMA_REG(id, 0xF4)
|
||||
#define FORCE_INITIAL_IRQ_STATUS BIT(6)
|
||||
#define RX_RDY_NEG_IRQ_STATUS BIT(5)
|
||||
#define RX_LOS_IRQ_STATUS BIT(4)
|
||||
#define RX_RDY_TIMEOUT_IRQ_STATUS BIT(2)
|
||||
#define PLL_LOCK_TIMEOUT_IRQ_STATUS BIT(0)
|
||||
|
||||
static const struct rk_serdes_pt des_pt[] = {
|
||||
{
|
||||
/* gpi_gpo_0 */
|
||||
@@ -813,3 +865,354 @@ void rkx120_des_pma_enable(struct rk_serdes *serdes, bool enable, u8 pma_id, u8
|
||||
|
||||
serdes->i2c_update_bits(client, DES_GRF_SOC_CON4, mask, val);
|
||||
}
|
||||
|
||||
|
||||
static void rkx120_linkrx_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_LINK_EN);
|
||||
|
||||
serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, FIFO_UNDERRUN_IRQ_OUTPUT_EN |
|
||||
FIFO_OVERFLOW_IRQ_OUTPUT_EN);
|
||||
}
|
||||
|
||||
static void rkx120_linkrx_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_LINK_DIS);
|
||||
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &val);
|
||||
val &= ~(FIFO_UNDERRUN_IRQ_OUTPUT_EN | FIFO_OVERFLOW_IRQ_OUTPUT_EN);
|
||||
serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, val);
|
||||
}
|
||||
|
||||
static void rkx120_linkrx_fifo_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_FIFO_STATUS, &value);
|
||||
dev_err(serdes->dev, "des rklink fifo status:0x%x\n", value);
|
||||
|
||||
if (value & AUDIO_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linkrx audio fifo underrun\n");
|
||||
if (value & AUDIO_ORDER_UNDERRUN)
|
||||
dev_err(serdes->dev, "linkrx audio order underrun\n");
|
||||
if (value & VIDEO_DATA_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linkrx video data fifo underrun\n");
|
||||
if (value & VIDEO_ORDER_UNDERRUN)
|
||||
dev_err(serdes->dev, "linkrx video order underrun\n");
|
||||
if (value & CMD_FIFO_UNDERRUN)
|
||||
dev_err(serdes->dev, "linkrx cmd fifo underrun\n");
|
||||
if (value & E1_ORDER_MIS)
|
||||
dev_err(serdes->dev, "linkrx e1 order miss\n");
|
||||
if (value & E0_ORDER_MIS)
|
||||
dev_err(serdes->dev, "linkrx e0 order miss\n");
|
||||
if (value & AUDIO_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linkrx audio fifo overflow\n");
|
||||
if (value & AUDIO_ORDER_OVERFLOW)
|
||||
dev_err(serdes->dev, "linkrx audio order overflow\n");
|
||||
if (value & VIDEO_DATA_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linkrx video data fifo overflow\n");
|
||||
if (value & VIDEO_ORDER_OVERFLOW)
|
||||
dev_err(serdes->dev, "linkrx video order overflow\n");
|
||||
if (value & CMD_FIFO_OVERFLOW)
|
||||
dev_err(serdes->dev, "linkrx cmd fifo overflow\n");
|
||||
|
||||
serdes->i2c_write_reg(client, RKLINK_DES_FIFO_STATUS, value);
|
||||
}
|
||||
|
||||
static void rkx120_linkrx_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 flag, value;
|
||||
int i = 0;
|
||||
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &flag);
|
||||
flag &= COMP_NOT_ENOUGH_IRQ_FLAG | VIDEO_FM_IRQ_FLAG | AUDIO_FM_IRQ_FLAG |
|
||||
ORDER_MIS_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG | FIFO_OVERFLOW_IRQ_FLAG |
|
||||
PKT_LOSE_IRQ_FLAG | LAST_ERROR_IRQ_FLAG | ECC2BIT_ERROR_IRQ_FLAG |
|
||||
ECC1BIT_ERROR_IRQ_FLAG | CRC_ERROR_IRQ_FLAG;
|
||||
dev_info(serdes->dev, "linkrx irq flag:0x%08x\n", flag);
|
||||
while (flag) {
|
||||
switch (flag & BIT(i)) {
|
||||
case COMP_NOT_ENOUGH_IRQ_FLAG:
|
||||
break;
|
||||
case VIDEO_FM_IRQ_FLAG:
|
||||
break;
|
||||
case AUDIO_FM_IRQ_FLAG:
|
||||
break;
|
||||
case ORDER_MIS_IRQ_FLAG:
|
||||
case FIFO_UNDERRUN_IRQ_FLAG:
|
||||
case FIFO_OVERFLOW_IRQ_FLAG:
|
||||
flag &= ~(ORDER_MIS_IRQ_FLAG | FIFO_UNDERRUN_IRQ_FLAG |
|
||||
FIFO_OVERFLOW_IRQ_FLAG);
|
||||
rkx120_linkrx_fifo_handler(serdes, dev_id);
|
||||
break;
|
||||
case PKT_LOSE_IRQ_FLAG:
|
||||
/* clear pkt lost irq flag */
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_LANE_ENGINE_CFG, &value);
|
||||
value |= LANE0_PKT_LOSE_NUM_CLR | LANE1_PKT_LOSE_NUM_CLR;
|
||||
serdes->i2c_write_reg(client, RKLINK_DES_LANE_ENGINE_CFG, value);
|
||||
break;
|
||||
case LAST_ERROR_IRQ_FLAG:
|
||||
case ECC2BIT_ERROR_IRQ_FLAG:
|
||||
case ECC1BIT_ERROR_IRQ_FLAG:
|
||||
case CRC_ERROR_IRQ_FLAG:
|
||||
flag &= ~(LAST_ERROR_IRQ_FLAG | ECC2BIT_ERROR_IRQ_FLAG |
|
||||
ECC1BIT_ERROR_IRQ_FLAG | CRC_ERROR_IRQ_FLAG);
|
||||
serdes->i2c_read_reg(client, RKLINK_DES_SINK_IRQ_EN, &value);
|
||||
dev_info(serdes->dev, "linkrx ecc crc result:0x%08x\n", value);
|
||||
/* clear ecc crc irq flag */
|
||||
serdes->i2c_write_reg(client, RKLINK_DES_SINK_IRQ_EN, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flag &= ~BIT(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
static void rkx120_pcs_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
val = pcs_id ? DES_IRQ_PCS1_EN : DES_IRQ_PCS0_EN;
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, PCS_REG30(pcs_id), DES_PCS_INI_EN(0xffff));
|
||||
}
|
||||
|
||||
static void rkx120_pcs_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
val = pcs_id ? DES_IRQ_PCS1_DIS : DES_IRQ_PCS0_DIS;
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, PCS_REG30(pcs_id), DES_PCS_INI_EN(0));
|
||||
}
|
||||
|
||||
static void rkx120_pcs_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, PCS_REG20(pcs_id), &value);
|
||||
dev_info(serdes->dev, "des pcs%d fatal status:0x%08x\n", pcs_id, value);
|
||||
|
||||
/* clear fatal status */
|
||||
serdes->i2c_write_reg(client, PCS_REG10(pcs_id), 0xffffffff);
|
||||
serdes->i2c_write_reg(client, PCS_REG10(pcs_id), 0xffff0000);
|
||||
}
|
||||
|
||||
static void rkx120_pma_irq_enable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
val = pcs_id ? DES_IRQ_PMA_ADAPT1_EN : DES_IRQ_PMA_ADAPT0_EN;
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, DES_PMA_IRQ_EN(pcs_id), FORCE_INITIAL_IRQ_EN |
|
||||
RX_RDY_NEG_IRQ_EN | RX_LOS_IRQ_EN | RX_RDY_TIMEOUT_IRQ_EN |
|
||||
PLL_LOCK_TIMEOUT_IRQ_EN);
|
||||
}
|
||||
|
||||
static void rkx120_pma_irq_disable(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 val = 0;
|
||||
|
||||
val = pcs_id ? DES_IRQ_PMA_ADAPT1_DIS : DES_IRQ_PMA_ADAPT0_DIS;
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, val);
|
||||
|
||||
serdes->i2c_write_reg(client, DES_PMA_IRQ_EN(pcs_id), 0);
|
||||
}
|
||||
|
||||
static void rkx120_pma_irq_handler(struct rk_serdes *serdes, u8 pcs_id, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 value;
|
||||
|
||||
serdes->i2c_read_reg(client, DES_PMA_IRQ_STATUS(pcs_id), &value);
|
||||
dev_info(serdes->dev, "des pma%d irq status:0x%08x\n", pcs_id, value);
|
||||
|
||||
if (value & FORCE_INITIAL_IRQ_STATUS)
|
||||
dev_info(serdes->dev, "des pma trig force initial pulse status\n");
|
||||
else if (value & RX_RDY_NEG_IRQ_STATUS)
|
||||
dev_info(serdes->dev, "des pma trig rx rdy neg status\n");
|
||||
else if (value & RX_LOS_IRQ_STATUS)
|
||||
dev_info(serdes->dev, "des pma trig rx los status\n");
|
||||
else if (value & RX_RDY_TIMEOUT_IRQ_STATUS)
|
||||
dev_info(serdes->dev, "des pma trig rx rdy timeout status\n");
|
||||
else if (value & PLL_LOCK_TIMEOUT_IRQ_STATUS)
|
||||
dev_info(serdes->dev, "des pma trig pll lock timeout status\n");
|
||||
|
||||
/* clear pma irq status */
|
||||
serdes->i2c_write_reg(client, DES_PMA_IRQ_STATUS(pcs_id), value);
|
||||
}
|
||||
|
||||
static void rkx120_remote_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
if (serdes->stream_type == STREAM_CAMERA) {
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_REMOTE_EN);
|
||||
rkx110_irq_enable(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void rkx120_remote_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
|
||||
if (serdes->stream_type == STREAM_CAMERA) {
|
||||
serdes->i2c_write_reg(client, DES_GRF_IRQ_EN, DES_IRQ_REMOTE_DIS);
|
||||
rkx110_irq_disable(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void rkx120_remote_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
if (serdes->stream_type == STREAM_CAMERA)
|
||||
rkx110_irq_handler(serdes, DEVICE_REMOTE0);
|
||||
}
|
||||
|
||||
void rkx120_irq_enable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
/* enable pcs irq */
|
||||
rkx120_pcs_irq_enable(serdes, 0, dev_id);
|
||||
|
||||
/* enable efuse irq */
|
||||
|
||||
/* enable gpio irq */
|
||||
|
||||
/* enable csitx irq */
|
||||
|
||||
/* enable mipi dsi host irq */
|
||||
|
||||
/* enable pma adapt irq */
|
||||
rkx120_pma_irq_enable(serdes, 0, dev_id);
|
||||
|
||||
/* enable remote irq and other lane irq */
|
||||
rkx120_remote_irq_enable(serdes, dev_id);
|
||||
|
||||
/* enable pwm irq */
|
||||
|
||||
/* enable dvp tx irq */
|
||||
|
||||
/* enable link irq */
|
||||
rkx120_linkrx_irq_enable(serdes, dev_id);
|
||||
|
||||
/* enable ext irq */
|
||||
|
||||
/* enable ext irq */
|
||||
}
|
||||
|
||||
void rkx120_irq_disable(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
/* disable pcs irq */
|
||||
rkx120_pcs_irq_disable(serdes, 0, dev_id);
|
||||
|
||||
/* disable efuse irq */
|
||||
|
||||
/* disable gpio irq */
|
||||
|
||||
/* disable csitx irq */
|
||||
|
||||
/* disable mipi dsi host irq */
|
||||
|
||||
/* disable pma adapt irq */
|
||||
rkx120_pma_irq_disable(serdes, 0, dev_id);
|
||||
|
||||
/* disable remote irq */
|
||||
rkx120_remote_irq_disable(serdes, dev_id);
|
||||
|
||||
/* disable pwm irq */
|
||||
|
||||
/* disable dvp tx irq */
|
||||
|
||||
/* disable link irq */
|
||||
rkx120_linkrx_irq_disable(serdes, dev_id);
|
||||
|
||||
/* disable ext irq */
|
||||
}
|
||||
|
||||
int rkx120_irq_handler(struct rk_serdes *serdes, u8 dev_id)
|
||||
{
|
||||
struct i2c_client *client = serdes->chip[dev_id].client;
|
||||
u32 status = 0;
|
||||
u32 mask = 0;
|
||||
u32 i = 0;
|
||||
|
||||
serdes->i2c_read_reg(client, DES_GRF_IRQ_EN, &mask);
|
||||
serdes->i2c_read_reg(client, DES_GRF_IRQ_STATUS, &status);
|
||||
dev_info(serdes->dev, "dev%d get the des irq status:0x%08x\n", dev_id, status);
|
||||
status &= mask;
|
||||
|
||||
while (status) {
|
||||
switch (status & BIT(i)) {
|
||||
case DES_IRQ_PCS0:
|
||||
rkx120_pcs_irq_handler(serdes, 0, dev_id);
|
||||
break;
|
||||
case DES_IRQ_PCS1:
|
||||
rkx120_pcs_irq_handler(serdes, 1, dev_id);
|
||||
break;
|
||||
case DES_IRQ_EFUSE:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_GPIO0:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_GPIO1:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_CSITX0:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_CSITX1:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_MIPI_DSI_HOST:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_PMA_ADAPT0:
|
||||
rkx120_pma_irq_handler(serdes, 0, dev_id);
|
||||
break;
|
||||
case DES_IRQ_PMA_ADAPT1:
|
||||
rkx120_pma_irq_handler(serdes, 1, dev_id);
|
||||
break;
|
||||
case DES_IRQ_REMOTE:
|
||||
rkx120_remote_irq_handler(serdes, dev_id);
|
||||
break;
|
||||
case DES_IRQ_PWM:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_DVP_TX:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_LINK:
|
||||
rkx120_linkrx_irq_handler(serdes, dev_id);
|
||||
break;
|
||||
case DES_IRQ_EXT:
|
||||
/* TBD */
|
||||
break;
|
||||
case DES_IRQ_OTHER_LANE:
|
||||
/* TBD */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
status &= ~BIT(i);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +328,8 @@ enum {
|
||||
#define DES_GRF_SOC_CON5 GRF_REG(0x114)
|
||||
#define DES_GRF_SOC_CON6 GRF_REG(0x118)
|
||||
#define DES_GRF_SOC_CON7 GRF_REG(0x11C)
|
||||
#define DES_GRF_IRQ_EN GRF_REG(0x140)
|
||||
#define DES_GRF_IRQ_STATUS GRF_REG(0x150)
|
||||
|
||||
enum {
|
||||
/* SOC_CON0 */
|
||||
@@ -433,6 +435,71 @@ enum {
|
||||
/* SOC_CON9 */
|
||||
|
||||
/* DES_GRF_IRQ_EN */
|
||||
DES_IRQ_OTHER_LANE_EN = HIWORD_UPDATE(1, BIT(15), 15),
|
||||
DES_IRQ_OTHER_LANE_DIS = HIWORD_UPDATE(0, BIT(15), 15),
|
||||
|
||||
DES_IRQ_EXT_EN = HIWORD_UPDATE(1, BIT(14), 14),
|
||||
DES_IRQ_EXT_DIS = HIWORD_UPDATE(0, BIT(14), 14),
|
||||
|
||||
DES_IRQ_LINK_EN = HIWORD_UPDATE(1, BIT(13), 13),
|
||||
DES_IRQ_LINK_DIS = HIWORD_UPDATE(0, BIT(13), 13),
|
||||
|
||||
DES_IRQ_DVP_TX_EN = HIWORD_UPDATE(1, BIT(12), 12),
|
||||
DES_IRQ_DVP_TX_DIS = HIWORD_UPDATE(0, BIT(12), 12),
|
||||
|
||||
DES_IRQ_PWM_EN = HIWORD_UPDATE(1, BIT(11), 11),
|
||||
DES_IRQ_PWM_DIS = HIWORD_UPDATE(0, BIT(11), 11),
|
||||
|
||||
DES_IRQ_REMOTE_EN = HIWORD_UPDATE(1, BIT(10), 10),
|
||||
DES_IRQ_REMOTE_DIS = HIWORD_UPDATE(0, BIT(10), 10),
|
||||
|
||||
DES_IRQ_PMA_ADAPT1_EN = HIWORD_UPDATE(1, BIT(9), 9),
|
||||
DES_IRQ_PMA_ADAPT1_DIS = HIWORD_UPDATE(0, BIT(9), 9),
|
||||
|
||||
DES_IRQ_PMA_ADAPT0_EN = HIWORD_UPDATE(1, BIT(8), 8),
|
||||
DES_IRQ_PMA_ADAPT0_DIS = HIWORD_UPDATE(0, BIT(8), 8),
|
||||
|
||||
DES_IRQ_MIPI_DSI_HOST_EN = HIWORD_UPDATE(1, BIT(7), 7),
|
||||
DES_IRQ_MIPI_DSI_HOST_DIS = HIWORD_UPDATE(0, BIT(7), 7),
|
||||
|
||||
DES_IRQ_CSITX1_EN = HIWORD_UPDATE(1, BIT(6), 6),
|
||||
DES_IRQ_CSITX1_DIS = HIWORD_UPDATE(0, BIT(6), 6),
|
||||
|
||||
DES_IRQ_CSITX0_EN = HIWORD_UPDATE(1, BIT(5), 5),
|
||||
DES_IRQ_CSITX0_DIS = HIWORD_UPDATE(0, BIT(5), 5),
|
||||
|
||||
DES_IRQ_GPIO1_EN = HIWORD_UPDATE(1, BIT(4), 4),
|
||||
DES_IRQ_GPIO1_DIS = HIWORD_UPDATE(0, BIT(4), 4),
|
||||
|
||||
DES_IRQ_GPIO0_EN = HIWORD_UPDATE(1, BIT(3), 3),
|
||||
DES_IRQ_GPIO0_DIS = HIWORD_UPDATE(0, BIT(3), 3),
|
||||
|
||||
DES_IRQ_EFUSE_EN = HIWORD_UPDATE(1, BIT(2), 2),
|
||||
DES_IRQ_EFUSE_DIS = HIWORD_UPDATE(0, BIT(2), 2),
|
||||
|
||||
DES_IRQ_PCS1_EN = HIWORD_UPDATE(1, BIT(1), 1),
|
||||
DES_IRQ_PCS1_DIS = HIWORD_UPDATE(0, BIT(1), 1),
|
||||
|
||||
DES_IRQ_PCS0_EN = HIWORD_UPDATE(1, BIT(0), 0),
|
||||
DES_IRQ_PCS0_DIS = HIWORD_UPDATE(0, BIT(0), 0),
|
||||
|
||||
/* DES_GRF_IRQ_STATUS */
|
||||
DES_IRQ_PCS0 = BIT(0),
|
||||
DES_IRQ_PCS1 = BIT(1),
|
||||
DES_IRQ_EFUSE = BIT(2),
|
||||
DES_IRQ_GPIO0 = BIT(3),
|
||||
DES_IRQ_GPIO1 = BIT(4),
|
||||
DES_IRQ_CSITX0 = BIT(5),
|
||||
DES_IRQ_CSITX1 = BIT(6),
|
||||
DES_IRQ_MIPI_DSI_HOST = BIT(7),
|
||||
DES_IRQ_PMA_ADAPT0 = BIT(8),
|
||||
DES_IRQ_PMA_ADAPT1 = BIT(9),
|
||||
DES_IRQ_REMOTE = BIT(10),
|
||||
DES_IRQ_PWM = BIT(11),
|
||||
DES_IRQ_DVP_TX = BIT(12),
|
||||
DES_IRQ_LINK = BIT(13),
|
||||
DES_IRQ_EXT = BIT(14),
|
||||
DES_IRQ_OTHER_LANE = BIT(15),
|
||||
|
||||
/* DES_GRF_SOC_STATUS0 */
|
||||
DES_PCS1_READY = BIT(1),
|
||||
|
||||
@@ -155,6 +155,10 @@ static unsigned int dw_wdt_get_min_timeout(struct dw_wdt *dw_wdt)
|
||||
break;
|
||||
}
|
||||
|
||||
/* For Coverity check */
|
||||
if (idx == DW_WDT_NUM_TOPS)
|
||||
idx = 0;
|
||||
|
||||
return dw_wdt->timeouts[idx].sec;
|
||||
}
|
||||
|
||||
@@ -178,6 +182,9 @@ static unsigned int dw_wdt_get_timeout(struct dw_wdt *dw_wdt)
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx == DW_WDT_NUM_TOPS)
|
||||
idx = 0;
|
||||
|
||||
/*
|
||||
* In IRQ mode due to the two stages counter, the actual timeout is
|
||||
* twice greater than the TOP setting.
|
||||
|
||||
Reference in New Issue
Block a user