Changes since v6: - change dual_edge to pclk-sample - remove dpi_pin_mode_swap and
Changes since v5: - fine tune the dt-bindings commit message.
Changes since v4: - move pin mode control and dual edge control to deveice tree. - update dt-bindings document for pin mode swap and dual edge control.
Changes since v3: - add dpi pin mode control when dpi on or off. - update dpi dual edge comment.
Changes since v2: - update dt-bindings document for mt8183 dpi. - separate dual edge modfication as independent patch.
Jitao Shi (4): dt-bindings: display: mediatek: update dpi supported chips drm/mediatek: dpi sample mode support drm/mediatek: add mt8183 dpi clock factor drm/mediatek: set dpi pin mode to gpio low to avoid leakage current
.../display/mediatek/mediatek,dpi.txt | 10 +++ drivers/gpu/drm/mediatek/mtk_dpi.c | 65 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-)
Add decriptions about supported chips, including MT2701 & MT8173 & mt8183
1. Add more chips support. ex. MT2701 & MT8173 & MT8183 2. Add property "pinctrl-names" to swap pin mode between gpio and dpi mode. Set pin mode to gpio oupput-low to avoid leakage current when dpi disable. 3. Add property "pclk-sample" to config the dpi sample on falling (0), rising (1), both falling and rising (2).
Signed-off-by: Jitao Shi jitao.shi@mediatek.com --- .../bindings/display/mediatek/mediatek,dpi.txt | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt index b6a7e7397b8b..0dee4f7a227e 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt @@ -7,6 +7,7 @@ output bus.
Required properties: - compatible: "mediatek,<chip>-dpi" + the supported chips are mt2701 , mt8173 and mt8183. - reg: Physical base address and length of the controller's registers - interrupts: The interrupt signal from the function block. - clocks: device clocks @@ -16,6 +17,11 @@ Required properties: Documentation/devicetree/bindings/graph.txt. This port should be connected to the input port of an attached HDMI or LVDS encoder chip.
+Optional properties: +- pinctrl-names: Contain "gpiomode" and "dpimode". +- pclk-sample: 0: sample in falling edge, 1: sample in rising edge, 2: sample + in both falling and rising edge. + Example:
dpi0: dpi@1401d000 { @@ -26,6 +32,10 @@ dpi0: dpi@1401d000 { <&mmsys CLK_MM_DPI_ENGINE>, <&apmixedsys CLK_APMIXED_TVDPLL>; clock-names = "pixel", "engine", "pll"; + pclk-sample = 0; + pinctrl-names = "gpiomode", "dpimode"; + pinctrl-0 = <&dpi_pin_gpio>; + pinctrl-1 = <&dpi_pin_func>;
port { dpi0_out: endpoint {
Hi, Jitao:
On Tue, 2020-02-25 at 14:46 +0800, Jitao Shi wrote:
Add decriptions about supported chips, including MT2701 & MT8173 & mt8183
descriptions
- Add more chips support. ex. MT2701 & MT8173 & MT8183
- Add property "pinctrl-names" to swap pin mode between gpio and dpi mode. Set pin mode to gpio oupput-low to avoid leakage current when dpi disable.
- Add property "pclk-sample" to config the dpi sample on falling (0), rising (1), both falling and rising (2).
The title is just about supported chips, so I prefer you move other modification to another patch. Of course, you could use a more rough title to include all what you do so you need not to break this patch.
Signed-off-by: Jitao Shi jitao.shi@mediatek.com
.../bindings/display/mediatek/mediatek,dpi.txt | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt index b6a7e7397b8b..0dee4f7a227e 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt @@ -7,6 +7,7 @@ output bus.
Required properties:
- compatible: "mediatek,<chip>-dpi"
- the supported chips are mt2701 , mt8173 and mt8183.
- reg: Physical base address and length of the controller's registers
- interrupts: The interrupt signal from the function block.
- clocks: device clocks
@@ -16,6 +17,11 @@ Required properties: Documentation/devicetree/bindings/graph.txt. This port should be connected to the input port of an attached HDMI or LVDS encoder chip.
+Optional properties: +- pinctrl-names: Contain "gpiomode" and "dpimode". +- pclk-sample: 0: sample in falling edge, 1: sample in rising edge, 2: sample
- in both falling and rising edge.
pinctrl-names & pclk-sample are defined in another document, please list the reference document, [1] is the sample. For pclk-sample, I think you should modify [2] to add 'sampling in both failing and rising edge'.
[1] Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt [2] Documentation/devicetree/bindings/media/video-interfaces.txt
Example:
dpi0: dpi@1401d000 { @@ -26,6 +32,10 @@ dpi0: dpi@1401d000 { <&mmsys CLK_MM_DPI_ENGINE>, <&apmixedsys CLK_APMIXED_TVDPLL>; clock-names = "pixel", "engine", "pll";
- pclk-sample = 0;
I think you should move pclk-sample into the port node according to [2].
Regards, CK
pinctrl-names = "gpiomode", "dpimode";
pinctrl-0 = <&dpi_pin_gpio>;
pinctrl-1 = <&dpi_pin_func>;
port { dpi0_out: endpoint {
DPI can sample on falling, rising or both edge. When DPI sample the data both rising and falling edge. It can reduce half data io pins.
Signed-off-by: Jitao Shi jitao.shi@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dpi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 01fa8b8d763d..08299042dda7 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -75,6 +75,7 @@ struct mtk_dpi { enum mtk_dpi_out_bit_num bit_num; enum mtk_dpi_out_channel_swap channel_swap; int refcount; + u32 pclk_sample; };
static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) @@ -348,6 +349,13 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); }
+static void mtk_dpi_enable_pclk_sample_dual_edge(struct mtk_dpi *dpi) +{ + mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE, + DDR_EN | DDR_4PHASE); + mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, EDGE_SEL, EDGE_SEL); +} + static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) { @@ -439,7 +447,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, pll_rate = clk_get_rate(dpi->tvd_clk);
vm.pixelclock = pll_rate / factor; - clk_set_rate(dpi->pixel_clk, vm.pixelclock); + clk_set_rate(dpi->pixel_clk, + vm.pixelclock * (dpi->pclk_sample > 1 ? 2 : 1)); vm.pixelclock = clk_get_rate(dpi->pixel_clk);
dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n", @@ -450,7 +459,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, limit.y_bottom = 0x0010; limit.y_top = 0x0FE0;
- dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING; + dpi_pol.ck_pol = dpi->pclk_sample == 1 ? + MTK_DPI_POLARITY_RISING : MTK_DPI_POLARITY_FALLING; dpi_pol.de_pol = MTK_DPI_POLARITY_RISING; dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ? MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; @@ -504,6 +514,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, mtk_dpi_config_color_format(dpi, dpi->color_format); mtk_dpi_config_2n_h_fre(dpi); mtk_dpi_config_disable_edge(dpi); + if (dpi->pclk_sample > 1) + mtk_dpi_enable_pclk_sample_dual_edge(dpi); mtk_dpi_sw_reset(dpi, false);
return 0; @@ -689,6 +701,8 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dpi->dev = dev; dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); + dpi->pclk_sample = of_property_read_u32_index(dev->of_node, + "pclk-sample");
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dpi->regs = devm_ioremap_resource(dev, mem);
The factor depends on the divider of DPI in MT8183, therefore, we should fix this factor to the right and new one.
Signed-off-by: Jitao Shi jitao.shi@mediatek.com Reviewed-by: CK Hu ck.hu@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dpi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 08299042dda7..c3e631b93c2e 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -676,6 +676,16 @@ static unsigned int mt2701_calculate_factor(int clock) return 1; }
+static unsigned int mt8183_calculate_factor(int clock) +{ + if (clock <= 27000) + return 8; + else if (clock <= 167000) + return 4; + else + return 2; +} + static const struct mtk_dpi_conf mt8173_conf = { .cal_factor = mt8173_calculate_factor, .reg_h_fre_con = 0xe0, @@ -687,6 +697,11 @@ static const struct mtk_dpi_conf mt2701_conf = { .edge_sel_en = true, };
+static const struct mtk_dpi_conf mt8183_conf = { + .cal_factor = mt8183_calculate_factor, + .reg_h_fre_con = 0xe0, +}; + static int mtk_dpi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -784,6 +799,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = { { .compatible = "mediatek,mt8173-dpi", .data = &mt8173_conf, }, + { .compatible = "mediatek,mt8183-dpi", + .data = &mt8183_conf, + }, { }, };
Config dpi pins mode to output and pull low when dpi is disabled. Aovid leakage current from some dpi pins (Hsync Vsync DE ... ).
Signed-off-by: Jitao Shi jitao.shi@mediatek.com --- drivers/gpu/drm/mediatek/mtk_dpi.c | 33 ++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index c3e631b93c2e..ca570040ffdf 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -10,7 +10,9 @@ #include <linux/kernel.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_gpio.h> #include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/types.h>
@@ -74,6 +76,9 @@ struct mtk_dpi { enum mtk_dpi_out_yc_map yc_map; enum mtk_dpi_out_bit_num bit_num; enum mtk_dpi_out_channel_swap channel_swap; + struct pinctrl *pinctrl; + struct pinctrl_state *pins_gpio; + struct pinctrl_state *pins_dpi; int refcount; u32 pclk_sample; }; @@ -387,6 +392,9 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi) if (--dpi->refcount != 0) return;
+ if (dpi->pinctrl && dpi->pins_gpio) + pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); + mtk_dpi_disable(dpi); clk_disable_unprepare(dpi->pixel_clk); clk_disable_unprepare(dpi->engine_clk); @@ -411,6 +419,9 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) goto err_pixel; }
+ if (dpi->pinctrl && dpi->pins_dpi) + pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); + mtk_dpi_enable(dpi); return 0;
@@ -716,8 +727,26 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dpi->dev = dev; dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); - dpi->pclk_sample = of_property_read_u32_index(dev->of_node, - "pclk-sample"); + of_property_read_u32_index(dev->of_node, "pclk-sample", 1, + &dpi->pclk_sample); + + dpi->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(dpi->pinctrl)) + dev_dbg(&pdev->dev, "Cannot find pinctrl!\n"); + + dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "gpiomode"); + if (IS_ERR(dpi->pins_gpio)) { + dpi->pins_gpio = NULL; + dev_dbg(&pdev->dev, "Cannot find pinctrl gpiomode!\n"); + } + if (dpi->pinctrl && dpi->pins_gpio) + pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); + + dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "dpimode"); + if (IS_ERR(dpi->pins_dpi)) { + dpi->pins_dpi = NULL; + dev_dbg(&pdev->dev, "Cannot find pinctrl dpimode!\n"); + }
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dpi->regs = devm_ioremap_resource(dev, mem);
Hi, Jitao:
On Tue, 2020-02-25 at 14:46 +0800, Jitao Shi wrote:
Config dpi pins mode to output and pull low when dpi is disabled. Aovid leakage current from some dpi pins (Hsync Vsync DE ... ).
Signed-off-by: Jitao Shi jitao.shi@mediatek.com
drivers/gpu/drm/mediatek/mtk_dpi.c | 33 ++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index c3e631b93c2e..ca570040ffdf 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -10,7 +10,9 @@ #include <linux/kernel.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/of_gpio.h> #include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/types.h>
@@ -74,6 +76,9 @@ struct mtk_dpi { enum mtk_dpi_out_yc_map yc_map; enum mtk_dpi_out_bit_num bit_num; enum mtk_dpi_out_channel_swap channel_swap;
- struct pinctrl *pinctrl;
- struct pinctrl_state *pins_gpio;
- struct pinctrl_state *pins_dpi; int refcount; u32 pclk_sample;
}; @@ -387,6 +392,9 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi) if (--dpi->refcount != 0) return;
- if (dpi->pinctrl && dpi->pins_gpio)
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
- mtk_dpi_disable(dpi); clk_disable_unprepare(dpi->pixel_clk); clk_disable_unprepare(dpi->engine_clk);
@@ -411,6 +419,9 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi) goto err_pixel; }
- if (dpi->pinctrl && dpi->pins_dpi)
pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
- mtk_dpi_enable(dpi); return 0;
@@ -716,8 +727,26 @@ static int mtk_dpi_probe(struct platform_device *pdev)
dpi->dev = dev; dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
- dpi->pclk_sample = of_property_read_u32_index(dev->of_node,
"pclk-sample");
- of_property_read_u32_index(dev->of_node, "pclk-sample", 1,
&dpi->pclk_sample);
Why this exists in this patch?
- dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
- if (IS_ERR(dpi->pinctrl))
dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
I think you should set dpi->pinctrl to NULL when error, and check dpi->pinctrl before you use it, such as pinctrl_lookup_state().
Regards, CK
dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "gpiomode");
if (IS_ERR(dpi->pins_gpio)) {
dpi->pins_gpio = NULL;
dev_dbg(&pdev->dev, "Cannot find pinctrl gpiomode!\n");
}
if (dpi->pinctrl && dpi->pins_gpio)
pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "dpimode");
if (IS_ERR(dpi->pins_dpi)) {
dpi->pins_dpi = NULL;
dev_dbg(&pdev->dev, "Cannot find pinctrl dpimode!\n");
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dpi->regs = devm_ioremap_resource(dev, mem);
dri-devel@lists.freedesktop.org