Commit 576d196c authored by Paul Kocialkowski's avatar Paul Kocialkowski Committed by Mauro Carvalho Chehab

media: sunxi: Add support for the A83T MIPI CSI-2 controller

The A83T supports MIPI CSI-2 with a composite controller, covering
both the protocol logic and the D-PHY implementation. This controller
seems to be found on the A83T only and probably was abandoned since.

This implementation splits the protocol and D-PHY registers and
uses the PHY framework internally. The D-PHY is not registered as a
standalone PHY driver since it cannot be used with any other
controller.

There are a few notable points about the controller:
- The initialisation sequence involes writing specific magic init
  values that do not seem to make any particular sense given the
  concerned register fields;
- Interrupts appear to be hitting regardless of the interrupt mask
  registers, which can cause a serious flood when transmission errors
  occur.

Only 8-bit and 10-bit Bayer formats are currently supported.
While up to 4 internal channels to the CSI controller exist, only one
is currently supported by this implementation.

This work is based on the first version of the driver submitted by
Kévin L'hôpital, which was adapted to mainline from the Allwinner BSP.
This version integrates MIPI CSI-2 support as a standalone V4L2 subdev
instead of merging it in the sun6i-csi driver.

It was tested on a Banana Pi M3 board with an OV8865 sensor in a 4-lane
configuration.
Signed-off-by: default avatarPaul Kocialkowski <paul.kocialkowski@bootlin.com>
Acked-by: default avatarMaxime Ripard <mripard@kernel.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent e4afdad6
......@@ -5,5 +5,6 @@ comment "Sunxi media platform drivers"
source "drivers/media/platform/sunxi/sun4i-csi/Kconfig"
source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
source "drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig"
source "drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig"
source "drivers/media/platform/sunxi/sun8i-di/Kconfig"
source "drivers/media/platform/sunxi/sun8i-rotate/Kconfig"
......@@ -3,5 +3,6 @@
obj-y += sun4i-csi/
obj-y += sun6i-csi/
obj-y += sun6i-mipi-csi2/
obj-y += sun8i-a83t-mipi-csi2/
obj-y += sun8i-di/
obj-y += sun8i-rotate/
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_SUN8I_A83T_MIPI_CSI2
tristate "Allwinner A83T MIPI CSI-2 Controller and D-PHY Driver"
depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV
depends on ARCH_SUNXI || COMPILE_TEST
depends on PM && COMMON_CLK
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
select V4L2_FWNODE
select REGMAP_MMIO
help
Support for the Allwinner A83T MIPI CSI-2 controller and D-PHY.
# SPDX-License-Identifier: GPL-2.0-only
sun8i-a83t-mipi-csi2-y += sun8i_a83t_mipi_csi2.o sun8i_a83t_dphy.o
obj-$(CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2) += sun8i-a83t-mipi-csi2.o
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2020-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include "sun8i_a83t_dphy.h"
#include "sun8i_a83t_mipi_csi2.h"
static int sun8i_a83t_dphy_configure(struct phy *dphy,
union phy_configure_opts *opts)
{
return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
}
static int sun8i_a83t_dphy_power_on(struct phy *dphy)
{
struct sun8i_a83t_mipi_csi2_device *csi2_dev = phy_get_drvdata(dphy);
struct regmap *regmap = csi2_dev->regmap;
regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG,
SUN8I_A83T_DPHY_CTRL_RESET_N |
SUN8I_A83T_DPHY_CTRL_SHUTDOWN_N);
regmap_write(regmap, SUN8I_A83T_DPHY_ANA0_REG,
SUN8I_A83T_DPHY_ANA0_REXT_EN |
SUN8I_A83T_DPHY_ANA0_RINT(2) |
SUN8I_A83T_DPHY_ANA0_SNK(2));
return 0;
};
static int sun8i_a83t_dphy_power_off(struct phy *dphy)
{
struct sun8i_a83t_mipi_csi2_device *csi2_dev = phy_get_drvdata(dphy);
struct regmap *regmap = csi2_dev->regmap;
regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 0);
return 0;
};
static const struct phy_ops sun8i_a83t_dphy_ops = {
.configure = sun8i_a83t_dphy_configure,
.power_on = sun8i_a83t_dphy_power_on,
.power_off = sun8i_a83t_dphy_power_off,
};
int sun8i_a83t_dphy_register(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
{
struct device *dev = csi2_dev->dev;
struct phy_provider *phy_provider;
csi2_dev->dphy = devm_phy_create(dev, NULL, &sun8i_a83t_dphy_ops);
if (IS_ERR(csi2_dev->dphy)) {
dev_err(dev, "failed to create D-PHY\n");
return PTR_ERR(csi2_dev->dphy);
}
phy_set_drvdata(csi2_dev->dphy, csi2_dev);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (IS_ERR(phy_provider)) {
dev_err(dev, "failed to register D-PHY provider\n");
return PTR_ERR(phy_provider);
}
return 0;
}
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>
* Copyright 2020-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#ifndef _SUN8I_A83T_DPHY_H_
#define _SUN8I_A83T_DPHY_H_
#include "sun8i_a83t_mipi_csi2.h"
#define SUN8I_A83T_DPHY_CTRL_REG 0x10
#define SUN8I_A83T_DPHY_CTRL_INIT_VALUE 0xb8df698e
#define SUN8I_A83T_DPHY_CTRL_RESET_N BIT(31)
#define SUN8I_A83T_DPHY_CTRL_SHUTDOWN_N BIT(15)
#define SUN8I_A83T_DPHY_CTRL_DEBUG BIT(8)
#define SUN8I_A83T_DPHY_STATUS_REG 0x14
#define SUN8I_A83T_DPHY_STATUS_CLK_STOP BIT(10)
#define SUN8I_A83T_DPHY_STATUS_CLK_ULPS BIT(9)
#define SUN8I_A83T_DPHY_STATUS_HSCLK BIT(8)
#define SUN8I_A83T_DPHY_STATUS_D3_STOP BIT(7)
#define SUN8I_A83T_DPHY_STATUS_D2_STOP BIT(6)
#define SUN8I_A83T_DPHY_STATUS_D1_STOP BIT(5)
#define SUN8I_A83T_DPHY_STATUS_D0_STOP BIT(4)
#define SUN8I_A83T_DPHY_STATUS_D3_ULPS BIT(3)
#define SUN8I_A83T_DPHY_STATUS_D2_ULPS BIT(2)
#define SUN8I_A83T_DPHY_STATUS_D1_ULPS BIT(1)
#define SUN8I_A83T_DPHY_STATUS_D0_ULPS BIT(0)
#define SUN8I_A83T_DPHY_ANA0_REG 0x30
#define SUN8I_A83T_DPHY_ANA0_REXT_EN BIT(31)
#define SUN8I_A83T_DPHY_ANA0_REXT BIT(30)
#define SUN8I_A83T_DPHY_ANA0_RINT(v) (((v) << 28) & GENMASK(29, 28))
#define SUN8I_A83T_DPHY_ANA0_SNK(v) (((v) << 20) & GENMASK(22, 20))
int sun8i_a83t_dphy_register(struct sun8i_a83t_mipi_csi2_device *csi2_dev);
#endif
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>
* Copyright 2020-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#ifndef _SUN8I_A83T_MIPI_CSI2_H_
#define _SUN8I_A83T_MIPI_CSI2_H_
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#define SUN8I_A83T_MIPI_CSI2_NAME "sun8i-a83t-mipi-csi2"
enum sun8i_a83t_mipi_csi2_pad {
SUN8I_A83T_MIPI_CSI2_PAD_SINK = 0,
SUN8I_A83T_MIPI_CSI2_PAD_SOURCE = 1,
SUN8I_A83T_MIPI_CSI2_PAD_COUNT = 2,
};
struct sun8i_a83t_mipi_csi2_format {
u32 mbus_code;
u8 data_type;
u32 bpp;
};
struct sun8i_a83t_mipi_csi2_bridge {
struct v4l2_subdev subdev;
struct media_pad pads[SUN8I_A83T_MIPI_CSI2_PAD_COUNT];
struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_notifier notifier;
struct v4l2_mbus_framefmt mbus_format;
struct mutex lock; /* Mbus format lock. */
struct v4l2_subdev *source_subdev;
};
struct sun8i_a83t_mipi_csi2_device {
struct device *dev;
struct regmap *regmap;
struct clk *clock_mod;
struct clk *clock_mipi;
struct clk *clock_misc;
struct reset_control *reset;
struct phy *dphy;
struct sun8i_a83t_mipi_csi2_bridge bridge;
};
#endif
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>
* Copyright 2020-2022 Bootlin
* Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*/
#ifndef _SUN8I_A83T_MIPI_CSI2_REG_H_
#define _SUN8I_A83T_MIPI_CSI2_REG_H_
#define SUN8I_A83T_MIPI_CSI2_VERSION_REG 0x0
#define SUN8I_A83T_MIPI_CSI2_CTRL_REG 0x4
#define SUN8I_A83T_MIPI_CSI2_CTRL_INIT_VALUE 0xb8c39bec
#define SUN8I_A83T_MIPI_CSI2_CTRL_RESET_N BIT(31)
#define SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_REG 0x8
#define SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_INIT_VALUE 0xb8d257f8
#define SUN8I_A83T_MIPI_CSI2_RSVD0_REG 0xc
#define SUN8I_A83T_MIPI_CSI2_RSVD1_REG 0x18
#define SUN8I_A83T_MIPI_CSI2_RSVD1_HW_LOCK_VALUE 0xb8c8a30c
#define SUN8I_A83T_MIPI_CSI2_RSVD2_REG 0x1c
#define SUN8I_A83T_MIPI_CSI2_RSVD2_HW_LOCK_VALUE 0xb8df8ad7
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_REG 0x20
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_ECC_ERR_DBL BIT(28)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_CKSM_ERR_VC3 BIT(27)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_CKSM_ERR_VC2 BIT(26)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_CKSM_ERR_VC1 BIT(25)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_CKSM_ERR_VC0 BIT(24)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_SEQ_ERR_DT3 BIT(23)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_SEQ_ERR_DT2 BIT(22)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_SEQ_ERR_DT1 BIT(21)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LINE_SEQ_ERR_DT0 BIT(20)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LS_LE_ERR_DT3 BIT(19)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LS_LE_ERR_DT2 BIT(18)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LS_LE_ERR_DT1 BIT(17)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_LS_LE_ERR_DT0 BIT(16)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_CRC_ERR_VC3 BIT(15)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_CRC_ERR_VC2 BIT(14)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_CRC_ERR_VC1 BIT(13)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_CRC_ERR_VC0 BIT(12)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FRM_SEQ_ERR_VC3 BIT(11)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FRM_SEQ_ERR_VC2 BIT(10)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FRM_SEQ_ERR_VC1 BIT(9)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FRM_SEQ_ERR_VC0 BIT(8)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FS_FE_ERR_VC3 BIT(7)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FS_FE_ERR_VC2 BIT(6)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FS_FE_ERR_VC1 BIT(5)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_FS_FE_ERR_VC0 BIT(4)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_SOT_SYNC_ERR_3 BIT(3)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_SOT_SYNC_ERR_2 BIT(2)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_SOT_SYNC_ERR_1 BIT(1)
#define SUN8I_A83T_MIPI_CSI2_INT_STA0_SOT_SYNC_ERR_0 BIT(0)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_REG 0x24
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LINE_SEQ_ERR_DT7 BIT(23)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LINE_SEQ_ERR_DT6 BIT(22)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LINE_SEQ_ERR_DT5 BIT(21)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LINE_SEQ_ERR_DT4 BIT(20)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LS_LE_ERR_DT7 BIT(19)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LS_LE_ERR_DT6 BIT(18)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LS_LE_ERR_DT5 BIT(17)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_LS_LE_ERR_DT4 BIT(16)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_DT_ERR_VC3 BIT(15)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_DT_ERR_VC2 BIT(14)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_DT_ERR_VC1 BIT(13)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_DT_ERR_VC0 BIT(12)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ECC_ERR1_VC3 BIT(11)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ECC_ERR1_VC2 BIT(10)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ECC_ERR1_VC1 BIT(9)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ECC_ERR1_VC0 BIT(8)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_SOT_ERR_3 BIT(7)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_SOT_ERR_2 BIT(6)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_SOT_ERR_1 BIT(5)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_SOT_ERR_0 BIT(4)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ESC_ENTRY_ERR_3 BIT(3)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ESC_ENTRY_ERR_2 BIT(2)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ESC_ENTRY_ERR_1 BIT(1)
#define SUN8I_A83T_MIPI_CSI2_INT_STA1_ESC_ENTRY_ERR_0 BIT(0)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_REG 0x28
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_ECC_ERR_DBL BIT(28)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CKSM_ERR_VC3 BIT(27)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CKSM_ERR_VC2 BIT(26)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CKSM_ERR_VC1 BIT(25)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CKSM_ERR_VC0 BIT(24)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LINE_SEQ_ERR_DT3 BIT(23)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LINE_SEQ_ERR_DT2 BIT(22)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LINE_SEQ_ERR_DT1 BIT(21)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LINE_SEQ_ERR_DT0 BIT(20)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LS_LE_ERR_DT3 BIT(19)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LS_LE_ERR_DT2 BIT(18)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LS_LE_ERR_DT1 BIT(17)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_LS_LE_ERR_DT0 BIT(16)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CRC_ERR_VC3 BIT(15)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CRC_ERR_VC2 BIT(14)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CRC_ERR_VC1 BIT(13)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_CRC_ERR_VC0 BIT(12)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FRM_SEQ_ERR_VC3 BIT(11)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FRM_SEQ_ERR_VC2 BIT(10)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FRM_SEQ_ERR_VC1 BIT(9)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FRM_SEQ_ERR_VC0 BIT(8)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FS_FE_ERR_VC3 BIT(7)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FS_FE_ERR_VC2 BIT(6)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FS_FE_ERR_VC1 BIT(5)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_FS_FE_ERR_VC0 BIT(4)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_SOT_SYNC_ERR_3 BIT(3)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_SOT_SYNC_ERR_2 BIT(2)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_SOT_SYNC_ERR_1 BIT(1)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK0_SOT_SYNC_ERR_0 BIT(0)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_REG 0x2c
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_DT_ERR_VC3 BIT(15)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_DT_ERR_VC2 BIT(14)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_DT_ERR_VC1 BIT(13)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_DT_ERR_VC0 BIT(12)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ECC_ERR1_VC3 BIT(11)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ECC_ERR1_VC2 BIT(10)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ECC_ERR1_VC1 BIT(9)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ECC_ERR1_VC0 BIT(8)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_SOT_ERR_3 BIT(7)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_SOT_ERR_2 BIT(6)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_SOT_ERR_1 BIT(5)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_SOT_ERR_0 BIT(4)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ESC_ENTRY_ERR_3 BIT(3)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ESC_ENTRY_ERR_2 BIT(2)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ESC_ENTRY_ERR_1 BIT(1)
#define SUN8I_A83T_MIPI_CSI2_INT_MSK1_ESC_ENTRY_ERR_0 BIT(0)
#define SUN8I_A83T_MIPI_CSI2_CFG_REG 0x100
#define SUN8I_A83T_MIPI_CSI2_CFG_INIT_VALUE 0xb8c64f24
#define SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN BIT(31)
#define SUN8I_A83T_MIPI_CSI2_CFG_BYPASS_ECC_EN BIT(29)
#define SUN8I_A83T_MIPI_CSI2_CFG_UNPKT_EN BIT(28)
#define SUN8I_A83T_MIPI_CSI2_CFG_NONE_UNPKT_RX_MODE BIT(27)
#define SUN8I_A83T_MIPI_CSI2_CFG_YC_SWAB BIT(26)
#define SUN8I_A83T_MIPI_CSI2_CFG_N_BYTE BIT(24)
#define SUN8I_A83T_MIPI_CSI2_CFG_SYNC_DLY_CYCLE(v) (((v) << 18) & \
GENMASK(22, 18))
#define SUN8I_A83T_MIPI_CSI2_CFG_N_CHANNEL(v) ((((v) - 1) << 16) & \
GENMASK(17, 16))
#define SUN8I_A83T_MIPI_CSI2_CFG_N_LANE(v) ((((v) - 1) << 4) & \
GENMASK(5, 4))
#define SUN8I_A83T_MIPI_CSI2_VCDT0_REG 0x104
#define SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(ch, vc) (((vc) & GENMASK(1, 0)) << \
((ch) * 8 + 6))
#define SUN8I_A83T_MIPI_CSI2_VCDT0_CH_DT(ch, t) (((t) & GENMASK(5, 0)) << \
((ch) * 8))
#define SUN8I_A83T_MIPI_CSI2_VCDT1_REG 0x108
#define SUN8I_A83T_MIPI_CSI2_VCDT1_CH_VC(ch, vc) (((vc) & GENMASK(1, 0)) << \
(((ch) - 4) * 8 + 6))
#define SUN8I_A83T_MIPI_CSI2_VCDT1_CH_DT(ch, t) (((t) & GENMASK(5, 0)) << \
(((ch) - 4) * 8))
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment