summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ide.c8
-rw-r--r--drivers/clk/imx/Kconfig16
-rw-r--r--drivers/clk/imx/Makefile1
-rw-r--r--drivers/clk/imx/clk-imxrt1020.c227
-rw-r--r--drivers/clk/imx/clk-imxrt1050.c30
-rw-r--r--drivers/clk/imx/clk-pllv3.c9
-rw-r--r--drivers/i2c/davinci_i2c.c2
-rw-r--r--drivers/i2c/kona_i2c.c2
-rw-r--r--drivers/i2c/sh_i2c.c2
-rw-r--r--drivers/i2c/soft_i2c.c2
-rw-r--r--drivers/phy/meson-gxl-usb2.c30
-rw-r--r--drivers/phy/meson-gxl-usb3.c44
-rw-r--r--drivers/phy/phy-uclass.c16
-rw-r--r--drivers/power/pmic/pfuze100.c2
-rw-r--r--drivers/pwm/Kconfig7
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/pwm-mtk.c188
-rw-r--r--drivers/tee/optee/core.c13
-rw-r--r--drivers/video/mxsfb.c94
-rw-r--r--drivers/video/sunxi/sunxi_display.c33
-rw-r--r--drivers/video/videomodes.c29
-rw-r--r--drivers/video/videomodes.h11
22 files changed, 662 insertions, 105 deletions
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 4b8a4eac176..67cc4fbc02e 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -231,7 +231,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
(unsigned char) ((buflen >> 8) & 0xFF));
ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
- ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
+ ide_outb(device, ATA_COMMAND, ATA_CMD_PACKET);
udelay(50);
mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
@@ -570,7 +570,7 @@ static void ide_ident(struct blk_desc *dev_desc)
/*
* Start Ident Command
*/
- ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT);
+ ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATAPI);
/*
* Wait for completion - ATAPI devices need more time
* to become ready
@@ -582,7 +582,7 @@ static void ide_ident(struct blk_desc *dev_desc)
/*
* Start Ident Command
*/
- ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT);
+ ide_outb(device, ATA_COMMAND, ATA_CMD_ID_ATA);
/*
* Wait for completion
@@ -966,7 +966,7 @@ ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt,
/* first check if the drive is in Powersaving mode, if yes,
* increase the timeout value */
- ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR);
+ ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_POWER);
udelay(50);
c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 059bc2fbb95..96721bcbf3b 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -69,6 +69,22 @@ config CLK_IMX8MP
help
This enables support clock driver for i.MX8MP platforms.
+config SPL_CLK_IMXRT1020
+ bool "SPL clock support for i.MXRT1020"
+ depends on ARCH_IMXRT && SPL
+ select SPL_CLK
+ select SPL_CLK_CCF
+ help
+ This enables SPL DM/DTS support for clock driver in i.MXRT1020
+
+config CLK_IMXRT1020
+ bool "Clock support for i.MXRT1020"
+ depends on ARCH_IMXRT
+ select CLK
+ select CLK_CCF
+ help
+ This enables support clock driver for i.MXRT1020 platforms.
+
config SPL_CLK_IMXRT1050
bool "SPL clock support for i.MXRT1050"
depends on ARCH_IMXRT && SPL
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 1e8a49d0f33..01bbbdf3aea 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
clk-composite-8m.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
diff --git a/drivers/clk/imx/clk-imxrt1020.c b/drivers/clk/imx/clk-imxrt1020.c
new file mode 100644
index 00000000000..840f783940f
--- /dev/null
+++ b/drivers/clk/imx/clk-imxrt1020.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright(C) 2020
+ * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imxrt1020-clock.h>
+
+#include "clk.h"
+
+static ulong imxrt1020_clk_get_rate(struct clk *clk)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu)\n", __func__, clk->id);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ return clk_get_rate(c);
+}
+
+static ulong imxrt1020_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ return clk_set_rate(c, rate);
+}
+
+static int __imxrt1020_clk_enable(struct clk *clk, bool enable)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ if (enable)
+ ret = clk_enable(c);
+ else
+ ret = clk_disable(c);
+
+ return ret;
+}
+
+static int imxrt1020_clk_disable(struct clk *clk)
+{
+ return __imxrt1020_clk_enable(clk, 0);
+}
+
+static int imxrt1020_clk_enable(struct clk *clk)
+{
+ return __imxrt1020_clk_enable(clk, 1);
+}
+
+static struct clk_ops imxrt1020_clk_ops = {
+ .set_rate = imxrt1020_clk_set_rate,
+ .get_rate = imxrt1020_clk_get_rate,
+ .enable = imxrt1020_clk_enable,
+ .disable = imxrt1020_clk_disable,
+};
+
+static const char * const pll2_bypass_sels[] = {"pll2_sys", "osc", };
+static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "osc", };
+
+static const char *const pre_periph_sels[] = { "pll2_sys", "pll2_pfd3_297m", "pll3_pfd3_454_74m", "arm_podf", };
+static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
+static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
+static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
+
+static int imxrt1020_clk_probe(struct udevice *dev)
+{
+ void *base;
+
+ /* Anatop clocks */
+ base = (void *)ANATOP_BASE_ADDR;
+
+ clk_dm(IMXRT1020_CLK_PLL2_SYS,
+ imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_sys", "osc",
+ base + 0x30, 0x1));
+ clk_dm(IMXRT1020_CLK_PLL3_USB_OTG,
+ imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc",
+ base + 0x10, 0x1));
+
+ /* PLL bypass out */
+ clk_dm(IMXRT1020_CLK_PLL2_BYPASS,
+ imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1,
+ pll2_bypass_sels,
+ ARRAY_SIZE(pll2_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMXRT1020_CLK_PLL3_BYPASS,
+ imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1,
+ pll3_bypass_sels,
+ ARRAY_SIZE(pll3_bypass_sels),
+ CLK_SET_RATE_PARENT));
+
+ clk_dm(IMXRT1020_CLK_PLL3_80M,
+ imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6));
+
+ clk_dm(IMXRT1020_CLK_PLL2_PFD0_352M,
+ imx_clk_pfd("pll2_pfd0_352m", "pll2_sys", base + 0x100, 0));
+ clk_dm(IMXRT1020_CLK_PLL2_PFD1_594M,
+ imx_clk_pfd("pll2_pfd1_594m", "pll2_sys", base + 0x100, 1));
+ clk_dm(IMXRT1020_CLK_PLL2_PFD2_396M,
+ imx_clk_pfd("pll2_pfd2_396m", "pll2_sys", base + 0x100, 2));
+ clk_dm(IMXRT1020_CLK_PLL2_PFD3_297M,
+ imx_clk_pfd("pll2_pfd3_297m", "pll2_sys", base + 0x100, 3));
+ clk_dm(IMXRT1020_CLK_PLL3_PFD1_664_62M,
+ imx_clk_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", base + 0xf0, 1));
+ clk_dm(IMXRT1020_CLK_PLL3_PFD3_454_74M,
+ imx_clk_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", base + 0xf0, 3));
+
+ /* CCM clocks */
+ base = dev_read_addr_ptr(dev);
+ if (base == (void *)FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ clk_dm(IMXRT1020_CLK_PRE_PERIPH_SEL,
+ imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2,
+ pre_periph_sels, ARRAY_SIZE(pre_periph_sels)));
+ clk_dm(IMXRT1020_CLK_PERIPH_SEL,
+ imx_clk_mux("periph_sel", base + 0x14, 25, 1,
+ periph_sels, ARRAY_SIZE(periph_sels)));
+ clk_dm(IMXRT1020_CLK_USDHC1_SEL,
+ imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1,
+ usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ clk_dm(IMXRT1020_CLK_USDHC2_SEL,
+ imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1,
+ usdhc_sels, ARRAY_SIZE(usdhc_sels)));
+ clk_dm(IMXRT1020_CLK_LPUART_SEL,
+ imx_clk_mux("lpuart_sel", base + 0x24, 6, 1,
+ lpuart_sels, ARRAY_SIZE(lpuart_sels)));
+ clk_dm(IMXRT1020_CLK_SEMC_ALT_SEL,
+ imx_clk_mux("semc_alt_sel", base + 0x14, 7, 1,
+ semc_alt_sels, ARRAY_SIZE(semc_alt_sels)));
+ clk_dm(IMXRT1020_CLK_SEMC_SEL,
+ imx_clk_mux("semc_sel", base + 0x14, 6, 1,
+ semc_sels, ARRAY_SIZE(semc_sels)));
+
+ clk_dm(IMXRT1020_CLK_AHB_PODF,
+ imx_clk_divider("ahb_podf", "periph_sel",
+ base + 0x14, 10, 3));
+ clk_dm(IMXRT1020_CLK_USDHC1_PODF,
+ imx_clk_divider("usdhc1_podf", "usdhc1_sel",
+ base + 0x24, 11, 3));
+ clk_dm(IMXRT1020_CLK_USDHC2_PODF,
+ imx_clk_divider("usdhc2_podf", "usdhc2_sel",
+ base + 0x24, 16, 3));
+ clk_dm(IMXRT1020_CLK_LPUART_PODF,
+ imx_clk_divider("lpuart_podf", "lpuart_sel",
+ base + 0x24, 0, 6));
+ clk_dm(IMXRT1020_CLK_SEMC_PODF,
+ imx_clk_divider("semc_podf", "semc_sel",
+ base + 0x14, 16, 3));
+
+ clk_dm(IMXRT1020_CLK_USDHC1,
+ imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2));
+ clk_dm(IMXRT1020_CLK_USDHC2,
+ imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4));
+ clk_dm(IMXRT1020_CLK_LPUART1,
+ imx_clk_gate2("lpuart1", "lpuart_podf", base + 0x7c, 24));
+ clk_dm(IMXRT1020_CLK_SEMC,
+ imx_clk_gate2("semc", "semc_podf", base + 0x74, 4));
+
+#ifdef CONFIG_SPL_BUILD
+ struct clk *clk, *clk1;
+
+ clk_get_by_id(IMXRT1020_CLK_SEMC_SEL, &clk1);
+ clk_get_by_id(IMXRT1020_CLK_SEMC_ALT_SEL, &clk);
+ clk_set_parent(clk1, clk);
+
+ /* Configure PLL3_USB_OTG to 480MHz */
+ clk_get_by_id(IMXRT1020_CLK_PLL3_USB_OTG, &clk);
+ clk_enable(clk);
+ clk_set_rate(clk, 480000000UL);
+
+ clk_get_by_id(IMXRT1020_CLK_PLL3_BYPASS, &clk1);
+ clk_set_parent(clk1, clk);
+
+ clk_get_by_id(IMXRT1020_CLK_PLL2_PFD3_297M, &clk);
+ clk_set_rate(clk, 297000000UL);
+
+ clk_get_by_id(IMXRT1020_CLK_PLL2_SYS, &clk);
+ clk_enable(clk);
+ clk_set_rate(clk, 528000000UL);
+
+ clk_get_by_id(IMXRT1020_CLK_PLL2_BYPASS, &clk1);
+ clk_set_parent(clk1, clk);
+
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id imxrt1020_clk_ids[] = {
+ { .compatible = "fsl,imxrt1020-ccm" },
+ { },
+};
+
+U_BOOT_DRIVER(imxrt1020_clk) = {
+ .name = "clk_imxrt1020",
+ .id = UCLASS_CLK,
+ .of_match = imxrt1020_clk_ids,
+ .ops = &imxrt1020_clk_ops,
+ .probe = imxrt1020_clk_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
index 44ca52c013e..329f4580c5a 100644
--- a/drivers/clk/imx/clk-imxrt1050.c
+++ b/drivers/clk/imx/clk-imxrt1050.c
@@ -71,11 +71,30 @@ static int imxrt1050_clk_enable(struct clk *clk)
return __imxrt1050_clk_enable(clk, 1);
}
+static int imxrt1050_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *c, *cp;
+ int ret;
+
+ debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(parent->id, &cp);
+ if (ret)
+ return ret;
+
+ return clk_set_parent(c, cp);
+}
+
static struct clk_ops imxrt1050_clk_ops = {
.set_rate = imxrt1050_clk_set_rate,
.get_rate = imxrt1050_clk_get_rate,
.enable = imxrt1050_clk_enable,
.disable = imxrt1050_clk_disable,
+ .set_parent = imxrt1050_clk_set_parent,
};
static const char * const pll_ref_sels[] = {"osc", "dummy", };
@@ -90,7 +109,7 @@ static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
-static const char *const lcdif_sels[] = { "pll2_sys", "pll3_pfd3_454_74m", "pll5_video:", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_664_62m"};
+static const char *const lcdif_sels[] = { "pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_664_62m"};
static int imxrt1050_clk_probe(struct udevice *dev)
{
@@ -238,9 +257,9 @@ static int imxrt1050_clk_probe(struct udevice *dev)
clk_dm(IMXRT1050_CLK_LCDIF,
imx_clk_gate2("lcdif", "lcdif_podf", base + 0x70, 28));
-#ifdef CONFIG_SPL_BUILD
struct clk *clk, *clk1;
+#ifdef CONFIG_SPL_BUILD
/* bypass pll1 before setting its rate */
clk_get_by_id(IMXRT1050_CLK_PLL1_REF_SEL, &clk);
clk_get_by_id(IMXRT1050_CLK_PLL1_BYPASS, &clk1);
@@ -271,7 +290,14 @@ static int imxrt1050_clk_probe(struct udevice *dev)
clk_get_by_id(IMXRT1050_CLK_PLL3_BYPASS, &clk1);
clk_set_parent(clk1, clk);
+#else
+ /* Set PLL5 for LCDIF to its default 650Mhz */
+ clk_get_by_id(IMXRT1050_CLK_PLL5_VIDEO, &clk);
+ clk_enable(clk);
+ clk_set_rate(clk, 650000000UL);
+ clk_get_by_id(IMXRT1050_CLK_PLL5_BYPASS, &clk1);
+ clk_set_parent(clk1, clk);
#endif
return 0;
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 525442debf0..b4a9d587e1b 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -25,6 +25,7 @@
#define PLL_DENOM_OFFSET 0x20
#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_LOCK (0x1 << 31)
struct clk_pllv3 {
@@ -32,6 +33,7 @@ struct clk_pllv3 {
void __iomem *base;
u32 power_bit;
bool powerup_set;
+ u32 enable_bit;
u32 div_mask;
u32 div_shift;
};
@@ -83,6 +85,9 @@ static int clk_pllv3_generic_enable(struct clk *clk)
val |= pll->power_bit;
else
val &= ~pll->power_bit;
+
+ val |= pll->enable_bit;
+
writel(val, pll->base);
return 0;
@@ -98,6 +103,9 @@ static int clk_pllv3_generic_disable(struct clk *clk)
val &= ~pll->power_bit;
else
val |= pll->power_bit;
+
+ val &= ~pll->enable_bit;
+
writel(val, pll->base);
return 0;
@@ -238,6 +246,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
return ERR_PTR(-ENOMEM);
pll->power_bit = BM_PLL_POWER;
+ pll->enable_bit = BM_PLL_ENABLE;
switch (type) {
case IMX_PLLV3_GENERIC:
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index 2c77234c60e..edc40f706c1 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -8,7 +8,7 @@
* --------------------------------------------------------
*
* NOTE: This driver should be converted to driver model before June 2017.
- * Please see doc/driver-model/i2c-howto.txt for instructions.
+ * Please see doc/driver-model/i2c-howto.rst for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c
index 0726b4c9567..8e31481c0fd 100644
--- a/drivers/i2c/kona_i2c.c
+++ b/drivers/i2c/kona_i2c.c
@@ -3,7 +3,7 @@
* Copyright 2013 Broadcom Corporation.
*
* NOTE: This driver should be converted to driver model before June 2017.
- * Please see doc/driver-model/i2c-howto.txt for instructions.
+ * Please see doc/driver-model/i2c-howto.rst for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/sh_i2c.c b/drivers/i2c/sh_i2c.c
index b69d2135939..834f1f2179f 100644
--- a/drivers/i2c/sh_i2c.c
+++ b/drivers/i2c/sh_i2c.c
@@ -4,7 +4,7 @@
* Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
*
* NOTE: This driver should be converted to driver model before June 2017.
- * Please see doc/driver-model/i2c-howto.txt for instructions.
+ * Please see doc/driver-model/i2c-howto.rst for instructions.
*/
#include <common.h>
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index 7f0303cc051..9ad1c281ff2 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -12,7 +12,7 @@
* Neil Russell.
*
* NOTE: This driver should be converted to driver model before June 2017.
- * Please see doc/driver-model/i2c-howto.txt for instructions.
+ * Please see doc/driver-model/i2c-howto.rst for instructions.
*/
#include <common.h>
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
index c98d12b627d..b4f4c3c76b9 100644
--- a/drivers/phy/meson-gxl-usb2.c
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -17,6 +17,9 @@
#include <regmap.h>
#include <power/regulator.h>
#include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
#include <linux/bitops.h>
#include <linux/compat.h>
@@ -121,15 +124,30 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
udelay(RESET_COMPLETE_TIME);
}
-static void
-phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode)
{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
uint val;
regmap_read(priv->regmap, U2P_R0, &val);
- val |= U2P_R0_DM_PULLDOWN;
- val |= U2P_R0_DP_PULLDOWN;
- val &= ~U2P_R0_ID_PULLUP;
+
+ switch (mode) {
+ case USB_DR_MODE_UNKNOWN:
+ case USB_DR_MODE_HOST:
+ case USB_DR_MODE_OTG:
+ val |= U2P_R0_DM_PULLDOWN;
+ val |= U2P_R0_DP_PULLDOWN;
+ val &= ~U2P_R0_ID_PULLUP;
+ break;
+
+ case USB_DR_MODE_PERIPHERAL:
+ val &= ~U2P_R0_DM_PULLDOWN;
+ val &= ~U2P_R0_DP_PULLDOWN;
+ val |= U2P_R0_ID_PULLUP;
+ break;
+ }
+
regmap_write(priv->regmap, U2P_R0, val);
phy_meson_gxl_usb2_reset(priv);
@@ -146,7 +164,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
val &= ~U2P_R0_POWER_ON_RESET;
regmap_write(priv->regmap, U2P_R0, val);
- phy_meson_gxl_usb2_set_host_mode(priv);
+ phy_meson_gxl_usb2_set_mode(phy, USB_DR_MODE_HOST);
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (priv->phy_supply) {
diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
index c2a8593b39f..9de55bb5df0 100644
--- a/drivers/phy/meson-gxl-usb3.c
+++ b/drivers/phy/meson-gxl-usb3.c
@@ -16,6 +16,9 @@
#include <generic-phy.h>
#include <regmap.h>
#include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
#include <linux/bitops.h>
#include <linux/compat.h>
@@ -93,20 +96,35 @@ struct phy_meson_gxl_usb3_priv {
#endif
};
-static int
-phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode)
{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
uint val;
- regmap_read(priv->regmap, USB_R0, &val);
- val &= ~USB_R0_U2D_ACT;
- regmap_write(priv->regmap, USB_R0, val);
-
- regmap_read(priv->regmap, USB_R4, &val);
- val &= ~USB_R4_P21_SLEEP_M0;
- regmap_write(priv->regmap, USB_R4, val);
-
- return 0;
+ switch (mode) {
+ case USB_DR_MODE_UNKNOWN:
+ case USB_DR_MODE_HOST:
+ case USB_DR_MODE_OTG:
+ regmap_read(priv->regmap, USB_R0, &val);
+ val &= ~USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val &= ~USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+ break;
+
+ case USB_DR_MODE_PERIPHERAL:
+ regmap_read(priv->regmap, USB_R0, &val);
+ val |= USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val |= USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+ break;
+ }
}
static int phy_meson_gxl_usb3_power_on(struct phy *phy)
@@ -122,7 +140,9 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy)
val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
regmap_write(priv->regmap, USB_R5, val);
- return phy_meson_gxl_usb3_set_host_mode(priv);
+ phy_meson_gxl_usb3_set_mode(phy, USB_DR_MODE_HOST);
+
+ return 0;
}
static int phy_meson_gxl_usb3_power_off(struct phy *phy)
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index e201a90c8c8..e463b0b400e 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -31,20 +31,20 @@ static int generic_phy_xlate_offs_flags(struct phy *phy,
return 0;
}
-int generic_phy_get_by_index(struct udevice *dev, int index,
- struct phy *phy)
+int generic_phy_get_by_node(ofnode node, int index, struct phy *phy)
{
struct ofnode_phandle_args args;
struct phy_ops *ops;
struct udevice *phydev;
int i, ret;
- debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
+ debug("%s(node=%s, index=%d, phy=%p)\n",
+ __func__, ofnode_get_name(node), index, phy);
assert(phy);
phy->dev = NULL;
- ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
- &args);
+ ret = ofnode_parse_phandle_with_args(node, "phys", "#phy-cells", 0,
+ index, &args);
if (ret) {
debug("%s: dev_read_phandle_with_args failed: err=%d\n",
__func__, ret);
@@ -90,6 +90,12 @@ err:
return ret;
}
+int generic_phy_get_by_index(struct udevice *dev, int index,
+ struct phy *phy)
+{
+ return generic_phy_get_by_node(dev_ofnode(dev), index, phy);
+}
+
int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
struct phy *phy)
{
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 6cf5f35f0f2..db630f3ad0e 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -41,7 +41,7 @@ static int pfuze100_write(struct udevice *dev, uint reg, const uint8_t *buff,
static int pfuze100_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
if (dm_i2c_read(dev, reg, buff, len)) {
- pr_err("read error from device: %p register: %#x!\n", dev, reg);
+ debug("read error from device: %p register: %#x!\n", dev, reg);
return -EIO;
}
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 1f36fc78fa7..edb3f0f538e 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -23,6 +23,13 @@ config PWM_IMX
help
This PWM is found i.MX27 and later i.MX SoCs.
+config PWM_MTK
+ bool "Enable support for MediaTek PWM"
+ depends on DM_PWM
+ help
+ This PWM is found on MT7622, MT7623, and MT7629. It supports a
+ programmable period and duty cycle.
+
config PWM_ROCKCHIP
bool "Enable support for the Rockchip PWM"
depends on DM_PWM
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index a837c35ed2e..2c3a069006a 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_DM_PWM) += pwm-uclass.o
obj-$(CONFIG_PWM_EXYNOS) += exynos_pwm.o
obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o
+obj-$(CONFIG_PWM_MTK) += pwm-mtk.o
obj-$(CONFIG_PWM_ROCKCHIP) += rk_pwm.o
obj-$(CONFIG_PWM_SANDBOX) += sandbox_pwm.o
obj-$(CONFIG_PWM_TEGRA) += tegra_pwm.o
diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c
new file mode 100644
index 00000000000..97ed477025f
--- /dev/null
+++ b/drivers/pwm/pwm-mtk.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <pwm.h>
+#include <div64.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+
+/* PWM registers and bits definitions */
+#define PWMCON 0x00
+#define PWMHDUR 0x04
+#define PWMLDUR 0x08
+#define PWMGDUR 0x0c
+#define PWMWAVENUM 0x28
+#define PWMDWIDTH 0x2c
+#define PWM45DWIDTH_FIXUP 0x30
+#define PWMTHRES 0x30
+#define PWM45THRES_FIXUP 0x34
+
+#define PWM_CLK_DIV_MAX 7
+#define MAX_PWM_NUM 8
+
+#define NSEC_PER_SEC 1000000000L
+
+static const unsigned int mtk_pwm_reg_offset[] = {
+ 0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
+};
+
+struct mtk_pwm_soc {
+ unsigned int num_pwms;
+ bool pwm45_fixup;
+};
+
+struct mtk_pwm_priv {
+ void __iomem *base;
+ struct clk top_clk;
+ struct clk main_clk;
+ struct clk pwm_clks[MAX_PWM_NUM];
+ const struct mtk_pwm_soc *soc;
+};
+
+static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint val)
+{
+ struct mtk_pwm_priv *priv = dev_get_priv(dev);
+ u32 offset = mtk_pwm_reg_offset[channel];
+
+ writel(val, priv->base + offset + reg);
+}
+
+static int mtk_pwm_set_config(struct udevice *dev, uint channel,
+ uint period_ns, uint duty_ns)
+{
+ struct mtk_pwm_priv *priv = dev_get_priv(dev);
+ u32 clkdiv = 0, clksel = 0, cnt_period, cnt_duty,
+ reg_width = PWMDWIDTH, reg_thres = PWMTHRES;
+ u64 resolution;
+ int ret = 0;
+
+ clk_enable(&priv->top_clk);
+ clk_enable(&priv->main_clk);
+ /* Using resolution in picosecond gets accuracy higher */
+ resolution = (u64)NSEC_PER_SEC * 1000;
+ do_div(resolution, clk_get_rate(&priv->pwm_clks[channel]));
+ cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
+ while (cnt_period > 8191) {
+ resolution *= 2;
+ clkdiv++;
+ cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000,
+ resolution);
+ if (clkdiv > PWM_CLK_DIV_MAX && clksel == 0) {
+ clksel = 1;
+ clkdiv = 0;
+ resolution = (u64)NSEC_PER_SEC * 1000 * 1625;
+ do_div(resolution,
+ clk_get_rate(&priv->pwm_clks[channel]));
+ cnt_period = DIV_ROUND_CLOSEST_ULL(
+ (u64)period_ns * 1000, resolution);
+ clk_enable(&priv->pwm_clks[channel]);
+ }
+ }
+ if (clkdiv > PWM_CLK_DIV_MAX && clksel == 1) {
+ printf("pwm period %u not supported\n", period_ns);
+ return -EINVAL;
+ }
+ if (priv->soc->pwm45_fixup && channel > 2) {
+ /*
+ * PWM[4,5] has distinct offset for PWMDWIDTH and PWMTHRES
+ * from the other PWMs on MT7623.
+ */
+ reg_width = PWM45DWIDTH_FIXUP;
+ reg_thres = PWM45THRES_FIXUP;
+ }
+ cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution);
+ if (clksel == 1)
+ mtk_pwm_w32(dev, channel, PWMCON, BIT(15) | BIT(3) | clkdiv);
+ else
+ mtk_pwm_w32(dev, channel, PWMCON, BIT(15) | clkdiv);
+ mtk_pwm_w32(dev, channel, reg_width, cnt_period);
+ mtk_pwm_w32(dev, channel, reg_thres, cnt_duty);
+
+ return ret;
+};
+
+static int mtk_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
+{
+ struct mtk_pwm_priv *priv = dev_get_priv(dev);
+ u32 val = 0;
+
+ val = readl(priv->base);
+ if (enable)
+ val |= BIT(channel);
+ else
+ val &= ~BIT(channel);
+ writel(val, priv->base);
+
+ return 0;
+};
+
+static int mtk_pwm_probe(struct udevice *dev)
+{
+ struct mtk_pwm_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+ int i;
+
+ priv->soc = (struct mtk_pwm_soc *)dev_get_driver_data(dev);
+ priv->base = (void __iomem *)devfdt_get_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+ ret = clk_get_by_name(dev, "top", &priv->top_clk);
+ if (ret < 0)
+ return ret;
+ ret = clk_get_by_name(dev, "main", &priv->main_clk);
+ if (ret < 0)
+ return ret;
+ for (i = 0; i < priv->soc->num_pwms; i++) {
+ char name[8];
+
+ snprintf(name, sizeof(name), "pwm%d", i + 1);
+ ret = clk_get_by_name(dev, name, &priv->pwm_clks[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct pwm_ops mtk_pwm_ops = {
+ .set_config = mtk_pwm_set_config,
+ .set_enable = mtk_pwm_set_enable,
+};
+
+static const struct mtk_pwm_soc mt7622_data = {
+ .num_pwms = 6,
+ .pwm45_fixup = false,
+};
+
+static const struct mtk_pwm_soc mt7623_data = {
+ .num_pwms = 5,
+ .pwm45_fixup = true,
+};
+
+static const struct mtk_pwm_soc mt7629_data = {
+ .num_pwms = 1,
+ .pwm45_fixup = false,
+};
+
+static const struct udevice_id mtk_pwm_ids[] = {
+ { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data },
+ { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data },
+ { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_pwm) = {
+ .name = "mtk_pwm",
+ .id = UCLASS_PWM,
+ .of_match = mtk_pwm_ids,
+ .ops = &mtk_pwm_ops,
+ .probe = mtk_pwm_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_pwm_priv),
+};
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 9fb5e658f92..5260dab3ac0 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -512,7 +512,7 @@ static bool is_optee_api(optee_invoke_fn *invoke_fn)
res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3;
}
-static void print_os_revision(optee_invoke_fn *invoke_fn)
+static void print_os_revision(struct udevice *dev, optee_invoke_fn *invoke_fn)
{
union {
struct arm_smccc_res smccc;
@@ -527,11 +527,12 @@ static void print_os_revision(optee_invoke_fn *invoke_fn)
&res.smccc);
if (res.result.build_id)
- debug("OP-TEE revision %lu.%lu (%08lx)\n", res.result.major,
- res.result.minor, res.result.build_id);
+ dev_info(dev, "OP-TEE: revision %lu.%lu (%08lx)\n",
+ res.result.major, res.result.minor,
+ res.result.build_id);
else
- debug("OP-TEE revision %lu.%lu\n", res.result.major,
- res.result.minor);
+ dev_info(dev, "OP-TEE: revision %lu.%lu\n",
+ res.result.major, res.result.minor);
}
static bool api_revision_is_compatible(optee_invoke_fn *invoke_fn)
@@ -626,7 +627,7 @@ static int optee_probe(struct udevice *dev)
return -ENOENT;
}
- print_os_revision(pdata->invoke_fn);
+ print_os_revision(dev, pdata->invoke_fn);
if (!api_revision_is_compatible(pdata->invoke_fn)) {
debug("%s: OP-TEE api revision mismatch\n", __func__);
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 585af3d5714..8a5a61c9fb7 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -5,6 +5,7 @@
* Copyright (C) 2011-2013 Marek Vasut <marex@denx.de>
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <env.h>
#include <dm/device_compat.h>
@@ -52,14 +53,34 @@ __weak void mxsfb_system_setup(void)
* le:89,ri:164,up:23,lo:10,hs:10,vs:10,sync:0,vmode:0
*/
-static void mxs_lcd_init(u32 fb_addr, struct ctfb_res_modes *mode, int bpp)
+static void mxs_lcd_init(struct udevice *dev, u32 fb_addr,
+ struct display_timing *timings, int bpp)
{
struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+ const enum display_flags flags = timings->flags;
uint32_t word_len = 0, bus_width = 0;
uint8_t valid_data = 0;
+ uint32_t vdctrl0;
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk per_clk;
+ int ret;
+
+ ret = clk_get_by_name(dev, "per", &per_clk);
+ if (ret) {
+ dev_err(dev, "Failed to get mxs clk: %d\n", ret);
+ return;
+ }
+
+ ret = clk_set_rate(&per_clk, timings->pixelclock.typ);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set mxs clk: %d\n", ret);
+ return;
+ }
+#else
/* Kick in the LCDIF clock */
- mxs_set_lcdclk(MXS_LCDIF_BASE, PS2KHZ(mode->pixclock));
+ mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000);
+#endif
/* Restart the LCDIF block */
mxs_reset_block(&regs->hw_lcdif_ctrl_reg);
@@ -96,25 +117,36 @@ static void mxs_lcd_init(u32 fb_addr, struct ctfb_res_modes *mode, int bpp)
mxsfb_system_setup();
- writel((mode->yres << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) | mode->xres,
- &regs->hw_lcdif_transfer_count);
-
- writel(LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_ENABLE_POL |
- LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
- LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
- mode->vsync_len, &regs->hw_lcdif_vdctrl0);
- writel(mode->upper_margin + mode->lower_margin +
- mode->vsync_len + mode->yres,
+ writel((timings->vactive.typ << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) |
+ timings->hactive.typ, &regs->hw_lcdif_transfer_count);
+
+ vdctrl0 = LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_ENABLE_POL |
+ LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
+ LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
+ timings->vsync_len.typ;
+
+ if(flags & DISPLAY_FLAGS_HSYNC_HIGH)
+ vdctrl0 |= LCDIF_VDCTRL0_HSYNC_POL;
+ if(flags & DISPLAY_FLAGS_VSYNC_HIGH)
+ vdctrl0 |= LCDIF_VDCTRL0_VSYNC_POL;
+ if(flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ vdctrl0 |= LCDIF_VDCTRL0_DOTCLK_POL;
+ if(flags & DISPLAY_FLAGS_DE_HIGH)
+ vdctrl0 |= LCDIF_VDCTRL0_ENABLE_POL;
+
+ writel(vdctrl0, &regs->hw_lcdif_vdctrl0);
+ writel(timings->vback_porch.typ + timings->vfront_porch.typ +
+ timings->vsync_len.typ + timings->vactive.typ,
&regs->hw_lcdif_vdctrl1);
- writel((mode->hsync_len << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_OFFSET) |
- (mode->left_margin + mode->right_margin +
- mode->hsync_len + mode->xres),
+ writel((timings->hsync_len.typ << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_OFFSET) |
+ (timings->hback_porch.typ + timings->hfront_porch.typ +
+ timings->hsync_len.typ + timings->hactive.typ),
&regs->hw_lcdif_vdctrl2);
- writel(((mode->left_margin + mode->hsync_len) <<
+ writel(((timings->hback_porch.typ + timings->hsync_len.typ) <<
LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_OFFSET) |
- (mode->upper_margin + mode->vsync_len),
+ (timings->vback_porch.typ + timings->vsync_len.typ),
&regs->hw_lcdif_vdctrl3);
- writel((0 << LCDIF_VDCTRL4_DOTCLK_DLY_SEL_OFFSET) | mode->xres,
+ writel((0 << LCDIF_VDCTRL4_DOTCLK_DLY_SEL_OFFSET) | timings->hactive.typ,
&regs->hw_lcdif_vdctrl4);
writel(fb_addr, &regs->hw_lcdif_cur_buf);
@@ -135,10 +167,11 @@ static void mxs_lcd_init(u32 fb_addr, struct ctfb_res_modes *mode, int bpp)
writel(LCDIF_CTRL_RUN, &regs->hw_lcdif_ctrl_set);
}
-static int mxs_probe_common(struct ctfb_res_modes *mode, int bpp, u32 fb)
+static int mxs_probe_common(struct udevice *dev, struct display_timing *timings,
+ int bpp, u32 fb)
{
/* Start framebuffer */
- mxs_lcd_init(fb, mode, bpp);
+ mxs_lcd_init(dev, fb, timings, bpp);
#ifdef CONFIG_VIDEO_MXS_MODE_SYSTEM
/*
@@ -204,6 +237,7 @@ void *video_hw_init(void)
char *penv;
void *fb = NULL;
struct ctfb_res_modes mode;
+ struct display_timing timings;
puts("Video: ");
@@ -260,7 +294,9 @@ void *video_hw_init(void)
printf("%s\n", panel.modeIdent);
- ret = mxs_probe_common(&mode, bpp, (u32)fb);
+ video_ctfb_mode_to_display_timing(&mode, &timings);
+
+ ret = mxs_probe_common(NULL, &timings, bpp, (u32)fb);
if (ret)
goto dealloc_fb;
@@ -314,7 +350,6 @@ static int mxs_video_probe(struct udevice *dev)
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
- struct ctfb_res_modes mode;
struct display_timing timings;
u32 bpp = 0;
u32 fb_start, fb_end;
@@ -327,17 +362,7 @@ static int mxs_video_probe(struct udevice *dev)
if (ret)
return ret;
- mode.xres = timings.hactive.typ;
- mode.yres = timings.vactive.typ;
- mode.left_margin = timings.hback_porch.typ;
- mode.right_margin = timings.hfront_porch.typ;
- mode.upper_margin = timings.vback_porch.typ;
- mode.lower_margin = timings.vfront_porch.typ;
- mode.hsync_len = timings.hsync_len.typ;
- mode.vsync_len = timings.vsync_len.typ;
- mode.pixclock = HZ2PS(timings.pixelclock.typ);
-
- ret = mxs_probe_common(&mode, bpp, plat->base);
+ ret = mxs_probe_common(dev, &timings, bpp, plat->base);
if (ret)
return ret;
@@ -358,8 +383,8 @@ static int mxs_video_probe(struct udevice *dev)
return -EINVAL;
}
- uc_priv->xsize = mode.xres;
- uc_priv->ysize = mode.yres;
+ uc_priv->xsize = timings.hactive.typ;
+ uc_priv->ysize = timings.vactive.typ;
/* Enable dcache for the frame buffer */
fb_start = plat->base & ~(MMU_SECTION_SIZE - 1);
@@ -420,6 +445,7 @@ static const struct udevice_id mxs_video_ids[] = {
{ .compatible = "fsl,imx23-lcdif" },
{ .compatible = "fsl,imx28-lcdif" },
{ .compatible = "fsl,imx7ulp-lcdif" },
+ { .compatible = "fsl,imxrt-lcdif" },
{ /* sentinel */ }
};
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index 4e1720ef7ea..40ee009f626 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -615,35 +615,6 @@ static void sunxi_lcdc_backlight_enable(void)
gpio_direction_output(pin, PWM_ON);
}
-static void sunxi_ctfb_mode_to_display_timing(const struct ctfb_res_modes *mode,
- struct display_timing *timing)
-{
- timing->pixelclock.typ = mode->pixclock_khz * 1000;
-
- timing->hactive.typ = mode->xres;
- timing->hfront_porch.typ = mode->right_margin;
- timing->hback_porch.typ = mode->left_margin;
- timing->hsync_len.typ = mode->hsync_len;
-
- timing->vactive.typ = mode->yres;
- timing->vfront_porch.typ = mode->lower_margin;
- timing->vback_porch.typ = mode->upper_margin;
- timing->vsync_len.typ = mode->vsync_len;
-
- timing->flags = 0;
-
- if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
- timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
- else
- timing->flags |= DISPLAY_FLAGS_HSYNC_LOW;
- if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
- timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
- else
- timing->flags |= DISPLAY_FLAGS_VSYNC_LOW;
- if (mode->vmode == FB_VMODE_INTERLACED)
- timing->flags |= DISPLAY_FLAGS_INTERLACED;
-}
-
static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
bool for_ext_vga_dac)
{
@@ -673,7 +644,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
sunxi_is_composite());
- sunxi_ctfb_mode_to_display_timing(mode, &timing);
+ video_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
}
@@ -689,7 +660,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct display_timing timing;
- sunxi_ctfb_mode_to_display_timing(mode, &timing);
+ video_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync,
sunxi_is_composite());
diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c
index ac25b45f819..89003eea727 100644
--- a/drivers/video/videomodes.c
+++ b/drivers/video/videomodes.c
@@ -444,3 +444,32 @@ int video_edid_dtd_to_ctfb_res_modes(struct edid_detailed_timing *t,
return 0;
}
+
+void video_ctfb_mode_to_display_timing(const struct ctfb_res_modes *mode,
+ struct display_timing *timing)
+{
+ timing->pixelclock.typ = mode->pixclock_khz * 1000;
+
+ timing->hactive.typ = mode->xres;
+ timing->hfront_porch.typ = mode->right_margin;
+ timing->hback_porch.typ = mode->left_margin;
+ timing->hsync_len.typ = mode->hsync_len;
+
+ timing->vactive.typ = mode->yres;
+ timing->vfront_porch.typ = mode->lower_margin;
+ timing->vback_porch.typ = mode->upper_margin;
+ timing->vsync_len.typ = mode->vsync_len;
+
+ timing->flags = 0;
+
+ if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+ timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
+ else
+ timing->flags |= DISPLAY_FLAGS_HSYNC_LOW;
+ if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+ timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
+ else
+ timing->flags |= DISPLAY_FLAGS_VSYNC_LOW;
+ if (mode->vmode == FB_VMODE_INTERLACED)
+ timing->flags |= DISPLAY_FLAGS_INTERLACED;
+}
diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h
index 29a3db4ae3c..aefe4ef94ab 100644
--- a/drivers/video/videomodes.h
+++ b/drivers/video/videomodes.h
@@ -92,3 +92,14 @@ int video_get_option_int(const char *options, const char *name, int def);
int video_edid_dtd_to_ctfb_res_modes(struct edid_detailed_timing *t,
struct ctfb_res_modes *mode);
+/**
+ * video_ctfb_mode_to_display_timing() - Convert a ctfb(Cathode Tube Frame
+ * Buffer)_res_modes struct to a
+ * display_timing struct.
+ *
+ * @mode: Input ctfb_res_modes structure pointer to be converted
+ * from
+ * @timing: Output display_timing structure pointer to be converted to
+ */
+void video_ctfb_mode_to_display_timing(const struct ctfb_res_modes *mode,
+ struct display_timing *timing);