From cd92c3bb88c9b47a4b57b27a0a5ff5e813165296 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 13 Aug 2019 09:13:00 +0200 Subject: [PATCH] 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 -