2018-05-30 09:11:50

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 0/8] add UniPhier DVB Frontend system support

This series adds support for DVB Frontend system named HSC support
for UniPhier LD11/LD20 SoCs. This driver supports MPEG2-TS serial
signal input from external demodulator and DMA MPEG2-TS stream data
onto memory.

UniPhier HSC driver provides many ports of TS input. Since the HSC
has mixed register map for those ports. It hard to split each register
areas.

Katsuhiro Suzuki (8):
media: uniphier: add DT bindings documentation for UniPhier HSC
media: uniphier: add headers of HSC MPEG2-TS I/O driver
media: uniphier: add submodules of HSC MPEG2-TS I/O driver
media: uniphier: add common module of HSC MPEG2-TS I/O driver
media: uniphier: add LD11/LD20 HSC support
media: uniphier: add common module of DVB adapter drivers
media: uniphier: add LD11 adapter driver for ISDB
media: uniphier: add LD20 adapter driver for ISDB

.../bindings/media/uniphier,hsc.txt | 38 ++
drivers/media/platform/Kconfig | 1 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/uniphier/Kconfig | 37 ++
drivers/media/platform/uniphier/Makefile | 12 +
drivers/media/platform/uniphier/hsc-core.c | 506 ++++++++++++++++++
drivers/media/platform/uniphier/hsc-css.c | 258 +++++++++
drivers/media/platform/uniphier/hsc-dma.c | 302 +++++++++++
drivers/media/platform/uniphier/hsc-ld11.c | 219 ++++++++
drivers/media/platform/uniphier/hsc-reg.h | 491 +++++++++++++++++
drivers/media/platform/uniphier/hsc-ts.c | 99 ++++
drivers/media/platform/uniphier/hsc-ucode.c | 436 +++++++++++++++
drivers/media/platform/uniphier/hsc.h | 480 +++++++++++++++++
.../platform/uniphier/ld11-mn884433-helene.c | 265 +++++++++
.../platform/uniphier/ld20-mn884434-helene.c | 274 ++++++++++
.../platform/uniphier/uniphier-adapter.c | 54 ++
.../platform/uniphier/uniphier-adapter.h | 42 ++
17 files changed, 3516 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/uniphier,hsc.txt
create mode 100644 drivers/media/platform/uniphier/Kconfig
create mode 100644 drivers/media/platform/uniphier/Makefile
create mode 100644 drivers/media/platform/uniphier/hsc-core.c
create mode 100644 drivers/media/platform/uniphier/hsc-css.c
create mode 100644 drivers/media/platform/uniphier/hsc-dma.c
create mode 100644 drivers/media/platform/uniphier/hsc-ld11.c
create mode 100644 drivers/media/platform/uniphier/hsc-reg.h
create mode 100644 drivers/media/platform/uniphier/hsc-ts.c
create mode 100644 drivers/media/platform/uniphier/hsc-ucode.c
create mode 100644 drivers/media/platform/uniphier/hsc.h
create mode 100644 drivers/media/platform/uniphier/ld11-mn884433-helene.c
create mode 100644 drivers/media/platform/uniphier/ld20-mn884434-helene.c
create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h

--
2.17.0



2018-05-30 09:11:09

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 1/8] media: uniphier: add DT bindings documentation for UniPhier HSC

This patch adds DT binding documentation for UniPhier HSC which is
MPEG2-TS input/output and demux subsystem.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
.../bindings/media/uniphier,hsc.txt | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/uniphier,hsc.txt

diff --git a/Documentation/devicetree/bindings/media/uniphier,hsc.txt b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
new file mode 100644
index 000000000000..4242483b2ecc
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
@@ -0,0 +1,38 @@
+Socionext UniPhier HSC (High-speed Stream Controller)
+
+The Socionext UniPhier HSC subsystem consists of MPEG2-TS input/output and
+demultiplexer cores in the same register space.
+
+This interface is support TS serial signals (clock, valid, sync, data) from
+external demodulators.
+
+Required properties:
+- compatible : should be one of the following:
+ "socionext,uniphier-ld11-hsc"
+ "socionext,uniphier-ld20-hsc"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain DMA and TSI error interrupt.
+- pinctrl-names : should be "default".
+- pinctrl-0 : defined TS serial signal pins for external demodulators.
+- clock-names : should include following entries:
+ "hsc", "stdmac"
+- clocks : a list of phandle, should contain an entry for each
+ entry in clock-names.
+- reset-names : should include following entries:
+ "hsc", "stdmac"
+- resets : a list of phandle, should contain an entry for each
+ entry in reset-names.
+
+Example:
+ hsc {
+ compatible = "socionext,uniphier-ld20-hsc";
+ reg = <0x5c000000 0x100000>;
+ interrupts = <0 100 4>, <0 101 4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hscin2_s>,
+ <&pinctrl_hscin3_s>;
+ clock-names = "stdmac", "hsc";
+ clocks = <&sys_clk 8>, <&sys_clk 9>;
+ reset-names = "stdmac", "hsc";
+ resets = <&sys_rst 8>, <&sys_rst 9>;
+ };
--
2.17.0


2018-05-30 09:12:31

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 2/8] media: uniphier: add headers of HSC MPEG2-TS I/O driver

This patch adds register definitions of HSC (High speed Stream
Controller) driver for Socionext UniPhier SoCs. The HSC enables to
input and output MPEG2-TS stream from/to outer world of SoC.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/Kconfig | 1 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/uniphier/Kconfig | 9 +
drivers/media/platform/uniphier/Makefile | 1 +
drivers/media/platform/uniphier/hsc-reg.h | 491 ++++++++++++++++++++++
drivers/media/platform/uniphier/hsc.h | 480 +++++++++++++++++++++
6 files changed, 984 insertions(+)
create mode 100644 drivers/media/platform/uniphier/Kconfig
create mode 100644 drivers/media/platform/uniphier/Makefile
create mode 100644 drivers/media/platform/uniphier/hsc-reg.h
create mode 100644 drivers/media/platform/uniphier/hsc.h

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 2728376b04b5..289ab4dfd30e 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -525,6 +525,7 @@ menuconfig DVB_PLATFORM_DRIVERS

if DVB_PLATFORM_DRIVERS
source "drivers/media/platform/sti/c8sectpfe/Kconfig"
+source "drivers/media/platform/uniphier/Kconfig"
endif #DVB_PLATFORM_DRIVERS

menuconfig CEC_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 04bc1502a30e..08d5052119ef 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -93,3 +93,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/
obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/

obj-y += meson/
+
+obj-$(CONFIG_DVB_UNIPHIER) += uniphier/
diff --git a/drivers/media/platform/uniphier/Kconfig b/drivers/media/platform/uniphier/Kconfig
new file mode 100644
index 000000000000..1b4543ec1e3c
--- /dev/null
+++ b/drivers/media/platform/uniphier/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+config DVB_UNIPHIER
+ tristate "Socionext UniPhier Frontend"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
+ depends on ARCH_UNIPHIER
+ help
+ Driver for UniPhier frontend for MPEG2-TS input/output,
+ demux and descramble.
+ Say Y when you want to support this frontend.
diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
new file mode 100644
index 000000000000..f66554cd5c45
--- /dev/null
+++ b/drivers/media/platform/uniphier/Makefile
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0
diff --git a/drivers/media/platform/uniphier/hsc-reg.h b/drivers/media/platform/uniphier/hsc-reg.h
new file mode 100644
index 000000000000..5f0a9b86cf49
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-reg.h
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+ *
+ * Copyright (c) 2018 Socionext Inc.
+ */
+
+#ifndef DVB_UNIPHIER_HSC_REG_H__
+#define DVB_UNIPHIER_HSC_REG_H__
+
+/*
+ * CH_0 : CIP-R8, W9
+ * CH_1 : CIP-R10,W11
+ * CH_2 : CIP-R12,W13
+ * CH_3 : CIP-R14,W15
+ * CH_4 : CIP-R16,W17
+ */
+enum HSC_CIP_FILE_NO {
+ HSC_CIP_FILE_NO_0 = 0x0,
+ HSC_CIP_FILE_NO_1,
+ HSC_CIP_FILE_NO_2,
+ HSC_CIP_FILE_NO_3,
+ HSC_CIP_FILE_NO_4,
+ HSC_CIP_FILE_NO_END,
+ HSC_CIP_FILE_NO_DISABLE,
+};
+
+#define HSC_CIP_FILE_TO_CIPR(i) ((i) * 2 + 0)
+#define HSC_CIP_FILE_TO_CIPW(i) ((i) * 2 + 1)
+#define HSC_CIP_FILE_TO_CIPR_DMCH(i) (HSC_CIP_FILE_TO_CIPR(i) + 8)
+#define HSC_CIP_FILE_TO_CIPW_DMCH(i) (HSC_CIP_FILE_TO_CIPW(i) + 8)
+
+/* RAM Address */
+#define FLT_PATN_RAM_TOP_ADDR 0x0a000
+#define FLT_MASK_RAM_TOP_ADDR 0x0b000
+#define SHARE_MEMORY_0_NORMAL 0x10000
+#define SHARE_MEMORY_1_NORMAL 0x11000
+#define SHARE_MEMORY_2_NORMAL 0x12000
+#define SHARE_MEMORY_3_NORMAL 0x13000
+#define SHARE_MEMORY_4_NORMAL 0x14000
+#define SHARE_MEMORY_5_NORMAL 0x15000
+#define SHARE_MEMORY_6_NORMAL 0x16000
+#define SHARE_MEMORY_7_NORMAL 0x17000
+
+/* RAM size */
+#define FLT_PATN_RAM_SIZE 0x0800
+#define FLT_MASK_RAM_SIZE 0x0800
+#define FLT_PIDPATTERN_SIZE 0x0160
+#define SHARE_MEMORY_0_SIZE 0x1000
+#define SHARE_MEMORY_1_SIZE 0x1000
+#define SHARE_MEMORY_2_SIZE 0x1000
+#define SHARE_MEMORY_3_SIZE 0x1000
+#define SHARE_MEMORY_4_SIZE 0x1000
+#define SHARE_MEMORY_5_SIZE 0x1000
+#define SHARE_MEMORY_6_SIZE 0x1000
+#define SHARE_MEMORY_7_SIZE 0x1000
+
+/* CIP SPU Stream */
+#define CIP_S_ID 0x14c0
+#define CIP_S_MODE 0x14c4
+#define CIP_S_CTRL 0x14c8
+#define CIP_S_SIZE 0x14cc
+#define CIP_S_BASE 0x14f8
+#define CIP_DEBUG 0x14fc
+
+/* CIP SPU HDC */
+#define HDC_CTRL 0x1520
+#define HDC_PTS 0x1524
+#define HDC_STAT 0x1528
+#define HDC_SPN_STAT 0x152c
+#define HDC_SPN 0x1530
+#define HDC_PATTERN 0x1534
+#define HDC_RESULT 0x1538
+#define HDC_RESULT_POS 0x153c
+
+/* CIP SPU File */
+#define CIP_F_ID 0x1540
+#define CIP_F_MODE 0x1544
+#define CIP_F_CTRL 0x1548
+#define CIP_F_SKIP 0x154c
+#define CIP_F_PAYLOAD 0x1560
+#define CIP_F_AUX0 0x156c
+#define CIP_F_AUX1 0x1570
+#define CIP_F_AUX2 0x1574
+#define CIP_F_REMAIN 0x1578
+#define CIP_F_EPNVERIFY1 0x157c
+#define CIP_F_EPNVERIFY2 0x1580
+#define CIP_F_EPNCNT 0x1584
+#define CIP_F_PKTCNT 0x1588
+#define CIP_F_STAT 0x1590
+#define CIP_F_SIZE 0x1594
+#define CIP_F_IBUF 0x1598
+#define CIP_F_OBUF 0x159c
+#define CIP_F_BASE 0x15b8
+#define CIP_F_BASEDIVX 0x15bc
+
+/* FLT1 SPU, FLT2 HOST */
+#define FLT_CTRL1 0x15c0
+#define FLT_CTRL2 0x15c4
+#define FLT_CTRL3 0x15c8
+#define FLT_CTRL4 0x15cc
+#define FLT_STATUS 0x15d0
+#define FLT_INTENABLE 0x15d4
+#define FLT_INTSTATUS 0x15d8
+#define FLT_LINE(i) (0x15e0 + (i) * 0x04)
+#define FLT_LENMODE 0x15f8
+#define FLT_LEN 0x15fc
+#define FLT_TRNUM 0x1600
+#define FLT_COUNT1 0x1604
+#define FLT_COUNT2 0x1608
+#define FLT_BUFCOUNT 0x160c
+#define FLT_INBUF(i) (0x1610 + (i) * 0x04)
+#define FLT_CRC 0x1624
+#define FLT_CRCCALC 0x1628
+#define FLT_SECNUM 0x1630
+#define FLT_COMP 0x1634
+#define FLT_SWACE 0x163c
+
+#define FLT_ATR(i) (0x1d00 + (i) * 0x04)
+#define FLT_PIDNUM 0x1d24
+
+/* SBC1, 2 */
+#define SBC_ACE_DMA_EN 0x6000
+#define SBC_DMAPARAM21 0x6004
+#define SBC_ACE_INTREN 0x6008
+#define SBC_ACE_INTRST 0x600c
+#define SBC_DMA_STATUS0 0x6010
+#define SBC_DMA_STATUS1 0x6014
+#define SBC_DMAPARAMA(i) (0x6018 + (i) * 0x04)
+#define SBC_DMAPARAMA_OFFSET_MASK GENMASK(31, 29)
+#define SBC_DMAPARAMA_LOOPADDR_MASK GENMASK(28, 23)
+#define SBC_DMAPARAMA_COUNT_MASK GENMASK(7, 0)
+#define SBC_DMAPARAMB(i) (0x6038 + (i) * 0x04)
+
+#define SBC_INTRENABLE0 0x60a0
+#define SBC_INTRSTATUS0 0x60a4
+#define SBC_INTRENABLE1 0x60a8
+#define SBC_INTRSTATUS1 0x60ac
+
+#define SBC_CONFIG0 0x60c0
+#define SBC_PARREGION0 0x60c4
+#define SBC_PARREGION1 0x60c8
+
+/* IOB1, 2, 3 */
+#define IOB_PKTCNT 0x1740
+#define IOB_PKTCNTRST 0x1744
+#define IOB_PKTCNTST 0x1744
+#define IOB_DUMMY_ENABLE 0x1748
+#define IOB_FORMATCHANGE_EN 0x174c
+#define IOB_UASSIST0 0x1750
+#define IOB_UASSIST1 0x1754
+#define IOB_URESERVE(i) (0x1758 + (i) * 0x4)
+#define IOB_PCRRECEN IOB_URESERVE(2)
+#define IOB_UPARTIAL(i) (0x1768 + (i) * 0x4)
+#define IOB_SPUINTREN 0x1778
+
+#define IOB_HSCREV 0x1a00
+#define IOB_SECCLK(i) (0x1a08 + (i) * 0x6c)
+#define IOB_SECTIMEH(i) (0x1a0c + (i) * 0x6c)
+#define IOB_SECTIMEL(i) (0x1a10 + (i) * 0x6c)
+#define IOB_RESET0 0x1a14
+#define IOB_RESET0_APCORE BIT(20)
+#define IOB_RESET1 0x1a18
+#define IOB_CLKSTOP 0x1a1c
+#define IOB_DEBUG 0x1a20
+#define IOB_DEBUG_SPUHALT BIT(0)
+#define IOB_INTREN(i) (0x1a24 + (i) * 0x8)
+#define IOB_INTRST(i) (0x1a28 + (i) * 0x8)
+#define IOB_INTREN0 0x1a24
+#define IOB_INTRST0 0x1a28
+#define IOB_INTREN0_1 0x1a2c
+#define IOB_INTRST0_1 0x1a30
+#define IOB_INTREN0_2 0x1a34
+#define IOB_INTRST0_2 0x1a38
+#define IOB_INTREN1 0x1a3c
+#define IOB_INTRST1 0x1a40
+#define IOB_INTREN1_1 0x1a44
+#define IOB_INTRST1_1 0x1a48
+#define IOB_INTREN2 0x1a4c
+#define IOB_INTRST2 0x1a50
+#define INTR2_DRV BIT(31)
+#define INTR2_CIP_FRMT(i) BIT((i) + 16)
+#define INTR2_CIP_NORMAL BIT(16)
+#define INTR2_SEC_CLK_A BIT(15)
+#define INTR2_SEC_CLK_S BIT(14)
+#define INTR2_MBC_CIP_W(i) BIT((i) + 9)
+#define INTR2_MBC_CIP_R(i) BIT((i) + 4)
+#define INTR2_CIP_AUTH_A BIT(1)
+#define INTR2_CIP_AUTH_S BIT(0)
+#define IOB_INTREN3 0x1a54
+#define IOB_INTRST3 0x1a58
+#define INTR3_DRV BIT(31)
+#define INTR3_CIP_FRMT(i) BIT((i) + 16)
+#define INTR3_SEC_CLK_A BIT(15)
+#define INTR3_SEC_CLK_S BIT(14)
+#define INTR3_MBC_CIP_W(i) BIT((i) + 9)
+#define INTR3_MBC_CIP_R(i) BIT((i) + 4)
+#define INTR3_CIP_AUTH_A BIT(1)
+#define INTR3_CIP_AUTH_S BIT(0)
+#define IOB_INTREN4 0x1a5c
+#define IOB_INTRST4 0x1a60
+#define IOB_CGCTRL 0x1a64
+#define IOB_VCXOCTL 0x1a68
+#define IOB_IO_ATTRIBUTE 0x1a6c
+
+#define IOB_MONDAT 0x5000
+#define IOB_MONDAT2 0x5004
+#define IOB_TESTMODE 0x5008
+#define IOB_TESTMODE2 0x500c
+#define IOB_DEBUGTCERT 0x5010
+
+/* MBC1-7 Common */
+#define CDMBC_STRT(i) (0x2300 + ((i) - 1) * 0x4)
+#define CDMBC_PERFCNFG 0x230c
+#define CDMBC_STAT(i) (0x2320 + (i) * 0x4)
+#define CDMBC_PARTRESET(i) (0x234c + (i) * 0x4)
+#define CDMBC_MONNUM 0x2358
+#define CDMBC_MONDAT 0x235c
+#define CDMBC_PRC0CHIE0 0x2380
+#define CDMBC_PRC0RBIE0 0x2384
+#define CDMBC_PRC1CHIE0 0x2388
+#define CDMBC_PRC2CHIE0 0x2390
+#define CDMBC_PRC2RBIE0 0x2394
+#define CDMBC_SOFTFLRQ 0x239c
+#define CDMBC_TDSTRT 0x23a0
+
+#define INTR_MBC_CH_END BIT(15)
+#define INTR_MBC_CH_STOP BIT(13)
+#define INTR_MBC_CH_ADDR BIT(6)
+#define INTR_MBC_CH_IWDONE BIT(3)
+#define INTR_MBC_CH_WDONE BIT(1)
+
+/* MBC
+ * i: channel number
+ * 1- 3: Record0,1,2
+ * 19-21: Record3,4,5
+ */
+#define CDMBC_CHTDCTRLH(i) (((i) < 19) ? \
+ (0x23a4 + ((i) - 1) * 0x20) : \
+ (0x23b4 + ((i) - 19) * 0x20))
+#define CDMBC_CHTDCTRLH_STREM_MASK GENMASK(20, 16)
+#define CDMBC_CHTDCTRLH_NOT_FLT BIT(7)
+#define CDMBC_CHTDCTRLH_ALL_EN BIT(6)
+#define CDMBC_CHTDCTRLU(i) (((i) < 19) ? \
+ (0x23a8 + ((i) - 1) * 0x20) : \
+ (0x23b8 + ((i) - 19) * 0x20))
+
+#define CDMBC_TDSTAT 0x23f8
+#define CDMBC_TDIR 0x23fc
+#define CDMBC_REPRATECTRL 0x2400
+#define CDMBC_ATRIBUTE0 0x24e8
+#define CDMBC_ATRIBUTE1 0x24ec
+#define CDMBC_ATRIBUTE2 0x24f0
+#define CDMBC_ATRIBUTE3 0x24f4
+#define CDMBC_ATRIBUTE4 0x24f8
+#define CDMBC_CIPMODE(i) (0x24fc + (i) * 0x4)
+#define CDMBC_CIPMODE_PUSH BIT(0)
+#define CDMBC_CIPPRIORITY(i) (0x2510 + (i) * 0x4)
+#define CDMBC_CIPPRIORITY_PRIOR_MASK GENMASK(1, 0)
+#define CDMBC_CH18ATTRIBUTE (0x2524)
+
+/* MBC Channel
+ * i: channel number
+ * 0 : Section
+ * 1- 3: Record0,1,2
+ * 4 : Partial
+ * 5- 7: Replay0,1,2
+ * 8-17: Even: CIP-Read
+ * Odd : CIP-Write
+ * 18 : AM32
+ * 19-21: Record3,4,5
+ * 22-24: Replay3,4,5
+ */
+#define CDMBC_CHCTRL1(i) (0x2540 + (i) * 0x50)
+#define CDMBC_CHCTRL1_LINKCH1_MASK GENMASK(12, 10)
+#define CDMBC_CHCTRL1_STATSEL_MASK GENMASK(9, 7)
+#define CDMBC_CHCTRL1_TYPE_INTERMIT BIT(1)
+#define CDMBC_CHCTRL1_IND_SIZE_UND BIT(0)
+#define CDMBC_CHCTRL2(i) (0x2544 + (i) * 0x50)
+#define CDMBC_CHDDR(i) (0x2548 + (i) * 0x50)
+#define CDMBC_CHDDR_REG_LOAD_ON BIT(4)
+#define CDMBC_CHDDR_AT_CHEN_ON BIT(3)
+#define CDMBC_CHDDR_SET_MCB_MASK GENMASK(2, 1)
+#define CDMBC_CHDDR_SET_MCB_WR (0x0 << 1)
+#define CDMBC_CHDDR_SET_MCB_RD (0x3 << 1)
+#define CDMBC_CHDDR_SET_DDR_1 BIT(0)
+#define CDMBC_CHCAUSECTRL(i) (0x254c + (i) * 0x50)
+#define CDMBC_CHCAUSECTRL_MODE_MASK BIT(31)
+#define CDMBC_CHCAUSECTRL_CSEL2_MASK GENMASK(20, 12)
+#define CDMBC_CHCAUSECTRL_CSEL1_MASK GENMASK(8, 0)
+#define CDMBC_CHSTAT(i) (0x2550 + (i) * 0x50)
+#define CDMBC_CHIR(i) (0x2554 + (i) * 0x50)
+#define CDMBC_CHIE(i) (0x2558 + (i) * 0x50)
+#define CDMBC_CHID(i) (0x255c + (i) * 0x50)
+#define CDMBC_CHI_STOPPED BIT(13)
+#define CDMBC_CHI_TRANSIT BIT(6)
+#define CDMBC_CHI_STARTING BIT(1)
+#define CDMBC_CHSRCAMODE(i) (0x2560 + (i) * 0x50)
+#define CDMBC_CHDSTAMODE(i) (0x2564 + (i) * 0x50)
+#define CDMBC_CHAMODE_TUNIT_MASK GENMASK(29, 28)
+#define CDMBC_CHAMODE_ENDIAN_MASK GENMASK(17, 16)
+#define CDMBC_CHAMODE_AUPDT_MASK GENMASK(5, 4)
+#define CDMBC_CHAMODE_TYPE_RB BIT(2)
+#define CDMBC_CHSRCSTRTADRSD(i) (0x2568 + (i) * 0x50)
+#define CDMBC_CHSRCSTRTADRSU(i) (0x256c + (i) * 0x50)
+#define CDMBC_CHDSTSTRTADRSD(i) (0x2570 + (i) * 0x50)
+#define CDMBC_CHDSTSTRTADRSU(i) (0x2574 + (i) * 0x50)
+#define CDMBC_CHDSTSTRTADRS_TID_MASK GENMASK(31, 28)
+#define CDMBC_CHDSTSTRTADRS_ID1_EN_MASK BIT(15)
+#define CDMBC_CHDSTSTRTADRS_KEY_ID1_MASK GENMASK(12, 8)
+#define CDMBC_CHDSTSTRTADRS_KEY_ID0_MASK GENMASK(4, 0)
+#define CDMBC_CHSIZE(i) (0x2578 + (i) * 0x50)
+#define CDMBC_CHIRADRSD(i) (0x2580 + (i) * 0x50)
+#define CDMBC_CHIRADRSU(i) (0x2584 + (i) * 0x50)
+#define CDMBC_CHDST1STUSIZE(i) (0x258C + (i) * 0x50)
+
+/* MBC DMA
+ * i: channel number
+ * 5- 7: Replay0,1,2
+ * 8-17: Even: CIP-Read
+ * Odd : CIP-Write
+ * 22-24: Replay3-5
+ */
+static inline int HSC_IT_INT(int i)
+{
+ if (i > 21)
+ return i - 9;
+
+ return i - 5;
+}
+
+#define CDMBC_ITCTRL(i) (0x3000 + HSC_IT_INT(i) * 0x20)
+#define CDMBC_ITSTEPS(i) (0x3018 + HSC_IT_INT(i) * 0x20)
+
+/* MBC Ring buffer
+ * i: channel number
+ * 0 : Section (RB0)
+ * 1- 3: Record0,1,2 (RB1-3)
+ * 5- 7: Replay0,1,2 (RB4-6)
+ * 8-17: Even: CIP-Read
+ * Odd : CIP-Write (RB7-16)
+ * 19-21: Record3-4 (RB17-19)
+ * 22-24: Replay3-4 (RB20-22)
+ */
+static inline int HSC_INT(int i)
+{
+ if (i > 18)
+ return i - 2;
+ if (i > 4)
+ return i - 1;
+
+ return i;
+}
+
+#define CDMBC_RBBGNADRS(i) (0x3200 + HSC_INT(i) * 0x40)
+#define CDMBC_RBBGNADRSD(i) (0x3200 + HSC_INT(i) * 0x40)
+#define CDMBC_RBBGNADRSU(i) (0x3204 + HSC_INT(i) * 0x40)
+#define CDMBC_RBENDADRS(i) (0x3208 + HSC_INT(i) * 0x40)
+#define CDMBC_RBENDADRSD(i) (0x3208 + HSC_INT(i) * 0x40)
+#define CDMBC_RBENDADRSU(i) (0x320C + HSC_INT(i) * 0x40)
+#define CDMBC_RBIR(i) (0x3214 + HSC_INT(i) * 0x40)
+#define CDMBC_RBIE(i) (0x3218 + HSC_INT(i) * 0x40)
+#define CDMBC_RBID(i) (0x321c + HSC_INT(i) * 0x40)
+#define CDMBC_RBRDPTR(i) (0x3220 + HSC_INT(i) * 0x40)
+#define CDMBC_RBRDPTRD(i) (0x3220 + HSC_INT(i) * 0x40)
+#define CDMBC_RBRDPTRU(i) (0x3224 + HSC_INT(i) * 0x40)
+#define CDMBC_RBWRPTR(i) (0x3228 + HSC_INT(i) * 0x40)
+#define CDMBC_RBWRPTRD(i) (0x3228 + HSC_INT(i) * 0x40)
+#define CDMBC_RBWRPTRU(i) (0x322C + HSC_INT(i) * 0x40)
+#define CDMBC_RBERRCNFG(i) (0x3238 + HSC_INT(i) * 0x40)
+
+/* MBC Rate */
+#define CDMBC_RCNMSKCYC(i) (MBC6_TOP_ADDR + 0x000 + (i) * 0x04)
+
+/* MBC Address Transfer */
+#define CDMBC_CHPSIZE(i) (0x3c00 + ((i) - 1) * 0x48)
+#define CDMBC_CHATCTRL(i) (0x3c04 + ((i) - 1) * 0x48)
+#define CDMBC_CHBTPAGE(i, j) (0x3c08 + ((i) - 1) * 0x48 + (j) * 0x10)
+#define CDMBC_CHBTPAGED(i, j) (0x3c08 + ((i) - 1) * 0x48 + (j) * 0x10)
+#define CDMBC_CHBTPAGEU(i, j) (0x3c0C + ((i) - 1) * 0x48 + (j) * 0x10)
+#define CDMBC_CHATPAGE(i, j) (0x3c10 + ((i) - 1) * 0x48 + (j) * 0x10)
+#define CDMBC_CHATPAGED(i, j) (0x3c10 + ((i) - 1) * 0x48 + (j) * 0x10)
+#define CDMBC_CHATPAGEU(i, j) (0x3c14 + ((i) - 1) * 0x48 + (j) * 0x10)
+
+/* CSS */
+#define CSS_PTSOCONFIG 0x1c00
+#define CSS_PTSISIGNALPOL 0x1c04
+#define CSS_SIGNALPOLCH(i) (0x1c08 + (i) * 0x4)
+#define CSS_OUTPUTENABLE 0x1c10
+#define CSS_OUTPUTCTRL(i) (0x1c14 + (i) * 0x4)
+#define CSS_STSOCONFIG 0x1c2c
+#define CSS_STSOSIGNALPOL 0x1c30
+#define CSS_DMDSIGNALPOL 0x1c34
+#define CSS_PTSOSIGNALPOL 0x1c38
+#define CSS_PF0CONFIG 0x1c3c
+#define CSS_PF1CONFIG 0x1c40
+#define CSS_PFINTENABLE 0x1c44
+#define CSS_PFINTSTATUS 0x1c48
+#define CSS_AVOUTPUTCTRL(i) (0x1c4c + (i) * 0x4)
+#define CSS_DPCTRL(i) (0x1c54 + (i) * 0x4)
+#define CSS_DPCTRL_DPSEL_MASK GENMASK(22, 0)
+#define CSS_DPCTRL_DPSEL_PLAY5 BIT(15)
+#define CSS_DPCTRL_DPSEL_PLAY4 BIT(14)
+#define CSS_DPCTRL_DPSEL_PLAY3 BIT(13)
+#define CSS_DPCTRL_DPSEL_PLAY2 BIT(12)
+#define CSS_DPCTRL_DPSEL_PLAY1 BIT(11)
+#define CSS_DPCTRL_DPSEL_PLAY0 BIT(10)
+#define CSS_DPCTRL_DPSEL_TSI4 BIT(4)
+#define CSS_DPCTRL_DPSEL_TSI3 BIT(3)
+#define CSS_DPCTRL_DPSEL_TSI2 BIT(2)
+#define CSS_DPCTRL_DPSEL_TSI1 BIT(1)
+#define CSS_DPCTRL_DPSEL_TSI0 BIT(0)
+
+/* TSI */
+#define TSI_SYNCCNTROL(i) (0x7100 + (i) * 0x70)
+#define TSI_SYNCCNTROL_FRAME_MASK GENMASK(18, 16)
+#define TSI_SYNCCNTROL_FRAME_EXTSYNC1 (0x0 << 16)
+#define TSI_SYNCCNTROL_FRAME_EXTSYNC2 (0x1 << 16)
+#define TSI_CONFIG(i) (0x7104 + (i) * 0x70)
+#define TSI_CONFIG_ATSMD_MASK GENMASK(22, 21)
+#define TSI_CONFIG_ATSMD_PCRPLL0 (0x0 << 21)
+#define TSI_CONFIG_ATSMD_PCRPLL1 (0x1 << 21)
+#define TSI_CONFIG_ATSMD_DPLL (0x3 << 21)
+#define TSI_CONFIG_ATSADD_ON BIT(20)
+#define TSI_CONFIG_STCMD_MASK GENMASK(7, 6)
+#define TSI_CONFIG_STCMD_PCRPLL0 (0x0 << 6)
+#define TSI_CONFIG_STCMD_PCRPLL1 (0x1 << 6)
+#define TSI_CONFIG_STCMD_DPLL (0x3 << 6)
+#define TSI_CONFIG_CHEN_START BIT(0)
+#define TSI_RATEUPLMT(i) (0x7108 + (i) * 0x70)
+#define TSI_RATELOWLMT(i) (0x710c + (i) * 0x70)
+#define TSI_CNTINTR(i) (0x7110 + (i) * 0x70)
+#define TSI_INTREN(i) (0x7114 + (i) * 0x70)
+#define TSI_INTR_NTP BIT(13)
+#define TSI_INTR_NTPCNT BIT(12)
+#define TSI_INTR_PKTEND BIT(11)
+#define TSI_INTR_PCR BIT(9)
+#define TSI_INTR_LOAD BIT(8)
+#define TSI_INTR_SERR BIT(7)
+#define TSI_INTR_SOF BIT(6)
+#define TSI_INTR_TOF BIT(5)
+#define TSI_INTR_UL BIT(4)
+#define TSI_INTR_LL BIT(3)
+#define TSI_INTR_CNT BIT(2)
+#define TSI_INTR_LOST BIT(1)
+#define TSI_INTR_LOCK BIT(0)
+#define TSI_SYNCSTATUS(i) (0x7118 + (i) * 0x70)
+#define TSI_STAT_PKTST_ERR BIT(21)
+#define TSI_STAT_LARGE_ERR BIT(20)
+#define TSI_STAT_SMALL_ERR BIT(19)
+#define TSI_STAT_LOCK BIT(18)
+#define TSI_STAT_SYNC BIT(17)
+#define TSI_STAT_SEARCH BIT(16)
+#define TSI_PCRPID(i) (0x711c + (i) * 0x70)
+#define TSI_PCRCTRL(i) (0x7120 + (i) * 0x70)
+#define TSI_STCBASE(i) (0x7124 + (i) * 0x70)
+#define TSI_STCEXT(i) (0x7128 + (i) * 0x70)
+#define TSI_CURSTC1(i) (0x712c + (i) * 0x70)
+#define TSI_CURSTCBASE(i) (0x712c + (i) * 0x70)
+#define TSI_CURSTC2(i) (0x7130 + (i) * 0x70)
+#define TSI_CURSTCEXT(i) (0x7130 + (i) * 0x70)
+#define TSI_STC2BASE(i) (0x7134 + (i) * 0x70)
+#define TSI_STC2EXT(i) (0x7138 + (i) * 0x70)
+#define TSI_PCRBASE(i) (0x713c + (i) * 0x70)
+#define TSI_PCREXT(i) (0x7140 + (i) * 0x70)
+#define TSI_TIMESTAMP(i) (0x7144 + (i) * 0x70)
+#define TSI_CNTCTRL0(i) (0x7148 + (i) * 0x70)
+#define TSI_CNTCTRL1(i) (0x714c + (i) * 0x70)
+#define TSI_DEBUG(i) (0x7150 + (i) * 0x70)
+
+#define TSI_STCCMPCTRL 0x7000
+#define VCXOSTCBASE(i) (0x7010 + (i) * 0x18)
+#define VCXOSTCEXT(i) (0x7014 + (i) * 0x18)
+#define VCXOCURSTC1(i) (0x7018 + (i) * 0x18)
+#define VCXOCURSTC2(i) (0x701c + (i) * 0x18)
+#define VCXOSTC2BASE(i) (0x7020 + (i) * 0x18)
+#define VCXOSTC2EXT(i) (0x7024 + (i) * 0x18)
+
+/* UCODE DL */
+#define UCODE_REVISION_AM 0x10fd0
+#define CIP_UCODEADDR_AM1 0x10fd4
+#define CIP_UCODEADDR_AM0 0x10fd8
+#define CORRECTATS_CTRL 0x10fdc
+#define UCODE_REVISION 0x10fe0
+#define AM_UCODE_IGPGCTRL 0x10fe4
+#define REPDPLLCTRLEN 0x10fe8
+#define UCODE_DLADDR1 0x10fec
+#define UCODE_DLADDR0 0x10ff0
+#define UCODE_ERRLOGCTRL 0x10ff4
+
+#endif /* DVB_UNIPHIER_HSC_REG_H__ */
diff --git a/drivers/media/platform/uniphier/hsc.h b/drivers/media/platform/uniphier/hsc.h
new file mode 100644
index 000000000000..ad57fea58675
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc.h
@@ -0,0 +1,480 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+ *
+ * Copyright (c) 2018 Socionext Inc.
+ */
+
+#ifndef DVB_UNIPHIER_HSC_H__
+#define DVB_UNIPHIER_HSC_H__
+
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+
+enum HSC_CORE {
+ HSC_CORE_0,
+ HSC_CORE_1,
+ HSC_CORE_2,
+};
+
+enum HSC_UCODE {
+ HSC_UCODE_SPU_0,
+ HSC_UCODE_SPU_1,
+ HSC_UCODE_ACE,
+};
+
+enum HSC_INTR_IOB {
+ HSC_INTR_IOB_0,
+ HSC_INTR_IOB_0_1,
+ HSC_INTR_IOB_0_2,
+ HSC_INTR_IOB_1,
+ HSC_INTR_IOB_1_1,
+ HSC_INTR_IOB_2,
+ HSC_INTR_IOB_3,
+ HSC_INTR_IOB_4,
+ HSC_INTR_IOB_5,
+ HSC_INTR_IOB_5_1,
+ HSC_INTR_IOB_5_2,
+ HSC_INTR_IOB_6,
+ HSC_INTR_IOB_6_1,
+ HSC_INTR_IOB_7,
+ HSC_INTR_IOB_8,
+ HSC_INTR_IOB_9,
+
+ HSC_INTR_IOB_NUM,
+};
+
+enum HSC_DPLL {
+ HSC_DPLL0,
+ HSC_DPLL1,
+ HSC_DPLL2,
+ HSC_DPLL3,
+
+ HSC_DPLL_NUM,
+};
+
+enum HSC_DPLL_SRC {
+ HSC_DPLL_SRC_NONE = -1,
+ HSC_DPLL_SRC_TSI0 = 0x00,
+ HSC_DPLL_SRC_TSI1,
+ HSC_DPLL_SRC_TSI2,
+ HSC_DPLL_SRC_TSI3,
+ HSC_DPLL_SRC_TSI4,
+ HSC_DPLL_SRC_TSI5,
+ HSC_DPLL_SRC_TSI6,
+ HSC_DPLL_SRC_TSI7,
+ HSC_DPLL_SRC_TSI8,
+ HSC_DPLL_SRC_TSI9,
+ HSC_DPLL_SRC_REP0 = 0x0a,
+ HSC_DPLL_SRC_REP1,
+ HSC_DPLL_SRC_REP2,
+ HSC_DPLL_SRC_REP3,
+ HSC_DPLL_SRC_REP4,
+ HSC_DPLL_SRC_REP5,
+
+ HSC_DPLL_SRC_NUM,
+};
+
+/* Port to send to CSS */
+enum HSC_CSS_IN {
+ HSC_CSS_IN_1394_0 = 0x00,
+ HSC_CSS_IN_1394_1,
+ HSC_CSS_IN_1394_2,
+ HSC_CSS_IN_1394_3,
+ HSC_CSS_IN_DMD0 = 0x04,
+ HSC_CSS_IN_DMD1,
+ HSC_CSS_IN_SRLTS0 = 0x06,
+ HSC_CSS_IN_SRLTS1,
+ HSC_CSS_IN_SRLTS2,
+ HSC_CSS_IN_SRLTS3,
+ HSC_CSS_IN_SRLTS4,
+ HSC_CSS_IN_SRLTS5,
+ HSC_CSS_IN_SRLTS6,
+ HSC_CSS_IN_SRLTS7,
+ HSC_CSS_IN_PARTS0 = 0x10,
+ HSC_CSS_IN_PARTS1,
+ HSC_CSS_IN_PARTS2,
+ HSC_CSS_IN_PARTS3,
+ HSC_CSS_IN_TSO0 = 0x18,
+ HSC_CSS_IN_TSO1,
+ HSC_CSS_IN_TSO2,
+ HSC_CSS_IN_TSO3,
+ HSC_CSS_IN_ENCORDER0_IN = 0x1c,
+ HSC_CSS_IN_ENCORDER1_IN,
+
+ HSC_CSS_IN_NUM,
+};
+
+/* Port to receive from CSS */
+enum HSC_CSS_OUT {
+ HSC_CSS_OUT_SRLTS0 = 0x00,
+ HSC_CSS_OUT_SRLTS1,
+ HSC_CSS_OUT_SRLTS2,
+ HSC_CSS_OUT_SRLTS3,
+ HSC_CSS_OUT_TSI0 = 0x04,
+ HSC_CSS_OUT_TSI1,
+ HSC_CSS_OUT_TSI2,
+ HSC_CSS_OUT_TSI3,
+ HSC_CSS_OUT_TSI4,
+ HSC_CSS_OUT_TSI5,
+ HSC_CSS_OUT_TSI6,
+ HSC_CSS_OUT_TSI7,
+ HSC_CSS_OUT_TSI8,
+ HSC_CSS_OUT_TSI9,
+ HSC_CSS_OUT_PARTS0 = 0x10,
+ HSC_CSS_OUT_PARTS1,
+ HSC_CSS_OUT_PKTFF0 = 0x14,
+ HSC_CSS_OUT_PKTFF1,
+};
+
+/* TS input interface */
+enum HSC_TS_IN {
+ HSC_TSI0,
+ HSC_TSI1,
+ HSC_TSI2,
+ HSC_TSI3,
+ HSC_TSI4,
+ HSC_TSI5,
+ HSC_TSI6,
+ HSC_TSI7,
+ HSC_TSI8,
+ HSC_TSI9,
+
+ HSC_TS_IN_NUM,
+};
+
+/* TS output interface */
+enum HSC_TS_OUT {
+ HSC_TS_OUT0,
+ HSC_TS_OUT1,
+ HSC_TS_OUT2,
+ HSC_TS_OUT3,
+ HSC_TS_OUT4,
+ HSC_TS_OUT5,
+ HSC_TS_OUT6,
+ HSC_TS_OUT7,
+ HSC_TS_OUT8,
+ HSC_TS_OUT9,
+
+ HSC_TS_OUT_NUM,
+};
+
+/* DMA to read from memory (Replay DMA) */
+enum HSC_DMA_IN {
+ HSC_DMA_IN0,
+ HSC_DMA_IN1,
+ HSC_DMA_IN2,
+ HSC_DMA_IN3,
+ HSC_DMA_IN4,
+ HSC_DMA_IN5,
+ HSC_DMA_IN6,
+ HSC_DMA_IN7,
+ HSC_DMA_IN8,
+ HSC_DMA_IN9,
+
+ HSC_DMA_IN_NUM,
+};
+
+/* DMA to write to memory (Record DMA) */
+enum HSC_DMA_OUT {
+ HSC_DMA_OUT0,
+ HSC_DMA_OUT1,
+ HSC_DMA_OUT2,
+ HSC_DMA_OUT3,
+ HSC_DMA_OUT4,
+ HSC_DMA_OUT5,
+ HSC_DMA_OUT6,
+ HSC_DMA_OUT7,
+ HSC_DMA_OUT8,
+ HSC_DMA_OUT9,
+
+ HSC_DMA_OUT_NUM,
+};
+
+enum HSC_TSIF_FMT {
+ HSC_TSIF_MPEG2_TS,
+ HSC_TSIF_MPEG2_TS_ATS,
+};
+
+#define HSC_STREAM_IF_NUM 2
+
+#define HSC_DMAIF_TS_BUFSIZE (192 * 1024 * 5)
+
+#define HSC_MBC_DMCH_REC0 1
+#define HSC_MBC_DMCH_REC1 2
+#define HSC_MBC_DMCH_REC2 3
+#define HSC_MBC_DMCH_REP0 5
+#define HSC_MBC_DMCH_REP1 6
+#define HSC_MBC_DMCH_REP2 7
+#define HSC_MBC_DMCH_CIP0_R 8
+#define HSC_MBC_DMCH_CIP0_W 9
+#define HSC_MBC_DMCH_CIP1_R 10
+#define HSC_MBC_DMCH_CIP1_W 11
+#define HSC_MBC_DMCH_CIP2_R 12
+#define HSC_MBC_DMCH_CIP2_W 13
+#define HSC_MBC_DMCH_CIP3_R 14
+#define HSC_MBC_DMCH_CIP3_W 15
+#define HSC_MBC_DMCH_CIP4_R 16
+#define HSC_MBC_DMCH_CIP4_W 17
+#define HSC_MBC_DMCH_REC3 19
+#define HSC_MBC_DMCH_REC4 20
+#define HSC_MBC_DMCH_REC5 21
+#define HSC_MBC_DMCH_REP3 22
+#define HSC_MBC_DMCH_REP4 23
+#define HSC_MBC_DMCH_REP5 24
+
+struct hsc_ucode_buf {
+ void *buf_code;
+ dma_addr_t phys_code;
+ size_t size_code;
+ void *buf_data;
+ dma_addr_t phys_data;
+ size_t size_data;
+};
+
+struct hsc_spec_ucode {
+ const char *name_code;
+ const char *name_data;
+};
+
+struct hsc_spec_init_ram {
+ u32 addr;
+ size_t size;
+ u32 pattern;
+};
+
+struct hsc_css_pol {
+ int valid;
+ u32 reg;
+ int sft_sync;
+ int sft_val;
+ int sft_clk;
+};
+
+struct hsc_css_sel {
+ int valid;
+ u32 reg;
+ u32 mask;
+};
+
+struct hsc_spec_css_in {
+ struct hsc_css_pol pol;
+};
+
+struct hsc_spec_css_out {
+ struct hsc_css_pol pol;
+ struct hsc_css_sel sel;
+};
+
+struct hsc_cmn_intr {
+ int valid;
+ u32 reg;
+ int sft_intr;
+};
+
+struct hsc_spec_ts {
+ struct hsc_cmn_intr intr;
+};
+
+struct hsc_dma_en {
+ int valid;
+ u32 reg;
+ int sft_toggle;
+};
+
+struct hsc_spec_dma {
+ int dma_ch;
+ struct hsc_dma_en en;
+ struct hsc_cmn_intr intr;
+};
+
+struct hsc_spec {
+ const struct hsc_spec_ucode ucode_spu;
+ const struct hsc_spec_ucode ucode_ace;
+ const struct hsc_spec_init_ram *init_rams;
+ size_t num_init_rams;
+ const struct hsc_spec_css_in *css_in;
+ size_t num_css_in;
+ const struct hsc_spec_css_out *css_out;
+ size_t num_css_out;
+ const struct hsc_spec_ts *ts_in;
+ size_t num_ts_in;
+ const struct hsc_spec_dma *dma_in;
+ size_t num_dma_in;
+ const struct hsc_spec_dma *dma_out;
+ size_t num_dma_out;
+};
+
+struct hsc_tsif {
+ struct hsc_chip *chip;
+
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend *fe;
+ int valid_adapter;
+ int valid_demux;
+ int valid_dmxdev;
+ int valid_fe;
+
+ enum HSC_CSS_IN css_in;
+ enum HSC_CSS_OUT css_out;
+ enum HSC_TS_IN tsi;
+ enum HSC_DPLL dpll;
+ enum HSC_DPLL_SRC dpll_src;
+ struct hsc_dmaif *dmaif;
+
+ int running;
+ struct delayed_work recover_work;
+ unsigned long recover_delay;
+};
+
+struct hsc_dma_in {
+ struct hsc_chip *chip;
+
+ enum HSC_DMA_IN id;
+ const struct hsc_spec_dma *spec;
+ struct hsc_dma_buf *buf;
+};
+
+struct hsc_dma_out {
+ struct hsc_chip *chip;
+
+ enum HSC_DMA_OUT id;
+ const struct hsc_spec_dma *spec;
+ struct hsc_dma_buf *buf;
+};
+
+struct hsc_dma_buf {
+ void *virt;
+ dma_addr_t phys;
+ u64 size;
+ u64 size_chk;
+ u64 rd_offs;
+ u64 wr_offs;
+ u64 chk_offs;
+};
+
+struct hsc_dmaif {
+ struct hsc_chip *chip;
+
+ struct hsc_dma_buf buf_out;
+ struct hsc_dma_out dma_out;
+
+ struct hsc_tsif *tsif;
+
+ /* guard read/write pointer of DMA buffer from interrupt handler */
+ spinlock_t lock;
+ int running;
+ struct work_struct feed_work;
+};
+
+struct hsc_chip {
+ const struct hsc_spec *spec;
+ short *adapter_nums;
+
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ struct clk *clk_stdmac;
+ struct clk *clk_hsc;
+ struct reset_control *rst_stdmac;
+ struct reset_control *rst_hsc;
+
+ struct hsc_dmaif dmaif[HSC_STREAM_IF_NUM];
+ struct hsc_tsif tsif[HSC_STREAM_IF_NUM];
+
+ struct hsc_ucode_buf ucode_spu;
+ struct hsc_ucode_buf ucode_am;
+};
+
+struct hsc_conf {
+ enum HSC_CSS_IN css_in;
+ enum HSC_CSS_OUT css_out;
+ enum HSC_DPLL dpll;
+ enum HSC_DMA_OUT dma_out;
+};
+
+static inline u32 field_prep(u32 mask, u32 v)
+{
+ int sft = ffs(mask) - 1;
+
+ return (v << sft) & mask;
+}
+
+static inline u32 field_get(u32 mask, u32 v)
+{
+ int sft = ffs(mask) - 1;
+
+ return (v & mask) >> sft;
+}
+
+/* CSS */
+enum HSC_TS_IN hsc_css_out_to_ts_in(enum HSC_CSS_OUT out);
+enum HSC_DPLL_SRC hsc_css_out_to_dpll_src(enum HSC_CSS_OUT out);
+
+int hsc_dpll_get_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
+ enum HSC_DPLL_SRC *src);
+int hsc_dpll_set_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
+ enum HSC_DPLL_SRC src);
+int hsc_css_in_get_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ bool *sync_bit, bool *val_bit, bool *clk_fall);
+int hsc_css_in_set_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ bool sync_bit, bool val_bit, bool clk_fall);
+int hsc_css_out_get_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
+ bool *sync_bit, bool *val_bit, bool *clk_fall);
+int hsc_css_out_set_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
+ bool sync_bit, bool val_bit, bool clk_fall);
+int hsc_css_out_get_src(struct hsc_chip *chip, enum HSC_CSS_IN *in,
+ enum HSC_CSS_OUT out, bool *en);
+int hsc_css_out_set_src(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ enum HSC_CSS_OUT out, bool en);
+
+/* TSI */
+const struct hsc_spec_tsi *hsc_ts_in_get_spec(struct hsc_chip *chip,
+ enum HSC_TS_IN in);
+int hsc_ts_in_set_enable(struct hsc_chip *chip, enum HSC_TS_IN in, bool en);
+int hsc_ts_in_set_dmaparam(struct hsc_chip *chip, enum HSC_TS_IN in,
+ enum HSC_TSIF_FMT ifmt);
+
+/* DMA */
+u64 hsc_rb_cnt(struct hsc_dma_buf *buf);
+u64 hsc_rb_cnt_to_end(struct hsc_dma_buf *buf);
+u64 hsc_rb_space(struct hsc_dma_buf *buf);
+u64 hsc_rb_space_to_end(struct hsc_dma_buf *buf);
+int hsc_dma_in_init(struct hsc_dma_in *dma_in, struct hsc_chip *chip,
+ enum HSC_DMA_IN in, struct hsc_dma_buf *buf);
+void hsc_dma_in_start(struct hsc_dma_in *dma_in, bool en);
+void hsc_dma_in_sync(struct hsc_dma_in *dma_in);
+int hsc_dma_in_get_intr(struct hsc_dma_in *dma_in, u32 *stat);
+void hsc_dma_in_clear_intr(struct hsc_dma_in *dma_in, u32 clear);
+int hsc_dma_out_init(struct hsc_dma_out *dma_out, struct hsc_chip *chip,
+ enum HSC_DMA_OUT out, struct hsc_dma_buf *buf);
+void hsc_dma_out_set_src_ts_in(struct hsc_dma_out *dma_out,
+ enum HSC_TS_IN ts_in);
+void hsc_dma_out_start(struct hsc_dma_out *dma_out, bool en);
+void hsc_dma_out_sync(struct hsc_dma_out *dma_out);
+int hsc_dma_out_get_intr(struct hsc_dma_out *dma_out, u32 *stat);
+void hsc_dma_out_clear_intr(struct hsc_dma_out *dma_out, u32 clear);
+
+/* UCODE DL */
+int hsc_ucode_load_all(struct hsc_chip *chip);
+int hsc_ucode_unload_all(struct hsc_chip *chip);
+
+/* For Adapter */
+int hsc_register_dvb(struct hsc_tsif *tsif);
+void hsc_unregister_dvb(struct hsc_tsif *tsif);
+int hsc_tsif_init(struct hsc_tsif *tsif, const struct hsc_conf *conf);
+void hsc_tsif_release(struct hsc_tsif *tsif);
+int hsc_dmaif_init(struct hsc_dmaif *dmaif, const struct hsc_conf *conf);
+void hsc_dmaif_release(struct hsc_dmaif *dmaif);
+extern const struct hsc_spec uniphier_hsc_ld11_spec;
+extern const struct hsc_spec uniphier_hsc_ld20_spec;
+
+#endif /* DVB_UNIPHIER_HSC_H__ */
--
2.17.0


2018-05-30 09:12:38

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 8/8] media: uniphier: add LD20 adapter driver for ISDB

This patch adds UniPhier LD20 DVB adapter driver for ISDB-S/T
that equipments SONY SUT-PJ series using CXD2858 tuner and Socionext
MN884434 demodulator.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Kconfig | 10 +
drivers/media/platform/uniphier/Makefile | 1 +
.../platform/uniphier/ld20-mn884434-helene.c | 274 ++++++++++++++++++
3 files changed, 285 insertions(+)
create mode 100644 drivers/media/platform/uniphier/ld20-mn884434-helene.c

diff --git a/drivers/media/platform/uniphier/Kconfig b/drivers/media/platform/uniphier/Kconfig
index 0fc9bbfc170b..1ad2b0f2716c 100644
--- a/drivers/media/platform/uniphier/Kconfig
+++ b/drivers/media/platform/uniphier/Kconfig
@@ -25,3 +25,13 @@ config DVB_UNIPHIER_LD11_ISDB
Demod: Socionext MN884433
Tuner: SONY HELENE (CXD2858ER)
Say Y when you want to support this adapters.
+
+config DVB_UNIPHIER_LD20_ISDB
+ bool "Support UniPhier LD20 ISDB adapters"
+ depends on DVB_UNIPHIER
+ help
+ Driver for LD20 ISDB-S/T adapters which use
+ Demux: Socionext LD20 HSC
+ Demod: Socionext MN884434
+ Tuner: SONY HELENE (CXD2858ER)
+ Say Y when you want to support this adapters.
diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index e4b06f8a37b5..9c12456748f9 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -9,3 +9,4 @@ ccflags-y += -Idrivers/media/tuners/

uniphier-dvb-y += uniphier-adapter.o
uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11_ISDB) += ld11-mn884433-helene.o
+uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD20_ISDB) += ld20-mn884434-helene.o
diff --git a/drivers/media/platform/uniphier/ld20-mn884434-helene.c b/drivers/media/platform/uniphier/ld20-mn884434-helene.c
new file mode 100644
index 000000000000..7ccbe52a50fb
--- /dev/null
+++ b/drivers/media/platform/uniphier/ld20-mn884434-helene.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier LD20 adapter driver for ISDB.
+// Using Socionext MN884434 ISDB-S/ISDB-T demodulator and
+// SONY HELENE tuner.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+
+#include "sc1501a.h"
+#include "helene.h"
+#include "hsc.h"
+#include "uniphier-adapter.h"
+
+static struct sc1501a_config mn884434_conf[] = {
+ { .if_freq = LOW_IF_4MHZ, },
+ { .if_freq = LOW_IF_4MHZ, },
+};
+
+static int uniphier_adapter_demod_probe(struct uniphier_adapter_priv *priv)
+{
+ const struct uniphier_adapter_spec *spec = priv->spec;
+ struct device *dev = &priv->pdev->dev;
+ struct device_node *node;
+ int ret, i;
+
+ priv->demod_mclk = devm_clk_get(dev, "demod-mclk");
+ if (IS_ERR(priv->demod_mclk)) {
+ dev_err(dev, "Failed to request demod-mclk: %ld\n",
+ PTR_ERR(priv->demod_mclk));
+ return PTR_ERR(priv->demod_mclk);
+ }
+
+ priv->demod_gpio = devm_gpiod_get_optional(dev, "reset-demod",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->demod_gpio)) {
+ dev_err(dev, "Failed to request demod_gpio: %ld\n",
+ PTR_ERR(priv->demod_gpio));
+ return PTR_ERR(priv->demod_gpio);
+ }
+
+ node = of_parse_phandle(dev->of_node, "demod-i2c-bus", 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse demod-i2c-bus\n");
+ return -ENODEV;
+ }
+
+ priv->demod_i2c_adapter = of_find_i2c_adapter_by_node(node);
+ if (!priv->demod_i2c_adapter) {
+ dev_err(dev, "Failed to find demod i2c adapter\n");
+ of_node_put(node);
+ return -ENODEV;
+ }
+ of_node_put(node);
+
+ mn884434_conf[0].reset_gpio = priv->demod_gpio;
+ for (i = 0; i < spec->adapters; i++) {
+ struct i2c_client *c;
+
+ mn884434_conf[i].mclk = priv->demod_mclk;
+ mn884434_conf[i].fe = &priv->fe[i].fe;
+
+ c = dvb_module_probe(spec->demod_i2c_info[i].type, NULL,
+ priv->demod_i2c_adapter,
+ spec->demod_i2c_info[i].addr,
+ &mn884434_conf[i]);
+ if (!c) {
+ dev_err(dev, "Failed to probe demod\n");
+ ret = -ENODEV;
+ goto err_out;
+ }
+ priv->fe[i].demod_i2c = c;
+ }
+
+ return 0;
+
+err_out:
+ for (i = 0; i < spec->adapters; i++)
+ dvb_module_release(priv->fe[i].demod_i2c);
+
+ return ret;
+}
+
+static struct helene_config helene_conf[] = {
+ { .xtal = SONY_HELENE_XTAL_16000, },
+ { .xtal = SONY_HELENE_XTAL_16000, },
+ { .xtal = SONY_HELENE_XTAL_16000, },
+};
+
+static int uniphier_adapter_tuner_probe(struct uniphier_adapter_priv *priv)
+{
+ const struct uniphier_adapter_spec *spec = priv->spec;
+ struct device *dev = &priv->pdev->dev;
+ struct device_node *node;
+ int ret, i;
+
+ priv->tuner_gpio = devm_gpiod_get_optional(dev, "reset-tuner",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->tuner_gpio)) {
+ dev_err(dev, "Failed to request tuner_gpio: %ld\n",
+ PTR_ERR(priv->tuner_gpio));
+ return PTR_ERR(priv->tuner_gpio);
+ }
+ gpiod_set_value_cansleep(priv->tuner_gpio, 0);
+
+ node = of_parse_phandle(dev->of_node, "tuner-i2c-bus", 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse tuner-i2c-bus\n");
+ return -ENODEV;
+ }
+
+ priv->tuner_i2c_adapter = of_find_i2c_adapter_by_node(node);
+ if (!priv->tuner_i2c_adapter) {
+ dev_err(dev, "Failed to find tuner i2c adapter\n");
+ of_node_put(node);
+ return -ENODEV;
+ }
+ of_node_put(node);
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ struct i2c_client *c;
+
+ helene_conf[i].fe = priv->fe[i].fe;
+
+ c = dvb_module_probe(spec->tuner_i2c_info[i].type, NULL,
+ priv->tuner_i2c_adapter,
+ spec->tuner_i2c_info[i].addr,
+ &helene_conf[i]);
+ if (!c) {
+ dev_err(dev, "Failed to probe tuner\n");
+ ret = -ENODEV;
+ goto err_out;
+ }
+ priv->fe[i].tuner_i2c = c;
+ }
+
+ return 0;
+
+err_out:
+ for (i = 0; i < spec->adapters; i++)
+ dvb_module_release(priv->fe[i].tuner_i2c);
+
+ return ret;
+}
+
+static int uniphier_adapter_probe(struct platform_device *pdev)
+{
+ struct uniphier_adapter_priv *priv;
+ struct device *dev = &pdev->dev;
+ int i, ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->pdev = pdev;
+
+ priv->spec = of_device_get_match_data(dev);
+ if (!priv->spec)
+ return -EINVAL;
+
+ priv->fe = devm_kzalloc(dev, sizeof(*priv->fe) * priv->spec->adapters,
+ GFP_KERNEL);
+ if (!priv->fe)
+ return -ENOMEM;
+
+ ret = uniphier_adapter_demux_probe(priv);
+ if (ret)
+ return ret;
+
+ ret = uniphier_adapter_demod_probe(priv);
+ if (ret)
+ return ret;
+
+ ret = uniphier_adapter_tuner_probe(priv);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, priv);
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ priv->chip->tsif[i].fe = priv->fe[i].fe;
+
+ ret = hsc_register_dvb(&priv->chip->tsif[i]);
+ if (ret) {
+ dev_err(dev, "Failed to register adapter\n");
+ goto err_out_if;
+ }
+ }
+
+ return 0;
+
+err_out_if:
+ for (i = 0; i < priv->spec->adapters; i++)
+ hsc_unregister_dvb(&priv->chip->tsif[i]);
+
+ return ret;
+}
+
+static int uniphier_adapter_remove(struct platform_device *pdev)
+{
+ struct uniphier_adapter_priv *priv = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ hsc_dmaif_release(&priv->chip->dmaif[i]);
+ hsc_tsif_release(&priv->chip->tsif[i]);
+ hsc_unregister_dvb(&priv->chip->tsif[i]);
+ dvb_module_release(priv->fe[i].tuner_i2c);
+ dvb_module_release(priv->fe[i].demod_i2c);
+ }
+
+ return 0;
+}
+
+static const struct hsc_conf ld20_hsc_conf[] = {
+ {
+ .css_in = HSC_CSS_IN_SRLTS2,
+ .css_out = HSC_CSS_OUT_TSI0,
+ .dpll = HSC_DPLL0,
+ .dma_out = HSC_DMA_OUT0,
+ },
+ {
+ .css_in = HSC_CSS_IN_SRLTS3,
+ .css_out = HSC_CSS_OUT_TSI1,
+ .dpll = HSC_DPLL1,
+ .dma_out = HSC_DMA_OUT1,
+ },
+};
+
+static const struct i2c_board_info mn884434_i2c_info[] = {
+ { .type = "mn884434-0", .addr = 0x68, },
+ { .type = "mn884434-1", .addr = 0x6a, },
+};
+
+static const struct i2c_board_info helene_i2c_info[] = {
+ { .type = "helene", .addr = 0x60, },
+ { .type = "helene", .addr = 0x61, },
+};
+
+static const struct uniphier_adapter_spec ld20_mn884434_helene_spec = {
+ .adapters = 2,
+ .hsc_conf = ld20_hsc_conf,
+ .demod_i2c_info = mn884434_i2c_info,
+ .tuner_i2c_info = helene_i2c_info,
+};
+
+static const struct of_device_id uniphier_hsc_adapter_of_match[] = {
+ {
+ .compatible = "socionext,uniphier-ld20-mn884434-helene",
+ .data = &ld20_mn884434_helene_spec,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, uniphier_hsc_adapter_of_match);
+
+static struct platform_driver uniphier_hsc_adapter_driver = {
+ .driver = {
+ .name = "uniphier-ld20-isdb",
+ .of_match_table = of_match_ptr(uniphier_hsc_adapter_of_match),
+ },
+ .probe = uniphier_adapter_probe,
+ .remove = uniphier_adapter_remove,
+};
+module_platform_driver(uniphier_hsc_adapter_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <[email protected]>");
+MODULE_DESCRIPTION("UniPhier LD20 adapter driver for ISDB.");
+MODULE_LICENSE("GPL v2");
--
2.17.0


2018-05-30 09:13:26

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 5/8] media: uniphier: add LD11/LD20 HSC support

This patch adds definition of registers specs to support of HSC
MPEG2-TS I/O driver for UniPhier LD11/LD20 SoCs.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Kconfig | 8 +
drivers/media/platform/uniphier/Makefile | 1 +
drivers/media/platform/uniphier/hsc-ld11.c | 219 +++++++++++++++++++++
3 files changed, 228 insertions(+)
create mode 100644 drivers/media/platform/uniphier/hsc-ld11.c

diff --git a/drivers/media/platform/uniphier/Kconfig b/drivers/media/platform/uniphier/Kconfig
index 1b4543ec1e3c..8f3a662a391c 100644
--- a/drivers/media/platform/uniphier/Kconfig
+++ b/drivers/media/platform/uniphier/Kconfig
@@ -7,3 +7,11 @@ config DVB_UNIPHIER
Driver for UniPhier frontend for MPEG2-TS input/output,
demux and descramble.
Say Y when you want to support this frontend.
+
+config DVB_UNIPHIER_LD11
+ bool "Support UniPhier LD11/LD20 HSC Device Driver"
+ depends on DVB_UNIPHIER
+ help
+ Driver for the HSC (High speed Stream Controller) for
+ UniPhier LD11/LD20.
+ Say Y when you want to support this hardware.
diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index 88bc860b391f..0622f04d9e68 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
+uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o

obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
diff --git a/drivers/media/platform/uniphier/hsc-ld11.c b/drivers/media/platform/uniphier/hsc-ld11.c
new file mode 100644
index 000000000000..df3cc85ac525
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-ld11.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+// For UniPhier LD11/LD20.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+static const struct hsc_spec_init_ram uniphier_hsc_ld11_init_rams[] = {
+ { FLT_PATN_RAM_TOP_ADDR, FLT_PATN_RAM_SIZE, ~0, },
+ { FLT_MASK_RAM_TOP_ADDR, FLT_MASK_RAM_SIZE, 0, },
+ /* FLT_PID Pattern */
+ { SHARE_MEMORY_0_NORMAL, FLT_PIDPATTERN_SIZE, ~0, },
+ /* FLT_PID Table */
+ { SHARE_MEMORY_0_NORMAL + FLT_PIDPATTERN_SIZE,
+ SHARE_MEMORY_0_SIZE - FLT_PIDPATTERN_SIZE, 0, },
+ { SHARE_MEMORY_1_NORMAL, SHARE_MEMORY_1_SIZE, 0, },
+ { SHARE_MEMORY_2_NORMAL, SHARE_MEMORY_2_SIZE, 0, },
+ { SHARE_MEMORY_3_NORMAL, SHARE_MEMORY_3_SIZE, 0, },
+ { SHARE_MEMORY_4_NORMAL, SHARE_MEMORY_4_SIZE, 0, },
+ { SHARE_MEMORY_5_NORMAL, SHARE_MEMORY_5_SIZE, 0, },
+};
+
+static const struct hsc_spec_init_ram uniphier_hsc_ld20_init_rams[] = {
+ { FLT_PATN_RAM_TOP_ADDR, FLT_PATN_RAM_SIZE, ~0, },
+ { FLT_MASK_RAM_TOP_ADDR, FLT_MASK_RAM_SIZE, 0, },
+ /* FLT_PID Pattern */
+ { SHARE_MEMORY_0_NORMAL, FLT_PIDPATTERN_SIZE, ~0, },
+ /* FLT_PID Table */
+ { SHARE_MEMORY_0_NORMAL + FLT_PIDPATTERN_SIZE,
+ SHARE_MEMORY_0_SIZE - FLT_PIDPATTERN_SIZE, 0, },
+ { SHARE_MEMORY_1_NORMAL, SHARE_MEMORY_1_SIZE, 0, },
+ { SHARE_MEMORY_2_NORMAL, SHARE_MEMORY_2_SIZE, 0, },
+ { SHARE_MEMORY_3_NORMAL, SHARE_MEMORY_3_SIZE, 0, },
+ { SHARE_MEMORY_4_NORMAL, SHARE_MEMORY_4_SIZE, 0, },
+ { SHARE_MEMORY_5_NORMAL, SHARE_MEMORY_5_SIZE, 0, },
+ { SHARE_MEMORY_6_NORMAL, SHARE_MEMORY_6_SIZE, 0, },
+ { SHARE_MEMORY_7_NORMAL, SHARE_MEMORY_7_SIZE, 0, },
+};
+
+static const struct hsc_spec_css_in uniphier_hsc_ld11_css_in[] = {
+ [HSC_CSS_IN_SRLTS0] = {
+ .pol = { true, CSS_SIGNALPOLCH(0), -1, 3, 0, },
+ },
+ [HSC_CSS_IN_SRLTS1] = {
+ .pol = { true, CSS_SIGNALPOLCH(0), -1, 11, 8, },
+ },
+ [HSC_CSS_IN_SRLTS2] = {
+ .pol = { true, CSS_SIGNALPOLCH(0), -1, 19, 16, },
+ },
+ [HSC_CSS_IN_SRLTS3] = {
+ .pol = { true, CSS_SIGNALPOLCH(0), -1, 27, 24, },
+ },
+ [HSC_CSS_IN_SRLTS4] = {
+ .pol = { true, CSS_SIGNALPOLCH(1), -1, 3, 0, },
+ },
+ [HSC_CSS_IN_PARTS0] = {
+ .pol = { true, CSS_PTSISIGNALPOL, -1, -1, 0, },
+ },
+ [HSC_CSS_IN_PARTS1] = {
+ .pol = { true, CSS_PTSISIGNALPOL, -1, -1, 8, },
+ },
+ [HSC_CSS_IN_DMD0] = {
+ .pol = { true, CSS_DMDSIGNALPOL, -1, -1, 16, },
+ },
+};
+
+static const struct hsc_spec_css_out uniphier_hsc_ld11_css_out[] = {
+ [HSC_CSS_OUT_SRLTS0] = {
+ .pol = { true, CSS_STSOSIGNALPOL, 6, -1, 0, },
+ .sel = { true, CSS_OUTPUTCTRL(0), GENMASK(4, 0), },
+ },
+ [HSC_CSS_OUT_SRLTS1] = {
+ .pol = { true, CSS_STSOSIGNALPOL, 14, -1, 8, },
+ .sel = { true, CSS_OUTPUTCTRL(0), GENMASK(12, 8), },
+ },
+ [HSC_CSS_OUT_TSI0] = {
+ .sel = { true, CSS_OUTPUTCTRL(1), GENMASK(4, 0), },
+ },
+ [HSC_CSS_OUT_TSI1] = {
+ .sel = { true, CSS_OUTPUTCTRL(1), GENMASK(12, 8), },
+ },
+ [HSC_CSS_OUT_TSI2] = {
+ .sel = { true, CSS_OUTPUTCTRL(1), GENMASK(20, 16), },
+ },
+ [HSC_CSS_OUT_TSI3] = {
+ .sel = { true, CSS_OUTPUTCTRL(1), GENMASK(28, 24), },
+ },
+ [HSC_CSS_OUT_TSI4] = {
+ .sel = { true, CSS_OUTPUTCTRL(2), GENMASK(4, 0), },
+ },
+ [HSC_CSS_OUT_PARTS0] = {
+ .pol = { true, CSS_PTSOSIGNALPOL, -1, -1, 0, },
+ .sel = { true, CSS_OUTPUTCTRL(4), GENMASK(4, 0), },
+ },
+ [HSC_CSS_OUT_PKTFF0] = {
+ .sel = { true, CSS_OUTPUTCTRL(5), GENMASK(4, 0), },
+ },
+};
+
+static const struct hsc_spec_ts uniphier_hsc_ld11_ts_in[] = {
+ [HSC_TSI0] = {
+ .intr = { true, IOB_INTREN0, 13 },
+ },
+ [HSC_TSI1] = {
+ .intr = { true, IOB_INTREN0, 14 },
+ },
+ [HSC_TSI2] = {
+ .intr = { true, IOB_INTREN0, 15 },
+ },
+ [HSC_TSI3] = {
+ .intr = { true, IOB_INTREN0, 16 },
+ },
+ [HSC_TSI4] = {
+ .intr = { true, IOB_INTREN0, 17 },
+ },
+};
+
+static const struct hsc_spec_dma uniphier_hsc_ld11_dma_in[] = {
+ [HSC_DMA_IN0] = {
+ .dma_ch = 5,
+ .en = { true, CDMBC_TDSTRT, 5 },
+ .intr = { true, IOB_INTREN1, 1 },
+ },
+ [HSC_DMA_IN1] = {
+ .dma_ch = 6,
+ .en = { true, CDMBC_TDSTRT, 6 },
+ .intr = { true, IOB_INTREN1, 2 },
+ },
+ [HSC_DMA_IN2] = {
+ .dma_ch = 7,
+ .en = { true, CDMBC_TDSTRT, 7 },
+ .intr = { true, IOB_INTREN1, 3 },
+ },
+ [HSC_DMA_IN3] = {
+ .dma_ch = 22,
+ .en = { true, CDMBC_TDSTRT, 13 },
+ .intr = { true, IOB_INTREN1, 4 },
+ },
+ [HSC_DMA_IN4] = {
+ .dma_ch = 23,
+ .en = { true, CDMBC_TDSTRT, 14 },
+ .intr = { true, IOB_INTREN1, 5 },
+ },
+ [HSC_DMA_IN5] = {
+ .dma_ch = 24,
+ .en = { true, CDMBC_TDSTRT, 15 },
+ .intr = { true, IOB_INTREN1, 6 },
+ },
+};
+
+static const struct hsc_spec_dma uniphier_hsc_ld11_dma_out[] = {
+ [HSC_DMA_OUT0] = {
+ .dma_ch = 1,
+ .en = { true, CDMBC_TDSTRT, 1 },
+ .intr = { true, IOB_INTREN1, 13 },
+ },
+ [HSC_DMA_OUT1] = {
+ .dma_ch = 2,
+ .en = { true, CDMBC_TDSTRT, 2 },
+ .intr = { true, IOB_INTREN1, 14 },
+ },
+ [HSC_DMA_OUT2] = {
+ .dma_ch = 3,
+ .en = { true, CDMBC_TDSTRT, 3 },
+ .intr = { true, IOB_INTREN1, 15 },
+ },
+ [HSC_DMA_OUT3] = {
+ .dma_ch = 19,
+ .en = { true, CDMBC_TDSTRT, 9 },
+ .intr = { true, IOB_INTREN1, 16 },
+ },
+ [HSC_DMA_OUT4] = {
+ .dma_ch = 20,
+ .en = { true, CDMBC_TDSTRT, 10 },
+ .intr = { true, IOB_INTREN1, 17 },
+ },
+ [HSC_DMA_OUT5] = {
+ .dma_ch = 21,
+ .en = { true, CDMBC_TDSTRT, 11 },
+ .intr = { true, IOB_INTREN1, 18 },
+ },
+};
+
+const struct hsc_spec uniphier_hsc_ld11_spec = {
+ .ucode_spu = { "hsc_spu_code_ld11.bin", "hsc_spu_data_ld11.bin" },
+ .ucode_ace = { "hsc_ace_code_ld11.bin", "hsc_ace_data_ld11.bin" },
+ .init_rams = uniphier_hsc_ld11_init_rams,
+ .num_init_rams = ARRAY_SIZE(uniphier_hsc_ld11_init_rams),
+ .css_in = uniphier_hsc_ld11_css_in,
+ .num_css_in = ARRAY_SIZE(uniphier_hsc_ld11_css_in),
+ .css_out = uniphier_hsc_ld11_css_out,
+ .num_css_out = ARRAY_SIZE(uniphier_hsc_ld11_css_out),
+ .ts_in = uniphier_hsc_ld11_ts_in,
+ .num_ts_in = ARRAY_SIZE(uniphier_hsc_ld11_ts_in),
+ .dma_in = uniphier_hsc_ld11_dma_in,
+ .num_dma_in = ARRAY_SIZE(uniphier_hsc_ld11_dma_in),
+ .dma_out = uniphier_hsc_ld11_dma_out,
+ .num_dma_out = ARRAY_SIZE(uniphier_hsc_ld11_dma_out),
+};
+
+const struct hsc_spec uniphier_hsc_ld20_spec = {
+ .ucode_spu = { "hsc_spu_code_ld11.bin", "hsc_spu_data_ld11.bin" },
+ .ucode_ace = { "hsc_ace_code_ld11.bin", "hsc_ace_data_ld11.bin" },
+ .init_rams = uniphier_hsc_ld20_init_rams,
+ .num_init_rams = ARRAY_SIZE(uniphier_hsc_ld20_init_rams),
+ .css_in = uniphier_hsc_ld11_css_in,
+ .num_css_in = ARRAY_SIZE(uniphier_hsc_ld11_css_in),
+ .css_out = uniphier_hsc_ld11_css_out,
+ .num_css_out = ARRAY_SIZE(uniphier_hsc_ld11_css_out),
+ .ts_in = uniphier_hsc_ld11_ts_in,
+ .num_ts_in = ARRAY_SIZE(uniphier_hsc_ld11_ts_in),
+ .dma_in = uniphier_hsc_ld11_dma_in,
+ .num_dma_in = ARRAY_SIZE(uniphier_hsc_ld11_dma_in),
+ .dma_out = uniphier_hsc_ld11_dma_out,
+ .num_dma_out = ARRAY_SIZE(uniphier_hsc_ld11_dma_out),
+};
--
2.17.0


2018-05-30 09:13:56

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 4/8] media: uniphier: add common module of HSC MPEG2-TS I/O driver

This patch adds common module of HSC (High speed Stream Controller)
driver for Socionext UniPhier SoCs.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Makefile | 2 +-
drivers/media/platform/uniphier/hsc-core.c | 514 +++++++++++++++++++++
2 files changed, 515 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/uniphier/hsc-core.c

diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index 92536bc56b31..88bc860b391f 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-uniphier-dvb-y += hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
+uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o

obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
diff --git a/drivers/media/platform/uniphier/hsc-core.c b/drivers/media/platform/uniphier/hsc-core.c
new file mode 100644
index 000000000000..cdb488e4df8c
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-core.c
@@ -0,0 +1,514 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+#define SZ_TS_PKT 188
+#define SZ_M2TS_PKT 192
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums);
+
+static int hsc_start_feed(struct dvb_demux_feed *feed)
+{
+ struct hsc_tsif *tsif = feed->demux->priv;
+ struct hsc_dmaif *dmaif = tsif->dmaif;
+ struct hsc_chip *chip = tsif->chip;
+
+ tsif->running = true;
+ dmaif->running = true;
+
+ hsc_ts_in_set_enable(chip, tsif->tsi, true);
+
+ hsc_dma_out_set_src_ts_in(&dmaif->dma_out, tsif->tsi);
+ hsc_dma_out_start(&dmaif->dma_out, true);
+
+ return 0;
+}
+
+static int hsc_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct hsc_tsif *tsif = feed->demux->priv;
+ struct hsc_dmaif *dmaif = tsif->dmaif;
+ struct hsc_chip *chip = tsif->chip;
+
+ hsc_ts_in_set_enable(chip, tsif->tsi, false);
+
+ hsc_dma_out_start(&dmaif->dma_out, false);
+
+ tsif->running = false;
+ dmaif->running = false;
+
+ return 0;
+}
+
+int hsc_register_dvb(struct hsc_tsif *tsif)
+{
+ struct device *dev = &tsif->chip->pdev->dev;
+ int ret;
+
+ tsif->adapter.priv = tsif;
+ ret = dvb_register_adapter(&tsif->adapter, "uniphier-hsc",
+ THIS_MODULE, dev, adapter_nums);
+ if (ret < 0) {
+ dev_err(dev, "Failed to register DVB adapter: %d\n", ret);
+ return ret;
+ }
+ tsif->valid_adapter = true;
+
+ tsif->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+ tsif->demux.priv = tsif;
+ tsif->demux.feednum = 256;
+ tsif->demux.filternum = 256;
+ tsif->demux.start_feed = hsc_start_feed;
+ tsif->demux.stop_feed = hsc_stop_feed;
+ tsif->demux.write_to_decoder = NULL;
+ ret = dvb_dmx_init(&tsif->demux);
+ if (ret) {
+ dev_err(dev, "Failed to register demux: %d\n", ret);
+ goto err_out_adapter;
+ }
+ tsif->valid_demux = true;
+
+ tsif->dmxdev.filternum = 256;
+ tsif->dmxdev.demux = &tsif->demux.dmx;
+ tsif->dmxdev.capabilities = 0;
+ ret = dvb_dmxdev_init(&tsif->dmxdev, &tsif->adapter);
+ if (ret) {
+ dev_err(dev, "Failed to register demux dev: %d\n", ret);
+ goto err_out_dmx;
+ }
+ tsif->valid_dmxdev = true;
+
+ ret = dvb_register_frontend(&tsif->adapter, tsif->fe);
+ if (ret) {
+ dev_err(dev, "Failed to register adapter: %d\n", ret);
+ goto err_out_dmxdev;
+ }
+ tsif->valid_fe = true;
+
+ return 0;
+
+err_out_dmxdev:
+ dvb_dmxdev_release(&tsif->dmxdev);
+
+err_out_dmx:
+ dvb_dmx_release(&tsif->demux);
+
+err_out_adapter:
+ dvb_unregister_adapter(&tsif->adapter);
+
+ return ret;
+}
+
+void hsc_unregister_dvb(struct hsc_tsif *tsif)
+{
+ if (tsif->valid_fe) {
+ dvb_frontend_detach(tsif->fe);
+ dvb_unregister_frontend(tsif->fe);
+ }
+ if (tsif->valid_dmxdev)
+ dvb_dmxdev_release(&tsif->dmxdev);
+ if (tsif->valid_demux)
+ dvb_dmx_release(&tsif->demux);
+ if (tsif->valid_adapter)
+ dvb_unregister_adapter(&tsif->adapter);
+}
+
+static bool is_tsi_error(struct hsc_tsif *tsif, u32 status)
+{
+ if (status & (TSI_INTR_SERR | TSI_INTR_SOF | TSI_INTR_TOF))
+ return true;
+
+ return false;
+}
+
+static void hsc_tsif_recover_worker(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct hsc_tsif *tsif = container_of(dwork,
+ struct hsc_tsif, recover_work);
+ struct hsc_chip *chip = tsif->chip;
+
+ if (!tsif->running)
+ return;
+
+ hsc_ts_in_set_enable(chip, tsif->tsi, true);
+}
+
+static irqreturn_t hsc_tsif_irq(int irq, void *p)
+{
+ struct platform_device *pdev = p;
+ struct device *dev = &pdev->dev;
+ struct hsc_chip *chip = platform_get_drvdata(pdev);
+ struct regmap *r = chip->regmap;
+ int i, ret = IRQ_NONE;
+
+ for (i = 0; i < ARRAY_SIZE(chip->tsif); i++) {
+ struct hsc_tsif *tsif = &chip->tsif[i];
+ u32 st;
+
+ if (!tsif->running)
+ continue;
+
+ regmap_read(r, TSI_SYNCSTATUS(tsif->tsi), &st);
+ if (!st)
+ continue;
+
+ regmap_write(r, TSI_SYNCSTATUS(tsif->tsi), 0xffff);
+
+ if (is_tsi_error(tsif, st)) {
+ /* Recovery */
+ dev_info(dev, "TS %d Sync lost, try recovery.\n",
+ tsif->tsi);
+ schedule_delayed_work(&tsif->recover_work,
+ tsif->recover_delay);
+ }
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+int hsc_tsif_init(struct hsc_tsif *tsif, const struct hsc_conf *conf)
+{
+ struct hsc_chip *chip = tsif->chip;
+ int ret;
+
+ if (!conf)
+ return -EINVAL;
+
+ tsif->css_in = conf->css_in;
+ tsif->css_out = conf->css_out;
+ tsif->dpll = conf->dpll;
+
+ tsif->tsi = hsc_css_out_to_ts_in(tsif->css_out);
+ if (tsif->tsi == -1)
+ return -EINVAL;
+
+ tsif->dpll_src = hsc_css_out_to_dpll_src(tsif->css_out);
+ if (tsif->dpll_src == -1)
+ return -EINVAL;
+
+ ret = hsc_css_out_set_src(chip, tsif->css_in, tsif->css_out, true);
+ if (ret)
+ return ret;
+
+ ret = hsc_css_in_set_polarity(chip, tsif->css_in, false, false, false);
+ if (ret)
+ return ret;
+
+ ret = hsc_ts_in_set_dmaparam(chip, tsif->tsi, HSC_TSIF_MPEG2_TS_ATS);
+ if (ret)
+ return ret;
+
+ ret = hsc_dpll_set_src(chip, tsif->dpll, tsif->dpll_src);
+ if (ret)
+ return ret;
+
+ INIT_DELAYED_WORK(&tsif->recover_work, hsc_tsif_recover_worker);
+ tsif->recover_delay = HZ / 10;
+
+ return 0;
+}
+
+void hsc_tsif_release(struct hsc_tsif *tsif)
+{
+ cancel_delayed_work(&tsif->recover_work);
+}
+
+static void hsc_dmaif_feed_worker(struct work_struct *work)
+{
+ struct hsc_dmaif *dmaif = container_of(work,
+ struct hsc_dmaif, feed_work);
+ struct hsc_tsif *tsif = dmaif->tsif;
+ struct hsc_dma_buf *buf = &dmaif->buf_out;
+ struct device *dev = &dmaif->chip->pdev->dev;
+ dma_addr_t dmapos;
+ u8 *pkt;
+ u64 cnt, i;
+ int wrap = 0;
+
+ if (!dmaif->running)
+ return;
+
+retry:
+ spin_lock(&dmaif->lock);
+ hsc_dma_out_sync(&dmaif->dma_out);
+ spin_unlock(&dmaif->lock);
+
+ dmapos = buf->phys + buf->rd_offs;
+ cnt = hsc_rb_cnt_to_end(buf);
+ cnt = DIV_ROUND_DOWN_ULL(cnt, SZ_M2TS_PKT) * SZ_M2TS_PKT;
+
+ dma_sync_single_for_cpu(dev, dmapos, cnt, DMA_FROM_DEVICE);
+ for (i = 0; i < cnt; i += SZ_M2TS_PKT) {
+ pkt = buf->virt + buf->rd_offs + i;
+
+ if (pkt[4] == 0x47 && pkt[5] == 0x1f && pkt[6] == 0xff)
+ continue;
+ if (pkt[5] & 0x80)
+ continue;
+ if (pkt[7] & 0xc0)
+ continue;
+
+ dvb_dmx_swfilter_packets(&tsif->demux, &pkt[4], 1);
+ }
+ dma_sync_single_for_device(dev, dmapos, cnt, DMA_FROM_DEVICE);
+
+ spin_lock(&dmaif->lock);
+
+ buf->rd_offs += cnt;
+ if (buf->rd_offs >= buf->size)
+ buf->rd_offs -= buf->size;
+
+ buf->chk_offs = buf->wr_offs + buf->size_chk;
+ if (buf->chk_offs >= buf->size)
+ buf->chk_offs -= buf->size;
+
+ if (!wrap && hsc_rb_cnt(buf) >= buf->size_chk / 2) {
+ wrap = 1;
+ spin_unlock(&dmaif->lock);
+ goto retry;
+ }
+
+ hsc_dma_out_sync(&dmaif->dma_out);
+
+ spin_unlock(&dmaif->lock);
+}
+
+static irqreturn_t hsc_dmaif_irq(int irq, void *p)
+{
+ struct platform_device *pdev = p;
+ struct hsc_chip *chip = platform_get_drvdata(pdev);
+ int i, ret = IRQ_NONE;
+ u32 st;
+
+ for (i = 0; i < ARRAY_SIZE(chip->tsif); i++) {
+ struct hsc_dmaif *dmaif = &chip->dmaif[i];
+
+ if (!dmaif->running)
+ continue;
+
+ hsc_dma_out_get_intr(&dmaif->dma_out, &st);
+ if (!st)
+ continue;
+
+ hsc_dma_out_clear_intr(&dmaif->dma_out, 0xffff);
+
+ spin_lock(&dmaif->lock);
+ hsc_dma_out_sync(&dmaif->dma_out);
+ spin_unlock(&dmaif->lock);
+
+ schedule_work(&dmaif->feed_work);
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+int hsc_dmaif_init(struct hsc_dmaif *dmaif, const struct hsc_conf *conf)
+{
+ struct hsc_chip *chip = dmaif->chip;
+ struct hsc_dma_buf *buf = &dmaif->buf_out;
+ struct device *dev = &chip->pdev->dev;
+ int ret;
+
+ if (!conf)
+ return -EINVAL;
+
+ ret = hsc_dma_out_init(&dmaif->dma_out, chip, conf->dma_out, buf);
+ if (ret)
+ return ret;
+
+ buf->size = HSC_DMAIF_TS_BUFSIZE;
+ buf->size_chk = HSC_DMAIF_TS_BUFSIZE / 4;
+ buf->virt = dma_alloc_coherent(dev, buf->size, &buf->phys, GFP_KERNEL);
+ if (!buf->virt)
+ return -ENOMEM;
+
+ spin_lock_init(&dmaif->lock);
+ INIT_WORK(&dmaif->feed_work, hsc_dmaif_feed_worker);
+
+ return 0;
+}
+
+void hsc_dmaif_release(struct hsc_dmaif *dmaif)
+{
+ struct hsc_chip *chip = dmaif->chip;
+ struct device *dev = &chip->pdev->dev;
+
+ flush_scheduled_work();
+
+ dma_free_coherent(dev, dmaif->buf_out.size, dmaif->buf_out.virt,
+ dmaif->buf_out.phys);
+}
+
+static const struct regmap_config hsc_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0xffffc,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int hsc_probe(struct platform_device *pdev)
+{
+ struct hsc_chip *chip;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *preg;
+ int irq, ret, i;
+
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+ chip->pdev = pdev;
+
+ chip->spec = of_device_get_match_data(dev);
+ if (!chip->spec)
+ return -EINVAL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ preg = devm_ioremap_resource(dev, res);
+ if (IS_ERR(preg))
+ return PTR_ERR(preg);
+
+ chip->regmap = devm_regmap_init_mmio(dev, preg,
+ &hsc_regmap_config);
+ if (IS_ERR(chip->regmap))
+ return PTR_ERR(chip->regmap);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(dev, "Could not get irq for TS I/F\n");
+ return irq;
+ }
+
+ ret = devm_request_irq(dev, irq, hsc_tsif_irq, IRQF_SHARED,
+ dev_name(dev), pdev);
+ if (ret)
+ return ret;
+
+ irq = platform_get_irq(pdev, 1);
+ if (irq < 0) {
+ dev_err(dev, "Could not get irq for DMA I/F\n");
+ return irq;
+ }
+
+ ret = devm_request_irq(dev, irq, hsc_dmaif_irq, IRQF_SHARED,
+ dev_name(dev), pdev);
+ if (ret)
+ return ret;
+
+ chip->clk_stdmac = devm_clk_get(dev, "stdmac");
+ if (IS_ERR(chip->clk_stdmac))
+ return PTR_ERR(chip->clk_stdmac);
+
+ chip->clk_hsc = devm_clk_get(dev, "hsc");
+ if (IS_ERR(chip->clk_hsc))
+ return PTR_ERR(chip->clk_hsc);
+
+ chip->rst_stdmac = devm_reset_control_get_shared(dev, "stdmac");
+ if (IS_ERR(chip->rst_stdmac))
+ return PTR_ERR(chip->rst_stdmac);
+
+ chip->rst_hsc = devm_reset_control_get_shared(dev, "hsc");
+ if (IS_ERR(chip->rst_hsc))
+ return PTR_ERR(chip->rst_hsc);
+
+ ret = clk_prepare_enable(chip->clk_stdmac);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(chip->clk_hsc);
+ if (ret)
+ goto err_out_clk_stdmac;
+
+ ret = reset_control_deassert(chip->rst_stdmac);
+ if (ret)
+ goto err_out_clk_hsc;
+
+ ret = reset_control_deassert(chip->rst_hsc);
+ if (ret)
+ goto err_out_rst_stdmac;
+
+ ret = hsc_ucode_load_all(chip);
+ if (ret)
+ goto err_out_rst_hsc;
+
+ for (i = 0; i < HSC_STREAM_IF_NUM; i++) {
+ chip->dmaif[i].chip = chip;
+ chip->dmaif[i].tsif = &chip->tsif[i];
+ chip->tsif[i].chip = chip;
+ chip->tsif[i].dmaif = &chip->dmaif[i];
+ }
+
+ platform_set_drvdata(pdev, chip);
+
+ return 0;
+
+err_out_rst_hsc:
+ reset_control_assert(chip->rst_hsc);
+
+err_out_rst_stdmac:
+ reset_control_assert(chip->rst_stdmac);
+
+err_out_clk_hsc:
+ clk_disable_unprepare(chip->clk_hsc);
+
+err_out_clk_stdmac:
+ clk_disable_unprepare(chip->clk_stdmac);
+
+ return ret;
+}
+
+static int hsc_remove(struct platform_device *pdev)
+{
+ struct hsc_chip *chip = platform_get_drvdata(pdev);
+
+ hsc_ucode_unload_all(chip);
+
+ reset_control_assert(chip->rst_hsc);
+ reset_control_assert(chip->rst_stdmac);
+ clk_disable_unprepare(chip->clk_hsc);
+ clk_disable_unprepare(chip->clk_stdmac);
+
+ return 0;
+}
+
+static const struct of_device_id uniphier_hsc_of_match[] = {
+ {
+ .compatible = "socionext,uniphier-ld11-hsc",
+ .data = &uniphier_hsc_ld11_spec,
+ },
+ {
+ .compatible = "socionext,uniphier-ld20-hsc",
+ .data = &uniphier_hsc_ld20_spec,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, uniphier_hsc_of_match);
+
+static struct platform_driver uniphier_hsc_driver = {
+ .driver = {
+ .name = "uniphier-hsc",
+ .of_match_table = of_match_ptr(uniphier_hsc_of_match),
+ },
+ .probe = hsc_probe,
+ .remove = hsc_remove,
+};
+module_platform_driver(uniphier_hsc_driver);
--
2.17.0


2018-05-30 09:14:02

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 3/8] media: uniphier: add submodules of HSC MPEG2-TS I/O driver

This patch adds submodules of HSC for UniPhier SoCs.
These work as follows:
ucode: Load uCode and start subsystems
css : Switch stream path
ts : Receive MPEG2-TS clock and signal
dma : Transfer MPEG2-TS data bytes to main memory

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Makefile | 3 +
drivers/media/platform/uniphier/hsc-css.c | 258 ++++++++++++
drivers/media/platform/uniphier/hsc-dma.c | 302 ++++++++++++++
drivers/media/platform/uniphier/hsc-ts.c | 99 +++++
drivers/media/platform/uniphier/hsc-ucode.c | 436 ++++++++++++++++++++
5 files changed, 1098 insertions(+)
create mode 100644 drivers/media/platform/uniphier/hsc-css.c
create mode 100644 drivers/media/platform/uniphier/hsc-dma.c
create mode 100644 drivers/media/platform/uniphier/hsc-ts.c
create mode 100644 drivers/media/platform/uniphier/hsc-ucode.c

diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index f66554cd5c45..92536bc56b31 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -1 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
+uniphier-dvb-y += hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
+
+obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
diff --git a/drivers/media/platform/uniphier/hsc-css.c b/drivers/media/platform/uniphier/hsc-css.c
new file mode 100644
index 000000000000..baa0a15ca98e
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-css.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+// CSS (Cross Stream Switch) connects MPEG2-TS input port and output port.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+enum HSC_TS_IN hsc_css_out_to_ts_in(enum HSC_CSS_OUT out)
+{
+ if (out >= HSC_CSS_OUT_TSI0 && out <= HSC_CSS_OUT_TSI9)
+ return HSC_TSI0 + (out - HSC_CSS_OUT_TSI0);
+
+ return -1;
+}
+
+enum HSC_DPLL_SRC hsc_css_out_to_dpll_src(enum HSC_CSS_OUT out)
+{
+ if (out >= HSC_CSS_OUT_TSI0 && out <= HSC_CSS_OUT_TSI9)
+ return HSC_DPLL_SRC_TSI0 + (out - HSC_CSS_OUT_TSI0);
+
+ return -1;
+}
+
+static bool css_in_is_valid(struct hsc_chip *chip, enum HSC_CSS_IN in)
+{
+ if (in >= chip->spec->num_css_in)
+ return false;
+
+ return true;
+}
+
+static bool css_out_is_valid(struct hsc_chip *chip, enum HSC_CSS_OUT out)
+{
+ if (out >= chip->spec->num_css_out)
+ return false;
+
+ return true;
+}
+
+static const struct hsc_spec_css_in *css_in_get_spec(struct hsc_chip *chip,
+ enum HSC_CSS_IN in)
+{
+ const struct hsc_spec_css_in *spec = chip->spec->css_in;
+
+ if (!css_in_is_valid(chip, in))
+ return NULL;
+
+ return &spec[in];
+}
+
+static const struct hsc_spec_css_out *css_out_get_spec(struct hsc_chip *chip,
+ enum HSC_CSS_OUT out)
+{
+ const struct hsc_spec_css_out *spec = chip->spec->css_out;
+
+ if (!css_out_is_valid(chip, out))
+ return NULL;
+
+ return &spec[out];
+}
+
+int hsc_dpll_get_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
+ enum HSC_DPLL_SRC *src)
+{
+ struct regmap *r = chip->regmap;
+ u32 v;
+
+ if (!src || dpll >= HSC_DPLL_NUM)
+ return -EINVAL;
+
+ regmap_read(r, CSS_DPCTRL(dpll), &v);
+ *src = ffs(v & CSS_DPCTRL_DPSEL_MASK) - 1;
+
+ return 0;
+}
+
+/**
+ * Select source clock of DPLL.
+ *
+ * @dpll: ID of DPLL
+ * @src : ID of clock source or HSC_DPLL_SRC_NONE to disconnect
+ */
+int hsc_dpll_set_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
+ enum HSC_DPLL_SRC src)
+{
+ struct regmap *r = chip->regmap;
+ u32 v = 0;
+
+ if (dpll >= HSC_DPLL_NUM || src >= HSC_DPLL_SRC_NUM)
+ return -EINVAL;
+
+ if (src != HSC_DPLL_SRC_NONE)
+ v = 1 << src;
+
+ regmap_write(r, CSS_DPCTRL(dpll), v);
+
+ return 0;
+}
+
+static int hsc_css_get_polarity(struct hsc_chip *chip,
+ const struct hsc_css_pol *pol,
+ bool *sync_bit, bool *val_bit, bool *clk_fall)
+{
+ struct regmap *r = chip->regmap;
+ u32 v;
+
+ if (!sync_bit || !val_bit || !clk_fall || !pol->valid)
+ return -EINVAL;
+
+ regmap_read(r, pol->reg, &v);
+
+ *sync_bit = !!(v & BIT(pol->sft_sync));
+ *val_bit = !!(v & BIT(pol->sft_val));
+ *clk_fall = !!(v & BIT(pol->sft_clk));
+
+ return 0;
+}
+
+/**
+ * Setup signal polarity of TS signals.
+ *
+ * @sync_bit : true : The sync signal keeps only 1bit period.
+ * false: The sync signal keeps during 8bits period.
+ * @valid_bit: true : The valid signal does not keep during 8bits period.
+ * false: The valid signal keeps during 8bits period.
+ * @clk_fall : true : Latch the data at falling edge of clock signal.
+ * false: Latch the data at rising edge of clock signal.
+ */
+static int hsc_css_set_polarity(struct hsc_chip *chip,
+ const struct hsc_css_pol *pol,
+ bool sync_bit, bool val_bit, bool clk_fall)
+{
+ struct regmap *r = chip->regmap;
+ u32 m = 0, v = 0;
+
+ if (!pol->valid)
+ return -EINVAL;
+
+ if (pol->sft_sync != -1) {
+ m |= BIT(pol->sft_sync);
+ if (sync_bit)
+ v |= BIT(pol->sft_sync);
+ }
+
+ if (pol->sft_val != -1) {
+ m |= BIT(pol->sft_val);
+ if (val_bit)
+ v |= BIT(pol->sft_val);
+ }
+
+ if (pol->sft_clk != -1) {
+ m |= BIT(pol->sft_clk);
+ if (clk_fall)
+ v |= BIT(pol->sft_clk);
+ }
+
+ regmap_update_bits(r, pol->reg, m, v);
+
+ return 0;
+}
+
+int hsc_css_in_get_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ bool *sync_bit, bool *val_bit, bool *clk_fall)
+{
+ const struct hsc_spec_css_in *speci = css_in_get_spec(chip, in);
+
+ if (!speci)
+ return -EINVAL;
+
+ return hsc_css_get_polarity(chip, &speci->pol,
+ sync_bit, val_bit, clk_fall);
+}
+
+int hsc_css_in_set_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ bool sync_bit, bool val_bit, bool clk_fall)
+{
+ const struct hsc_spec_css_in *speci = css_in_get_spec(chip, in);
+
+ if (!speci)
+ return -EINVAL;
+
+ return hsc_css_set_polarity(chip, &speci->pol,
+ sync_bit, val_bit, clk_fall);
+}
+
+int hsc_css_out_get_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
+ bool *sync_bit, bool *val_bit, bool *clk_fall)
+{
+ const struct hsc_spec_css_out *speco = css_out_get_spec(chip, out);
+
+ if (!speco)
+ return -EINVAL;
+
+ return hsc_css_get_polarity(chip, &speco->pol,
+ sync_bit, val_bit, clk_fall);
+}
+
+int hsc_css_out_set_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
+ bool sync_bit, bool val_bit, bool clk_fall)
+{
+ const struct hsc_spec_css_out *speco = css_out_get_spec(chip, out);
+
+ if (!speco)
+ return -EINVAL;
+
+ return hsc_css_set_polarity(chip, &speco->pol,
+ sync_bit, val_bit, clk_fall);
+}
+
+int hsc_css_out_get_src(struct hsc_chip *chip, enum HSC_CSS_IN *in,
+ enum HSC_CSS_OUT out, bool *en)
+{
+ struct regmap *r = chip->regmap;
+ const struct hsc_spec_css_out *speco = css_out_get_spec(chip, out);
+ u32 v;
+
+ if (!in || !en || !speco || !speco->sel.valid)
+ return -EINVAL;
+
+ regmap_read(r, speco->sel.reg, &v);
+ *in = field_get(speco->sel.mask, v);
+
+ regmap_read(r, CSS_OUTPUTENABLE, &v);
+ *en = !!(v & BIT(out));
+
+ return 0;
+}
+
+/**
+ * Connect the input port and output port using CSS (Cross Stream Switch).
+ *
+ * @in : Input port number.
+ * @out : Output port number.
+ * @en : false: Disable this path.
+ * true : Enable this path.
+ */
+int hsc_css_out_set_src(struct hsc_chip *chip, enum HSC_CSS_IN in,
+ enum HSC_CSS_OUT out, bool en)
+{
+ struct regmap *r = chip->regmap;
+ const struct hsc_spec_css_out *speco = css_out_get_spec(chip, out);
+
+ if (!css_in_is_valid(chip, in) || !speco || !speco->sel.valid)
+ return -EINVAL;
+
+ regmap_update_bits(r, speco->sel.reg, speco->sel.mask,
+ field_prep(speco->sel.mask, in));
+
+ regmap_update_bits(r, CSS_OUTPUTENABLE, BIT(out), (en) ? ~0 : 0);
+
+ return 0;
+}
diff --git a/drivers/media/platform/uniphier/hsc-dma.c b/drivers/media/platform/uniphier/hsc-dma.c
new file mode 100644
index 000000000000..0b3e471a68f7
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-dma.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+// MPEG2-TS DMA control.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+u64 hsc_rb_cnt(struct hsc_dma_buf *buf)
+{
+ if (buf->rd_offs <= buf->wr_offs)
+ return buf->wr_offs - buf->rd_offs;
+ else
+ return buf->size - (buf->rd_offs - buf->wr_offs);
+}
+
+u64 hsc_rb_cnt_to_end(struct hsc_dma_buf *buf)
+{
+ if (buf->rd_offs <= buf->wr_offs)
+ return buf->wr_offs - buf->rd_offs;
+ else
+ return buf->size - buf->rd_offs;
+}
+
+u64 hsc_rb_space(struct hsc_dma_buf *buf)
+{
+ if (buf->rd_offs <= buf->wr_offs)
+ return buf->size - (buf->wr_offs - buf->rd_offs) - 8;
+ else
+ return buf->rd_offs - buf->wr_offs - 8;
+}
+
+u64 hsc_rb_space_to_end(struct hsc_dma_buf *buf)
+{
+ if (buf->rd_offs > buf->wr_offs)
+ return buf->rd_offs - buf->wr_offs - 8;
+ else if (buf->rd_offs > 0)
+ return buf->size - buf->wr_offs;
+ else
+ return buf->size - buf->wr_offs - 8;
+}
+
+static void dma_set_buffer(struct hsc_chip *chip, int dma_ch,
+ u64 bg, u64 ed)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, CDMBC_RBBGNADRSD(dma_ch), bg);
+ regmap_write(r, CDMBC_RBBGNADRSU(dma_ch), bg >> 32);
+ regmap_write(r, CDMBC_RBENDADRSD(dma_ch), ed);
+ regmap_write(r, CDMBC_RBENDADRSU(dma_ch), ed >> 32);
+}
+
+static u64 dma_get_rp(struct hsc_chip *chip, int dma_ch)
+{
+ struct regmap *r = chip->regmap;
+ u32 d, u;
+
+ regmap_read(r, CDMBC_RBRDPTRD(dma_ch), &d);
+ regmap_read(r, CDMBC_RBRDPTRU(dma_ch), &u);
+
+ return ((u64)u << 32) | d;
+}
+
+static void dma_set_rp(struct hsc_chip *chip, int dma_ch, u64 pos)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, CDMBC_RBRDPTRD(dma_ch), pos);
+ regmap_write(r, CDMBC_RBRDPTRU(dma_ch), pos >> 32);
+}
+
+static u64 dma_get_wp(struct hsc_chip *chip, int dma_ch)
+{
+ struct regmap *r = chip->regmap;
+ u32 d, u;
+
+ regmap_read(r, CDMBC_RBWRPTRD(dma_ch), &d);
+ regmap_read(r, CDMBC_RBWRPTRU(dma_ch), &u);
+
+ return ((u64)u << 32) | d;
+}
+
+static void dma_set_wp(struct hsc_chip *chip, int dma_ch, u64 pos)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, CDMBC_RBWRPTRD(dma_ch), pos);
+ regmap_write(r, CDMBC_RBWRPTRU(dma_ch), pos >> 32);
+}
+
+static void dma_set_chkp(struct hsc_chip *chip, int dma_ch, u64 pos)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, CDMBC_CHIRADRSD(dma_ch), pos);
+ regmap_write(r, CDMBC_CHIRADRSU(dma_ch), pos >> 32);
+}
+
+static void dma_set_enable(struct hsc_chip *chip, int dma_ch,
+ const struct hsc_dma_en *dma_en, bool en)
+{
+ struct regmap *r = chip->regmap;
+ u32 v;
+ bool now;
+
+ regmap_read(r, dma_en->reg, &v);
+ now = !!(v & BIT(dma_en->sft_toggle));
+
+ /* Toggle DMA state if needed */
+ if ((en && !now) || (!en && now))
+ regmap_write(r, dma_en->reg, BIT(dma_en->sft_toggle));
+}
+
+static bool dma_in_is_valid(struct hsc_chip *chip, enum HSC_DMA_IN in)
+{
+ if (in >= chip->spec->num_dma_in ||
+ !chip->spec->dma_in[in].intr.valid)
+ return false;
+
+ return true;
+}
+
+int hsc_dma_in_init(struct hsc_dma_in *dma_in, struct hsc_chip *chip,
+ enum HSC_DMA_IN in, struct hsc_dma_buf *buf)
+{
+ if (!dma_in || !dma_in_is_valid(chip, in))
+ return -EINVAL;
+
+ dma_in->chip = chip;
+ dma_in->id = in;
+ dma_in->spec = &chip->spec->dma_in[in];
+ dma_in->buf = buf;
+
+ return 0;
+}
+
+void hsc_dma_in_start(struct hsc_dma_in *dma_in, bool en)
+{
+ struct hsc_chip *chip = dma_in->chip;
+ const struct hsc_spec_dma *spec = dma_in->spec;
+ struct hsc_dma_buf *buf = dma_in->buf;
+ struct regmap *r = chip->regmap;
+ u64 bg, ed;
+ u32 v;
+
+ bg = buf->phys;
+ ed = buf->phys + buf->size;
+ dma_set_buffer(chip, spec->dma_ch, bg, ed);
+
+ buf->rd_offs = 0;
+ buf->wr_offs = 0;
+ buf->chk_offs = buf->size_chk;
+ dma_set_rp(chip, spec->dma_ch, buf->rd_offs + buf->phys);
+ dma_set_wp(chip, spec->dma_ch, buf->wr_offs + buf->phys);
+ dma_set_chkp(chip, spec->dma_ch, buf->chk_offs + buf->phys);
+
+ regmap_update_bits(r, CDMBC_CHSRCAMODE(spec->dma_ch),
+ CDMBC_CHAMODE_TYPE_RB, ~0);
+ regmap_update_bits(r, CDMBC_CHCTRL1(spec->dma_ch),
+ CDMBC_CHCTRL1_IND_SIZE_UND, ~0);
+
+ v = (en) ? ~0 : 0;
+ regmap_update_bits(r, CDMBC_CHIE(spec->dma_ch), CDMBC_CHI_TRANSIT, v);
+ regmap_update_bits(r, spec->intr.reg, BIT(spec->intr.sft_intr), v);
+
+ dma_set_enable(chip, spec->dma_ch, &spec->en, en);
+}
+
+void hsc_dma_in_sync(struct hsc_dma_in *dma_in)
+{
+ struct hsc_chip *chip = dma_in->chip;
+ const struct hsc_spec_dma *spec = dma_in->spec;
+ struct hsc_dma_buf *buf = dma_in->buf;
+
+ buf->rd_offs = dma_get_rp(chip, spec->dma_ch) - buf->phys;
+ dma_set_wp(chip, spec->dma_ch, buf->rd_offs + buf->phys);
+ dma_set_chkp(chip, spec->dma_ch, buf->chk_offs + buf->phys);
+}
+
+int hsc_dma_in_get_intr(struct hsc_dma_in *dma_in, u32 *stat)
+{
+ struct regmap *r = dma_in->chip->regmap;
+
+ if (!stat)
+ return -EINVAL;
+
+ regmap_read(r, CDMBC_CHID(dma_in->spec->dma_ch), stat);
+
+ return 0;
+}
+
+void hsc_dma_in_clear_intr(struct hsc_dma_in *dma_in, u32 v)
+{
+ struct regmap *r = dma_in->chip->regmap;
+
+ regmap_write(r, CDMBC_CHIR(dma_in->spec->dma_ch), v);
+}
+
+static bool dma_out_is_valid(struct hsc_chip *chip, enum HSC_DMA_OUT out)
+{
+ if (out >= chip->spec->num_dma_out ||
+ !chip->spec->dma_out[out].intr.valid)
+ return false;
+
+ return true;
+}
+
+int hsc_dma_out_init(struct hsc_dma_out *dma_out, struct hsc_chip *chip,
+ enum HSC_DMA_OUT out, struct hsc_dma_buf *buf)
+{
+ if (!dma_out || !dma_out_is_valid(chip, out))
+ return -EINVAL;
+
+ dma_out->chip = chip;
+ dma_out->id = out;
+ dma_out->spec = &chip->spec->dma_out[out];
+ dma_out->buf = buf;
+
+ return 0;
+}
+
+void hsc_dma_out_set_src_ts_in(struct hsc_dma_out *dma_out,
+ enum HSC_TS_IN ts_in)
+{
+ struct regmap *r = dma_out->chip->regmap;
+ const struct hsc_spec_dma *spec = dma_out->spec;
+ u32 m, v;
+
+ m = CDMBC_CHTDCTRLH_STREM_MASK |
+ CDMBC_CHTDCTRLH_ALL_EN;
+ v = FIELD_PREP(CDMBC_CHTDCTRLH_STREM_MASK, ts_in) |
+ CDMBC_CHTDCTRLH_ALL_EN;
+ regmap_update_bits(r, CDMBC_CHTDCTRLH(spec->dma_ch), m, v);
+}
+
+void hsc_dma_out_start(struct hsc_dma_out *dma_out, bool en)
+{
+ struct hsc_chip *chip = dma_out->chip;
+ const struct hsc_spec_dma *spec = dma_out->spec;
+ struct hsc_dma_buf *buf = dma_out->buf;
+ struct regmap *r = chip->regmap;
+ u64 bg, ed;
+ u32 v;
+
+ bg = buf->phys;
+ ed = buf->phys + buf->size;
+ dma_set_buffer(chip, spec->dma_ch, bg, ed);
+
+ buf->rd_offs = 0;
+ buf->wr_offs = 0;
+ buf->chk_offs = buf->size_chk;
+ dma_set_rp(chip, spec->dma_ch, buf->rd_offs + buf->phys);
+ dma_set_wp(chip, spec->dma_ch, buf->wr_offs + buf->phys);
+ dma_set_chkp(chip, spec->dma_ch, buf->chk_offs + buf->phys);
+
+ regmap_update_bits(r, CDMBC_CHDSTAMODE(spec->dma_ch),
+ CDMBC_CHAMODE_TYPE_RB, ~0);
+ regmap_update_bits(r, CDMBC_CHCTRL1(spec->dma_ch),
+ CDMBC_CHCTRL1_IND_SIZE_UND, ~0);
+
+ v = (en) ? ~0 : 0;
+ regmap_update_bits(r, CDMBC_CHIE(spec->dma_ch), CDMBC_CHI_TRANSIT, v);
+ regmap_update_bits(r, spec->intr.reg, BIT(spec->intr.sft_intr), v);
+
+ dma_set_enable(chip, spec->dma_ch, &spec->en, en);
+}
+
+void hsc_dma_out_sync(struct hsc_dma_out *dma_out)
+{
+ struct hsc_chip *chip = dma_out->chip;
+ const struct hsc_spec_dma *spec = dma_out->spec;
+ struct hsc_dma_buf *buf = dma_out->buf;
+
+ dma_set_rp(chip, spec->dma_ch, buf->rd_offs + buf->phys);
+ buf->wr_offs = dma_get_wp(chip, spec->dma_ch) - buf->phys;
+ dma_set_chkp(chip, spec->dma_ch, buf->chk_offs + buf->phys);
+}
+
+int hsc_dma_out_get_intr(struct hsc_dma_out *dma_out, u32 *stat)
+{
+ struct regmap *r = dma_out->chip->regmap;
+
+ if (!stat)
+ return -EINVAL;
+
+ regmap_read(r, CDMBC_CHID(dma_out->spec->dma_ch), stat);
+
+ return 0;
+}
+
+void hsc_dma_out_clear_intr(struct hsc_dma_out *dma_out, u32 clear)
+{
+ struct regmap *r = dma_out->chip->regmap;
+
+ regmap_write(r, CDMBC_CHIR(dma_out->spec->dma_ch), clear);
+}
diff --git a/drivers/media/platform/uniphier/hsc-ts.c b/drivers/media/platform/uniphier/hsc-ts.c
new file mode 100644
index 000000000000..4539c3280021
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-ts.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+// MPEG2-TS input/output port setting.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+#define PARAMA_OFFSET_TS 0x02
+#define PARAMA_LOOPADDR_TS 0x31
+#define PARAMA_COUNT_TS 0xc4
+
+static bool ts_in_is_valid(struct hsc_chip *chip, enum HSC_TS_IN in)
+{
+ if (in >= chip->spec->num_ts_in || !chip->spec->ts_in[in].intr.valid)
+ return false;
+
+ return true;
+}
+
+static const struct hsc_spec_ts *ts_in_get_spec(struct hsc_chip *chip,
+ enum HSC_TS_IN in)
+{
+ const struct hsc_spec_ts *spec = chip->spec->ts_in;
+
+ if (!ts_in_is_valid(chip, in))
+ return NULL;
+
+ return &spec[in];
+}
+
+int hsc_ts_in_set_enable(struct hsc_chip *chip, enum HSC_TS_IN in, bool en)
+{
+ struct regmap *r = chip->regmap;
+ const struct hsc_spec_ts *speci = ts_in_get_spec(chip, in);
+ u32 m, v;
+
+ if (!speci)
+ return -EINVAL;
+
+ m = TSI_SYNCCNTROL_FRAME_MASK;
+ v = TSI_SYNCCNTROL_FRAME_EXTSYNC2;
+ regmap_update_bits(r, TSI_SYNCCNTROL(in), m, v);
+
+ m = TSI_CONFIG_ATSMD_MASK | TSI_CONFIG_STCMD_MASK |
+ TSI_CONFIG_CHEN_START;
+ v = TSI_CONFIG_ATSMD_DPLL | TSI_CONFIG_STCMD_DPLL;
+ if (en)
+ v |= TSI_CONFIG_CHEN_START;
+ regmap_update_bits(r, TSI_CONFIG(in), m, v);
+
+ v = (en) ? ~0 : 0;
+ regmap_update_bits(r, TSI_INTREN(in),
+ TSI_INTR_SERR | TSI_INTR_LOST, v);
+ regmap_update_bits(r, speci->intr.reg, BIT(speci->intr.sft_intr), v);
+
+ return 0;
+}
+
+int hsc_ts_in_set_dmaparam(struct hsc_chip *chip, enum HSC_TS_IN in,
+ enum HSC_TSIF_FMT ifmt)
+{
+ struct regmap *r = chip->regmap;
+ u32 v, ats, offset, loop, cnt;
+
+ if (!ts_in_is_valid(chip, in))
+ return -EINVAL;
+
+ switch (ifmt) {
+ case HSC_TSIF_MPEG2_TS:
+ ats = 0;
+ offset = PARAMA_OFFSET_TS;
+ loop = PARAMA_LOOPADDR_TS;
+ cnt = PARAMA_COUNT_TS;
+ break;
+ case HSC_TSIF_MPEG2_TS_ATS:
+ ats = TSI_CONFIG_ATSADD_ON;
+ offset = PARAMA_OFFSET_TS;
+ loop = PARAMA_LOOPADDR_TS;
+ cnt = PARAMA_COUNT_TS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_update_bits(r, TSI_CONFIG(in), TSI_CONFIG_ATSADD_ON, ats);
+
+ v = FIELD_PREP(SBC_DMAPARAMA_OFFSET_MASK, offset) |
+ FIELD_PREP(SBC_DMAPARAMA_LOOPADDR_MASK, loop) |
+ FIELD_PREP(SBC_DMAPARAMA_COUNT_MASK, cnt);
+ regmap_write(r, SBC_DMAPARAMA(in), v);
+
+ return 0;
+}
diff --git a/drivers/media/platform/uniphier/hsc-ucode.c b/drivers/media/platform/uniphier/hsc-ucode.c
new file mode 100644
index 000000000000..bad1d70b0968
--- /dev/null
+++ b/drivers/media/platform/uniphier/hsc-ucode.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+// Core init and uCode loader.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/bitfield.h>
+#include <linux/firmware.h>
+#include <linux/kernel.h>
+
+#include "hsc.h"
+#include "hsc-reg.h"
+
+struct hsc_cip_file_dma_param {
+ u32 cip_file_ch;
+ dma_addr_t cip_r_sdram;
+ dma_addr_t cip_w_sdram;
+ size_t inter_size;
+ size_t total_size;
+ u8 key_id1;
+ u8 key_id0;
+ u8 endian;
+ int id1_en;
+ int push;
+};
+
+static void core_start(struct hsc_chip *chip)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, IOB_RESET0, ~0);
+ regmap_write(r, IOB_RESET1, ~0);
+
+ regmap_write(r, IOB_CLKSTOP, 0);
+ /* Deassert all internal resets, but AP core is later for uCode */
+ regmap_write(r, IOB_RESET0, IOB_RESET0_APCORE);
+ regmap_write(r, IOB_RESET1, 0);
+
+ /* Halt SPU for uCode */
+ regmap_write(r, IOB_DEBUG, IOB_DEBUG_SPUHALT);
+}
+
+static void core_stop(struct hsc_chip *chip)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, IOB_RESET0, 0);
+ regmap_write(r, IOB_RESET1, 0);
+
+ regmap_write(r, IOB_CLKSTOP, ~0);
+}
+
+static void core_clear_ram(struct hsc_chip *chip)
+{
+ struct regmap *r = chip->regmap;
+ const struct hsc_spec_init_ram *rams = chip->spec->init_rams;
+ size_t i, s;
+
+ for (i = 0; i < chip->spec->num_init_rams; i++)
+ for (s = 0; s < rams[i].size; s += 4)
+ regmap_write(r, rams[i].addr + s, rams[i].pattern);
+}
+
+static void core_start_spu(struct hsc_chip *chip)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, IOB_DEBUG, 0);
+}
+
+static void core_start_ap(struct hsc_chip *chip)
+{
+ struct regmap *r = chip->regmap;
+
+ regmap_write(r, IOB_RESET0, 0);
+}
+
+static int ucode_set_data_addr(struct hsc_chip *chip, int mode)
+{
+ struct regmap *r = chip->regmap;
+ dma_addr_t addr;
+
+ switch (mode) {
+ case HSC_UCODE_SPU_0:
+ case HSC_UCODE_SPU_1:
+ addr = chip->ucode_spu.phys_data;
+ regmap_write(r, UCODE_DLADDR0, addr);
+ regmap_write(r, UCODE_DLADDR1, addr >> 32);
+ break;
+ case HSC_UCODE_ACE:
+ addr = chip->ucode_am.phys_data;
+ regmap_write(r, CIP_UCODEADDR_AM0, addr);
+ regmap_write(r, CIP_UCODEADDR_AM1, addr >> 32);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void file_channel_dma_set(struct hsc_chip *chip,
+ struct hsc_cip_file_dma_param *p)
+{
+ struct regmap *r = chip->regmap;
+ u32 cipr_rsc_no;
+ u32 cipw_rsc_no;
+ dma_addr_t cipr_sdram_start;
+ dma_addr_t cipw_sdram_start;
+ dma_addr_t cipr_sdram_end;
+ dma_addr_t cipw_sdram_end;
+ u32 v;
+
+ cipr_rsc_no = HSC_CIP_FILE_TO_CIPR_DMCH(p->cip_file_ch);
+ cipw_rsc_no = HSC_CIP_FILE_TO_CIPW_DMCH(p->cip_file_ch);
+ cipr_sdram_start = p->cip_r_sdram;
+ cipw_sdram_start = p->cip_w_sdram;
+ cipr_sdram_end = p->cip_r_sdram + p->total_size;
+ cipw_sdram_end = p->cip_w_sdram + p->total_size;
+
+ /* For CIP Read */
+ v = FIELD_PREP(CDMBC_CHCTRL1_LINKCH1_MASK, 1) |
+ FIELD_PREP(CDMBC_CHCTRL1_STATSEL_MASK, 4) |
+ CDMBC_CHCTRL1_TYPE_INTERMIT;
+ regmap_write(r, CDMBC_CHCTRL1(cipr_rsc_no), v);
+
+ regmap_write(r, CDMBC_CHCAUSECTRL(cipr_rsc_no), 0);
+
+ v = FIELD_PREP(CDMBC_CHAMODE_ENDIAN_MASK, p->endian) |
+ FIELD_PREP(CDMBC_CHAMODE_AUPDT_MASK, 0) |
+ CDMBC_CHAMODE_TYPE_RB;
+ regmap_write(r, CDMBC_CHSRCAMODE(cipr_rsc_no), v);
+
+ v = FIELD_PREP(CDMBC_CHAMODE_ENDIAN_MASK, 1) |
+ FIELD_PREP(CDMBC_CHAMODE_AUPDT_MASK, 2);
+ regmap_write(r, CDMBC_CHDSTAMODE(cipr_rsc_no), v);
+
+ v = FIELD_PREP(CDMBC_CHDSTSTRTADRS_TID_MASK, 0xc) |
+ FIELD_PREP(CDMBC_CHDSTSTRTADRS_ID1_EN_MASK, p->id1_en) |
+ FIELD_PREP(CDMBC_CHDSTSTRTADRS_KEY_ID1_MASK, p->key_id1) |
+ FIELD_PREP(CDMBC_CHDSTSTRTADRS_KEY_ID0_MASK, p->key_id0);
+ regmap_write(r, CDMBC_CHDSTSTRTADRSD(cipr_rsc_no), v);
+
+ regmap_write(r, CDMBC_CHSIZE(cipr_rsc_no), p->inter_size);
+
+ /* For CIP Write */
+ v = FIELD_PREP(CDMBC_CHCTRL1_LINKCH1_MASK, 5) |
+ FIELD_PREP(CDMBC_CHCTRL1_STATSEL_MASK, 4) |
+ CDMBC_CHCTRL1_TYPE_INTERMIT |
+ CDMBC_CHCTRL1_IND_SIZE_UND;
+ regmap_write(r, CDMBC_CHCTRL1(cipw_rsc_no), v);
+
+ v = FIELD_PREP(CDMBC_CHAMODE_ENDIAN_MASK, 1) |
+ FIELD_PREP(CDMBC_CHAMODE_AUPDT_MASK, 2);
+ regmap_write(r, CDMBC_CHSRCAMODE(cipw_rsc_no), v);
+
+ v = FIELD_PREP(CDMBC_CHAMODE_ENDIAN_MASK, p->endian) |
+ FIELD_PREP(CDMBC_CHAMODE_AUPDT_MASK, 0) |
+ CDMBC_CHAMODE_TYPE_RB;
+ regmap_write(r, CDMBC_CHDSTAMODE(cipw_rsc_no), v);
+
+ /* Transferring size */
+ regmap_write(r, CDMBC_ITSTEPS(cipr_rsc_no), p->total_size);
+
+ /* For ring buffer */
+ regmap_write(r, CDMBC_RBBGNADRSD(cipr_rsc_no), cipr_sdram_start);
+ regmap_write(r, CDMBC_RBENDADRSD(cipr_rsc_no), cipr_sdram_end);
+ regmap_write(r, CDMBC_RBRDPTRD(cipr_rsc_no), cipr_sdram_start);
+ regmap_write(r, CDMBC_RBWRPTRD(cipr_rsc_no), cipr_sdram_end);
+
+ regmap_write(r, CDMBC_RBBGNADRSU(cipr_rsc_no), cipr_sdram_start >> 32);
+ regmap_write(r, CDMBC_RBENDADRSU(cipr_rsc_no), cipr_sdram_end >> 32);
+ regmap_write(r, CDMBC_RBRDPTRU(cipr_rsc_no), cipr_sdram_start >> 32);
+ regmap_write(r, CDMBC_RBWRPTRU(cipr_rsc_no), cipr_sdram_end >> 32);
+
+ regmap_write(r, CDMBC_RBBGNADRSD(cipw_rsc_no), cipw_sdram_start);
+ regmap_write(r, CDMBC_RBENDADRSD(cipw_rsc_no), cipw_sdram_end);
+ regmap_write(r, CDMBC_RBRDPTRD(cipw_rsc_no), cipw_sdram_end);
+ regmap_write(r, CDMBC_RBWRPTRD(cipw_rsc_no), cipw_sdram_start);
+
+ regmap_write(r, CDMBC_RBBGNADRSU(cipw_rsc_no), cipw_sdram_start >> 32);
+ regmap_write(r, CDMBC_RBENDADRSU(cipw_rsc_no), cipw_sdram_end >> 32);
+ regmap_write(r, CDMBC_RBRDPTRU(cipw_rsc_no), cipw_sdram_end >> 32);
+ regmap_write(r, CDMBC_RBWRPTRU(cipw_rsc_no), cipw_sdram_start >> 32);
+
+ /* Transfer settings */
+ regmap_write(r, CDMBC_CIPMODE(p->cip_file_ch),
+ (p->push) ? CDMBC_CIPMODE_PUSH : 0);
+
+ regmap_write(r, CDMBC_CIPPRIORITY(p->cip_file_ch),
+ FIELD_PREP(CDMBC_CIPPRIORITY_PRIOR_MASK, 3));
+}
+
+static void file_channel_start(struct hsc_chip *chip, int cip_file_ch,
+ bool push, bool mmu_en)
+{
+ struct regmap *r = chip->regmap;
+ int cipr_rsc_no, cipw_rsc_no;
+ int cipr_tdbp_no, cipw_tdbp_no;
+ u32 v = 0;
+
+ cipr_rsc_no = HSC_CIP_FILE_TO_CIPR_DMCH(cip_file_ch);
+ cipw_rsc_no = HSC_CIP_FILE_TO_CIPW_DMCH(cip_file_ch);
+ cipr_tdbp_no = HSC_CIP_FILE_TO_CIPR(cip_file_ch);
+ cipw_tdbp_no = HSC_CIP_FILE_TO_CIPW(cip_file_ch);
+
+ regmap_write(r, CDMBC_CIPMODE(cip_file_ch),
+ (push) ? CDMBC_CIPMODE_PUSH : 0);
+
+ if (mmu_en) {
+ v = CDMBC_CHDDR_REG_LOAD_ON | CDMBC_CHDDR_AT_CHEN_ON;
+
+ /* Enable IOMMU for CIP-R and CIP-W */
+ regmap_write(r, CDMBC_CHDDR(cipr_rsc_no),
+ v | CDMBC_CHDDR_SET_MCB_RD);
+ regmap_write(r, CDMBC_CHDDR(cipw_rsc_no),
+ v | CDMBC_CHDDR_SET_MCB_WR);
+ }
+
+ v = 0x01000000 | (1 << cipr_tdbp_no) | (1 << cipw_tdbp_no);
+ regmap_write(r, CDMBC_STRT(1), v);
+}
+
+static int ucode_load_dma(struct hsc_chip *chip, int mode)
+{
+ struct regmap *r = chip->regmap;
+ struct hsc_ucode_buf *ucode;
+ struct hsc_cip_file_dma_param dma_p = {0};
+ u32 cip_f_ctrl, v;
+
+ switch (mode) {
+ case HSC_UCODE_SPU_0:
+ case HSC_UCODE_SPU_1:
+ ucode = &chip->ucode_spu;
+ cip_f_ctrl = 0x2f090001;
+ break;
+ case HSC_UCODE_ACE:
+ ucode = &chip->ucode_am;
+ cip_f_ctrl = 0x3f090001;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap_write(r, CIP_F_CTRL, cip_f_ctrl);
+
+ regmap_write(r, IOB_INTREN(HSC_INTR_IOB_2),
+ INTR2_CIP_AUTH_S |
+ INTR2_MBC_CIP_R(0) | INTR2_MBC_CIP_W(0));
+
+ dma_p.cip_file_ch = HSC_CIP_FILE_NO_0;
+ dma_p.cip_r_sdram = ucode->phys_code;
+ dma_p.cip_w_sdram = 0;
+ dma_p.inter_size = ucode->size_code;
+ dma_p.total_size = ucode->size_code;
+ dma_p.key_id1 = 0;
+ dma_p.key_id0 = 0;
+ dma_p.endian = 1;
+ dma_p.id1_en = 0;
+ file_channel_dma_set(chip, &dma_p);
+ file_channel_start(chip, HSC_CIP_FILE_NO_0, true, false);
+
+ do {
+ regmap_read(r, CDMBC_CHIR(HSC_MBC_DMCH_CIP0_R), &v);
+ msleep(20);
+ } while (!(v & INTR_MBC_CH_WDONE));
+ regmap_write(r, CDMBC_CHIR(HSC_MBC_DMCH_CIP0_R), v);
+
+ do {
+ regmap_read(r, CDMBC_CHIR(HSC_MBC_DMCH_CIP0_W), &v);
+ msleep(20);
+ } while (!(v & INTR_MBC_CH_WDONE));
+ regmap_write(r, CDMBC_CHIR(HSC_MBC_DMCH_CIP0_W), v);
+
+ regmap_read(r, CDMBC_RBIR(HSC_MBC_DMCH_CIP0_R), &v);
+ regmap_write(r, CDMBC_RBIR(HSC_MBC_DMCH_CIP0_R), v);
+
+ regmap_read(r, CDMBC_RBIR(HSC_MBC_DMCH_CIP0_W), &v);
+ regmap_write(r, CDMBC_RBIR(HSC_MBC_DMCH_CIP0_W), v);
+
+ /* Clear & disable interrupt */
+ regmap_read(r, IOB_INTRST(HSC_INTR_IOB_2), &v);
+ regmap_write(r, IOB_INTRST(HSC_INTR_IOB_2), v);
+
+ regmap_write(r, IOB_INTREN(HSC_INTR_IOB_2), 0);
+
+ return 0;
+}
+
+static int ucode_load(struct hsc_chip *chip, int mode)
+{
+ struct device *dev = &chip->pdev->dev;
+ const struct hsc_spec_ucode *spec;
+ struct hsc_ucode_buf *ucode;
+ const struct firmware *firm_code, *firm_data;
+ int ret;
+
+ switch (mode) {
+ case HSC_UCODE_SPU_0:
+ case HSC_UCODE_SPU_1:
+ spec = &chip->spec->ucode_spu;
+ ucode = &chip->ucode_spu;
+ break;
+ case HSC_UCODE_ACE:
+ spec = &chip->spec->ucode_ace;
+ ucode = &chip->ucode_am;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = request_firmware(&firm_code, spec->name_code, dev);
+ if (ret) {
+ dev_err(dev, "Failed to load firmware '%s'.\n",
+ spec->name_code);
+ return ret;
+ }
+
+ ret = request_firmware(&firm_data, spec->name_data, dev);
+ if (ret) {
+ dev_err(dev, "Failed to load firmware '%s'.\n",
+ spec->name_data);
+ goto err_firm_code;
+ }
+
+ ucode->buf_code = dma_alloc_coherent(dev, firm_code->size,
+ &ucode->phys_code, GFP_KERNEL);
+ if (!ucode->buf_code) {
+ ret = -ENOMEM;
+ goto err_firm_data;
+ }
+ ucode->size_code = firm_code->size;
+
+ ucode->buf_data = dma_alloc_coherent(dev, firm_data->size,
+ &ucode->phys_data, GFP_KERNEL);
+ if (!ucode->buf_data) {
+ ret = -ENOMEM;
+ goto err_buf_code;
+ }
+ ucode->size_data = firm_data->size;
+
+ memcpy(ucode->buf_code, firm_code->data, firm_code->size);
+ memcpy(ucode->buf_data, firm_data->data, firm_data->size);
+
+ ret = ucode_set_data_addr(chip, mode);
+ if (ret)
+ goto err_buf_data;
+
+ ret = ucode_load_dma(chip, mode);
+ if (ret)
+ goto err_buf_data;
+
+ release_firmware(firm_data);
+ release_firmware(firm_code);
+
+ return 0;
+
+err_buf_data:
+ dma_free_coherent(dev, ucode->size_data, ucode->buf_data,
+ ucode->phys_data);
+
+err_buf_code:
+ dma_free_coherent(dev, ucode->size_code, ucode->buf_code,
+ ucode->phys_code);
+
+err_firm_data:
+ release_firmware(firm_data);
+
+err_firm_code:
+ release_firmware(firm_code);
+
+ return ret;
+}
+
+static int ucode_unload(struct hsc_chip *chip, int mode)
+{
+ struct device *dev = &chip->pdev->dev;
+ struct hsc_ucode_buf *ucode;
+
+ switch (mode) {
+ case HSC_UCODE_SPU_0:
+ case HSC_UCODE_SPU_1:
+ ucode = &chip->ucode_spu;
+ break;
+ case HSC_UCODE_ACE:
+ ucode = &chip->ucode_am;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dma_free_coherent(dev, ucode->size_data, ucode->buf_data,
+ ucode->phys_data);
+ dma_free_coherent(dev, ucode->size_code, ucode->buf_code,
+ ucode->phys_code);
+
+ return 0;
+}
+
+int hsc_ucode_load_all(struct hsc_chip *chip)
+{
+ int ret;
+
+ core_start(chip);
+ core_clear_ram(chip);
+
+ ret = ucode_load(chip, HSC_UCODE_SPU_0);
+ if (ret)
+ return ret;
+ core_start_spu(chip);
+
+ ret = ucode_load(chip, HSC_UCODE_ACE);
+ if (ret)
+ return ret;
+ core_start_ap(chip);
+
+ return 0;
+}
+
+int hsc_ucode_unload_all(struct hsc_chip *chip)
+{
+ int ret;
+
+ core_stop(chip);
+
+ ret = ucode_unload(chip, HSC_UCODE_SPU_0);
+ if (ret)
+ return ret;
+
+ ret = ucode_unload(chip, HSC_UCODE_ACE);
+ if (ret)
+ return ret;
+
+ return 0;
+}
--
2.17.0


2018-05-30 09:14:38

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers

This patch adds common module for UniPhier DVB adapter drivers
that equipments tuners and demod that connected by I2C and
UniPhier demux.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Makefile | 5 ++
drivers/media/platform/uniphier/hsc-core.c | 8 ---
.../platform/uniphier/uniphier-adapter.c | 54 +++++++++++++++++++
.../platform/uniphier/uniphier-adapter.h | 42 +++++++++++++++
4 files changed, 101 insertions(+), 8 deletions(-)
create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h

diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index 0622f04d9e68..9e75ad081b77 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -3,3 +3,8 @@ uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o

obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
+
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
+
+uniphier-dvb-y += uniphier-adapter.o
diff --git a/drivers/media/platform/uniphier/hsc-core.c b/drivers/media/platform/uniphier/hsc-core.c
index cdb488e4df8c..a8d247cfd302 100644
--- a/drivers/media/platform/uniphier/hsc-core.c
+++ b/drivers/media/platform/uniphier/hsc-core.c
@@ -256,14 +256,6 @@ static void hsc_dmaif_feed_worker(struct work_struct *work)
dma_sync_single_for_cpu(dev, dmapos, cnt, DMA_FROM_DEVICE);
for (i = 0; i < cnt; i += SZ_M2TS_PKT) {
pkt = buf->virt + buf->rd_offs + i;
-
- if (pkt[4] == 0x47 && pkt[5] == 0x1f && pkt[6] == 0xff)
- continue;
- if (pkt[5] & 0x80)
- continue;
- if (pkt[7] & 0xc0)
- continue;
-
dvb_dmx_swfilter_packets(&tsif->demux, &pkt[4], 1);
}
dma_sync_single_for_device(dev, dmapos, cnt, DMA_FROM_DEVICE);
diff --git a/drivers/media/platform/uniphier/uniphier-adapter.c b/drivers/media/platform/uniphier/uniphier-adapter.c
new file mode 100644
index 000000000000..c895bbd9988e
--- /dev/null
+++ b/drivers/media/platform/uniphier/uniphier-adapter.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier LD20 adapter driver for ISDB.
+// Using Socionext MN884434 ISDB-S/ISDB-T demodulator and
+// SONY HELENE tuner.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include "hsc.h"
+#include "uniphier-adapter.h"
+
+int uniphier_adapter_demux_probe(struct uniphier_adapter_priv *priv)
+{
+ const struct uniphier_adapter_spec *spec = priv->spec;
+ struct device *dev = &priv->pdev->dev;
+ struct device_node *node;
+ int ret, i;
+
+ node = of_parse_phandle(dev->of_node, "demux", 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse demux\n");
+ return -ENODEV;
+ }
+
+ priv->pdev_demux = of_find_device_by_node(node);
+ if (!priv->pdev_demux) {
+ dev_err(dev, "Failed to find demux device\n");
+ of_node_put(node);
+ return -ENODEV;
+ }
+ of_node_put(node);
+
+ priv->chip = platform_get_drvdata(priv->pdev_demux);
+
+ for (i = 0; i < spec->adapters; i++) {
+ ret = hsc_tsif_init(&priv->chip->tsif[i], &spec->hsc_conf[i]);
+ if (ret) {
+ dev_err(dev, "Failed to init TS I/F\n");
+ return ret;
+ }
+
+ ret = hsc_dmaif_init(&priv->chip->dmaif[i], &spec->hsc_conf[i]);
+ if (ret) {
+ dev_err(dev, "Failed to init DMA I/F\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/media/platform/uniphier/uniphier-adapter.h b/drivers/media/platform/uniphier/uniphier-adapter.h
new file mode 100644
index 000000000000..1faada3fd378
--- /dev/null
+++ b/drivers/media/platform/uniphier/uniphier-adapter.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
+ *
+ * Copyright (c) 2018 Socionext Inc.
+ */
+
+#ifndef DVB_UNIPHIER_ADAPTER_H__
+#define DVB_UNIPHIER_ADAPTER_H__
+
+struct uniphier_adapter_spec {
+ int adapters;
+ const struct hsc_conf *hsc_conf;
+ const struct i2c_board_info *demod_i2c_info;
+ const struct i2c_board_info *tuner_i2c_info;
+};
+
+struct uniphier_adapter_fe {
+ struct i2c_client *demod_i2c;
+ struct i2c_client *tuner_i2c;
+ struct dvb_frontend *fe;
+};
+
+struct uniphier_adapter_priv {
+ const struct uniphier_adapter_spec *spec;
+
+ struct platform_device *pdev;
+ struct hsc_chip *chip;
+
+ struct platform_device *pdev_demux;
+ struct clk *demod_mclk;
+ struct gpio_desc *demod_gpio;
+ struct i2c_adapter *demod_i2c_adapter;
+ struct gpio_desc *tuner_gpio;
+ struct i2c_adapter *tuner_i2c_adapter;
+
+ struct uniphier_adapter_fe *fe;
+};
+
+int uniphier_adapter_demux_probe(struct uniphier_adapter_priv *priv);
+
+#endif /* DVB_UNIPHIER_ADAPTER_H__ */
--
2.17.0


2018-05-30 09:15:14

by Katsuhiro Suzuki

[permalink] [raw]
Subject: [PATCH 7/8] media: uniphier: add LD11 adapter driver for ISDB

This patch adds UniPhier LD11 DVB adapter driver for ISDB-S/T
that equipments SONY SUT-PJ series using CXD2858 tuner and Socionext
MN884433 demodulator.

Signed-off-by: Katsuhiro Suzuki <[email protected]>
---
drivers/media/platform/uniphier/Kconfig | 10 +
drivers/media/platform/uniphier/Makefile | 1 +
.../platform/uniphier/ld11-mn884433-helene.c | 265 ++++++++++++++++++
3 files changed, 276 insertions(+)
create mode 100644 drivers/media/platform/uniphier/ld11-mn884433-helene.c

diff --git a/drivers/media/platform/uniphier/Kconfig b/drivers/media/platform/uniphier/Kconfig
index 8f3a662a391c..0fc9bbfc170b 100644
--- a/drivers/media/platform/uniphier/Kconfig
+++ b/drivers/media/platform/uniphier/Kconfig
@@ -15,3 +15,13 @@ config DVB_UNIPHIER_LD11
Driver for the HSC (High speed Stream Controller) for
UniPhier LD11/LD20.
Say Y when you want to support this hardware.
+
+config DVB_UNIPHIER_LD11_ISDB
+ bool "Support UniPhier LD11 ISDB adapters"
+ depends on DVB_UNIPHIER
+ help
+ Driver for LD11 ISDB-S/T adapters which use
+ Demux: Socionext LD11 HSC
+ Demod: Socionext MN884433
+ Tuner: SONY HELENE (CXD2858ER)
+ Say Y when you want to support this adapters.
diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
index 9e75ad081b77..e4b06f8a37b5 100644
--- a/drivers/media/platform/uniphier/Makefile
+++ b/drivers/media/platform/uniphier/Makefile
@@ -8,3 +8,4 @@ ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/

uniphier-dvb-y += uniphier-adapter.o
+uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11_ISDB) += ld11-mn884433-helene.o
diff --git a/drivers/media/platform/uniphier/ld11-mn884433-helene.c b/drivers/media/platform/uniphier/ld11-mn884433-helene.c
new file mode 100644
index 000000000000..f4f48b6a0211
--- /dev/null
+++ b/drivers/media/platform/uniphier/ld11-mn884433-helene.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier LD11 adapter driver for ISDB.
+// Using Socionext MN884433 ISDB-S/ISDB-T demodulator and
+// SONY HELENE tuner.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+
+#include "sc1501a.h"
+#include "cxd2858.h"
+#include "helene.h"
+#include "hsc.h"
+#include "uniphier-adapter.h"
+
+static struct sc1501a_config mn884433_conf[] = {
+ { .if_freq = LOW_IF_4MHZ, },
+};
+
+static int uniphier_adapter_demod_probe(struct uniphier_adapter_priv *priv)
+{
+ const struct uniphier_adapter_spec *spec = priv->spec;
+ struct device *dev = &priv->pdev->dev;
+ struct device_node *node;
+ int ret, i;
+
+ priv->demod_mclk = devm_clk_get(dev, "demod-mclk");
+ if (IS_ERR(priv->demod_mclk)) {
+ dev_err(dev, "Failed to request demod-mclk: %ld\n",
+ PTR_ERR(priv->demod_mclk));
+ return PTR_ERR(priv->demod_mclk);
+ }
+
+ priv->demod_gpio = devm_gpiod_get_optional(dev, "reset-demod",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->demod_gpio)) {
+ dev_err(dev, "Failed to request demod_gpio: %ld\n",
+ PTR_ERR(priv->demod_gpio));
+ return PTR_ERR(priv->demod_gpio);
+ }
+
+ node = of_parse_phandle(dev->of_node, "demod-i2c-bus", 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse demod-i2c-bus\n");
+ return -ENODEV;
+ }
+
+ priv->demod_i2c_adapter = of_find_i2c_adapter_by_node(node);
+ if (!priv->demod_i2c_adapter) {
+ dev_err(dev, "Failed to find demod i2c adapter\n");
+ of_node_put(node);
+ return -ENODEV;
+ }
+ of_node_put(node);
+
+ mn884433_conf[0].reset_gpio = priv->demod_gpio;
+ for (i = 0; i < spec->adapters; i++) {
+ struct i2c_client *c;
+
+ mn884433_conf[i].mclk = priv->demod_mclk;
+ mn884433_conf[i].fe = &priv->fe[i].fe;
+
+ c = dvb_module_probe(spec->demod_i2c_info[i].type, NULL,
+ priv->demod_i2c_adapter,
+ spec->demod_i2c_info[i].addr,
+ &mn884433_conf[i]);
+ if (!c) {
+ dev_err(dev, "Failed to probe demod\n");
+ ret = -ENODEV;
+ goto err_out;
+ }
+ priv->fe[i].demod_i2c = c;
+ }
+
+ return 0;
+
+err_out:
+ for (i = 0; i < spec->adapters; i++)
+ dvb_module_release(priv->fe[i].demod_i2c);
+
+ return ret;
+}
+
+static struct helene_config helene_conf[] = {
+ { .xtal = SONY_HELENE_XTAL_16000, },
+ { .xtal = SONY_HELENE_XTAL_16000, },
+};
+
+static int uniphier_adapter_tuner_probe(struct uniphier_adapter_priv *priv)
+{
+ const struct uniphier_adapter_spec *spec = priv->spec;
+ struct device *dev = &priv->pdev->dev;
+ struct device_node *node;
+ int ret, i;
+
+ priv->tuner_gpio = devm_gpiod_get_optional(dev, "reset-tuner",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->tuner_gpio)) {
+ dev_err(dev, "Failed to request tuner_gpio: %ld\n",
+ PTR_ERR(priv->tuner_gpio));
+ return PTR_ERR(priv->tuner_gpio);
+ }
+ gpiod_set_value_cansleep(priv->tuner_gpio, 0);
+
+ node = of_parse_phandle(dev->of_node, "tuner-i2c-bus", 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse tuner-i2c-bus\n");
+ return -ENODEV;
+ }
+
+ priv->tuner_i2c_adapter = of_find_i2c_adapter_by_node(node);
+ if (!priv->tuner_i2c_adapter) {
+ dev_err(dev, "Failed to find tuner i2c adapter\n");
+ of_node_put(node);
+ return -ENODEV;
+ }
+ of_node_put(node);
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ struct i2c_client *c;
+
+ helene_conf[i].fe = priv->fe[i].fe;
+
+ c = dvb_module_probe(spec->tuner_i2c_info[i].type, NULL,
+ priv->tuner_i2c_adapter,
+ spec->tuner_i2c_info[i].addr,
+ &helene_conf[i]);
+ if (!c) {
+ dev_err(dev, "Failed to probe tuner\n");
+ ret = -ENODEV;
+ goto err_out;
+ }
+ priv->fe[i].tuner_i2c = c;
+ }
+
+ return 0;
+
+err_out:
+ for (i = 0; i < spec->adapters; i++)
+ dvb_module_release(priv->fe[i].tuner_i2c);
+
+ return ret;
+}
+
+static int uniphier_adapter_probe(struct platform_device *pdev)
+{
+ struct uniphier_adapter_priv *priv;
+ struct device *dev = &pdev->dev;
+ int i, ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->pdev = pdev;
+
+ priv->spec = of_device_get_match_data(dev);
+ if (!priv->spec)
+ return -EINVAL;
+
+ priv->fe = devm_kzalloc(dev, sizeof(*priv->fe) * priv->spec->adapters,
+ GFP_KERNEL);
+ if (!priv->fe)
+ return -ENOMEM;
+
+ ret = uniphier_adapter_demux_probe(priv);
+ if (ret)
+ return ret;
+
+ ret = uniphier_adapter_demod_probe(priv);
+ if (ret)
+ return ret;
+
+ ret = uniphier_adapter_tuner_probe(priv);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, priv);
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ priv->chip->tsif[i].fe = priv->fe[i].fe;
+
+ ret = hsc_register_dvb(&priv->chip->tsif[i]);
+ if (ret) {
+ dev_err(dev, "Failed to register adapter\n");
+ goto err_out_if;
+ }
+ }
+
+ return 0;
+
+err_out_if:
+ for (i = 0; i < priv->spec->adapters; i++)
+ hsc_unregister_dvb(&priv->chip->tsif[i]);
+
+ return ret;
+}
+
+static int uniphier_adapter_remove(struct platform_device *pdev)
+{
+ struct uniphier_adapter_priv *priv = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < priv->spec->adapters; i++) {
+ hsc_dmaif_release(&priv->chip->dmaif[i]);
+ hsc_tsif_release(&priv->chip->tsif[i]);
+ hsc_unregister_dvb(&priv->chip->tsif[i]);
+ dvb_module_release(priv->fe[i].tuner_i2c);
+ dvb_module_release(priv->fe[i].demod_i2c);
+ }
+
+ return 0;
+}
+
+static const struct hsc_conf ld11_hsc_conf[] = {
+ {
+ .css_in = HSC_CSS_IN_SRLTS0,
+ .css_out = HSC_CSS_OUT_TSI0,
+ .dpll = HSC_DPLL0,
+ .dma_out = HSC_DMA_OUT0,
+ },
+};
+
+static const struct i2c_board_info mn884433_i2c_info[] = {
+ { .type = "mn884433", .addr = 0x68, },
+};
+
+static const struct i2c_board_info helene_i2c_info[] = {
+ { .type = "helene", .addr = 0x61, },
+};
+
+static const struct uniphier_adapter_spec ld11_mn884433_helene_spec = {
+ .adapters = 1,
+ .hsc_conf = ld11_hsc_conf,
+ .demod_i2c_info = mn884433_i2c_info,
+ .tuner_i2c_info = helene_i2c_info,
+};
+
+static const struct of_device_id uniphier_hsc_adapter_of_match[] = {
+ {
+ .compatible = "socionext,uniphier-ld11-mn884433-helene",
+ .data = &ld11_mn884433_helene_spec,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, uniphier_hsc_adapter_of_match);
+
+static struct platform_driver uniphier_hsc_adapter_driver = {
+ .driver = {
+ .name = "uniphier-ld11-isdb",
+ .of_match_table = of_match_ptr(uniphier_hsc_adapter_of_match),
+ },
+ .probe = uniphier_adapter_probe,
+ .remove = uniphier_adapter_remove,
+};
+module_platform_driver(uniphier_hsc_adapter_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <[email protected]>");
+MODULE_DESCRIPTION("UniPhier LD11 adapter driver for ISDB.");
+MODULE_LICENSE("GPL v2");
--
2.17.0


2018-06-02 08:02:51

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 1/8] media: uniphier: add DT bindings documentation for UniPhier HSC

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds DT binding documentation for UniPhier HSC which is
> MPEG2-TS input/output and demux subsystem.
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> .../bindings/media/uniphier,hsc.txt | 38 +++++++++++++++++++
> 1 file changed, 38 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/uniphier,hsc.txt
>
> diff --git a/Documentation/devicetree/bindings/media/uniphier,hsc.txt b/Documentation/devicetree/bindings/media/uniphier,hsc.txt


This file name is strange.

A comma should be used a separator between a vendor name and a device name.

The "uniphier" is not a vendor name.


socionext,uniphier-hsc.txt

or

uniphier-hsc.txt





> new file mode 100644
> index 000000000000..4242483b2ecc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> @@ -0,0 +1,38 @@
> +Socionext UniPhier HSC (High-speed Stream Controller)
> +
> +The Socionext UniPhier HSC subsystem consists of MPEG2-TS input/output and
> +demultiplexer cores in the same register space.
> +
> +This interface is support TS serial signals (clock, valid, sync, data) from


"is support" -> "supports"


> +external demodulators.
> +
> +Required properties:
> +- compatible : should be one of the following:
> + "socionext,uniphier-ld11-hsc"
> + "socionext,uniphier-ld20-hsc"
> +- reg : offset and length of the register set for the device.
> +- interrupts : should contain DMA and TSI error interrupt.
> +- pinctrl-names : should be "default".
> +- pinctrl-0 : defined TS serial signal pins for external demodulators.
> +- clock-names : should include following entries:
> + "hsc", "stdmac"
> +- clocks : a list of phandle, should contain an entry for each
> + entry in clock-names.
> +- reset-names : should include following entries:
> + "hsc", "stdmac"
> +- resets : a list of phandle, should contain an entry for each
> + entry in reset-names.
> +
> +Example:
> + hsc {
> + compatible = "socionext,uniphier-ld20-hsc";
> + reg = <0x5c000000 0x100000>;
> + interrupts = <0 100 4>, <0 101 4>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_hscin2_s>,
> + <&pinctrl_hscin3_s>;
> + clock-names = "stdmac", "hsc";
> + clocks = <&sys_clk 8>, <&sys_clk 9>;
> + reset-names = "stdmac", "hsc";
> + resets = <&sys_rst 8>, <&sys_rst 9>;
> + };
> --
> 2.17.0
>



--
Best Regards
Masahiro Yamada

2018-06-02 09:52:47

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 1/8] media: uniphier: add DT bindings documentation for UniPhier HSC

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds DT binding documentation for UniPhier HSC which is
> MPEG2-TS input/output and demux subsystem.
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> .../bindings/media/uniphier,hsc.txt | 38 +++++++++++++++++++
> 1 file changed, 38 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/uniphier,hsc.txt
>
> diff --git a/Documentation/devicetree/bindings/media/uniphier,hsc.txt b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> new file mode 100644
> index 000000000000..4242483b2ecc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> @@ -0,0 +1,38 @@
> +Socionext UniPhier HSC (High-speed Stream Controller)
> +
> +The Socionext UniPhier HSC subsystem consists of MPEG2-TS input/output and
> +demultiplexer cores in the same register space.
> +
> +This interface is support TS serial signals (clock, valid, sync, data) from
> +external demodulators.
> +
> +Required properties:
> +- compatible : should be one of the following:
> + "socionext,uniphier-ld11-hsc"
> + "socionext,uniphier-ld20-hsc"
> +- reg : offset and length of the register set for the device.
> +- interrupts : should contain DMA and TSI error interrupt.
> +- pinctrl-names : should be "default".
> +- pinctrl-0 : defined TS serial signal pins for external demodulators.
> +- clock-names : should include following entries:


"the following entries:"



> + "hsc", "stdmac"
> +- clocks : a list of phandle, should contain an entry for each
> + entry in clock-names.
> +- reset-names : should include following entries:


Ditto.



> + "hsc", "stdmac"
> +- resets : a list of phandle, should contain an entry for each
> + entry in reset-names.
> +
> +Example:
> + hsc {
> + compatible = "socionext,uniphier-ld20-hsc";
> + reg = <0x5c000000 0x100000>;
> + interrupts = <0 100 4>, <0 101 4>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_hscin2_s>,
> + <&pinctrl_hscin3_s>;
> + clock-names = "stdmac", "hsc";
> + clocks = <&sys_clk 8>, <&sys_clk 9>;
> + reset-names = "stdmac", "hsc";
> + resets = <&sys_rst 8>, <&sys_rst 9>;
> + };
> --
> 2.17.0
>



--
Best Regards
Masahiro Yamada

2018-06-02 11:58:32

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 2/8] media: uniphier: add headers of HSC MPEG2-TS I/O driver

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds register definitions of HSC (High speed Stream
> Controller) driver for Socionext UniPhier SoCs. The HSC enables to
> input and output MPEG2-TS stream from/to outer world of SoC.
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> drivers/media/platform/Kconfig | 1 +
> drivers/media/platform/Makefile | 2 +
> drivers/media/platform/uniphier/Kconfig | 9 +
> drivers/media/platform/uniphier/Makefile | 1 +
> drivers/media/platform/uniphier/hsc-reg.h | 491 ++++++++++++++++++++++
> drivers/media/platform/uniphier/hsc.h | 480 +++++++++++++++++++++
> 6 files changed, 984 insertions(+)
> create mode 100644 drivers/media/platform/uniphier/Kconfig
> create mode 100644 drivers/media/platform/uniphier/Makefile
> create mode 100644 drivers/media/platform/uniphier/hsc-reg.h
> create mode 100644 drivers/media/platform/uniphier/hsc.h

What's the point of adding an empty Makefile,
and header files in a separate commit?

Anyway, ...


>
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 2728376b04b5..289ab4dfd30e 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -525,6 +525,7 @@ menuconfig DVB_PLATFORM_DRIVERS
>
> if DVB_PLATFORM_DRIVERS
> source "drivers/media/platform/sti/c8sectpfe/Kconfig"
> +source "drivers/media/platform/uniphier/Kconfig"
> endif #DVB_PLATFORM_DRIVERS
>
> menuconfig CEC_PLATFORM_DRIVERS
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 04bc1502a30e..08d5052119ef 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -93,3 +93,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/
> obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
>
> obj-y += meson/
> +
> +obj-$(CONFIG_DVB_UNIPHIER) += uniphier/
> diff --git a/drivers/media/platform/uniphier/Kconfig b/drivers/media/platform/uniphier/Kconfig
> new file mode 100644
> index 000000000000..1b4543ec1e3c
> --- /dev/null
> +++ b/drivers/media/platform/uniphier/Kconfig
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0
> +config DVB_UNIPHIER
> + tristate "Socionext UniPhier Frontend"
> + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
> + depends on ARCH_UNIPHIER


depends on ARCH_UNIPHIER || COMPILE_TEST


Not so sure if regmap is useful here.
Anyway this driver uses regmap_{read,write},
but 'select REGMAP_MMIO' is missing.





> + help
> + Driver for UniPhier frontend for MPEG2-TS input/output,
> + demux and descramble.
> + Say Y when you want to support this frontend.
> diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
> new file mode 100644
> index 000000000000..f66554cd5c45
> --- /dev/null
> +++ b/drivers/media/platform/uniphier/Makefile
> @@ -0,0 +1 @@
> +# SPDX-License-Identifier: GPL-2.0
> diff --git a/drivers/media/platform/uniphier/hsc-reg.h b/drivers/media/platform/uniphier/hsc-reg.h
> new file mode 100644
> index 000000000000..5f0a9b86cf49
> --- /dev/null
> +++ b/drivers/media/platform/uniphier/hsc-reg.h
> @@ -0,0 +1,491 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
> + *
> + * Copyright (c) 2018 Socionext Inc.
> + */
> +
> +#ifndef DVB_UNIPHIER_HSC_REG_H__
> +#define DVB_UNIPHIER_HSC_REG_H__
> +
> +/*
> + * CH_0 : CIP-R8, W9
> + * CH_1 : CIP-R10,W11
> + * CH_2 : CIP-R12,W13
> + * CH_3 : CIP-R14,W15
> + * CH_4 : CIP-R16,W17
> + */
> +enum HSC_CIP_FILE_NO {


Please use lower cases for enum.


> + HSC_CIP_FILE_NO_0 = 0x0,
> + HSC_CIP_FILE_NO_1,
> + HSC_CIP_FILE_NO_2,
> + HSC_CIP_FILE_NO_3,
> + HSC_CIP_FILE_NO_4,
> + HSC_CIP_FILE_NO_END,
> + HSC_CIP_FILE_NO_DISABLE,
> +};

This is OK.

The members of enum should be capitalized.





[ snip ]

> +
> +/* MBC
> + * i: channel number
> + * 1- 3: Record0,1,2
> + * 19-21: Record3,4,5
> + */


Why is this block comment sylte?


Documentation/process/coding-style.rst says
this style is used only files under net/ and drivers/net.




> +#define CDMBC_CHTDCTRLH(i) (((i) < 19) ? \
> + (0x23a4 + ((i) - 1) * 0x20) : \
> + (0x23b4 + ((i) - 19) * 0x20))
> +#define CDMBC_CHTDCTRLH_STREM_MASK GENMASK(20, 16)
> +#define CDMBC_CHTDCTRLH_NOT_FLT BIT(7)
> +#define CDMBC_CHTDCTRLH_ALL_EN BIT(6)
> +#define CDMBC_CHTDCTRLU(i) (((i) < 19) ? \
> + (0x23a8 + ((i) - 1) * 0x20) : \
> + (0x23b8 + ((i) - 19) * 0x20))


Hmm, OK this is macro...



> +#define CDMBC_TDSTAT 0x23f8
> +#define CDMBC_TDIR 0x23fc
> +#define CDMBC_REPRATECTRL 0x2400
> +#define CDMBC_ATRIBUTE0 0x24e8
> +#define CDMBC_ATRIBUTE1 0x24ec
> +#define CDMBC_ATRIBUTE2 0x24f0
> +#define CDMBC_ATRIBUTE3 0x24f4
> +#define CDMBC_ATRIBUTE4 0x24f8
> +#define CDMBC_CIPMODE(i) (0x24fc + (i) * 0x4)
> +#define CDMBC_CIPMODE_PUSH BIT(0)
> +#define CDMBC_CIPPRIORITY(i) (0x2510 + (i) * 0x4)
> +#define CDMBC_CIPPRIORITY_PRIOR_MASK GENMASK(1, 0)
> +#define CDMBC_CH18ATTRIBUTE (0x2524)
> +
> +/* MBC Channel
> + * i: channel number
> + * 0 : Section
> + * 1- 3: Record0,1,2
> + * 4 : Partial
> + * 5- 7: Replay0,1,2
> + * 8-17: Even: CIP-Read
> + * Odd : CIP-Write
> + * 18 : AM32
> + * 19-21: Record3,4,5
> + * 22-24: Replay3,4,5
> + */
> +#define CDMBC_CHCTRL1(i) (0x2540 + (i) * 0x50)
> +#define CDMBC_CHCTRL1_LINKCH1_MASK GENMASK(12, 10)
> +#define CDMBC_CHCTRL1_STATSEL_MASK GENMASK(9, 7)
> +#define CDMBC_CHCTRL1_TYPE_INTERMIT BIT(1)
> +#define CDMBC_CHCTRL1_IND_SIZE_UND BIT(0)
> +#define CDMBC_CHCTRL2(i) (0x2544 + (i) * 0x50)
> +#define CDMBC_CHDDR(i) (0x2548 + (i) * 0x50)
> +#define CDMBC_CHDDR_REG_LOAD_ON BIT(4)
> +#define CDMBC_CHDDR_AT_CHEN_ON BIT(3)
> +#define CDMBC_CHDDR_SET_MCB_MASK GENMASK(2, 1)
> +#define CDMBC_CHDDR_SET_MCB_WR (0x0 << 1)
> +#define CDMBC_CHDDR_SET_MCB_RD (0x3 << 1)
> +#define CDMBC_CHDDR_SET_DDR_1 BIT(0)
> +#define CDMBC_CHCAUSECTRL(i) (0x254c + (i) * 0x50)
> +#define CDMBC_CHCAUSECTRL_MODE_MASK BIT(31)
> +#define CDMBC_CHCAUSECTRL_CSEL2_MASK GENMASK(20, 12)
> +#define CDMBC_CHCAUSECTRL_CSEL1_MASK GENMASK(8, 0)
> +#define CDMBC_CHSTAT(i) (0x2550 + (i) * 0x50)
> +#define CDMBC_CHIR(i) (0x2554 + (i) * 0x50)
> +#define CDMBC_CHIE(i) (0x2558 + (i) * 0x50)
> +#define CDMBC_CHID(i) (0x255c + (i) * 0x50)
> +#define CDMBC_CHI_STOPPED BIT(13)
> +#define CDMBC_CHI_TRANSIT BIT(6)
> +#define CDMBC_CHI_STARTING BIT(1)
> +#define CDMBC_CHSRCAMODE(i) (0x2560 + (i) * 0x50)
> +#define CDMBC_CHDSTAMODE(i) (0x2564 + (i) * 0x50)
> +#define CDMBC_CHAMODE_TUNIT_MASK GENMASK(29, 28)
> +#define CDMBC_CHAMODE_ENDIAN_MASK GENMASK(17, 16)
> +#define CDMBC_CHAMODE_AUPDT_MASK GENMASK(5, 4)
> +#define CDMBC_CHAMODE_TYPE_RB BIT(2)
> +#define CDMBC_CHSRCSTRTADRSD(i) (0x2568 + (i) * 0x50)
> +#define CDMBC_CHSRCSTRTADRSU(i) (0x256c + (i) * 0x50)
> +#define CDMBC_CHDSTSTRTADRSD(i) (0x2570 + (i) * 0x50)
> +#define CDMBC_CHDSTSTRTADRSU(i) (0x2574 + (i) * 0x50)
> +#define CDMBC_CHDSTSTRTADRS_TID_MASK GENMASK(31, 28)
> +#define CDMBC_CHDSTSTRTADRS_ID1_EN_MASK BIT(15)
> +#define CDMBC_CHDSTSTRTADRS_KEY_ID1_MASK GENMASK(12, 8)
> +#define CDMBC_CHDSTSTRTADRS_KEY_ID0_MASK GENMASK(4, 0)
> +#define CDMBC_CHSIZE(i) (0x2578 + (i) * 0x50)
> +#define CDMBC_CHIRADRSD(i) (0x2580 + (i) * 0x50)
> +#define CDMBC_CHIRADRSU(i) (0x2584 + (i) * 0x50)
> +#define CDMBC_CHDST1STUSIZE(i) (0x258C + (i) * 0x50)
> +
> +/* MBC DMA
> + * i: channel number
> + * 5- 7: Replay0,1,2
> + * 8-17: Even: CIP-Read
> + * Odd : CIP-Write
> + * 22-24: Replay3-5
> + */
> +static inline int HSC_IT_INT(int i)
> +{
> + if (i > 21)
> + return i - 9;
> +
> + return i - 5;
> +}
> +
> +#define CDMBC_ITCTRL(i) (0x3000 + HSC_IT_INT(i) * 0x20)
> +#define CDMBC_ITSTEPS(i) (0x3018 + HSC_IT_INT(i) * 0x20)
> +
> +/* MBC Ring buffer
> + * i: channel number
> + * 0 : Section (RB0)
> + * 1- 3: Record0,1,2 (RB1-3)
> + * 5- 7: Replay0,1,2 (RB4-6)
> + * 8-17: Even: CIP-Read
> + * Odd : CIP-Write (RB7-16)
> + * 19-21: Record3-4 (RB17-19)
> + * 22-24: Replay3-4 (RB20-22)
> + */
> +static inline int HSC_INT(int i)
> +{
> + if (i > 18)
> + return i - 2;
> + if (i > 4)
> + return i - 1;
> +
> + return i;
> +}

CDMBC_CHTDCTRLH(i) was a macro,
but HSC_INT() is a static inline function inconsistently,
then used from the lots of macros below...
Wow.

This is already enough crap.
Is there any other way instead of
putting all the mess into registers?


> +#define CDMBC_RBBGNADRS(i) (0x3200 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBBGNADRSD(i) (0x3200 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBBGNADRSU(i) (0x3204 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBENDADRS(i) (0x3208 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBENDADRSD(i) (0x3208 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBENDADRSU(i) (0x320C + HSC_INT(i) * 0x40)
> +#define CDMBC_RBIR(i) (0x3214 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBIE(i) (0x3218 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBID(i) (0x321c + HSC_INT(i) * 0x40)
> +#define CDMBC_RBRDPTR(i) (0x3220 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBRDPTRD(i) (0x3220 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBRDPTRU(i) (0x3224 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBWRPTR(i) (0x3228 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBWRPTRD(i) (0x3228 + HSC_INT(i) * 0x40)
> +#define CDMBC_RBWRPTRU(i) (0x322C + HSC_INT(i) * 0x40)
> +#define CDMBC_RBERRCNFG(i) (0x3238 + HSC_INT(i) * 0x40)
> +
> +/* MBC Rate */
> +#define CDMBC_RCNMSKCYC(i) (MBC6_TOP_ADDR + 0x000 + (i) * 0x04)
> +
> +/* MBC Address Transfer */
> +#define CDMBC_CHPSIZE(i) (0x3c00 + ((i) - 1) * 0x48)
> +#define CDMBC_CHATCTRL(i) (0x3c04 + ((i) - 1) * 0x48)
> +#define CDMBC_CHBTPAGE(i, j) (0x3c08 + ((i) - 1) * 0x48 + (j) * 0x10)
> +#define CDMBC_CHBTPAGED(i, j) (0x3c08 + ((i) - 1) * 0x48 + (j) * 0x10)
> +#define CDMBC_CHBTPAGEU(i, j) (0x3c0C + ((i) - 1) * 0x48 + (j) * 0x10)
> +#define CDMBC_CHATPAGE(i, j) (0x3c10 + ((i) - 1) * 0x48 + (j) * 0x10)
> +#define CDMBC_CHATPAGED(i, j) (0x3c10 + ((i) - 1) * 0x48 + (j) * 0x10)
> +#define CDMBC_CHATPAGEU(i, j) (0x3c14 + ((i) - 1) * 0x48 + (j) * 0x10)
> +
> +/* CSS */
> +#define CSS_PTSOCONFIG 0x1c00
> +#define CSS_PTSISIGNALPOL 0x1c04
> +#define CSS_SIGNALPOLCH(i) (0x1c08 + (i) * 0x4)
> +#define CSS_OUTPUTENABLE 0x1c10
> +#define CSS_OUTPUTCTRL(i) (0x1c14 + (i) * 0x4)
> +#define CSS_STSOCONFIG 0x1c2c
> +#define CSS_STSOSIGNALPOL 0x1c30
> +#define CSS_DMDSIGNALPOL 0x1c34
> +#define CSS_PTSOSIGNALPOL 0x1c38
> +#define CSS_PF0CONFIG 0x1c3c
> +#define CSS_PF1CONFIG 0x1c40
> +#define CSS_PFINTENABLE 0x1c44
> +#define CSS_PFINTSTATUS 0x1c48
> +#define CSS_AVOUTPUTCTRL(i) (0x1c4c + (i) * 0x4)
> +#define CSS_DPCTRL(i) (0x1c54 + (i) * 0x4)
> +#define CSS_DPCTRL_DPSEL_MASK GENMASK(22, 0)
> +#define CSS_DPCTRL_DPSEL_PLAY5 BIT(15)
> +#define CSS_DPCTRL_DPSEL_PLAY4 BIT(14)
> +#define CSS_DPCTRL_DPSEL_PLAY3 BIT(13)
> +#define CSS_DPCTRL_DPSEL_PLAY2 BIT(12)
> +#define CSS_DPCTRL_DPSEL_PLAY1 BIT(11)
> +#define CSS_DPCTRL_DPSEL_PLAY0 BIT(10)
> +#define CSS_DPCTRL_DPSEL_TSI4 BIT(4)
> +#define CSS_DPCTRL_DPSEL_TSI3 BIT(3)
> +#define CSS_DPCTRL_DPSEL_TSI2 BIT(2)
> +#define CSS_DPCTRL_DPSEL_TSI1 BIT(1)
> +#define CSS_DPCTRL_DPSEL_TSI0 BIT(0)
> +
> +/* TSI */
> +#define TSI_SYNCCNTROL(i) (0x7100 + (i) * 0x70)
> +#define TSI_SYNCCNTROL_FRAME_MASK GENMASK(18, 16)
> +#define TSI_SYNCCNTROL_FRAME_EXTSYNC1 (0x0 << 16)
> +#define TSI_SYNCCNTROL_FRAME_EXTSYNC2 (0x1 << 16)
> +#define TSI_CONFIG(i) (0x7104 + (i) * 0x70)
> +#define TSI_CONFIG_ATSMD_MASK GENMASK(22, 21)
> +#define TSI_CONFIG_ATSMD_PCRPLL0 (0x0 << 21)
> +#define TSI_CONFIG_ATSMD_PCRPLL1 (0x1 << 21)
> +#define TSI_CONFIG_ATSMD_DPLL (0x3 << 21)
> +#define TSI_CONFIG_ATSADD_ON BIT(20)
> +#define TSI_CONFIG_STCMD_MASK GENMASK(7, 6)
> +#define TSI_CONFIG_STCMD_PCRPLL0 (0x0 << 6)
> +#define TSI_CONFIG_STCMD_PCRPLL1 (0x1 << 6)
> +#define TSI_CONFIG_STCMD_DPLL (0x3 << 6)
> +#define TSI_CONFIG_CHEN_START BIT(0)
> +#define TSI_RATEUPLMT(i) (0x7108 + (i) * 0x70)
> +#define TSI_RATELOWLMT(i) (0x710c + (i) * 0x70)
> +#define TSI_CNTINTR(i) (0x7110 + (i) * 0x70)
> +#define TSI_INTREN(i) (0x7114 + (i) * 0x70)
> +#define TSI_INTR_NTP BIT(13)
> +#define TSI_INTR_NTPCNT BIT(12)
> +#define TSI_INTR_PKTEND BIT(11)
> +#define TSI_INTR_PCR BIT(9)
> +#define TSI_INTR_LOAD BIT(8)
> +#define TSI_INTR_SERR BIT(7)
> +#define TSI_INTR_SOF BIT(6)
> +#define TSI_INTR_TOF BIT(5)
> +#define TSI_INTR_UL BIT(4)
> +#define TSI_INTR_LL BIT(3)
> +#define TSI_INTR_CNT BIT(2)
> +#define TSI_INTR_LOST BIT(1)
> +#define TSI_INTR_LOCK BIT(0)
> +#define TSI_SYNCSTATUS(i) (0x7118 + (i) * 0x70)
> +#define TSI_STAT_PKTST_ERR BIT(21)
> +#define TSI_STAT_LARGE_ERR BIT(20)
> +#define TSI_STAT_SMALL_ERR BIT(19)
> +#define TSI_STAT_LOCK BIT(18)
> +#define TSI_STAT_SYNC BIT(17)
> +#define TSI_STAT_SEARCH BIT(16)
> +#define TSI_PCRPID(i) (0x711c + (i) * 0x70)
> +#define TSI_PCRCTRL(i) (0x7120 + (i) * 0x70)
> +#define TSI_STCBASE(i) (0x7124 + (i) * 0x70)
> +#define TSI_STCEXT(i) (0x7128 + (i) * 0x70)
> +#define TSI_CURSTC1(i) (0x712c + (i) * 0x70)
> +#define TSI_CURSTCBASE(i) (0x712c + (i) * 0x70)
> +#define TSI_CURSTC2(i) (0x7130 + (i) * 0x70)
> +#define TSI_CURSTCEXT(i) (0x7130 + (i) * 0x70)
> +#define TSI_STC2BASE(i) (0x7134 + (i) * 0x70)
> +#define TSI_STC2EXT(i) (0x7138 + (i) * 0x70)
> +#define TSI_PCRBASE(i) (0x713c + (i) * 0x70)
> +#define TSI_PCREXT(i) (0x7140 + (i) * 0x70)
> +#define TSI_TIMESTAMP(i) (0x7144 + (i) * 0x70)
> +#define TSI_CNTCTRL0(i) (0x7148 + (i) * 0x70)
> +#define TSI_CNTCTRL1(i) (0x714c + (i) * 0x70)
> +#define TSI_DEBUG(i) (0x7150 + (i) * 0x70)
> +
> +#define TSI_STCCMPCTRL 0x7000
> +#define VCXOSTCBASE(i) (0x7010 + (i) * 0x18)
> +#define VCXOSTCEXT(i) (0x7014 + (i) * 0x18)
> +#define VCXOCURSTC1(i) (0x7018 + (i) * 0x18)
> +#define VCXOCURSTC2(i) (0x701c + (i) * 0x18)
> +#define VCXOSTC2BASE(i) (0x7020 + (i) * 0x18)
> +#define VCXOSTC2EXT(i) (0x7024 + (i) * 0x18)
> +
> +/* UCODE DL */
> +#define UCODE_REVISION_AM 0x10fd0
> +#define CIP_UCODEADDR_AM1 0x10fd4
> +#define CIP_UCODEADDR_AM0 0x10fd8
> +#define CORRECTATS_CTRL 0x10fdc
> +#define UCODE_REVISION 0x10fe0
> +#define AM_UCODE_IGPGCTRL 0x10fe4
> +#define REPDPLLCTRLEN 0x10fe8
> +#define UCODE_DLADDR1 0x10fec
> +#define UCODE_DLADDR0 0x10ff0
> +#define UCODE_ERRLOGCTRL 0x10ff4
> +
> +#endif /* DVB_UNIPHIER_HSC_REG_H__ */
> diff --git a/drivers/media/platform/uniphier/hsc.h b/drivers/media/platform/uniphier/hsc.h
> new file mode 100644
> index 000000000000..ad57fea58675
> --- /dev/null
> +++ b/drivers/media/platform/uniphier/hsc.h
> @@ -0,0 +1,480 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Socionext UniPhier DVB driver for High-speed Stream Controller (HSC).
> + *
> + * Copyright (c) 2018 Socionext Inc.
> + */
> +
> +#ifndef DVB_UNIPHIER_HSC_H__
> +#define DVB_UNIPHIER_HSC_H__
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/types.h>
> +
> +#include <media/dmxdev.h>
> +#include <media/dvbdev.h>
> +#include <media/dvb_demux.h>
> +#include <media/dvb_frontend.h>
> +
> +enum HSC_CORE {
> + HSC_CORE_0,
> + HSC_CORE_1,
> + HSC_CORE_2,
> +};
> +
> +enum HSC_UCODE {
> + HSC_UCODE_SPU_0,
> + HSC_UCODE_SPU_1,
> + HSC_UCODE_ACE,
> +};
> +
> +enum HSC_INTR_IOB {
> + HSC_INTR_IOB_0,
> + HSC_INTR_IOB_0_1,
> + HSC_INTR_IOB_0_2,
> + HSC_INTR_IOB_1,
> + HSC_INTR_IOB_1_1,
> + HSC_INTR_IOB_2,
> + HSC_INTR_IOB_3,
> + HSC_INTR_IOB_4,
> + HSC_INTR_IOB_5,
> + HSC_INTR_IOB_5_1,
> + HSC_INTR_IOB_5_2,
> + HSC_INTR_IOB_6,
> + HSC_INTR_IOB_6_1,
> + HSC_INTR_IOB_7,
> + HSC_INTR_IOB_8,
> + HSC_INTR_IOB_9,
> +
> + HSC_INTR_IOB_NUM,
> +};
> +
> +enum HSC_DPLL {
> + HSC_DPLL0,
> + HSC_DPLL1,
> + HSC_DPLL2,
> + HSC_DPLL3,
> +
> + HSC_DPLL_NUM,
> +};
> +
> +enum HSC_DPLL_SRC {
> + HSC_DPLL_SRC_NONE = -1,
> + HSC_DPLL_SRC_TSI0 = 0x00,
> + HSC_DPLL_SRC_TSI1,
> + HSC_DPLL_SRC_TSI2,
> + HSC_DPLL_SRC_TSI3,
> + HSC_DPLL_SRC_TSI4,
> + HSC_DPLL_SRC_TSI5,
> + HSC_DPLL_SRC_TSI6,
> + HSC_DPLL_SRC_TSI7,
> + HSC_DPLL_SRC_TSI8,
> + HSC_DPLL_SRC_TSI9,
> + HSC_DPLL_SRC_REP0 = 0x0a,
> + HSC_DPLL_SRC_REP1,
> + HSC_DPLL_SRC_REP2,
> + HSC_DPLL_SRC_REP3,
> + HSC_DPLL_SRC_REP4,
> + HSC_DPLL_SRC_REP5,
> +
> + HSC_DPLL_SRC_NUM,
> +};
> +
> +/* Port to send to CSS */
> +enum HSC_CSS_IN {
> + HSC_CSS_IN_1394_0 = 0x00,
> + HSC_CSS_IN_1394_1,
> + HSC_CSS_IN_1394_2,
> + HSC_CSS_IN_1394_3,
> + HSC_CSS_IN_DMD0 = 0x04,
> + HSC_CSS_IN_DMD1,
> + HSC_CSS_IN_SRLTS0 = 0x06,
> + HSC_CSS_IN_SRLTS1,
> + HSC_CSS_IN_SRLTS2,
> + HSC_CSS_IN_SRLTS3,
> + HSC_CSS_IN_SRLTS4,
> + HSC_CSS_IN_SRLTS5,
> + HSC_CSS_IN_SRLTS6,
> + HSC_CSS_IN_SRLTS7,
> + HSC_CSS_IN_PARTS0 = 0x10,
> + HSC_CSS_IN_PARTS1,
> + HSC_CSS_IN_PARTS2,
> + HSC_CSS_IN_PARTS3,
> + HSC_CSS_IN_TSO0 = 0x18,

Look like each must have a particular value.

Is it important to HSC_CSS_IN_TSO0 == 0x18 ?

If so, it might be better to do


#define HSC_CSS_IN_TSO0 0x18



> + HSC_CSS_IN_TSO1,
> + HSC_CSS_IN_TSO2,
> + HSC_CSS_IN_TSO3,
> + HSC_CSS_IN_ENCORDER0_IN = 0x1c,
> + HSC_CSS_IN_ENCORDER1_IN,
> +
> + HSC_CSS_IN_NUM,
> +};


[snip]

> +struct hsc_spec_dma {
> + int dma_ch;
> + struct hsc_dma_en en;
> + struct hsc_cmn_intr intr;
> +};
> +
> +struct hsc_spec {
> + const struct hsc_spec_ucode ucode_spu;

Suspicious usage of 'const'
since ucode_spu is not a pointer.

Look like you constified the whole hsc_spec,
so this 'const' should be here.


> + const struct hsc_spec_ucode ucode_ace;

Ditto.

> + const struct hsc_spec_init_ram *init_rams;

OK, this 'const' is legitimate since init-rams a pointer.


> + size_t num_init_rams;
> + const struct hsc_spec_css_in *css_in;
> + size_t num_css_in;
> + const struct hsc_spec_css_out *css_out;
> + size_t num_css_out;
> + const struct hsc_spec_ts *ts_in;
> + size_t num_ts_in;
> + const struct hsc_spec_dma *dma_in;
> + size_t num_dma_in;
> + const struct hsc_spec_dma *dma_out;
> + size_t num_dma_out;
> +};
> +
> +struct hsc_tsif {
> + struct hsc_chip *chip;
> +
> + struct dvb_adapter adapter;
> + struct dvb_demux demux;
> + struct dmxdev dmxdev;
> + struct dvb_frontend *fe;
> + int valid_adapter;
> + int valid_demux;
> + int valid_dmxdev;
> + int valid_fe;
> +
> + enum HSC_CSS_IN css_in;
> + enum HSC_CSS_OUT css_out;
> + enum HSC_TS_IN tsi;
> + enum HSC_DPLL dpll;
> + enum HSC_DPLL_SRC dpll_src;
> + struct hsc_dmaif *dmaif;
> +
> + int running;
> + struct delayed_work recover_work;
> + unsigned long recover_delay;
> +};
> +
> +struct hsc_dma_in {
> + struct hsc_chip *chip;
> +
> + enum HSC_DMA_IN id;
> + const struct hsc_spec_dma *spec;
> + struct hsc_dma_buf *buf;
> +};
> +
> +struct hsc_dma_out {
> + struct hsc_chip *chip;
> +
> + enum HSC_DMA_OUT id;
> + const struct hsc_spec_dma *spec;
> + struct hsc_dma_buf *buf;
> +};
> +
> +struct hsc_dma_buf {
> + void *virt;
> + dma_addr_t phys;
> + u64 size;
> + u64 size_chk;
> + u64 rd_offs;
> + u64 wr_offs;
> + u64 chk_offs;
> +};
> +
> +struct hsc_dmaif {
> + struct hsc_chip *chip;
> +
> + struct hsc_dma_buf buf_out;
> + struct hsc_dma_out dma_out;
> +
> + struct hsc_tsif *tsif;
> +
> + /* guard read/write pointer of DMA buffer from interrupt handler */
> + spinlock_t lock;
> + int running;
> + struct work_struct feed_work;
> +};
> +
> +struct hsc_chip {
> + const struct hsc_spec *spec;
> + short *adapter_nums;
> +
> + struct platform_device *pdev;
> + struct regmap *regmap;
> + struct clk *clk_stdmac;
> + struct clk *clk_hsc;
> + struct reset_control *rst_stdmac;
> + struct reset_control *rst_hsc;
> +
> + struct hsc_dmaif dmaif[HSC_STREAM_IF_NUM];
> + struct hsc_tsif tsif[HSC_STREAM_IF_NUM];
> +
> + struct hsc_ucode_buf ucode_spu;
> + struct hsc_ucode_buf ucode_am;
> +};
> +
> +struct hsc_conf {
> + enum HSC_CSS_IN css_in;
> + enum HSC_CSS_OUT css_out;
> + enum HSC_DPLL dpll;
> + enum HSC_DMA_OUT dma_out;
> +};
> +
> +static inline u32 field_prep(u32 mask, u32 v)
> +{
> + int sft = ffs(mask) - 1;
> +
> + return (v << sft) & mask;
> +}
> +
> +static inline u32 field_get(u32 mask, u32 v)
> +{
> + int sft = ffs(mask) - 1;
> +
> + return (v & mask) >> sft;
> +}

A good thing of <linux/bitfield.h> is, it is compile-time computable,
but this is not.

It might be better to re-consider the hsc_spec_css_out data arrangement.
For example, shift & width pair instead of shifted-mask.





> +/* CSS */
> +enum HSC_TS_IN hsc_css_out_to_ts_in(enum HSC_CSS_OUT out);
> +enum HSC_DPLL_SRC hsc_css_out_to_dpll_src(enum HSC_CSS_OUT out);
> +
> +int hsc_dpll_get_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
> + enum HSC_DPLL_SRC *src);
> +int hsc_dpll_set_src(struct hsc_chip *chip, enum HSC_DPLL dpll,
> + enum HSC_DPLL_SRC src);
> +int hsc_css_in_get_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
> + bool *sync_bit, bool *val_bit, bool *clk_fall);
> +int hsc_css_in_set_polarity(struct hsc_chip *chip, enum HSC_CSS_IN in,
> + bool sync_bit, bool val_bit, bool clk_fall);
> +int hsc_css_out_get_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
> + bool *sync_bit, bool *val_bit, bool *clk_fall);
> +int hsc_css_out_set_polarity(struct hsc_chip *chip, enum HSC_CSS_OUT out,
> + bool sync_bit, bool val_bit, bool clk_fall);
> +int hsc_css_out_get_src(struct hsc_chip *chip, enum HSC_CSS_IN *in,
> + enum HSC_CSS_OUT out, bool *en);
> +int hsc_css_out_set_src(struct hsc_chip *chip, enum HSC_CSS_IN in,
> + enum HSC_CSS_OUT out, bool en);
> +
> +/* TSI */
> +const struct hsc_spec_tsi *hsc_ts_in_get_spec(struct hsc_chip *chip,
> + enum HSC_TS_IN in);
> +int hsc_ts_in_set_enable(struct hsc_chip *chip, enum HSC_TS_IN in, bool en);
> +int hsc_ts_in_set_dmaparam(struct hsc_chip *chip, enum HSC_TS_IN in,
> + enum HSC_TSIF_FMT ifmt);
> +
> +/* DMA */
> +u64 hsc_rb_cnt(struct hsc_dma_buf *buf);
> +u64 hsc_rb_cnt_to_end(struct hsc_dma_buf *buf);
> +u64 hsc_rb_space(struct hsc_dma_buf *buf);
> +u64 hsc_rb_space_to_end(struct hsc_dma_buf *buf);
> +int hsc_dma_in_init(struct hsc_dma_in *dma_in, struct hsc_chip *chip,
> + enum HSC_DMA_IN in, struct hsc_dma_buf *buf);
> +void hsc_dma_in_start(struct hsc_dma_in *dma_in, bool en);
> +void hsc_dma_in_sync(struct hsc_dma_in *dma_in);
> +int hsc_dma_in_get_intr(struct hsc_dma_in *dma_in, u32 *stat);
> +void hsc_dma_in_clear_intr(struct hsc_dma_in *dma_in, u32 clear);
> +int hsc_dma_out_init(struct hsc_dma_out *dma_out, struct hsc_chip *chip,
> + enum HSC_DMA_OUT out, struct hsc_dma_buf *buf);
> +void hsc_dma_out_set_src_ts_in(struct hsc_dma_out *dma_out,
> + enum HSC_TS_IN ts_in);
> +void hsc_dma_out_start(struct hsc_dma_out *dma_out, bool en);
> +void hsc_dma_out_sync(struct hsc_dma_out *dma_out);
> +int hsc_dma_out_get_intr(struct hsc_dma_out *dma_out, u32 *stat);
> +void hsc_dma_out_clear_intr(struct hsc_dma_out *dma_out, u32 clear);
> +
> +/* UCODE DL */
> +int hsc_ucode_load_all(struct hsc_chip *chip);
> +int hsc_ucode_unload_all(struct hsc_chip *chip);
> +
> +/* For Adapter */
> +int hsc_register_dvb(struct hsc_tsif *tsif);
> +void hsc_unregister_dvb(struct hsc_tsif *tsif);
> +int hsc_tsif_init(struct hsc_tsif *tsif, const struct hsc_conf *conf);
> +void hsc_tsif_release(struct hsc_tsif *tsif);
> +int hsc_dmaif_init(struct hsc_dmaif *dmaif, const struct hsc_conf *conf);
> +void hsc_dmaif_release(struct hsc_dmaif *dmaif);
> +extern const struct hsc_spec uniphier_hsc_ld11_spec;
> +extern const struct hsc_spec uniphier_hsc_ld20_spec;
> +
> +#endif /* DVB_UNIPHIER_HSC_H__ */
> --
> 2.17.0
>



--
Best Regards
Masahiro Yamada

2018-06-02 12:03:00

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 3/8] media: uniphier: add submodules of HSC MPEG2-TS I/O driver

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds submodules of HSC for UniPhier SoCs.
> These work as follows:
> ucode: Load uCode and start subsystems
> css : Switch stream path
> ts : Receive MPEG2-TS clock and signal
> dma : Transfer MPEG2-TS data bytes to main memory
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> drivers/media/platform/uniphier/Makefile | 3 +
> drivers/media/platform/uniphier/hsc-css.c | 258 ++++++++++++
> drivers/media/platform/uniphier/hsc-dma.c | 302 ++++++++++++++
> drivers/media/platform/uniphier/hsc-ts.c | 99 +++++
> drivers/media/platform/uniphier/hsc-ucode.c | 436 ++++++++++++++++++++
> 5 files changed, 1098 insertions(+)
> create mode 100644 drivers/media/platform/uniphier/hsc-css.c
> create mode 100644 drivers/media/platform/uniphier/hsc-dma.c
> create mode 100644 drivers/media/platform/uniphier/hsc-ts.c
> create mode 100644 drivers/media/platform/uniphier/hsc-ucode.c
>
> diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
> index f66554cd5c45..92536bc56b31 100644
> --- a/drivers/media/platform/uniphier/Makefile
> +++ b/drivers/media/platform/uniphier/Makefile
> @@ -1 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0
> +uniphier-dvb-y += hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
> +
> +obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o



If you claim this driver is tristate,
you need to do compile-test with =m.


I see the following warning for allmodconfig.


CC [M] drivers/media/platform/uniphier/hsc-ucode.o
CC [M] drivers/media/platform/uniphier/hsc-css.o
CC [M] drivers/media/platform/uniphier/hsc-ts.o
CC [M] drivers/media/platform/uniphier/hsc-dma.o
LD [M] drivers/media/platform/uniphier/uniphier-dvb.o
WARNING: modpost: missing MODULE_LICENSE() in
drivers/media/platform/uniphier/uniphier-dvb.o
see include/linux/module.h for more information










--
Best Regards
Masahiro Yamada

2018-06-02 12:03:03

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds common module for UniPhier DVB adapter drivers
> that equipments tuners and demod that connected by I2C and
> UniPhier demux.
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> drivers/media/platform/uniphier/Makefile | 5 ++
> drivers/media/platform/uniphier/hsc-core.c | 8 ---
> .../platform/uniphier/uniphier-adapter.c | 54 +++++++++++++++++++
> .../platform/uniphier/uniphier-adapter.h | 42 +++++++++++++++
> 4 files changed, 101 insertions(+), 8 deletions(-)
> create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
> create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h
>
> diff --git a/drivers/media/platform/uniphier/Makefile b/drivers/media/platform/uniphier/Makefile
> index 0622f04d9e68..9e75ad081b77 100644
> --- a/drivers/media/platform/uniphier/Makefile
> +++ b/drivers/media/platform/uniphier/Makefile
> @@ -3,3 +3,8 @@ uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o hsc-dma.o
> uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o
>
> obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
> +
> +ccflags-y += -Idrivers/media/dvb-frontends/
> +ccflags-y += -Idrivers/media/tuners/


Please add $(srctree)/ like

ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
ccflags-y += -I$(srctree)/drivers/media/tuners/


Currently, it works $(srctree)/,
but I really want to rip off the build system hack.





--
Best Regards
Masahiro Yamada

2018-06-02 12:03:11

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 7/8] media: uniphier: add LD11 adapter driver for ISDB

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> diff --git a/drivers/media/platform/uniphier/ld11-mn884433-helene.c b/drivers/media/platform/uniphier/ld11-mn884433-helene.c
> new file mode 100644
> index 000000000000..f4f48b6a0211
> --- /dev/null
> +++ b/drivers/media/platform/uniphier/ld11-mn884433-helene.c
> @@ -0,0 +1,265 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Socionext UniPhier LD11 adapter driver for ISDB.
> +// Using Socionext MN884433 ISDB-S/ISDB-T demodulator and
> +// SONY HELENE tuner.
> +//
> +// Copyright (c) 2018 Socionext Inc.
> +
> +#include <linux/clk.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/reset.h>
> +
> +#include "sc1501a.h"


"sc1501a.h" is not included in this patch series.


It took some time to notice that
this series actually depends on the following:
https://patchwork.kernel.org/patch/10434159/

Otherwise, this cause a build error.


scripts/kconfig/conf --syncconfig Kconfig
CHK include/config/kernel.release
CHK include/generated/uapi/linux/version.h
CHK scripts/mod/devicetable-offsets.h
CHK include/generated/utsrelease.h
CHK include/generated/bounds.h
CHK include/generated/timeconst.h
CHK include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
CC [M] drivers/media/platform/uniphier/ld11-mn884433-helene.o
drivers/media/platform/uniphier/ld11-mn884433-helene.c:16:10: fatal
error: sc1501a.h: No such file or directory
#include "sc1501a.h"
^~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.build:313:
drivers/media/platform/uniphier/ld11-mn884433-helene.o] Error 1
make[1]: *** [scripts/Makefile.build:559:
drivers/media/platform/uniphier] Error 2
make: *** [Makefile:1746: drivers/media/platform/] Error 2




I applied that patch, but still fail to build this series.


CC [M] drivers/media/platform/uniphier/hsc-core.o
CC [M] drivers/media/platform/uniphier/hsc-ucode.o
CC [M] drivers/media/platform/uniphier/hsc-css.o
CC [M] drivers/media/platform/uniphier/hsc-ts.o
CC [M] drivers/media/platform/uniphier/hsc-dma.o
CC [M] drivers/media/platform/uniphier/hsc-ld11.o
CC [M] drivers/media/platform/uniphier/uniphier-adapter.o
CC [M] drivers/media/platform/uniphier/ld11-mn884433-helene.o
drivers/media/platform/uniphier/ld11-mn884433-helene.c:17:10: fatal
error: cxd2858.h: No such file or directory
#include "cxd2858.h"
^~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.build:312:
drivers/media/platform/uniphier/ld11-mn884433-helene.o] Error 1
make: *** [Makefile:1665: drivers/media/platform/uniphier/] Error 2





I give up searching pre-requisite patches.


You need to describe this information under '---'
if your series needs pre-requisite patches that have not been applied yet.






> +#include "cxd2858.h"
> +#include "helene.h"
> +#include "hsc.h"
> +#include "uniphier-adapter.h"
> +
> +static struct sc1501a_config mn884433_conf[] = {
> + { .if_freq = LOW_IF_4MHZ, },
> +};
> +
> +static int uniphier_adapter_demod_probe(struct uniphier_adapter_priv *priv)
> +{
> + const struct uniphier_adapter_spec *spec = priv->spec;
> + struct device *dev = &priv->pdev->dev;
> + struct device_node *node;
> + int ret, i;
> +
> + priv->demod_mclk = devm_clk_get(dev, "demod-mclk");
> + if (IS_ERR(priv->demod_mclk)) {
> + dev_err(dev, "Failed to request demod-mclk: %ld\n",
> + PTR_ERR(priv->demod_mclk));
> + return PTR_ERR(priv->demod_mclk);
> + }
> +
> + priv->demod_gpio = devm_gpiod_get_optional(dev, "reset-demod",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(priv->demod_gpio)) {
> + dev_err(dev, "Failed to request demod_gpio: %ld\n",
> + PTR_ERR(priv->demod_gpio));
> + return PTR_ERR(priv->demod_gpio);
> + }
> +
> + node = of_parse_phandle(dev->of_node, "demod-i2c-bus", 0);
> + if (!node) {
> + dev_err(dev, "Failed to parse demod-i2c-bus\n");
> + return -ENODEV;
> + }
> +
> + priv->demod_i2c_adapter = of_find_i2c_adapter_by_node(node);
> + if (!priv->demod_i2c_adapter) {
> + dev_err(dev, "Failed to find demod i2c adapter\n");
> + of_node_put(node);
> + return -ENODEV;
> + }
> + of_node_put(node);
> +
> + mn884433_conf[0].reset_gpio = priv->demod_gpio;
> + for (i = 0; i < spec->adapters; i++) {
> + struct i2c_client *c;
> +
> + mn884433_conf[i].mclk = priv->demod_mclk;
> + mn884433_conf[i].fe = &priv->fe[i].fe;
> +
> + c = dvb_module_probe(spec->demod_i2c_info[i].type, NULL,
> + priv->demod_i2c_adapter,
> + spec->demod_i2c_info[i].addr,
> + &mn884433_conf[i]);
> + if (!c) {
> + dev_err(dev, "Failed to probe demod\n");
> + ret = -ENODEV;
> + goto err_out;
> + }
> + priv->fe[i].demod_i2c = c;
> + }
> +
> + return 0;
> +
> +err_out:
> + for (i = 0; i < spec->adapters; i++)
> + dvb_module_release(priv->fe[i].demod_i2c);
> +
> + return ret;
> +}
> +
> +static struct helene_config helene_conf[] = {
> + { .xtal = SONY_HELENE_XTAL_16000, },
> + { .xtal = SONY_HELENE_XTAL_16000, },
> +};
> +
> +static int uniphier_adapter_tuner_probe(struct uniphier_adapter_priv *priv)
> +{
> + const struct uniphier_adapter_spec *spec = priv->spec;
> + struct device *dev = &priv->pdev->dev;
> + struct device_node *node;
> + int ret, i;
> +
> + priv->tuner_gpio = devm_gpiod_get_optional(dev, "reset-tuner",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(priv->tuner_gpio)) {
> + dev_err(dev, "Failed to request tuner_gpio: %ld\n",
> + PTR_ERR(priv->tuner_gpio));
> + return PTR_ERR(priv->tuner_gpio);
> + }
> + gpiod_set_value_cansleep(priv->tuner_gpio, 0);
> +
> + node = of_parse_phandle(dev->of_node, "tuner-i2c-bus", 0);
> + if (!node) {
> + dev_err(dev, "Failed to parse tuner-i2c-bus\n");
> + return -ENODEV;
> + }
> +
> + priv->tuner_i2c_adapter = of_find_i2c_adapter_by_node(node);
> + if (!priv->tuner_i2c_adapter) {
> + dev_err(dev, "Failed to find tuner i2c adapter\n");
> + of_node_put(node);
> + return -ENODEV;
> + }
> + of_node_put(node);
> +
> + for (i = 0; i < priv->spec->adapters; i++) {
> + struct i2c_client *c;
> +
> + helene_conf[i].fe = priv->fe[i].fe;
> +
> + c = dvb_module_probe(spec->tuner_i2c_info[i].type, NULL,
> + priv->tuner_i2c_adapter,
> + spec->tuner_i2c_info[i].addr,
> + &helene_conf[i]);
> + if (!c) {
> + dev_err(dev, "Failed to probe tuner\n");
> + ret = -ENODEV;
> + goto err_out;
> + }
> + priv->fe[i].tuner_i2c = c;
> + }
> +
> + return 0;
> +
> +err_out:
> + for (i = 0; i < spec->adapters; i++)
> + dvb_module_release(priv->fe[i].tuner_i2c);
> +
> + return ret;
> +}
> +
> +static int uniphier_adapter_probe(struct platform_device *pdev)
> +{
> + struct uniphier_adapter_priv *priv;
> + struct device *dev = &pdev->dev;
> + int i, ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> + priv->pdev = pdev;
> +
> + priv->spec = of_device_get_match_data(dev);
> + if (!priv->spec)
> + return -EINVAL;
> +
> + priv->fe = devm_kzalloc(dev, sizeof(*priv->fe) * priv->spec->adapters,
> + GFP_KERNEL);
> + if (!priv->fe)
> + return -ENOMEM;
> +
> + ret = uniphier_adapter_demux_probe(priv);
> + if (ret)
> + return ret;
> +
> + ret = uniphier_adapter_demod_probe(priv);
> + if (ret)
> + return ret;
> +
> + ret = uniphier_adapter_tuner_probe(priv);
> + if (ret)
> + return ret;
> +
> + platform_set_drvdata(pdev, priv);
> +
> + for (i = 0; i < priv->spec->adapters; i++) {
> + priv->chip->tsif[i].fe = priv->fe[i].fe;
> +
> + ret = hsc_register_dvb(&priv->chip->tsif[i]);
> + if (ret) {
> + dev_err(dev, "Failed to register adapter\n");
> + goto err_out_if;
> + }
> + }
> +
> + return 0;
> +
> +err_out_if:
> + for (i = 0; i < priv->spec->adapters; i++)
> + hsc_unregister_dvb(&priv->chip->tsif[i]);
> +
> + return ret;
> +}
> +
> +static int uniphier_adapter_remove(struct platform_device *pdev)
> +{
> + struct uniphier_adapter_priv *priv = platform_get_drvdata(pdev);
> + int i;
> +
> + for (i = 0; i < priv->spec->adapters; i++) {
> + hsc_dmaif_release(&priv->chip->dmaif[i]);
> + hsc_tsif_release(&priv->chip->tsif[i]);
> + hsc_unregister_dvb(&priv->chip->tsif[i]);
> + dvb_module_release(priv->fe[i].tuner_i2c);
> + dvb_module_release(priv->fe[i].demod_i2c);
> + }
> +
> + return 0;
> +}
> +
> +static const struct hsc_conf ld11_hsc_conf[] = {
> + {
> + .css_in = HSC_CSS_IN_SRLTS0,
> + .css_out = HSC_CSS_OUT_TSI0,
> + .dpll = HSC_DPLL0,
> + .dma_out = HSC_DMA_OUT0,
> + },
> +};
> +
> +static const struct i2c_board_info mn884433_i2c_info[] = {
> + { .type = "mn884433", .addr = 0x68, },
> +};
> +
> +static const struct i2c_board_info helene_i2c_info[] = {
> + { .type = "helene", .addr = 0x61, },
> +};
> +
> +static const struct uniphier_adapter_spec ld11_mn884433_helene_spec = {
> + .adapters = 1,
> + .hsc_conf = ld11_hsc_conf,
> + .demod_i2c_info = mn884433_i2c_info,
> + .tuner_i2c_info = helene_i2c_info,
> +};
> +
> +static const struct of_device_id uniphier_hsc_adapter_of_match[] = {
> + {
> + .compatible = "socionext,uniphier-ld11-mn884433-helene",
> + .data = &ld11_mn884433_helene_spec,
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, uniphier_hsc_adapter_of_match);
> +
> +static struct platform_driver uniphier_hsc_adapter_driver = {
> + .driver = {
> + .name = "uniphier-ld11-isdb",
> + .of_match_table = of_match_ptr(uniphier_hsc_adapter_of_match),
> + },
> + .probe = uniphier_adapter_probe,
> + .remove = uniphier_adapter_remove,
> +};
> +module_platform_driver(uniphier_hsc_adapter_driver);
> +
> +MODULE_AUTHOR("Katsuhiro Suzuki <[email protected]>");
> +MODULE_DESCRIPTION("UniPhier LD11 adapter driver for ISDB.");
> +MODULE_LICENSE("GPL v2");
> --
> 2.17.0
>



--
Best Regards
Masahiro Yamada

2018-06-02 12:06:53

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 8/8] media: uniphier: add LD20 adapter driver for ISDB

2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> This patch adds UniPhier LD20 DVB adapter driver for ISDB-S/T
> that equipments SONY SUT-PJ series using CXD2858 tuner and Socionext
> MN884434 demodulator.
>
> Signed-off-by: Katsuhiro Suzuki <[email protected]>
> ---
> drivers/media/platform/uniphier/Kconfig | 10 +
> drivers/media/platform/uniphier/Makefile | 1 +
> .../platform/uniphier/ld20-mn884434-helene.c | 274 ++++++++++++++++++
> 3 files changed, 285 insertions(+)
> create mode 100644 drivers/media/platform/uniphier/ld20-mn884434-helene.c
>


> +
> +static const struct of_device_id uniphier_hsc_adapter_of_match[] = {
> + {
> + .compatible = "socionext,uniphier-ld20-mn884434-helene",
> + .data = &ld20_mn884434_helene_spec,
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, uniphier_hsc_adapter_of_match);
> +
> +static struct platform_driver uniphier_hsc_adapter_driver = {
> + .driver = {
> + .name = "uniphier-ld20-isdb",
> + .of_match_table = of_match_ptr(uniphier_hsc_adapter_of_match),
> + },
> + .probe = uniphier_adapter_probe,
> + .remove = uniphier_adapter_remove,
> +};
> +module_platform_driver(uniphier_hsc_adapter_driver);
> +
> +MODULE_AUTHOR("Katsuhiro Suzuki <[email protected]>");
> +MODULE_DESCRIPTION("UniPhier LD20 adapter driver for ISDB.");
> +MODULE_LICENSE("GPL v2");


This is weird.

From drivers/media/platform/uniphier/Makefile,
obviously you link all the objects into the single module, uniphier-dvb.ko


It contains zero, one, or two sets of MODULE_* depending on CONFIG options.


- Zero MODULE_LICENSE / MODULE_AUTHOR / MODULE_DESCRIPTION
if CONFIG_DVB_UNIPHIER_LD11_ISDB=n &&
CONFIG_DVB_UNIPHIER_LD20_ISDB=n


- Two sets of MODULE_LICENSE / MODULE_AUTHOR / MODULE_DESCRIPTION
if CONFIG_DVB_UNIPHIER_LD11_ISDB=y &&
CONFIG_DVB_UNIPHIER_LD20_ISDB=y



What you can do is:

- Split the module into core, ld11, ld20

or

- Move the module tags and entry to hsc-core.c
and leave only the data arrays in ld11, ld20.






--
Best Regards
Masahiro Yamada

2018-06-03 23:51:25

by Katsuhiro Suzuki

[permalink] [raw]
Subject: Re: [PATCH 1/8] media: uniphier: add DT bindings documentation for UniPhier HSC

Hello Yamada-san,

Thank you for your review and comments.
I'll fix this mail and other your replies!

Regards,
--
Katsuhiro Suzuki


> -----Original Message-----
> From: Masahiro Yamada <[email protected]>
> Sent: Saturday, June 2, 2018 6:50 PM
> To: Suzuki, Katsuhiro/鈴木 勝博 <[email protected]>
> Cc: Mauro Carvalho Chehab <[email protected]>;
> [email protected]; Masami Hiramatsu <[email protected]>;
> Jassi Brar <[email protected]>; linux-arm-kernel
> <[email protected]>; Linux Kernel Mailing List
> <[email protected]>
> Subject: Re: [PATCH 1/8] media: uniphier: add DT bindings documentation for UniPhier
> HSC
>
> 2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> > This patch adds DT binding documentation for UniPhier HSC which is
> > MPEG2-TS input/output and demux subsystem.
> >
> > Signed-off-by: Katsuhiro Suzuki <[email protected]>
> > ---
> > .../bindings/media/uniphier,hsc.txt | 38 +++++++++++++++++++
> > 1 file changed, 38 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/media/uniphier,hsc.txt
> >
> > diff --git a/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> > new file mode 100644
> > index 000000000000..4242483b2ecc
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/uniphier,hsc.txt
> > @@ -0,0 +1,38 @@
> > +Socionext UniPhier HSC (High-speed Stream Controller)
> > +
> > +The Socionext UniPhier HSC subsystem consists of MPEG2-TS input/output and
> > +demultiplexer cores in the same register space.
> > +
> > +This interface is support TS serial signals (clock, valid, sync, data) from
> > +external demodulators.
> > +
> > +Required properties:
> > +- compatible : should be one of the following:
> > + "socionext,uniphier-ld11-hsc"
> > + "socionext,uniphier-ld20-hsc"
> > +- reg : offset and length of the register set for the device.
> > +- interrupts : should contain DMA and TSI error interrupt.
> > +- pinctrl-names : should be "default".
> > +- pinctrl-0 : defined TS serial signal pins for external demodulators.
> > +- clock-names : should include following entries:
>
>
> "the following entries:"
>
>
>
> > + "hsc", "stdmac"
> > +- clocks : a list of phandle, should contain an entry for each
> > + entry in clock-names.
> > +- reset-names : should include following entries:
>
>
> Ditto.
>
>
>
> > + "hsc", "stdmac"
> > +- resets : a list of phandle, should contain an entry for each
> > + entry in reset-names.
> > +
> > +Example:
> > + hsc {
> > + compatible = "socionext,uniphier-ld20-hsc";
> > + reg = <0x5c000000 0x100000>;
> > + interrupts = <0 100 4>, <0 101 4>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_hscin2_s>,
> > + <&pinctrl_hscin3_s>;
> > + clock-names = "stdmac", "hsc";
> > + clocks = <&sys_clk 8>, <&sys_clk 9>;
> > + reset-names = "stdmac", "hsc";
> > + resets = <&sys_rst 8>, <&sys_rst 9>;
> > + };
> > --
> > 2.17.0
> >
>
>
>
> --
> Best Regards
> Masahiro Yamada



2018-06-04 00:09:18

by Katsuhiro Suzuki

[permalink] [raw]
Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers

Hello Yamada-san,

> -----Original Message-----
> From: Masahiro Yamada <[email protected]>
> Sent: Saturday, June 2, 2018 9:00 PM
> To: Suzuki, Katsuhiro/鈴木 勝博 <[email protected]>
> Cc: Mauro Carvalho Chehab <[email protected]>;
> [email protected]; Masami Hiramatsu <[email protected]>;
> Jassi Brar <[email protected]>; linux-arm-kernel
> <[email protected]>; Linux Kernel Mailing List
> <[email protected]>
> Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers
>
> 2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> > This patch adds common module for UniPhier DVB adapter drivers
> > that equipments tuners and demod that connected by I2C and
> > UniPhier demux.
> >
> > Signed-off-by: Katsuhiro Suzuki <[email protected]>
> > ---
> > drivers/media/platform/uniphier/Makefile | 5 ++
> > drivers/media/platform/uniphier/hsc-core.c | 8 ---
> > .../platform/uniphier/uniphier-adapter.c | 54 +++++++++++++++++++
> > .../platform/uniphier/uniphier-adapter.h | 42 +++++++++++++++
> > 4 files changed, 101 insertions(+), 8 deletions(-)
> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h
> >
> > diff --git a/drivers/media/platform/uniphier/Makefile
> b/drivers/media/platform/uniphier/Makefile
> > index 0622f04d9e68..9e75ad081b77 100644
> > --- a/drivers/media/platform/uniphier/Makefile
> > +++ b/drivers/media/platform/uniphier/Makefile
> > @@ -3,3 +3,8 @@ uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o
> hsc-dma.o
> > uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o
> >
> > obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
> > +
> > +ccflags-y += -Idrivers/media/dvb-frontends/
> > +ccflags-y += -Idrivers/media/tuners/
>
>
> Please add $(srctree)/ like
>
> ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
> ccflags-y += -I$(srctree)/drivers/media/tuners/
>
>
> Currently, it works $(srctree)/,
> but I really want to rip off the build system hack.

Thanks, I agree with your opinion, but other Makefiles in drivers/media use
same hack. I don't know other way to include headers of demodulators and
tuners...

Do you have any good ideas?


Regards,
--
Katsuhiro Suzuki


>
>
>
>
>
> --
> Best Regards
> Masahiro Yamada



2018-06-04 00:54:16

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers

2018-06-04 9:08 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> Hello Yamada-san,
>
>> -----Original Message-----
>> From: Masahiro Yamada <[email protected]>
>> Sent: Saturday, June 2, 2018 9:00 PM
>> To: Suzuki, Katsuhiro/鈴木 勝博 <[email protected]>
>> Cc: Mauro Carvalho Chehab <[email protected]>;
>> [email protected]; Masami Hiramatsu <[email protected]>;
>> Jassi Brar <[email protected]>; linux-arm-kernel
>> <[email protected]>; Linux Kernel Mailing List
>> <[email protected]>
>> Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers
>>
>> 2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
>> > This patch adds common module for UniPhier DVB adapter drivers
>> > that equipments tuners and demod that connected by I2C and
>> > UniPhier demux.
>> >
>> > Signed-off-by: Katsuhiro Suzuki <[email protected]>
>> > ---
>> > drivers/media/platform/uniphier/Makefile | 5 ++
>> > drivers/media/platform/uniphier/hsc-core.c | 8 ---
>> > .../platform/uniphier/uniphier-adapter.c | 54 +++++++++++++++++++
>> > .../platform/uniphier/uniphier-adapter.h | 42 +++++++++++++++
>> > 4 files changed, 101 insertions(+), 8 deletions(-)
>> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
>> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h
>> >
>> > diff --git a/drivers/media/platform/uniphier/Makefile
>> b/drivers/media/platform/uniphier/Makefile
>> > index 0622f04d9e68..9e75ad081b77 100644
>> > --- a/drivers/media/platform/uniphier/Makefile
>> > +++ b/drivers/media/platform/uniphier/Makefile
>> > @@ -3,3 +3,8 @@ uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o
>> hsc-dma.o
>> > uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o
>> >
>> > obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
>> > +
>> > +ccflags-y += -Idrivers/media/dvb-frontends/
>> > +ccflags-y += -Idrivers/media/tuners/
>>
>>
>> Please add $(srctree)/ like
>>
>> ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
>> ccflags-y += -I$(srctree)/drivers/media/tuners/
>>
>>
>> Currently, it works $(srctree)/,
>> but I really want to rip off the build system hack.
>
> Thanks, I agree with your opinion, but other Makefiles in drivers/media use
> same hack. I don't know other way to include headers of demodulators and
> tuners...
>
> Do you have any good ideas?
>
>


My suggestion is to add '$(srctree)/'.

For clarification,



Bad:

ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/



Good:

ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
ccflags-y += -I$(srctree)/drivers/media/tuners/





I want to fix this tree-wide,
then remove the 'addtree' from scripts/Kbuild.include
but I have not been able to find time for that.

This is a new file, so just suggested to add '$(srctree)/'



If you want to know the context:
https://patchwork.kernel.org/patch/9632347/


--
Best Regards
Masahiro Yamada

2018-06-04 01:55:13

by Katsuhiro Suzuki

[permalink] [raw]
Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers

Hello Yamada-san,

> -----Original Message-----
> From: Masahiro Yamada <[email protected]>
> Sent: Monday, June 4, 2018 9:53 AM
> To: Suzuki, Katsuhiro/鈴木 勝博 <[email protected]>
> Cc: Mauro Carvalho Chehab <[email protected]>;
> [email protected]; Masami Hiramatsu <[email protected]>;
> Jassi Brar <[email protected]>; linux-arm-kernel
> <[email protected]>; Linux Kernel Mailing List
> <[email protected]>
> Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers
>
> 2018-06-04 9:08 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> > Hello Yamada-san,
> >
> >> -----Original Message-----
> >> From: Masahiro Yamada <[email protected]>
> >> Sent: Saturday, June 2, 2018 9:00 PM
> >> To: Suzuki, Katsuhiro/鈴木 勝博 <[email protected]>
> >> Cc: Mauro Carvalho Chehab <[email protected]>;
> >> [email protected]; Masami Hiramatsu <[email protected]>;
> >> Jassi Brar <[email protected]>; linux-arm-kernel
> >> <[email protected]>; Linux Kernel Mailing List
> >> <[email protected]>
> >> Subject: Re: [PATCH 6/8] media: uniphier: add common module of DVB adapter drivers
> >>
> >> 2018-05-30 18:09 GMT+09:00 Katsuhiro Suzuki <[email protected]>:
> >> > This patch adds common module for UniPhier DVB adapter drivers
> >> > that equipments tuners and demod that connected by I2C and
> >> > UniPhier demux.
> >> >
> >> > Signed-off-by: Katsuhiro Suzuki <[email protected]>
> >> > ---
> >> > drivers/media/platform/uniphier/Makefile | 5 ++
> >> > drivers/media/platform/uniphier/hsc-core.c | 8 ---
> >> > .../platform/uniphier/uniphier-adapter.c | 54 +++++++++++++++++++
> >> > .../platform/uniphier/uniphier-adapter.h | 42 +++++++++++++++
> >> > 4 files changed, 101 insertions(+), 8 deletions(-)
> >> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.c
> >> > create mode 100644 drivers/media/platform/uniphier/uniphier-adapter.h
> >> >
> >> > diff --git a/drivers/media/platform/uniphier/Makefile
> >> b/drivers/media/platform/uniphier/Makefile
> >> > index 0622f04d9e68..9e75ad081b77 100644
> >> > --- a/drivers/media/platform/uniphier/Makefile
> >> > +++ b/drivers/media/platform/uniphier/Makefile
> >> > @@ -3,3 +3,8 @@ uniphier-dvb-y += hsc-core.o hsc-ucode.o hsc-css.o hsc-ts.o
> >> hsc-dma.o
> >> > uniphier-dvb-$(CONFIG_DVB_UNIPHIER_LD11) += hsc-ld11.o
> >> >
> >> > obj-$(CONFIG_DVB_UNIPHIER) += uniphier-dvb.o
> >> > +
> >> > +ccflags-y += -Idrivers/media/dvb-frontends/
> >> > +ccflags-y += -Idrivers/media/tuners/
> >>
> >>
> >> Please add $(srctree)/ like
> >>
> >> ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
> >> ccflags-y += -I$(srctree)/drivers/media/tuners/
> >>
> >>
> >> Currently, it works $(srctree)/,
> >> but I really want to rip off the build system hack.
> >
> > Thanks, I agree with your opinion, but other Makefiles in drivers/media use
> > same hack. I don't know other way to include headers of demodulators and
> > tuners...
> >
> > Do you have any good ideas?
> >
> >
>
>
> My suggestion is to add '$(srctree)/'.
>
> For clarification,
>
>
>
> Bad:
>
> ccflags-y += -Idrivers/media/dvb-frontends/
> ccflags-y += -Idrivers/media/tuners/
>
>
>
> Good:
>
> ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
> ccflags-y += -I$(srctree)/drivers/media/tuners/
>
>

OK, I understand.


>
>
>
> I want to fix this tree-wide,
> then remove the 'addtree' from scripts/Kbuild.include
> but I have not been able to find time for that.
>
> This is a new file, so just suggested to add '$(srctree)/'
>
>
>
> If you want to know the context:
> https://patchwork.kernel.org/patch/9632347/
>

Thank you, that's interesting issue...


Regards,
--
Katsuhiro Suzuki


>
> --
> Best Regards
> Masahiro Yamada