From cd92c3bb88c9b47a4b57b27a0a5ff5e813165296 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 13 Aug 2019 09:13:00 +0200 Subject: [PATCH 1/2] Allwinner: Join already upstreamed patches --- .../devices/H6/patches/linux/04-dma.patch | 658 ------------------ .../devices/H6/patches/linux/07-opi3.patch | 217 ------ ...ts-allwinner-OrangePiOnePlus-updates.patch | 13 +- ...enable-usb3.patch => 10-beelink-gs1.patch} | 27 + .../linux/11-beelink-gs1-enable-ddc-reg.patch | 40 -- .../linux/0002-backport-from-5.3.patch | 633 +++++++++++++++++ ...ing.patch => 0003-backport-from-5.4.patch} | 304 +++++++- .../patches/linux/0013-force-full-range.patch | 43 ++ .../patches/linux/0014-regulator-fixes.patch | 75 -- 9 files changed, 974 insertions(+), 1036 deletions(-) delete mode 100644 projects/Allwinner/devices/H6/patches/linux/04-dma.patch rename projects/Allwinner/devices/H6/patches/linux/{10-beelink-gs1-enable-usb3.patch => 10-beelink-gs1.patch} (50%) delete mode 100644 projects/Allwinner/devices/H6/patches/linux/11-beelink-gs1-enable-ddc-reg.patch rename projects/Allwinner/patches/linux/{0013-color-range-encoding.patch => 0003-backport-from-5.4.patch} (60%) create mode 100644 projects/Allwinner/patches/linux/0013-force-full-range.patch delete mode 100644 projects/Allwinner/patches/linux/0014-regulator-fixes.patch diff --git a/projects/Allwinner/devices/H6/patches/linux/04-dma.patch b/projects/Allwinner/devices/H6/patches/linux/04-dma.patch deleted file mode 100644 index a5c67e12bc..0000000000 --- a/projects/Allwinner/devices/H6/patches/linux/04-dma.patch +++ /dev/null @@ -1,658 +0,0 @@ -From f04472a823847403fd9ea34915803c21b8c27175 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 09:47:17 +0100 -Subject: [PATCH 01/12] dt-bindings: arm64: allwinner: h6: Add binding for DMA - controller - -DMA in H6 is similar to other DMA controller, except it is first which -supports more than 32 request sources and has 16 channels. It also needs -additional clock to be enabled. - -Signed-off-by: Jernej Skrabec ---- - Documentation/devicetree/bindings/dma/sun6i-dma.txt | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt -index 7fccc20d8331..cae31f4e77ba 100644 ---- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt -+++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt -@@ -28,12 +28,17 @@ Example: - }; - - ------------------------------------------------------------------------------ --For A64 DMA controller: -+For A64 and H6 DMA controller: - - Required properties: --- compatible: "allwinner,sun50i-a64-dma" -+- compatible: Must be one of -+ "allwinner,sun50i-a64-dma" -+ "allwinner,sun50i-h6-dma" - - dma-channels: Number of DMA channels supported by the controller. - Refer to Documentation/devicetree/bindings/dma/dma.txt -+- clocks: In addition to parent AHB clock, it should also contain mbus -+ clock (H6 only) -+- clock-names: Should contain "bus" and "mbus" (H6 only) - - all properties above, i.e. reg, interrupts, clocks, resets and #dma-cells - - Optional properties: --- -2.20.1 - - -From 638f21d14b0f22c7e9709edb4ac7b52f0e2a744e Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 09:55:38 +0100 -Subject: [PATCH 02/12] dmaengine: sun6i: Add a quirk for additional mbus clock - -H6 DMA controller needs additional mbus clock to be enabled. - -Add a quirk for it and handle it accordingly. - -Signed-off-by: Jernej Skrabec ---- - drivers/dma/sun6i-dma.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c -index 0cd13f17fc11..761555080325 100644 ---- a/drivers/dma/sun6i-dma.c -+++ b/drivers/dma/sun6i-dma.c -@@ -129,6 +129,7 @@ struct sun6i_dma_config { - u32 dst_burst_lengths; - u32 src_addr_widths; - u32 dst_addr_widths; -+ bool mbus_clk; - }; - - /* -@@ -182,6 +183,7 @@ struct sun6i_dma_dev { - struct dma_device slave; - void __iomem *base; - struct clk *clk; -+ struct clk *clk_mbus; - int irq; - spinlock_t lock; - struct reset_control *rstc; -@@ -1208,6 +1210,14 @@ static int sun6i_dma_probe(struct platform_device *pdev) - return PTR_ERR(sdc->clk); - } - -+ if (sdc->cfg->mbus_clk) { -+ sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus"); -+ if (IS_ERR(sdc->clk_mbus)) { -+ dev_err(&pdev->dev, "No mbus clock specified\n"); -+ return PTR_ERR(sdc->clk_mbus); -+ } -+ } -+ - sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); - if (IS_ERR(sdc->rstc)) { - dev_err(&pdev->dev, "No reset controller specified\n"); -@@ -1312,11 +1322,19 @@ static int sun6i_dma_probe(struct platform_device *pdev) - goto err_reset_assert; - } - -+ if (sdc->cfg->mbus_clk) { -+ ret = clk_prepare_enable(sdc->clk_mbus); -+ if (ret) { -+ dev_err(&pdev->dev, "Couldn't enable mbus clock\n"); -+ goto err_clk_disable; -+ } -+ } -+ - ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, - dev_name(&pdev->dev), sdc); - if (ret) { - dev_err(&pdev->dev, "Cannot request IRQ\n"); -- goto err_clk_disable; -+ goto err_mbus_clk_disable; - } - - ret = dma_async_device_register(&sdc->slave); -@@ -1341,6 +1359,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) - dma_async_device_unregister(&sdc->slave); - err_irq_disable: - sun6i_kill_tasklet(sdc); -+err_mbus_clk_disable: -+ clk_disable_unprepare(sdc->clk_mbus); - err_clk_disable: - clk_disable_unprepare(sdc->clk); - err_reset_assert: -@@ -1359,6 +1379,7 @@ static int sun6i_dma_remove(struct platform_device *pdev) - - sun6i_kill_tasklet(sdc); - -+ clk_disable_unprepare(sdc->clk_mbus); - clk_disable_unprepare(sdc->clk); - reset_control_assert(sdc->rstc); - --- -2.20.1 - - -From 74a1f9f2f199e9b23ce0b9710efabbaee82f5605 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 12:51:35 +0100 -Subject: [PATCH 03/12] dmaengine: sun6i: Add a quirk for setting DRQ fields - -H6 DMA has more than 32 possible DRQs. That means that current maximum -of 31 DRQs is not enough anymore. - -Add a quirk which will set source and destination DRQ number. - -Signed-off-by: Jernej Skrabec ---- - drivers/dma/sun6i-dma.c | 48 ++++++++++++++++++++++++----------------- - 1 file changed, 28 insertions(+), 20 deletions(-) - -diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c -index 761555080325..9dd23b76d841 100644 ---- a/drivers/dma/sun6i-dma.c -+++ b/drivers/dma/sun6i-dma.c -@@ -68,15 +68,15 @@ - #define DMA_CHAN_LLI_ADDR 0x08 - - #define DMA_CHAN_CUR_CFG 0x0c --#define DMA_CHAN_MAX_DRQ 0x1f --#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ) -+#define DMA_CHAN_MAX_DRQ_A31 0x1f -+#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) - #define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) - #define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) - #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) - #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) - #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) - --#define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16) -+#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) - #define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) - #define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) - #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) -@@ -125,6 +125,7 @@ struct sun6i_dma_config { - */ - void (*clock_autogate_enable)(struct sun6i_dma_dev *); - void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); -+ void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); - u32 src_burst_lengths; - u32 dst_burst_lengths; - u32 src_addr_widths; -@@ -311,6 +312,12 @@ static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst) - DMA_CHAN_CFG_DST_BURST_H3(dst_burst); - } - -+static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) -+{ -+ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) | -+ DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); -+} -+ - static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) - { - struct sun6i_desc *txd = pchan->desc; -@@ -634,14 +641,13 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( - - burst = convert_burst(8); - width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); -- v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_DST_LINEAR_MODE | -+ v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE | - DMA_CHAN_CFG_SRC_LINEAR_MODE | - DMA_CHAN_CFG_SRC_WIDTH(width) | - DMA_CHAN_CFG_DST_WIDTH(width); - - sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); -+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); - - sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); - -@@ -695,9 +701,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( - v_lli->dst = sconfig->dst_addr; - v_lli->cfg = lli_cfg | - DMA_CHAN_CFG_DST_IO_MODE | -- DMA_CHAN_CFG_SRC_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_DST_DRQ(vchan->port); -+ DMA_CHAN_CFG_SRC_LINEAR_MODE; -+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); - - dev_dbg(chan2dev(chan), - "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", -@@ -710,9 +715,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( - v_lli->dst = sg_dma_address(sg); - v_lli->cfg = lli_cfg | - DMA_CHAN_CFG_DST_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_IO_MODE | -- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_SRC_DRQ(vchan->port); -+ DMA_CHAN_CFG_SRC_IO_MODE; -+ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); - - dev_dbg(chan2dev(chan), - "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", -@@ -780,17 +784,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( - v_lli->dst = sconfig->dst_addr; - v_lli->cfg = lli_cfg | - DMA_CHAN_CFG_DST_IO_MODE | -- DMA_CHAN_CFG_SRC_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_DST_DRQ(vchan->port); -+ DMA_CHAN_CFG_SRC_LINEAR_MODE; -+ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); - } else { - v_lli->src = sconfig->src_addr; - v_lli->dst = buf_addr + period_len * i; - v_lli->cfg = lli_cfg | - DMA_CHAN_CFG_DST_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_IO_MODE | -- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | -- DMA_CHAN_CFG_SRC_DRQ(vchan->port); -+ DMA_CHAN_CFG_SRC_IO_MODE; -+ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); - } - - prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); -@@ -1055,6 +1057,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { - .nr_max_requests = 30, - .nr_max_vchans = 53, - .set_burst_length = sun6i_set_burst_length_a31, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1076,6 +1079,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = { - .nr_max_vchans = 37, - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1092,6 +1096,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = { - .nr_max_vchans = 39, - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1115,6 +1120,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { - .nr_max_vchans = 34, - .clock_autogate_enable = sun6i_enable_clock_autogate_h3, - .set_burst_length = sun6i_set_burst_length_h3, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1134,6 +1140,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { - static struct sun6i_dma_config sun50i_a64_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_h3, - .set_burst_length = sun6i_set_burst_length_h3, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1157,6 +1164,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = { - .nr_max_vchans = 24, - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, -+ .set_drq = sun6i_set_drq_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1272,8 +1280,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) - ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); - if (ret && !sdc->max_request) { - dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", -- DMA_CHAN_MAX_DRQ); -- sdc->max_request = DMA_CHAN_MAX_DRQ; -+ DMA_CHAN_MAX_DRQ_A31); -+ sdc->max_request = DMA_CHAN_MAX_DRQ_A31; - } - - /* --- -2.20.1 - - -From 20465d9f33a6686cc283f5874428d80fbce29f46 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 13:35:02 +0100 -Subject: [PATCH 04/12] dmaengine: sun6i: Add a quirk for setting mode fields - -H6 DMA has mode fields in different position than any other currently -supported DMA controller. - -Add a quirk for that. - -Signed-off-by: Jernej Skrabec ---- - drivers/dma/sun6i-dma.c | 46 ++++++++++++++++++++++++----------------- - 1 file changed, 27 insertions(+), 19 deletions(-) - -diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c -index 9dd23b76d841..6a37f8bb39b1 100644 ---- a/drivers/dma/sun6i-dma.c -+++ b/drivers/dma/sun6i-dma.c -@@ -70,15 +70,13 @@ - #define DMA_CHAN_CUR_CFG 0x0c - #define DMA_CHAN_MAX_DRQ_A31 0x1f - #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) --#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) --#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) -+#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) - #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) - #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) - #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) - - #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) --#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) --#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) -+#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) - #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) - #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) - #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) -@@ -98,6 +96,8 @@ - #define LLI_LAST_ITEM 0xfffff800 - #define NORMAL_WAIT 8 - #define DRQ_SDRAM 1 -+#define LINEAR_MODE 0 -+#define IO_MODE 1 - - /* forward declaration */ - struct sun6i_dma_dev; -@@ -126,6 +126,7 @@ struct sun6i_dma_config { - void (*clock_autogate_enable)(struct sun6i_dma_dev *); - void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); - void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); -+ void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode); - u32 src_burst_lengths; - u32 dst_burst_lengths; - u32 src_addr_widths; -@@ -318,6 +319,12 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) - DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); - } - -+static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) -+{ -+ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | -+ DMA_CHAN_CFG_DST_MODE_A31(dst_mode); -+} -+ - static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) - { - struct sun6i_desc *txd = pchan->desc; -@@ -641,13 +648,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( - - burst = convert_burst(8); - width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); -- v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_WIDTH(width) | -+ v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) | - DMA_CHAN_CFG_DST_WIDTH(width); - - sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); - sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); -+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE); - - sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); - -@@ -699,10 +705,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( - if (dir == DMA_MEM_TO_DEV) { - v_lli->src = sg_dma_address(sg); - v_lli->dst = sconfig->dst_addr; -- v_lli->cfg = lli_cfg | -- DMA_CHAN_CFG_DST_IO_MODE | -- DMA_CHAN_CFG_SRC_LINEAR_MODE; -+ v_lli->cfg = lli_cfg; - sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); -+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); - - dev_dbg(chan2dev(chan), - "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", -@@ -713,10 +718,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( - } else { - v_lli->src = sconfig->src_addr; - v_lli->dst = sg_dma_address(sg); -- v_lli->cfg = lli_cfg | -- DMA_CHAN_CFG_DST_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_IO_MODE; -+ v_lli->cfg = lli_cfg; - sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); -+ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); - - dev_dbg(chan2dev(chan), - "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", -@@ -782,17 +786,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( - if (dir == DMA_MEM_TO_DEV) { - v_lli->src = buf_addr + period_len * i; - v_lli->dst = sconfig->dst_addr; -- v_lli->cfg = lli_cfg | -- DMA_CHAN_CFG_DST_IO_MODE | -- DMA_CHAN_CFG_SRC_LINEAR_MODE; -+ v_lli->cfg = lli_cfg; - sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); -+ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); - } else { - v_lli->src = sconfig->src_addr; - v_lli->dst = buf_addr + period_len * i; -- v_lli->cfg = lli_cfg | -- DMA_CHAN_CFG_DST_LINEAR_MODE | -- DMA_CHAN_CFG_SRC_IO_MODE; -+ v_lli->cfg = lli_cfg; - sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); -+ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); - } - - prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); -@@ -1058,6 +1060,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { - .nr_max_vchans = 53, - .set_burst_length = sun6i_set_burst_length_a31, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1080,6 +1083,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1097,6 +1101,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1121,6 +1126,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_h3, - .set_burst_length = sun6i_set_burst_length_h3, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1141,6 +1147,7 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_h3, - .set_burst_length = sun6i_set_burst_length_h3, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1165,6 +1172,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = { - .clock_autogate_enable = sun6i_enable_clock_autogate_a23, - .set_burst_length = sun6i_set_burst_length_a31, - .set_drq = sun6i_set_drq_a31, -+ .set_mode = sun6i_set_mode_a31, - .src_burst_lengths = BIT(1) | BIT(8), - .dst_burst_lengths = BIT(1) | BIT(8), - .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | --- -2.20.1 - - -From 7d4d497a1c5395d452930fdf0177f82520c09066 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 13:50:24 +0100 -Subject: [PATCH 05/12] dmaengine: sun6i: Add support for H6 DMA - -H6 DMA has more than 32 supported DRQs, which means that configuration -register is slightly rearranged. It also needs additional clock to be -enabled. - -Add support for it. - -Signed-off-by: Jernej Skrabec ---- - drivers/dma/sun6i-dma.c | 44 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 42 insertions(+), 2 deletions(-) - -diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c -index 6a37f8bb39b1..eceedd139651 100644 ---- a/drivers/dma/sun6i-dma.c -+++ b/drivers/dma/sun6i-dma.c -@@ -69,14 +69,19 @@ - - #define DMA_CHAN_CUR_CFG 0x0c - #define DMA_CHAN_MAX_DRQ_A31 0x1f -+#define DMA_CHAN_MAX_DRQ_H6 0x3f - #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) -+#define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6) - #define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) -+#define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8) - #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) - #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) - #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) - - #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) -+#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16) - #define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) -+#define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16) - #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) - #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) - #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) -@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) - DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); - } - -+static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq) -+{ -+ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) | -+ DMA_CHAN_CFG_DST_DRQ_H6(dst_drq); -+} -+ - static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) - { - *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | - DMA_CHAN_CFG_DST_MODE_A31(dst_mode); - } - -+static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode) -+{ -+ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) | -+ DMA_CHAN_CFG_DST_MODE_H6(dst_mode); -+} -+ - static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) - { - struct sun6i_desc *txd = pchan->desc; -@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { - BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), - }; - -+/* -+ * The H6 binding uses the number of dma channels from the -+ * device tree node. -+ */ -+static struct sun6i_dma_config sun50i_h6_dma_cfg = { -+ .clock_autogate_enable = sun6i_enable_clock_autogate_h3, -+ .set_burst_length = sun6i_set_burst_length_h3, -+ .set_drq = sun6i_set_drq_h6, -+ .set_mode = sun6i_set_mode_h6, -+ .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), -+ .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), -+ .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | -+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | -+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), -+ .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | -+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | -+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), -+ .mbus_clk = true, -+}; -+ - /* - * The V3s have only 8 physical channels, a maximum DRQ port id of 23, - * and a total of 24 usable source and destination endpoints. -@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = { - { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, - { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, - { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, -+ { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, sun6i_dma_match); -@@ -1288,8 +1328,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) - ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); - if (ret && !sdc->max_request) { - dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", -- DMA_CHAN_MAX_DRQ_A31); -- sdc->max_request = DMA_CHAN_MAX_DRQ_A31; -+ DMA_CHAN_MAX_DRQ_H6); -+ sdc->max_request = DMA_CHAN_MAX_DRQ_H6; - } - - /* --- -2.20.1 - - -From b9d20d1b5577e4d73b47b9303798484f6699cfd4 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 26 Jan 2019 14:20:21 +0100 -Subject: [PATCH 06/12] arm64: dts: allwinner: h6: Add DMA node - -H6 has DMA controller which supports 16 channels. - -Add a node for it. - -Signed-off-by: Jernej Skrabec ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index d93a7add67e7..62a0eae77639 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -178,6 +178,18 @@ - #reset-cells = <1>; - }; - -+ dma: dma-controller@3002000 { -+ compatible = "allwinner,sun50i-h6-dma"; -+ reg = <0x03002000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>; -+ clock-names = "bus", "mbus"; -+ dma-channels = <16>; -+ dma-requests = <46>; -+ resets = <&ccu RST_BUS_DMA>; -+ #dma-cells = <1>; -+ }; -+ - gic: interrupt-controller@3021000 { - compatible = "arm,gic-400"; - reg = <0x03021000 0x1000>, --- -2.20.1 diff --git a/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch b/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch index d302a8ad9a..f6f80226ef 100644 --- a/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch +++ b/projects/Allwinner/devices/H6/patches/linux/07-opi3.patch @@ -367,223 +367,6 @@ index 17d4969901086..6d6b1f66796d9 100644 vmmc-supply = <®_cldo1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ -From b641bc59468e93ab57fd016ad36b037f3890b994 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 26 Mar 2019 15:06:37 +0100 -Subject: [PATCH 15/34] drm: sun4i: Add support for enabling DDC I2C bus power - to dw_hdmi glue - -Orange Pi 3 board requires enabling DDC I2C bus via some GPIO connected -transistors, before the bus can be used. - -Model this as a power supply for DDC bus on the HDMI connector connected -to the output port (port 1) of the HDMI controller. - -Signed-off-by: Ondrej Jirman ---- - drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 60 ++++++++++++++++++++++++++- - drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 + - 2 files changed, 60 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -index 39d8509d96a0d..1b6ffba41177f 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -@@ -98,6 +98,30 @@ static u32 sun8i_dw_hdmi_find_possible_crtcs(struct drm_device *drm, - return crtcs; - } - -+static int sun8i_dw_hdmi_find_connector_pdev(struct device *dev, -+ struct platform_device **pdev_out) -+{ -+ struct platform_device* pdev; -+ struct device_node *remote; -+ -+ remote = of_graph_get_remote_node(dev->of_node, 1, -1); -+ if (!remote) -+ return -ENODEV; -+ -+ if (!of_device_is_compatible(remote, "hdmi-connector")) { -+ of_node_put(remote); -+ return -ENODEV; -+ } -+ -+ pdev = of_find_device_by_node(remote); -+ of_node_put(remote); -+ if (!pdev) -+ return -ENODEV; -+ -+ *pdev_out = pdev; -+ return 0; -+} -+ - static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - void *data) - { -@@ -151,16 +175,34 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - return PTR_ERR(hdmi->regulator); - } - -+ ret = sun8i_dw_hdmi_find_connector_pdev(dev, &hdmi->connector_pdev); -+ if (!ret) { -+ hdmi->ddc_regulator = regulator_get(&hdmi->connector_pdev->dev, "ddc"); -+ if (IS_ERR(hdmi->ddc_regulator)) { -+ platform_device_put(hdmi->connector_pdev); -+ dev_err(dev, "Couldn't get ddc regulator\n"); -+ return PTR_ERR(hdmi->ddc_regulator); -+ } -+ } -+ - ret = regulator_enable(hdmi->regulator); - if (ret) { - dev_err(dev, "Failed to enable regulator\n"); -- return ret; -+ goto err_unref_ddc_regulator; -+ } -+ -+ if (hdmi->ddc_regulator) { -+ ret = regulator_enable(hdmi->ddc_regulator); -+ if (ret) { -+ dev_err(dev, "Failed to enable ddc regulator\n"); -+ goto err_disable_regulator; -+ } - } - - ret = reset_control_deassert(hdmi->rst_ctrl); - if (ret) { - dev_err(dev, "Could not deassert ctrl reset control\n"); -- goto err_disable_regulator; -+ goto err_disable_ddc_regulator; - } - - ret = clk_prepare_enable(hdmi->clk_tmds); -@@ -213,8 +255,15 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - clk_disable_unprepare(hdmi->clk_tmds); - err_assert_ctrl_reset: - reset_control_assert(hdmi->rst_ctrl); -+err_disable_ddc_regulator: -+ if (hdmi->ddc_regulator) -+ regulator_disable(hdmi->ddc_regulator); - err_disable_regulator: - regulator_disable(hdmi->regulator); -+err_unref_ddc_regulator: -+ if (hdmi->ddc_regulator) -+ regulator_put(hdmi->ddc_regulator); -+ platform_device_put(hdmi->connector_pdev); - - return ret; - } -@@ -229,6 +278,13 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, - clk_disable_unprepare(hdmi->clk_tmds); - reset_control_assert(hdmi->rst_ctrl); - regulator_disable(hdmi->regulator); -+ -+ if (hdmi->ddc_regulator) { -+ regulator_disable(hdmi->ddc_regulator); -+ regulator_put(hdmi->ddc_regulator); -+ } -+ -+ platform_device_put(hdmi->connector_pdev); - } - - static const struct component_ops sun8i_dw_hdmi_ops = { -diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -index 720c5aa8adc14..60f5200aee73b 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -@@ -188,8 +188,10 @@ struct sun8i_dw_hdmi { - struct sun8i_hdmi_phy *phy; - struct dw_hdmi_plat_data plat_data; - struct regulator *regulator; -+ struct regulator *ddc_regulator; - const struct sun8i_dw_hdmi_quirks *quirks; - struct reset_control *rst_ctrl; -+ struct platform_device *connector_pdev; - }; - - static inline struct sun8i_dw_hdmi * - -From c1d7c7796ea7e76829c71b993c7531f23c0f5913 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 9 Apr 2019 01:41:58 +0200 -Subject: [PATCH 16/34] arm64: dts: allwinner: orange-pi-3: Enable HDMI output - -Orange Pi 3 has a DDC_CEC_EN signal connected to PH2, that enables the DDC -I2C bus voltage shifter. Before EDID can be read, we need to pull PH2 high. - -Signed-off-by: Ondrej Jirman ---- - .../dts/allwinner/sun50i-h6-orangepi-3.dts | 35 +++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts -index 6d6b1f66796d9..58a6635c909e3 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts -@@ -22,6 +22,18 @@ - stdout-path = "serial0:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ ddc-supply = <®_ddc>; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - -@@ -37,6 +49,15 @@ - }; - }; - -+ reg_ddc: ddc-io { -+ compatible = "regulator-fixed"; -+ regulator-name = "ddc-io"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ -+ }; -+ - reg_vcc5v: vcc5v { - /* board wide 5V supply directly from the DC jack */ - compatible = "regulator-fixed"; -@@ -72,6 +93,10 @@ - cpu-supply = <®_dcdca>; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - status = "okay"; - }; -@@ -91,6 +116,16 @@ - status = "okay"; - }; - -+&hdmi { -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - From 200cf18794214700f023440021cb7fd40dcc0f01 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Tue, 9 Apr 2019 00:16:35 +0200 diff --git a/projects/Allwinner/devices/H6/patches/linux/08-arm64-dts-allwinner-OrangePiOnePlus-updates.patch b/projects/Allwinner/devices/H6/patches/linux/08-arm64-dts-allwinner-OrangePiOnePlus-updates.patch index a83150bb81..43c32bc988 100644 --- a/projects/Allwinner/devices/H6/patches/linux/08-arm64-dts-allwinner-OrangePiOnePlus-updates.patch +++ b/projects/Allwinner/devices/H6/patches/linux/08-arm64-dts-allwinner-OrangePiOnePlus-updates.patch @@ -2,7 +2,7 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts b/arc index 12e17567ab56..fd9dcefcd223 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts -@@ -9,4 +9,86 @@ +@@ -9,4 +9,77 @@ / { model = "OrangePi One Plus"; compatible = "xunlong,orangepi-one-plus", "allwinner,sun50i-h6"; @@ -14,7 +14,7 @@ index 12e17567ab56..fd9dcefcd223 100644 + connector { + compatible = "hdmi-connector"; + type = "a"; -+ ddc-supply = <®_ddc>; ++ ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ + + port { + hdmi_con_in: endpoint { @@ -23,15 +23,6 @@ index 12e17567ab56..fd9dcefcd223 100644 + }; + }; + -+ reg_ddc: ddc-io { -+ compatible = "regulator-fixed"; -+ regulator-name = "ddc-io"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ -+ }; -+ + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc-gmac-3v3"; diff --git a/projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1-enable-usb3.patch b/projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1.patch similarity index 50% rename from projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1-enable-usb3.patch rename to projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1.patch index 057b7c0b41..7caa8d9fd6 100644 --- a/projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1-enable-usb3.patch +++ b/projects/Allwinner/devices/H6/patches/linux/10-beelink-gs1.patch @@ -38,3 +38,30 @@ index 0dc33c90dd60..ef595e6a0cd6 100644 -- 2.20.1 +From: =?utf-8?b?Q2zDqW1lbnQgUMOpcm9u?= +Subject: [PATCH] arm64: dts: allwinner: Enable DDC regulator for Beelink GS1 +Date: Mon, 12 Aug 2019 12:23:55 +0200 +Content-Type: text/plain; charset="utf-8" + +Beelink GS1 has a DDC I2C bus voltage shifter. This is actually missing +and video is limited to 1024x768 due to missing EDID information. + +Add the DDC regulator in the device-tree. + +Signed-off-by: Clément Péron +--- + arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +index 680dc29cb089..67d7f269c5da 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +@@ -25,6 +25,7 @@ + connector { + compatible = "hdmi-connector"; + type = "a"; ++ ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ + + port { + hdmi_con_in: endpoint { diff --git a/projects/Allwinner/devices/H6/patches/linux/11-beelink-gs1-enable-ddc-reg.patch b/projects/Allwinner/devices/H6/patches/linux/11-beelink-gs1-enable-ddc-reg.patch deleted file mode 100644 index 2c3d2f0f78..0000000000 --- a/projects/Allwinner/devices/H6/patches/linux/11-beelink-gs1-enable-ddc-reg.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ad3b90a4e8009cc87cfdaf1bf08ba7fd85422b17 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= -Date: Sun, 11 Aug 2019 19:34:25 +0200 -Subject: [PATCH] ARM: dts: allwinner: Beelink GS1 enable DDC regulator - ---- - .../arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -index 680dc29cb089..bc67dda37690 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts -@@ -25,6 +25,7 @@ - connector { - compatible = "hdmi-connector"; - type = "a"; -+ ddc-supply = <®_ddc>; - - port { - hdmi_con_in: endpoint { -@@ -43,6 +44,15 @@ - }; - }; - -+ reg_ddc: ddc-io { -+ compatible = "regulator-fixed"; -+ regulator-name = "ddc-io"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ -+ }; -+ - reg_vcc5v: vcc5v { - /* board wide 5V supply directly from the DC jack */ - compatible = "regulator-fixed"; --- -2.20.1 - diff --git a/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch b/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch index 64d8ced047..5a4442f34c 100644 --- a/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch +++ b/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch @@ -2525,3 +2525,636 @@ index 4802902e128f..9e464d40cbff 100644 -- 2.21.0 +From 43a90fc76a3ebe0ce3315725c7f0fa832df50c8e Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 27 May 2019 22:14:54 +0200 +Subject: [PATCH 1/4] dmaengine: sun6i: Add a quirk for additional mbus clock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +H6 DMA controller needs additional mbus clock to be enabled. + +Add a quirk for it and handle it accordingly. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Vinod Koul +--- + drivers/dma/sun6i-dma.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c +index 0cd13f17fc11..7d9606997251 100644 +--- a/drivers/dma/sun6i-dma.c ++++ b/drivers/dma/sun6i-dma.c +@@ -129,6 +129,7 @@ struct sun6i_dma_config { + u32 dst_burst_lengths; + u32 src_addr_widths; + u32 dst_addr_widths; ++ bool has_mbus_clk; + }; + + /* +@@ -182,6 +183,7 @@ struct sun6i_dma_dev { + struct dma_device slave; + void __iomem *base; + struct clk *clk; ++ struct clk *clk_mbus; + int irq; + spinlock_t lock; + struct reset_control *rstc; +@@ -1208,6 +1210,14 @@ static int sun6i_dma_probe(struct platform_device *pdev) + return PTR_ERR(sdc->clk); + } + ++ if (sdc->cfg->has_mbus_clk) { ++ sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus"); ++ if (IS_ERR(sdc->clk_mbus)) { ++ dev_err(&pdev->dev, "No mbus clock specified\n"); ++ return PTR_ERR(sdc->clk_mbus); ++ } ++ } ++ + sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); + if (IS_ERR(sdc->rstc)) { + dev_err(&pdev->dev, "No reset controller specified\n"); +@@ -1312,11 +1322,19 @@ static int sun6i_dma_probe(struct platform_device *pdev) + goto err_reset_assert; + } + ++ if (sdc->cfg->has_mbus_clk) { ++ ret = clk_prepare_enable(sdc->clk_mbus); ++ if (ret) { ++ dev_err(&pdev->dev, "Couldn't enable mbus clock\n"); ++ goto err_clk_disable; ++ } ++ } ++ + ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, + dev_name(&pdev->dev), sdc); + if (ret) { + dev_err(&pdev->dev, "Cannot request IRQ\n"); +- goto err_clk_disable; ++ goto err_mbus_clk_disable; + } + + ret = dma_async_device_register(&sdc->slave); +@@ -1341,6 +1359,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) + dma_async_device_unregister(&sdc->slave); + err_irq_disable: + sun6i_kill_tasklet(sdc); ++err_mbus_clk_disable: ++ clk_disable_unprepare(sdc->clk_mbus); + err_clk_disable: + clk_disable_unprepare(sdc->clk); + err_reset_assert: +@@ -1359,6 +1379,7 @@ static int sun6i_dma_remove(struct platform_device *pdev) + + sun6i_kill_tasklet(sdc); + ++ clk_disable_unprepare(sdc->clk_mbus); + clk_disable_unprepare(sdc->clk); + reset_control_assert(sdc->rstc); + +-- +2.22.0 + + +From 67f34055118cb6dcdfeea9e1980309afa80b2b7c Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 27 May 2019 22:14:55 +0200 +Subject: [PATCH 2/4] dmaengine: sun6i: Add a quirk for setting DRQ fields +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +H6 DMA has more than 32 possible DRQs. That means that current maximum +of 31 DRQs is not enough anymore. + +Add a quirk which will set source and destination DRQ number. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Vinod Koul +--- + drivers/dma/sun6i-dma.c | 48 ++++++++++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 20 deletions(-) + +diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c +index 7d9606997251..f725b93fd21a 100644 +--- a/drivers/dma/sun6i-dma.c ++++ b/drivers/dma/sun6i-dma.c +@@ -68,15 +68,15 @@ + #define DMA_CHAN_LLI_ADDR 0x08 + + #define DMA_CHAN_CUR_CFG 0x0c +-#define DMA_CHAN_MAX_DRQ 0x1f +-#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ) ++#define DMA_CHAN_MAX_DRQ_A31 0x1f ++#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) + #define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) + #define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) + #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) + #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) + #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) + +-#define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16) ++#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) + #define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) + #define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) + #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) +@@ -125,6 +125,7 @@ struct sun6i_dma_config { + */ + void (*clock_autogate_enable)(struct sun6i_dma_dev *); + void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); ++ void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); + u32 src_burst_lengths; + u32 dst_burst_lengths; + u32 src_addr_widths; +@@ -311,6 +312,12 @@ static void sun6i_set_burst_length_h3(u32 *p_cfg, s8 src_burst, s8 dst_burst) + DMA_CHAN_CFG_DST_BURST_H3(dst_burst); + } + ++static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) ++{ ++ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) | ++ DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); ++} ++ + static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) + { + struct sun6i_desc *txd = pchan->desc; +@@ -634,14 +641,13 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( + + burst = convert_burst(8); + width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); +- v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_DST_LINEAR_MODE | ++ v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE | + DMA_CHAN_CFG_SRC_LINEAR_MODE | + DMA_CHAN_CFG_SRC_WIDTH(width) | + DMA_CHAN_CFG_DST_WIDTH(width); + + sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); ++ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); + + sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); + +@@ -695,9 +701,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( + v_lli->dst = sconfig->dst_addr; + v_lli->cfg = lli_cfg | + DMA_CHAN_CFG_DST_IO_MODE | +- DMA_CHAN_CFG_SRC_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_DST_DRQ(vchan->port); ++ DMA_CHAN_CFG_SRC_LINEAR_MODE; ++ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); + + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", +@@ -710,9 +715,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( + v_lli->dst = sg_dma_address(sg); + v_lli->cfg = lli_cfg | + DMA_CHAN_CFG_DST_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_IO_MODE | +- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_SRC_DRQ(vchan->port); ++ DMA_CHAN_CFG_SRC_IO_MODE; ++ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); + + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", +@@ -780,17 +784,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( + v_lli->dst = sconfig->dst_addr; + v_lli->cfg = lli_cfg | + DMA_CHAN_CFG_DST_IO_MODE | +- DMA_CHAN_CFG_SRC_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_DST_DRQ(vchan->port); ++ DMA_CHAN_CFG_SRC_LINEAR_MODE; ++ sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); + } else { + v_lli->src = sconfig->src_addr; + v_lli->dst = buf_addr + period_len * i; + v_lli->cfg = lli_cfg | + DMA_CHAN_CFG_DST_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_IO_MODE | +- DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | +- DMA_CHAN_CFG_SRC_DRQ(vchan->port); ++ DMA_CHAN_CFG_SRC_IO_MODE; ++ sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); + } + + prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); +@@ -1055,6 +1057,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { + .nr_max_requests = 30, + .nr_max_vchans = 53, + .set_burst_length = sun6i_set_burst_length_a31, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1076,6 +1079,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = { + .nr_max_vchans = 37, + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1092,6 +1096,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = { + .nr_max_vchans = 39, + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1115,6 +1120,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { + .nr_max_vchans = 34, + .clock_autogate_enable = sun6i_enable_clock_autogate_h3, + .set_burst_length = sun6i_set_burst_length_h3, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1134,6 +1140,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { + static struct sun6i_dma_config sun50i_a64_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_h3, + .set_burst_length = sun6i_set_burst_length_h3, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1157,6 +1164,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = { + .nr_max_vchans = 24, + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, ++ .set_drq = sun6i_set_drq_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1272,8 +1280,8 @@ static int sun6i_dma_probe(struct platform_device *pdev) + ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); + if (ret && !sdc->max_request) { + dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", +- DMA_CHAN_MAX_DRQ); +- sdc->max_request = DMA_CHAN_MAX_DRQ; ++ DMA_CHAN_MAX_DRQ_A31); ++ sdc->max_request = DMA_CHAN_MAX_DRQ_A31; + } + + /* +-- +2.22.0 + + +From 802440bdf3b78721402f12495dffbb25522119bf Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 27 May 2019 22:14:56 +0200 +Subject: [PATCH 3/4] dmaengine: sun6i: Add a quirk for setting mode fields +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +H6 DMA has mode fields in different position than any other currently +supported DMA controller. + +Add a quirk for that. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Vinod Koul +--- + drivers/dma/sun6i-dma.c | 46 ++++++++++++++++++++++++----------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c +index f725b93fd21a..f5cb5e89bf7b 100644 +--- a/drivers/dma/sun6i-dma.c ++++ b/drivers/dma/sun6i-dma.c +@@ -70,15 +70,13 @@ + #define DMA_CHAN_CUR_CFG 0x0c + #define DMA_CHAN_MAX_DRQ_A31 0x1f + #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) +-#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) +-#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) ++#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) + #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) + #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) + #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) + + #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) +-#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) +-#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) ++#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) + #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) + #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) + #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) +@@ -98,6 +96,8 @@ + #define LLI_LAST_ITEM 0xfffff800 + #define NORMAL_WAIT 8 + #define DRQ_SDRAM 1 ++#define LINEAR_MODE 0 ++#define IO_MODE 1 + + /* forward declaration */ + struct sun6i_dma_dev; +@@ -126,6 +126,7 @@ struct sun6i_dma_config { + void (*clock_autogate_enable)(struct sun6i_dma_dev *); + void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); + void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); ++ void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode); + u32 src_burst_lengths; + u32 dst_burst_lengths; + u32 src_addr_widths; +@@ -318,6 +319,12 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) + DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); + } + ++static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) ++{ ++ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | ++ DMA_CHAN_CFG_DST_MODE_A31(dst_mode); ++} ++ + static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) + { + struct sun6i_desc *txd = pchan->desc; +@@ -641,13 +648,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( + + burst = convert_burst(8); + width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); +- v_lli->cfg = DMA_CHAN_CFG_DST_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_WIDTH(width) | ++ v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) | + DMA_CHAN_CFG_DST_WIDTH(width); + + sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); ++ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE); + + sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); + +@@ -699,10 +705,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( + if (dir == DMA_MEM_TO_DEV) { + v_lli->src = sg_dma_address(sg); + v_lli->dst = sconfig->dst_addr; +- v_lli->cfg = lli_cfg | +- DMA_CHAN_CFG_DST_IO_MODE | +- DMA_CHAN_CFG_SRC_LINEAR_MODE; ++ v_lli->cfg = lli_cfg; + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); ++ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); + + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", +@@ -713,10 +718,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( + } else { + v_lli->src = sconfig->src_addr; + v_lli->dst = sg_dma_address(sg); +- v_lli->cfg = lli_cfg | +- DMA_CHAN_CFG_DST_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_IO_MODE; ++ v_lli->cfg = lli_cfg; + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); ++ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); + + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", +@@ -782,17 +786,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( + if (dir == DMA_MEM_TO_DEV) { + v_lli->src = buf_addr + period_len * i; + v_lli->dst = sconfig->dst_addr; +- v_lli->cfg = lli_cfg | +- DMA_CHAN_CFG_DST_IO_MODE | +- DMA_CHAN_CFG_SRC_LINEAR_MODE; ++ v_lli->cfg = lli_cfg; + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); ++ sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); + } else { + v_lli->src = sconfig->src_addr; + v_lli->dst = buf_addr + period_len * i; +- v_lli->cfg = lli_cfg | +- DMA_CHAN_CFG_DST_LINEAR_MODE | +- DMA_CHAN_CFG_SRC_IO_MODE; ++ v_lli->cfg = lli_cfg; + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); ++ sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); + } + + prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); +@@ -1058,6 +1060,7 @@ static struct sun6i_dma_config sun6i_a31_dma_cfg = { + .nr_max_vchans = 53, + .set_burst_length = sun6i_set_burst_length_a31, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1080,6 +1083,7 @@ static struct sun6i_dma_config sun8i_a23_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1097,6 +1101,7 @@ static struct sun6i_dma_config sun8i_a83t_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1121,6 +1126,7 @@ static struct sun6i_dma_config sun8i_h3_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_h3, + .set_burst_length = sun6i_set_burst_length_h3, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1141,6 +1147,7 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_h3, + .set_burst_length = sun6i_set_burst_length_h3, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +@@ -1165,6 +1172,7 @@ static struct sun6i_dma_config sun8i_v3s_dma_cfg = { + .clock_autogate_enable = sun6i_enable_clock_autogate_a23, + .set_burst_length = sun6i_set_burst_length_a31, + .set_drq = sun6i_set_drq_a31, ++ .set_mode = sun6i_set_mode_a31, + .src_burst_lengths = BIT(1) | BIT(8), + .dst_burst_lengths = BIT(1) | BIT(8), + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | +-- +2.22.0 + + +From 2fe5575f36cacaab860ed9822eb6b2ea7b6a52ba Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 27 May 2019 22:14:57 +0200 +Subject: [PATCH 4/4] dmaengine: sun6i: Add support for H6 DMA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +H6 DMA has more than 32 supported DRQs, which means that configuration +register is slightly rearranged. It also needs additional clock to be +enabled. + +Add support for it. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Vinod Koul +--- + drivers/dma/sun6i-dma.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c +index f5cb5e89bf7b..ddef87ebdfdb 100644 +--- a/drivers/dma/sun6i-dma.c ++++ b/drivers/dma/sun6i-dma.c +@@ -69,14 +69,19 @@ + + #define DMA_CHAN_CUR_CFG 0x0c + #define DMA_CHAN_MAX_DRQ_A31 0x1f ++#define DMA_CHAN_MAX_DRQ_H6 0x3f + #define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) ++#define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6) + #define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) ++#define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8) + #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) + #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) + #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) + + #define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) ++#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16) + #define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) ++#define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16) + #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) + #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) + #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) +@@ -319,12 +324,24 @@ static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) + DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); + } + ++static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq) ++{ ++ *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) | ++ DMA_CHAN_CFG_DST_DRQ_H6(dst_drq); ++} ++ + static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) + { + *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | + DMA_CHAN_CFG_DST_MODE_A31(dst_mode); + } + ++static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode) ++{ ++ *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) | ++ DMA_CHAN_CFG_DST_MODE_H6(dst_mode); ++} ++ + static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) + { + struct sun6i_desc *txd = pchan->desc; +@@ -1160,6 +1177,28 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = { + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), + }; + ++/* ++ * The H6 binding uses the number of dma channels from the ++ * device tree node. ++ */ ++static struct sun6i_dma_config sun50i_h6_dma_cfg = { ++ .clock_autogate_enable = sun6i_enable_clock_autogate_h3, ++ .set_burst_length = sun6i_set_burst_length_h3, ++ .set_drq = sun6i_set_drq_h6, ++ .set_mode = sun6i_set_mode_h6, ++ .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), ++ .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), ++ .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | ++ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | ++ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | ++ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), ++ .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | ++ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | ++ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | ++ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), ++ .has_mbus_clk = true, ++}; ++ + /* + * The V3s have only 8 physical channels, a maximum DRQ port id of 23, + * and a total of 24 usable source and destination endpoints. +@@ -1190,6 +1229,7 @@ static const struct of_device_id sun6i_dma_match[] = { + { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, + { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, + { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, ++ { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, sun6i_dma_match); +-- +2.22.0 + +From 9164665a390a2a42e9f56094eeec8c4a52748723 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Tue, 11 Jun 2019 23:40:55 +0200 +Subject: [PATCH] arm64: dts: allwinner: h6: Add DMA node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +H6 has DMA controller which supports 16 channels. + +Add a node for it. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index b9a7dc8d2a40..7628a7c83096 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -203,6 +203,18 @@ + #reset-cells = <1>; + }; + ++ dma: dma-controller@3002000 { ++ compatible = "allwinner,sun50i-h6-dma"; ++ reg = <0x03002000 0x1000>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>; ++ clock-names = "bus", "mbus"; ++ dma-channels = <16>; ++ dma-requests = <46>; ++ resets = <&ccu RST_BUS_DMA>; ++ #dma-cells = <1>; ++ }; ++ + sid: sid@3006000 { + compatible = "allwinner,sun50i-h6-sid"; + reg = <0x03006000 0x400>; +-- +2.22.0 + diff --git a/projects/Allwinner/patches/linux/0013-color-range-encoding.patch b/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch similarity index 60% rename from projects/Allwinner/patches/linux/0013-color-range-encoding.patch rename to projects/Allwinner/patches/linux/0003-backport-from-5.4.patch index e7c1ffc619..4aa7d6154b 100644 --- a/projects/Allwinner/patches/linux/0013-color-range-encoding.patch +++ b/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch @@ -371,47 +371,281 @@ index 240a800217df..011924a75263 100644 -- 2.22.0 - -From c8217462c6c143a9fada595bf3e34af83eb15f87 Mon Sep 17 00:00:00 2001 +From 95b579d069348a59d0fa6463a2f821089876ebfd Mon Sep 17 00:00:00 2001 From: Jernej Skrabec -Date: Thu, 27 Jun 2019 21:50:16 +0200 -Subject: [PATCH 4/4] HACK: Force full range +Date: Sat, 6 Jul 2019 11:07:49 +0200 +Subject: [PATCH 1/2] regulator: axp20x: fix DCDCA and DCDCD for AXP806 +Refactoring of the driver introduced few bugs in AXP806's DCDCA and +DCDCD regulator definitions. + +Fix them. + +Fixes: db4a555f7c4cf ("regulator: axp20x: use defines for masks") Signed-off-by: Jernej Skrabec --- - drivers/gpu/drm/sun4i/sun8i_csc.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) + drivers/regulator/axp20x-regulator.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 70c792d052fe..7b60fce1a8c6 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -160,10 +160,10 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, +diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c +index 152053361862..c951568994a1 100644 +--- a/drivers/regulator/axp20x-regulator.c ++++ b/drivers/regulator/axp20x-regulator.c +@@ -240,7 +240,7 @@ + #define AXP806_DCDCA_600mV_END \ + (AXP806_DCDCA_600mV_START + AXP806_DCDCA_600mV_STEPS) + #define AXP806_DCDCA_1120mV_START 0x33 +-#define AXP806_DCDCA_1120mV_STEPS 14 ++#define AXP806_DCDCA_1120mV_STEPS 20 + #define AXP806_DCDCA_1120mV_END \ + (AXP806_DCDCA_1120mV_START + AXP806_DCDCA_1120mV_STEPS) + #define AXP806_DCDCA_NUM_VOLTAGES 72 +@@ -774,8 +774,8 @@ static const struct regulator_linear_range axp806_dcdcd_ranges[] = { + AXP806_DCDCD_600mV_END, + 20000), + REGULATOR_LINEAR_RANGE(1600000, +- AXP806_DCDCD_600mV_START, +- AXP806_DCDCD_600mV_END, ++ AXP806_DCDCD_1600mV_START, ++ AXP806_DCDCD_1600mV_END, + 100000), + }; - switch (mode) { - case SUN8I_CSC_MODE_YUV2RGB: -- table = yuv2rgb[range][encoding]; -+ table = yuv2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - case SUN8I_CSC_MODE_YVU2RGB: -- table = yvu2rgb[range][encoding]; -+ table = yvu2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - default: - DRM_WARN("Wrong CSC mode specified.\n"); -@@ -184,10 +184,10 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, - - switch (mode) { - case SUN8I_CSC_MODE_YUV2RGB: -- table = yuv2rgb_de3[range][encoding]; -+ table = yuv2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - case SUN8I_CSC_MODE_YVU2RGB: -- table = yvu2rgb_de3[range][encoding]; -+ table = yvu2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - default: - DRM_WARN("Wrong CSC mode specified.\n"); -- 2.22.0 +From a8e790b1850f368daff2d3c35b52f8a69978be6e Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 6 Jul 2019 11:15:13 +0200 +Subject: [PATCH 2/2] regulator: axp20x: fix DCDC6 for AXP803 + +Refactoring of axp20x driver introduced a bug in AXP803's DCDC6 +regulator definition. + +Fix it. + +Fixes: db4a555f7c4cf ("regulator: axp20x: use defines for masks") +Signed-off-by: Jernej Skrabec +--- + drivers/regulator/axp20x-regulator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c +index c951568994a1..29b92ce521b7 100644 +--- a/drivers/regulator/axp20x-regulator.c ++++ b/drivers/regulator/axp20x-regulator.c +@@ -181,7 +181,7 @@ + #define AXP803_DCDC6_600mV_END \ + (AXP803_DCDC6_600mV_START + AXP803_DCDC6_600mV_STEPS) + #define AXP803_DCDC6_1120mV_START 0x33 +-#define AXP803_DCDC6_1120mV_STEPS 14 ++#define AXP803_DCDC6_1120mV_STEPS 20 + #define AXP803_DCDC6_1120mV_END \ + (AXP803_DCDC6_1120mV_START + AXP803_DCDC6_1120mV_STEPS) + #define AXP803_DCDC6_NUM_VOLTAGES 72 +-- +2.22.0 + +From: Ondrej Jirman +Subject: [PATCH v8 3/4] drm: sun4i: Add support for enabling DDC I2C bus to + sun8i_dw_hdmi glue +Date: Tue, 6 Aug 2019 17:57:42 +0200 +Content-Type: text/plain; charset="us-ascii" + +Orange Pi 3 board requires enabling a voltage shifting circuit via GPIO +for the DDC bus to be usable. + +Add support for hdmi-connector node's optional ddc-en-gpios property to +support this use case. + +Signed-off-by: Ondrej Jirman +Reviewed-by: Jernej Skrabec +--- + drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 54 +++++++++++++++++++++++++-- + drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 + + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +index 8ca5af0c912f..a44dca4b0219 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +@@ -97,10 +97,34 @@ static u32 sun8i_dw_hdmi_find_possible_crtcs(struct drm_device *drm, + return crtcs; + } + ++static int sun8i_dw_hdmi_find_connector_pdev(struct device *dev, ++ struct platform_device **pdev_out) ++{ ++ struct platform_device *pdev; ++ struct device_node *remote; ++ ++ remote = of_graph_get_remote_node(dev->of_node, 1, -1); ++ if (!remote) ++ return -ENODEV; ++ ++ if (!of_device_is_compatible(remote, "hdmi-connector")) { ++ of_node_put(remote); ++ return -ENODEV; ++ } ++ ++ pdev = of_find_device_by_node(remote); ++ of_node_put(remote); ++ if (!pdev) ++ return -ENODEV; ++ ++ *pdev_out = pdev; ++ return 0; ++} ++ + static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + void *data) + { +- struct platform_device *pdev = to_platform_device(dev); ++ struct platform_device *pdev = to_platform_device(dev), *connector_pdev; + struct dw_hdmi_plat_data *plat_data; + struct drm_device *drm = data; + struct device_node *phy_node; +@@ -150,16 +174,30 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + return PTR_ERR(hdmi->regulator); + } + ++ ret = sun8i_dw_hdmi_find_connector_pdev(dev, &connector_pdev); ++ if (!ret) { ++ hdmi->ddc_en = gpiod_get_optional(&connector_pdev->dev, ++ "ddc-en", GPIOD_OUT_HIGH); ++ platform_device_put(connector_pdev); ++ ++ if (IS_ERR(hdmi->ddc_en)) { ++ dev_err(dev, "Couldn't get ddc-en gpio\n"); ++ return PTR_ERR(hdmi->ddc_en); ++ } ++ } ++ + ret = regulator_enable(hdmi->regulator); + if (ret) { + dev_err(dev, "Failed to enable regulator\n"); +- return ret; ++ goto err_unref_ddc_en; + } + ++ gpiod_set_value(hdmi->ddc_en, 1); ++ + ret = reset_control_deassert(hdmi->rst_ctrl); + if (ret) { + dev_err(dev, "Could not deassert ctrl reset control\n"); +- goto err_disable_regulator; ++ goto err_disable_ddc_en; + } + + ret = clk_prepare_enable(hdmi->clk_tmds); +@@ -212,8 +250,12 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + clk_disable_unprepare(hdmi->clk_tmds); + err_assert_ctrl_reset: + reset_control_assert(hdmi->rst_ctrl); +-err_disable_regulator: ++err_disable_ddc_en: ++ gpiod_set_value(hdmi->ddc_en, 0); + regulator_disable(hdmi->regulator); ++err_unref_ddc_en: ++ if (hdmi->ddc_en) ++ gpiod_put(hdmi->ddc_en); + + return ret; + } +@@ -227,7 +269,11 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, + sun8i_hdmi_phy_remove(hdmi); + clk_disable_unprepare(hdmi->clk_tmds); + reset_control_assert(hdmi->rst_ctrl); ++ gpiod_set_value(hdmi->ddc_en, 0); + regulator_disable(hdmi->regulator); ++ ++ if (hdmi->ddc_en) ++ gpiod_put(hdmi->ddc_en); + } + + static const struct component_ops sun8i_dw_hdmi_ops = { +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +index 720c5aa8adc1..d707c9171824 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -190,6 +191,7 @@ struct sun8i_dw_hdmi { + struct regulator *regulator; + const struct sun8i_dw_hdmi_quirks *quirks; + struct reset_control *rst_ctrl; ++ struct gpio_desc *ddc_en; + }; + + static inline struct sun8i_dw_hdmi * +From: Ondrej Jirman +Subject: [PATCH v8 4/4] arm64: dts: allwinner: orange-pi-3: Enable HDMI output +Date: Tue, 6 Aug 2019 17:57:43 +0200 +Content-Type: text/plain; charset="us-ascii" + +Orange Pi 3 has a DDC_CEC_EN signal connected to PH2, that enables the DDC +I2C bus voltage shifter. Before EDID can be read, we need to pull PH2 high. +This is realized by the ddc-en-gpios property. + +Signed-off-by: Ondrej Jirman +--- + .../dts/allwinner/sun50i-h6-orangepi-3.dts | 26 +++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index 2c6807b74ff6..01bb1bafe284 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -22,6 +22,18 @@ + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -72,6 +84,10 @@ + cpu-supply = <®_dcdca>; + }; + ++&de { ++ status = "okay"; ++}; ++ + &ehci0 { + status = "okay"; + }; +@@ -91,6 +107,16 @@ + status = "okay"; + }; + ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &mmc0 { + vmmc-supply = <®_cldo1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ diff --git a/projects/Allwinner/patches/linux/0013-force-full-range.patch b/projects/Allwinner/patches/linux/0013-force-full-range.patch new file mode 100644 index 0000000000..edb1240a5e --- /dev/null +++ b/projects/Allwinner/patches/linux/0013-force-full-range.patch @@ -0,0 +1,43 @@ +From c8217462c6c143a9fada595bf3e34af83eb15f87 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Thu, 27 Jun 2019 21:50:16 +0200 +Subject: [PATCH 4/4] HACK: Force full range + +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/sun4i/sun8i_csc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c +index 70c792d052fe..7b60fce1a8c6 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_csc.c ++++ b/drivers/gpu/drm/sun4i/sun8i_csc.c +@@ -160,10 +160,10 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, + + switch (mode) { + case SUN8I_CSC_MODE_YUV2RGB: +- table = yuv2rgb[range][encoding]; ++ table = yuv2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; + break; + case SUN8I_CSC_MODE_YVU2RGB: +- table = yvu2rgb[range][encoding]; ++ table = yvu2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; + break; + default: + DRM_WARN("Wrong CSC mode specified.\n"); +@@ -184,10 +184,10 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, + + switch (mode) { + case SUN8I_CSC_MODE_YUV2RGB: +- table = yuv2rgb_de3[range][encoding]; ++ table = yuv2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; + break; + case SUN8I_CSC_MODE_YVU2RGB: +- table = yvu2rgb_de3[range][encoding]; ++ table = yvu2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; + break; + default: + DRM_WARN("Wrong CSC mode specified.\n"); +-- +2.22.0 + diff --git a/projects/Allwinner/patches/linux/0014-regulator-fixes.patch b/projects/Allwinner/patches/linux/0014-regulator-fixes.patch deleted file mode 100644 index c52f646630..0000000000 --- a/projects/Allwinner/patches/linux/0014-regulator-fixes.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 95b579d069348a59d0fa6463a2f821089876ebfd Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 6 Jul 2019 11:07:49 +0200 -Subject: [PATCH 1/2] regulator: axp20x: fix DCDCA and DCDCD for AXP806 - -Refactoring of the driver introduced few bugs in AXP806's DCDCA and -DCDCD regulator definitions. - -Fix them. - -Fixes: db4a555f7c4cf ("regulator: axp20x: use defines for masks") -Signed-off-by: Jernej Skrabec ---- - drivers/regulator/axp20x-regulator.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c -index 152053361862..c951568994a1 100644 ---- a/drivers/regulator/axp20x-regulator.c -+++ b/drivers/regulator/axp20x-regulator.c -@@ -240,7 +240,7 @@ - #define AXP806_DCDCA_600mV_END \ - (AXP806_DCDCA_600mV_START + AXP806_DCDCA_600mV_STEPS) - #define AXP806_DCDCA_1120mV_START 0x33 --#define AXP806_DCDCA_1120mV_STEPS 14 -+#define AXP806_DCDCA_1120mV_STEPS 20 - #define AXP806_DCDCA_1120mV_END \ - (AXP806_DCDCA_1120mV_START + AXP806_DCDCA_1120mV_STEPS) - #define AXP806_DCDCA_NUM_VOLTAGES 72 -@@ -774,8 +774,8 @@ static const struct regulator_linear_range axp806_dcdcd_ranges[] = { - AXP806_DCDCD_600mV_END, - 20000), - REGULATOR_LINEAR_RANGE(1600000, -- AXP806_DCDCD_600mV_START, -- AXP806_DCDCD_600mV_END, -+ AXP806_DCDCD_1600mV_START, -+ AXP806_DCDCD_1600mV_END, - 100000), - }; - --- -2.22.0 - -From a8e790b1850f368daff2d3c35b52f8a69978be6e Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sat, 6 Jul 2019 11:15:13 +0200 -Subject: [PATCH 2/2] regulator: axp20x: fix DCDC6 for AXP803 - -Refactoring of axp20x driver introduced a bug in AXP803's DCDC6 -regulator definition. - -Fix it. - -Fixes: db4a555f7c4cf ("regulator: axp20x: use defines for masks") -Signed-off-by: Jernej Skrabec ---- - drivers/regulator/axp20x-regulator.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c -index c951568994a1..29b92ce521b7 100644 ---- a/drivers/regulator/axp20x-regulator.c -+++ b/drivers/regulator/axp20x-regulator.c -@@ -181,7 +181,7 @@ - #define AXP803_DCDC6_600mV_END \ - (AXP803_DCDC6_600mV_START + AXP803_DCDC6_600mV_STEPS) - #define AXP803_DCDC6_1120mV_START 0x33 --#define AXP803_DCDC6_1120mV_STEPS 14 -+#define AXP803_DCDC6_1120mV_STEPS 20 - #define AXP803_DCDC6_1120mV_END \ - (AXP803_DCDC6_1120mV_START + AXP803_DCDC6_1120mV_STEPS) - #define AXP803_DCDC6_NUM_VOLTAGES 72 --- -2.22.0 - From 05c7c9d271dc56231343ac34ae906395635e12d8 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 13 Aug 2019 10:01:41 +0200 Subject: [PATCH 2/2] Allwinner: Add upstream support for A64/H6 IR --- .../patches/linux/08-enable-opi-win-ir.patch | 135 ----- .../linux/0002-backport-from-5.3.patch | 40 ++ .../linux/0003-backport-from-5.4.patch | 573 ++++++++++++++++++ 3 files changed, 613 insertions(+), 135 deletions(-) delete mode 100644 projects/Allwinner/devices/A64/patches/linux/08-enable-opi-win-ir.patch diff --git a/projects/Allwinner/devices/A64/patches/linux/08-enable-opi-win-ir.patch b/projects/Allwinner/devices/A64/patches/linux/08-enable-opi-win-ir.patch deleted file mode 100644 index b9d63eb19f..0000000000 --- a/projects/Allwinner/devices/A64/patches/linux/08-enable-opi-win-ir.patch +++ /dev/null @@ -1,135 +0,0 @@ -From c642dca33a893b38770003f92de5708b2ef82878 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 10 Jan 2019 20:00:25 +0100 -Subject: [PATCH 1/4] media: dt: bindings: sunxi-ir: Add A64 compatible - -A64 IR is compatible with A13, so add A64 compatible with A13 as a -fallback. - -Signed-off-by: Jernej Skrabec ---- - Documentation/devicetree/bindings/media/sunxi-ir.txt | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/media/sunxi-ir.txt -index 278098987edb..ecac6964b69b 100644 ---- a/Documentation/devicetree/bindings/media/sunxi-ir.txt -+++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt -@@ -1,7 +1,10 @@ - Device-Tree bindings for SUNXI IR controller found in sunXi SoC family - - Required properties: --- compatible : "allwinner,sun4i-a10-ir" or "allwinner,sun5i-a13-ir" -+- compatible : value must be one of: -+ * "allwinner,sun4i-a10-ir" -+ * "allwinner,sun5i-a13-ir" -+ * "allwinner,sun50i-a64-ir", "allwinner,sun5i-a13-ir" - - clocks : list of clock specifiers, corresponding to - entries in clock-names property; - - clock-names : should contain "apb" and "ir" entries; --- -2.20.1 - - -From 85923b765bbd31be033a7b7d8bf0018accb386dd Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 10 Jan 2019 20:50:15 +0100 -Subject: [PATCH 2/4] arm64: dts: allwinner: a64: Add IR pinmux - -IR on A64 has a dedicated pin. Add pinmux setting for it. - -Signed-off-by: Jernej Skrabec ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 839b2ae88583..86ff1d3a4ffa 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -1043,6 +1043,11 @@ - function = "s_i2c"; - }; - -+ r_ir_pins: ir-pins { -+ pins = "PL11"; -+ function = "s_cir_rx"; -+ }; -+ - r_pwm_pin: r-pwm-pin { - pins = "PL10"; - function = "s_pwm"; --- -2.20.1 - - -From 943855104927268a641bd4f5f35c0592398e39ec Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 10 Jan 2019 20:19:32 +0100 -Subject: [PATCH 3/4] arm64: dts: allwinner: a64: Add IR node - -IR is similar to that in A13 and can use same driver. - -Signed-off-by: Jernej Skrabec ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 86ff1d3a4ffa..8238caedd90e 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -1004,6 +1004,17 @@ - status = "disabled"; - }; - -+ r_ir: ir@1f02000 { -+ compatible = "allwinner,sun50i-a64-ir", -+ "allwinner,sun5i-a13-ir"; -+ reg = <0x01f02000 0x400>; -+ clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; -+ clock-names = "apb", "ir"; -+ resets = <&r_ccu RST_APB0_IR>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ - r_i2c: i2c@1f02400 { - compatible = "allwinner,sun50i-a64-i2c", - "allwinner,sun6i-a31-i2c"; --- -2.20.1 - - -From 3020e7d85fe574cda8e6803330ffd75fffdbbf6b Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 10 Jan 2019 20:25:18 +0100 -Subject: [PATCH 4/4] arm64: dts: allwinner: a64: Orange Pi Win: Enable IR - -OrangePi Win board contains IR receiver. Enable it. - -Signed-off-by: Jernej Skrabec ---- - arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -index b0c64f75792c..c6c759511f5e 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -@@ -144,6 +144,12 @@ - }; - }; - -+&r_ir { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&r_ir_pins>; -+ status = "okay"; -+}; -+ - &mdio { - ext_rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; --- -2.20.1 - diff --git a/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch b/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch index 5a4442f34c..e7b67b0c89 100644 --- a/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch +++ b/projects/Allwinner/patches/linux/0002-backport-from-5.3.patch @@ -3158,3 +3158,43 @@ index b9a7dc8d2a40..7628a7c83096 100644 -- 2.22.0 +From f167675486c37b88620d344fbb12d06e34f11d47 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Tue, 4 Jun 2019 17:40:36 +0200 +Subject: [PATCH] clk: sunxi-ng: sun50i-h6-r: Fix incorrect W1 clock gate + register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The current code defines W1 clock gate to be at 0x1cc, overlaying it +with the IR gate. + +Clock gate for r-apb1-w1 is at 0x1ec. This fixes issues with IR receiver +causing interrupt floods on H6 (because interrupt flags can't be cleared, +due to IR module's bus being disabled). + +Fixes: b7c7b05065aa77ae ("clk: sunxi-ng: add support for H6 PRCM CCU") +Signed-off-by: Ondrej Jirman +Acked-by: Clément Péron +Signed-off-by: Maxime Ripard +--- + drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +index 27554eaf6929..8d05d4f1f8a1 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c ++++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +@@ -104,7 +104,7 @@ static SUNXI_CCU_GATE(r_apb2_i2c_clk, "r-apb2-i2c", "r-apb2", + static SUNXI_CCU_GATE(r_apb1_ir_clk, "r-apb1-ir", "r-apb1", + 0x1cc, BIT(0), 0); + static SUNXI_CCU_GATE(r_apb1_w1_clk, "r-apb1-w1", "r-apb1", +- 0x1cc, BIT(0), 0); ++ 0x1ec, BIT(0), 0); + + /* Information of IR(RX) mod clock is gathered from BSP source code */ + static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" }; +-- +2.22.0 + diff --git a/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch b/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch index 4aa7d6154b..2bfe873bb9 100644 --- a/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch +++ b/projects/Allwinner/patches/linux/0003-backport-from-5.4.patch @@ -649,3 +649,576 @@ index 2c6807b74ff6..01bb1bafe284 100644 &mmc0 { vmmc-supply = <®_cldo1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + +From 6b197cb5b4dc7be463599daeb28dfb8d24674746 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Fri, 7 Jun 2019 20:10:49 -0300 +Subject: [PATCH 1/3] media: rc: Introduce sunxi_ir_quirks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This driver is used in various Allwinner SoC with different configuration. + +Introduce a quirks struct to know the fifo size and if a reset is required. + +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/media/rc/sunxi-cir.c | 61 +++++++++++++++++++++++++++--------- + 1 file changed, 47 insertions(+), 14 deletions(-) + +diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c +index aa719d0ae6b0..29fe152fd9bc 100644 +--- a/drivers/media/rc/sunxi-cir.c ++++ b/drivers/media/rc/sunxi-cir.c +@@ -72,6 +72,17 @@ + /* Time after which device stops sending data in ms */ + #define SUNXI_IR_TIMEOUT 120 + ++/** ++ * struct sunxi_ir_quirks - Differences between SoC variants. ++ * ++ * @has_reset: SoC needs reset deasserted. ++ * @fifo_size: size of the fifo. ++ */ ++struct sunxi_ir_quirks { ++ bool has_reset; ++ int fifo_size; ++}; ++ + struct sunxi_ir { + spinlock_t ir_lock; + struct rc_dev *rc; +@@ -134,6 +145,7 @@ static int sunxi_ir_probe(struct platform_device *pdev) + + struct device *dev = &pdev->dev; + struct device_node *dn = dev->of_node; ++ const struct sunxi_ir_quirks *quirks; + struct resource *res; + struct sunxi_ir *ir; + u32 b_clk_freq = SUNXI_IR_BASE_CLK; +@@ -142,12 +154,15 @@ static int sunxi_ir_probe(struct platform_device *pdev) + if (!ir) + return -ENOMEM; + ++ quirks = of_device_get_match_data(&pdev->dev); ++ if (!quirks) { ++ dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); ++ return -ENODEV; ++ } ++ + spin_lock_init(&ir->ir_lock); + +- if (of_device_is_compatible(dn, "allwinner,sun5i-a13-ir")) +- ir->fifo_size = 64; +- else +- ir->fifo_size = 16; ++ ir->fifo_size = quirks->fifo_size; + + /* Clock */ + ir->apb_clk = devm_clk_get(dev, "apb"); +@@ -164,13 +179,15 @@ static int sunxi_ir_probe(struct platform_device *pdev) + /* Base clock frequency (optional) */ + of_property_read_u32(dn, "clock-frequency", &b_clk_freq); + +- /* Reset (optional) */ +- ir->rst = devm_reset_control_get_optional_exclusive(dev, NULL); +- if (IS_ERR(ir->rst)) +- return PTR_ERR(ir->rst); +- ret = reset_control_deassert(ir->rst); +- if (ret) +- return ret; ++ /* Reset */ ++ if (quirks->has_reset) { ++ ir->rst = devm_reset_control_get_exclusive(dev, NULL); ++ if (IS_ERR(ir->rst)) ++ return PTR_ERR(ir->rst); ++ ret = reset_control_deassert(ir->rst); ++ if (ret) ++ return ret; ++ } + + ret = clk_set_rate(ir->clk, b_clk_freq); + if (ret) { +@@ -306,10 +323,26 @@ static int sunxi_ir_remove(struct platform_device *pdev) + return 0; + } + ++static const struct sunxi_ir_quirks sun4i_a10_ir_quirks = { ++ .has_reset = false, ++ .fifo_size = 16, ++}; ++ ++static const struct sunxi_ir_quirks sun5i_a13_ir_quirks = { ++ .has_reset = false, ++ .fifo_size = 64, ++}; ++ + static const struct of_device_id sunxi_ir_match[] = { +- { .compatible = "allwinner,sun4i-a10-ir", }, +- { .compatible = "allwinner,sun5i-a13-ir", }, +- {}, ++ { ++ .compatible = "allwinner,sun4i-a10-ir", ++ .data = &sun4i_a10_ir_quirks, ++ }, ++ { ++ .compatible = "allwinner,sun5i-a13-ir", ++ .data = &sun5i_a13_ir_quirks, ++ }, ++ {} + }; + MODULE_DEVICE_TABLE(of, sunxi_ir_match); + +-- +2.22.0 + + +From 87d0609801ebcdf18639bb30ec5ec9a380f15be8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Fri, 7 Jun 2019 20:10:50 -0300 +Subject: [PATCH 2/3] media: rc: sunxi: Add A31 compatible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allwiner A31 has a different memory mapping so add the compatible +we will need it later. + +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/media/rc/sunxi-cir.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c +index 29fe152fd9bc..e9b9c582f818 100644 +--- a/drivers/media/rc/sunxi-cir.c ++++ b/drivers/media/rc/sunxi-cir.c +@@ -333,6 +333,11 @@ static const struct sunxi_ir_quirks sun5i_a13_ir_quirks = { + .fifo_size = 64, + }; + ++static const struct sunxi_ir_quirks sun6i_a31_ir_quirks = { ++ .has_reset = true, ++ .fifo_size = 64, ++}; ++ + static const struct of_device_id sunxi_ir_match[] = { + { + .compatible = "allwinner,sun4i-a10-ir", +@@ -342,6 +347,10 @@ static const struct of_device_id sunxi_ir_match[] = { + .compatible = "allwinner,sun5i-a13-ir", + .data = &sun5i_a13_ir_quirks, + }, ++ { ++ .compatible = "allwinner,sun6i-a31-ir", ++ .data = &sun6i_a31_ir_quirks, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, sunxi_ir_match); +-- +2.22.0 + + +From b136d72cb89dc2bd11ba001c90cdc65b5f5a1034 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Fri, 7 Jun 2019 20:10:51 -0300 +Subject: [PATCH 3/3] media: rc: sunxi: Add RXSTA bits definition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We are using RXINT bits definition when looking at RXSTA register. + +These bits are equal but it's not really proper. + +Introduce the RXSTA bits and use them to have coherency. + +Signed-off-by: Clément Péron +Acked-by: Maxime Ripard +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/media/rc/sunxi-cir.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c +index e9b9c582f818..f91154c2f45c 100644 +--- a/drivers/media/rc/sunxi-cir.c ++++ b/drivers/media/rc/sunxi-cir.c +@@ -39,11 +39,11 @@ + + /* Rx Interrupt Enable */ + #define SUNXI_IR_RXINT_REG 0x2C +-/* Rx FIFO Overflow */ ++/* Rx FIFO Overflow Interrupt Enable */ + #define REG_RXINT_ROI_EN BIT(0) +-/* Rx Packet End */ ++/* Rx Packet End Interrupt Enable */ + #define REG_RXINT_RPEI_EN BIT(1) +-/* Rx FIFO Data Available */ ++/* Rx FIFO Data Available Interrupt Enable */ + #define REG_RXINT_RAI_EN BIT(4) + + /* Rx FIFO available byte level */ +@@ -51,6 +51,12 @@ + + /* Rx Interrupt Status */ + #define SUNXI_IR_RXSTA_REG 0x30 ++/* Rx FIFO Overflow */ ++#define REG_RXSTA_ROI REG_RXINT_ROI_EN ++/* Rx Packet End */ ++#define REG_RXSTA_RPE REG_RXINT_RPEI_EN ++/* Rx FIFO Data Available */ ++#define REG_RXSTA_RA REG_RXINT_RAI_EN + /* RX FIFO Get Available Counter */ + #define REG_RXSTA_GET_AC(val) (((val) >> 8) & (ir->fifo_size * 2 - 1)) + /* Clear all interrupt status value */ +@@ -110,7 +116,7 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) + /* clean all pending statuses */ + writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); + +- if (status & (REG_RXINT_RAI_EN | REG_RXINT_RPEI_EN)) { ++ if (status & (REG_RXSTA_RA | REG_RXSTA_RPE)) { + /* How many messages in fifo */ + rc = REG_RXSTA_GET_AC(status); + /* Sanity check */ +@@ -126,9 +132,9 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) + } + } + +- if (status & REG_RXINT_ROI_EN) { ++ if (status & REG_RXSTA_ROI) { + ir_raw_event_reset(ir->rc); +- } else if (status & REG_RXINT_RPEI_EN) { ++ } else if (status & REG_RXSTA_RPE) { + ir_raw_event_set_idle(ir->rc, true); + ir_raw_event_handle(ir->rc); + } +-- +2.22.0 + +From 342d23a7dacf9c254c6b98b9b211e566820b7bad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Sat, 8 Jun 2019 01:10:52 +0200 +Subject: [PATCH 1/6] ARM: dts: sunxi: Prefer A31 bindings for IR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since A31, memory mapping of the IR driver has changed. + +Prefer the A31 bindings instead of A13. + +Signed-off-by: Clément Péron +Acked-by: Sean Young +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sun6i-a31.dtsi | 2 +- + arch/arm/boot/dts/sun8i-a83t.dtsi | 2 +- + arch/arm/boot/dts/sun9i-a80.dtsi | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi +index dcddc3392460..9ddde111f675 100644 +--- a/arch/arm/boot/dts/sun6i-a31.dtsi ++++ b/arch/arm/boot/dts/sun6i-a31.dtsi +@@ -1364,7 +1364,7 @@ + }; + + ir: ir@1f02000 { +- compatible = "allwinner,sun5i-a13-ir"; ++ compatible = "allwinner,sun6i-a31-ir"; + clocks = <&apb0_gates 1>, <&ir_clk>; + clock-names = "apb", "ir"; + resets = <&apb0_rst 1>; +diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi +index 8de139521451..13bc83191899 100644 +--- a/arch/arm/boot/dts/sun8i-a83t.dtsi ++++ b/arch/arm/boot/dts/sun8i-a83t.dtsi +@@ -1096,7 +1096,7 @@ + + r_cir: ir@1f02000 { + compatible = "allwinner,sun8i-a83t-ir", +- "allwinner,sun5i-a13-ir"; ++ "allwinner,sun6i-a31-ir"; + clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; + clock-names = "apb", "ir"; + resets = <&r_ccu RST_APB0_IR>; +diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi +index 0c1eec9000e3..310cd972ee5b 100644 +--- a/arch/arm/boot/dts/sun9i-a80.dtsi ++++ b/arch/arm/boot/dts/sun9i-a80.dtsi +@@ -1167,7 +1167,7 @@ + }; + + r_ir: ir@8002000 { +- compatible = "allwinner,sun5i-a13-ir"; ++ compatible = "allwinner,sun6i-a31-ir"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&r_ir_pins>; +-- +2.22.0 + + +From 8fa345e711bfdb69a18f548b717d5eb502b9892a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Sat, 8 Jun 2019 01:10:53 +0200 +Subject: [PATCH 2/6] ARM: dts: sunxi: Prefer A31 bindings for IR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since A31, memory mapping of the IR driver has changed. + +Prefer the A31 bindings instead of A13. + +Signed-off-by: Clément Péron +Acked-by: Sean Young +Signed-off-by: Maxime Ripard +--- + arch/arm/boot/dts/sunxi-h3-h5.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi +index b4a6035ae9f5..97550a40b6e1 100644 +--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi ++++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi +@@ -822,7 +822,7 @@ + }; + + ir: ir@1f02000 { +- compatible = "allwinner,sun5i-a13-ir"; ++ compatible = "allwinner,sun6i-a31-ir"; + clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; + clock-names = "apb", "ir"; + resets = <&r_ccu RST_APB0_IR>; +-- +2.22.0 + + +From 44a4f416c8388449fc5f9263788857d449e2a65f Mon Sep 17 00:00:00 2001 +From: Igors Makejevs +Date: Sat, 8 Jun 2019 01:10:55 +0200 +Subject: [PATCH 3/6] arm64: dts: allwinner: a64: Add IR node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +IR peripheral is completely compatible with A31 one. + +Signed-off-by: Igors Makejevs +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Sean Young +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +index aa9897f270ba..ddb6f11e89df 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +@@ -1094,6 +1094,19 @@ + #size-cells = <0>; + }; + ++ r_ir: ir@1f02000 { ++ compatible = "allwinner,sun50i-a64-ir", ++ "allwinner,sun6i-a31-ir"; ++ reg = <0x01f02000 0x400>; ++ clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; ++ clock-names = "apb", "ir"; ++ resets = <&r_ccu RST_APB0_IR>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&r_ir_rx_pin>; ++ status = "disabled"; ++ }; ++ + r_pwm: pwm@1f03800 { + compatible = "allwinner,sun50i-a64-pwm", + "allwinner,sun5i-a13-pwm"; +@@ -1121,6 +1134,11 @@ + function = "s_i2c"; + }; + ++ r_ir_rx_pin: r-ir-rx-pin { ++ pins = "PL11"; ++ function = "s_cir_rx"; ++ }; ++ + r_pwm_pin: r-pwm-pin { + pins = "PL10"; + function = "s_pwm"; +-- +2.22.0 + + +From 63eb1e149576294717e3e5de48e902ca9d2f080d Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 8 Jun 2019 01:10:56 +0200 +Subject: [PATCH 4/6] arm64: dts: allwinner: a64: Enable IR on Orange Pi Win +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +OrangePi Win board contains IR receiver. Enable it. + +Signed-off-by: Jernej Skrabec +Signed-off-by: Clément Péron +Acked-by: Sean Young +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +index 5ef3c62c765e..04446e4716c4 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +@@ -190,6 +190,10 @@ + status = "okay"; + }; + ++&r_ir { ++ status = "okay"; ++}; ++ + &r_rsb { + status = "okay"; + +-- +2.22.0 + + +From 9267811aad3524c857cf2e16bbadd8c569e15ab9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Sat, 8 Jun 2019 01:10:58 +0200 +Subject: [PATCH 5/6] arm64: dts: allwinner: h6: Add IR receiver node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allwinner H6 IR is similar to A31 and can use same driver. + +Add support for it. + +Signed-off-by: Clément Péron +Acked-by: Sean Young +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index 35942bae0a34..e8bed58e7246 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -675,6 +675,25 @@ + pins = "PL0", "PL1"; + function = "s_i2c"; + }; ++ ++ r_ir_rx_pin: r-ir-rx-pin { ++ pins = "PL9"; ++ function = "s_cir_rx"; ++ }; ++ }; ++ ++ r_ir: ir@7040000 { ++ compatible = "allwinner,sun50i-h6-ir", ++ "allwinner,sun6i-a31-ir"; ++ reg = <0x07040000 0x400>; ++ interrupts = ; ++ clocks = <&r_ccu CLK_R_APB1_IR>, ++ <&r_ccu CLK_IR>; ++ clock-names = "apb", "ir"; ++ resets = <&r_ccu RST_R_APB1_IR>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&r_ir_rx_pin>; ++ status = "disabled"; + }; + + r_i2c: i2c@7081400 { +-- +2.22.0 + + +From 86be740845e3811c4517de1a8a36121190155e22 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= +Date: Sat, 8 Jun 2019 01:10:59 +0200 +Subject: [PATCH 6/6] arm64: dts: allwinner: h6: Enable IR on H6 boards +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Beelink GS1, OrangePi H6 boards and Pine H64 have an IR receiver. + +Enable it in their device-tree. + +Signed-off-by: Clément Péron +Signed-off-by: Maxime Ripard +--- + arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 4 ++++ + arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi | 4 ++++ + arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 4 ++++ + 3 files changed, 12 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +index 0dc33c90dd60..680dc29cb089 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +@@ -232,6 +232,10 @@ + }; + }; + ++&r_ir { ++ status = "okay"; ++}; ++ + &r_pio { + /* + * PL0 and PL1 are used for PMIC I2C +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +index 62e27948a3fa..ec9b6a578e3f 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +@@ -189,6 +189,10 @@ + }; + }; + ++&r_ir { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +index 189834518391..30102daf83cc 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +@@ -255,6 +255,10 @@ + }; + }; + ++&r_ir { ++ status = "okay"; ++}; ++ + &r_pio { + vcc-pm-supply = <®_aldo1>; + }; +-- +2.22.0 +