diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dfu/dfu.c | 6 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/mxs_ocotp.c | 311 | ||||
-rw-r--r-- | drivers/mmc/s5p_sdhci.c | 129 | ||||
-rw-r--r-- | drivers/net/cpsw.c | 6 | ||||
-rw-r--r-- | drivers/pci/pcie_imx.c | 13 | ||||
-rw-r--r-- | drivers/power/pmic/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/pmic/pmic_pfuze100.c | 32 | ||||
-rw-r--r-- | drivers/spi/omap3_spi.c | 5 | ||||
-rw-r--r-- | drivers/video/exynos_fb.c | 12 | ||||
-rw-r--r-- | drivers/video/exynos_mipi_dsi.c | 96 |
11 files changed, 603 insertions, 9 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index f94c412..8a09aaf 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -19,6 +19,7 @@ static bool dfu_reset_request; static LIST_HEAD(dfu_list); static int dfu_alt_num; +static int alt_num_cnt; bool dfu_reset(void) { @@ -379,6 +380,8 @@ void dfu_free_entities(void) if (t) free(t); INIT_LIST_HEAD(&dfu_list); + + alt_num_cnt = 0; } int dfu_config_entities(char *env, char *interface, int num) @@ -396,11 +399,12 @@ int dfu_config_entities(char *env, char *interface, int num) for (i = 0; i < dfu_alt_num; i++) { s = strsep(&env, ";"); - ret = dfu_fill_entity(&dfu[i], s, i, interface, num); + ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt, interface, num); if (ret) return -1; list_add_tail(&dfu[i].list, &dfu_list); + alt_num_cnt++; } return 0; diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c25e92d..2f2e48f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_FSL_IIM) += fsl_iim.o obj-$(CONFIG_GPIO_LED) += gpio_led.o obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o +obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NS87308) += ns87308.o obj-$(CONFIG_PDSP188x) += pdsp188x.o obj-$(CONFIG_STATUS_LED) += status_led.o diff --git a/drivers/misc/mxs_ocotp.c b/drivers/misc/mxs_ocotp.c new file mode 100644 index 0000000..545d3eb --- /dev/null +++ b/drivers/misc/mxs_ocotp.c @@ -0,0 +1,311 @@ +/* + * Freescale i.MX28 OCOTP Driver + * + * Copyright (C) 2014 Marek Vasut <marex@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Note: The i.MX23/i.MX28 OCOTP block is a predecessor to the OCOTP block + * used in i.MX6 . While these blocks are very similar at the first + * glance, by digging deeper, one will notice differences (like the + * tight dependence on MXS power block, some completely new registers + * etc.) which would make common driver an ifdef nightmare :-( + */ + +#include <common.h> +#include <fuse.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> + +#define MXS_OCOTP_TIMEOUT 100000 + +static struct mxs_ocotp_regs *ocotp_regs = + (struct mxs_ocotp_regs *)MXS_OCOTP_BASE; +static struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; +static struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + +static int mxs_ocotp_wait_busy_clear(void) +{ + uint32_t reg; + int timeout = MXS_OCOTP_TIMEOUT; + + while (--timeout) { + reg = readl(&ocotp_regs->hw_ocotp_ctrl); + if (!(reg & OCOTP_CTRL_BUSY)) + break; + udelay(10); + } + + if (!timeout) + return -EINVAL; + + /* Wait a little as per FSL datasheet's 'write postamble' section. */ + udelay(10); + + return 0; +} + +static void mxs_ocotp_clear_error(void) +{ + writel(OCOTP_CTRL_ERROR, &ocotp_regs->hw_ocotp_ctrl_clr); +} + +static int mxs_ocotp_read_bank_open(bool open) +{ + int ret = 0; + + if (open) { + writel(OCOTP_CTRL_RD_BANK_OPEN, + &ocotp_regs->hw_ocotp_ctrl_set); + + /* + * Wait before polling the BUSY bit, since the BUSY bit might + * be asserted only after a few HCLK cycles and if we were to + * poll immediatelly, we could miss the busy bit. + */ + udelay(10); + ret = mxs_ocotp_wait_busy_clear(); + } else { + writel(OCOTP_CTRL_RD_BANK_OPEN, + &ocotp_regs->hw_ocotp_ctrl_clr); + } + + return ret; +} + +static void mxs_ocotp_scale_vddio(bool enter, uint32_t *val) +{ + uint32_t scale_val; + + if (enter) { + /* + * Enter the fuse programming VDDIO voltage setup. We start + * scaling the voltage from it's current value down to 2.8V + * which is the one and only correct voltage for programming + * the OCOTP fuses (according to datasheet). + */ + scale_val = readl(&power_regs->hw_power_vddioctrl); + scale_val &= POWER_VDDIOCTRL_TRG_MASK; + + /* Return the original voltage. */ + *val = scale_val; + + /* + * Start scaling VDDIO down to 0x2, which is 2.8V . Actually, + * the value 0x0 should be 2.8V, but that's not the case on + * most designs due to load etc., so we play safe. Undervolt + * can actually cause incorrect programming of the fuses and + * or reboots of the board. + */ + while (scale_val > 2) { + clrsetbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_TRG_MASK, --scale_val); + udelay(500); + } + } else { + /* Start scaling VDDIO up to original value . */ + for (scale_val = 2; scale_val <= *val; scale_val++) { + clrsetbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_TRG_MASK, scale_val); + udelay(500); + } + } + + mdelay(10); +} + +static int mxs_ocotp_wait_hclk_ready(void) +{ + uint32_t reg, timeout = MXS_OCOTP_TIMEOUT; + + while (--timeout) { + reg = readl(&clkctrl_regs->hw_clkctrl_hbus); + if (!(reg & CLKCTRL_HBUS_ASM_BUSY)) + break; + } + + if (!timeout) + return -EINVAL; + + return 0; +} + +static int mxs_ocotp_scale_hclk(bool enter, uint32_t *val) +{ + uint32_t scale_val; + int ret; + + ret = mxs_ocotp_wait_hclk_ready(); + if (ret) + return ret; + + /* Set CPU bypass */ + writel(CLKCTRL_CLKSEQ_BYPASS_CPU, + &clkctrl_regs->hw_clkctrl_clkseq_set); + + if (enter) { + /* Return the original HCLK clock speed. */ + *val = readl(&clkctrl_regs->hw_clkctrl_hbus); + *val &= CLKCTRL_HBUS_DIV_MASK; + + /* Scale the HCLK to 454/19 = 23.9 MHz . */ + scale_val = (~19) << CLKCTRL_HBUS_DIV_OFFSET; + scale_val &= CLKCTRL_HBUS_DIV_MASK; + } else { + /* Scale the HCLK back to original frequency. */ + scale_val = (~(*val)) << CLKCTRL_HBUS_DIV_OFFSET; + scale_val &= CLKCTRL_HBUS_DIV_MASK; + } + + writel(CLKCTRL_HBUS_DIV_MASK, + &clkctrl_regs->hw_clkctrl_hbus_set); + writel(scale_val, + &clkctrl_regs->hw_clkctrl_hbus_clr); + + mdelay(10); + + ret = mxs_ocotp_wait_hclk_ready(); + if (ret) + return ret; + + /* Disable CPU bypass */ + writel(CLKCTRL_CLKSEQ_BYPASS_CPU, + &clkctrl_regs->hw_clkctrl_clkseq_clr); + + mdelay(10); + + return 0; +} + +static int mxs_ocotp_write_fuse(uint32_t addr, uint32_t mask) +{ + uint32_t hclk_val, vddio_val; + int ret; + + /* Make sure the banks are closed for reading. */ + ret = mxs_ocotp_read_bank_open(0); + if (ret) { + puts("Failed closing banks for reading!\n"); + return ret; + } + + ret = mxs_ocotp_scale_hclk(1, &hclk_val); + if (ret) { + puts("Failed scaling down the HCLK!\n"); + return ret; + } + mxs_ocotp_scale_vddio(1, &vddio_val); + + ret = mxs_ocotp_wait_busy_clear(); + if (ret) { + puts("Failed waiting for ready state!\n"); + goto fail; + } + + /* Program the fuse address */ + writel(addr | OCOTP_CTRL_WR_UNLOCK_KEY, &ocotp_regs->hw_ocotp_ctrl); + + /* Program the data. */ + writel(mask, &ocotp_regs->hw_ocotp_data); + + udelay(10); + + ret = mxs_ocotp_wait_busy_clear(); + if (ret) { + puts("Failed waiting for ready state!\n"); + goto fail; + } + +fail: + mxs_ocotp_scale_vddio(0, &vddio_val); + ret = mxs_ocotp_scale_hclk(0, &hclk_val); + if (ret) { + puts("Failed scaling up the HCLK!\n"); + return ret; + } + + return ret; +} + +static int mxs_ocotp_read_fuse(uint32_t reg, uint32_t *val) +{ + int ret; + + /* Register offset from CUST0 */ + reg = ((uint32_t)&ocotp_regs->hw_ocotp_cust0) + (reg << 4); + + ret = mxs_ocotp_wait_busy_clear(); + if (ret) { + puts("Failed waiting for ready state!\n"); + return ret; + } + + mxs_ocotp_clear_error(); + + ret = mxs_ocotp_read_bank_open(1); + if (ret) { + puts("Failed opening banks for reading!\n"); + return ret; + } + + *val = readl(reg); + + ret = mxs_ocotp_read_bank_open(0); + if (ret) { + puts("Failed closing banks for reading!\n"); + return ret; + } + + return ret; +} + +static int mxs_ocotp_valid(u32 bank, u32 word) +{ + if (bank > 4) + return -EINVAL; + if (word > 7) + return -EINVAL; + return 0; +} + +/* + * The 'fuse' command API + */ +int fuse_read(u32 bank, u32 word, u32 *val) +{ + int ret; + + ret = mxs_ocotp_valid(bank, word); + if (ret) + return ret; + + return mxs_ocotp_read_fuse((bank << 3) | word, val); +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + int ret; + + ret = mxs_ocotp_valid(bank, word); + if (ret) + return ret; + + return mxs_ocotp_write_fuse((bank << 3) | word, val); +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + /* We do not support sensing :-( */ + return -EINVAL; +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + /* We do not support overriding :-( */ + return -EINVAL; +} diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 40ff873..ccae4cc 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -8,8 +8,15 @@ #include <common.h> #include <malloc.h> #include <sdhci.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <asm/gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/clk.h> +#include <errno.h> +#ifdef CONFIG_OF_CONTROL +#include <asm/arch/pinmux.h> +#endif static char *S5P_NAME = "SAMSUNG SDHCI"; static void s5p_sdhci_set_control_reg(struct sdhci_host *host) @@ -86,3 +93,125 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width) return add_sdhci(host, 52000000, 400000); } + +#ifdef CONFIG_OF_CONTROL +struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS]; + +static int do_sdhci_init(struct sdhci_host *host) +{ + int dev_id, flag; + int err = 0; + + flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; + dev_id = host->index + PERIPH_ID_SDMMC0; + + if (fdt_gpio_isvalid(&host->pwr_gpio)) { + gpio_direction_output(host->pwr_gpio.gpio, 1); + err = exynos_pinmux_config(dev_id, flag); + if (err) { + debug("MMC not configured\n"); + return err; + } + } + + if (fdt_gpio_isvalid(&host->cd_gpio)) { + gpio_direction_output(host->cd_gpio.gpio, 0xf); + if (gpio_get_value(host->cd_gpio.gpio)) + return -ENODEV; + + err = exynos_pinmux_config(dev_id, flag); + if (err) { + printf("external SD not configured\n"); + return err; + } + } + + host->name = S5P_NAME; + + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | + SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_WAIT_SEND_CMD; + host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + + host->set_control_reg = &s5p_sdhci_set_control_reg; + host->set_clock = set_mmc_clk; + + host->host_caps = MMC_MODE_HC; + + return add_sdhci(host, 52000000, 400000); +} + +static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) +{ + int bus_width, dev_id; + unsigned int base; + + /* Get device id */ + dev_id = pinmux_decode_periph_id(blob, node); + if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) { + debug("MMC: Can't get device id\n"); + return -1; + } + host->index = dev_id - PERIPH_ID_SDMMC0; + + /* Get bus width */ + bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); + if (bus_width <= 0) { + debug("MMC: Can't get bus-width\n"); + return -1; + } + host->bus_width = bus_width; + + /* Get the base address from the device node */ + base = fdtdec_get_addr(blob, node, "reg"); + if (!base) { + debug("MMC: Can't get base address\n"); + return -1; + } + host->ioaddr = (void *)base; + + fdtdec_decode_gpio(blob, node, "pwr-gpios", &host->pwr_gpio); + fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); + + return 0; +} + +static int process_nodes(const void *blob, int node_list[], int count) +{ + struct sdhci_host *host; + int i, node; + + debug("%s: count = %d\n", __func__, count); + + /* build sdhci_host[] for each controller */ + for (i = 0; i < count; i++) { + node = node_list[i]; + if (node <= 0) + continue; + + host = &sdhci_host[i]; + + if (sdhci_get_config(blob, node, host)) { + printf("%s: failed to decode dev %d\n", __func__, i); + return -1; + } + do_sdhci_init(host); + } + return 0; +} + +int exynos_mmc_init(const void *blob) +{ + int count; + int node_list[SDHCI_MAX_HOSTS]; + + count = fdtdec_find_aliases_for_id(blob, "mmc", + COMPAT_SAMSUNG_EXYNOS_MMC, node_list, + SDHCI_MAX_HOSTS); + + process_nodes(blob, node_list, count); + + return 1; +} +#endif diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index dd6c26a..bd5fba2 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -941,11 +941,7 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave) { struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv; struct phy_device *phydev; - u32 supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); + u32 supported = PHY_GBIT_FEATURES; phydev = phy_connect(priv->bus, slave->data->phy_addr, diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 1f600aa..c48737e 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -451,6 +451,17 @@ static int imx6_pcie_init_phy(void) return 0; } +__weak int imx6_pcie_toggle_power(void) +{ +#ifdef CONFIG_PCIE_IMX_POWER_GPIO + gpio_direction_output(CONFIG_PCIE_IMX_POWER_GPIO, 0); + mdelay(20); + gpio_set_value(CONFIG_PCIE_IMX_POWER_GPIO, 1); + mdelay(20); +#endif + return 0; +} + __weak int imx6_pcie_toggle_reset(void) { /* @@ -496,7 +507,7 @@ static int imx6_pcie_deassert_core_reset(void) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; - /* FIXME: Power-up GPIO goes here. */ + imx6_pcie_toggle_power(); /* Enable PCIe */ clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN); diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 0b45ffa..4129bda 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -9,5 +9,6 @@ obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o +obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o diff --git a/drivers/power/pmic/pmic_pfuze100.c b/drivers/power/pmic/pmic_pfuze100.c new file mode 100644 index 0000000..22c1f15 --- /dev/null +++ b/drivers/power/pmic/pmic_pfuze100.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Gateworks Corporation + * Tim Harvey <tharvey@gateworks.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <i2c.h> +#include <power/pmic.h> +#include <power/pfuze100_pmic.h> + +int pmic_init(unsigned char bus) +{ + static const char name[] = "PFUZE100_PMIC"; + struct pmic *p = pmic_alloc(); + + if (!p) { + printf("%s: POWER allocation error!\n", __func__); + return -ENOMEM; + } + + p->name = name; + p->interface = PMIC_I2C; + p->number_of_regs = PMIC_NUM_OF_REGS; + p->hw.i2c.addr = CONFIG_POWER_PFUZE100_I2C_ADDR; + p->hw.i2c.tx_num = 1; + p->bus = bus; + + return 0; +} diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index a3ad056..651e46e 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -260,8 +260,9 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp, } /* wait to finish of transfer */ - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & - OMAP3_MCSPI_CHSTAT_EOT)); + while ((readl(&ds->regs->channel[ds->slave.cs].chstat) & + (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) != + (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)); /* Disable the channel otherwise the next immediate RX will get affected */ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index 00a0a11..e1e0d80 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -104,6 +104,13 @@ void __exynos_backlight_reset(void) void exynos_backlight_reset(void) __attribute__((weak, alias("__exynos_backlight_reset"))); +int __exynos_lcd_misc_init(vidinfo_t *vid) +{ + return 0; +} +int exynos_lcd_misc_init(vidinfo_t *vid) + __attribute__((weak, alias("__exynos_lcd_misc_init"))); + static void lcd_panel_on(vidinfo_t *vid) { udelay(vid->init_delay); @@ -281,10 +288,15 @@ void lcd_ctrl_init(void *lcdbase) #ifdef CONFIG_OF_CONTROL if (exynos_fimd_parse_dt(gd->fdt_blob)) debug("Can't get proper panel info\n"); +#ifdef CONFIG_EXYNOS_MIPI_DSIM + exynos_init_dsim_platform_data(&panel_info); +#endif + exynos_lcd_misc_init(&panel_info); #else /* initialize parameters which is specific to panel. */ init_panel_info(&panel_info); #endif + panel_width = panel_info.vl_width; panel_height = panel_info.vl_height; diff --git a/drivers/video/exynos_mipi_dsi.c b/drivers/video/exynos_mipi_dsi.c index 8bb8fea..7dd4652 100644 --- a/drivers/video/exynos_mipi_dsi.c +++ b/drivers/video/exynos_mipi_dsi.c @@ -9,6 +9,8 @@ #include <common.h> #include <malloc.h> +#include <fdtdec.h> +#include <libfdt.h> #include <linux/err.h> #include <asm/arch/dsim.h> #include <asm/arch/mipi_dsim.h> @@ -22,7 +24,14 @@ #define master_to_driver(a) (a->dsim_lcd_drv) #define master_to_device(a) (a->dsim_lcd_dev) +DECLARE_GLOBAL_DATA_PTR; + static struct exynos_platform_mipi_dsim *dsim_pd; +#ifdef CONFIG_OF_CONTROL +static struct mipi_dsim_config dsim_config_dt; +static struct exynos_platform_mipi_dsim dsim_platform_data_dt; +static struct mipi_dsim_lcd_device mipi_lcd_device_dt; +#endif struct mipi_dsim_ddi { int bus_id; @@ -238,3 +247,90 @@ void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd) dsim_pd = pd; } + +#ifdef CONFIG_OF_CONTROL +int exynos_dsim_config_parse_dt(const void *blob) +{ + int node; + + node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_MIPI_DSI); + if (node <= 0) { + printf("exynos_mipi_dsi: Can't get device node for mipi dsi\n"); + return -ENODEV; + } + + dsim_config_dt.e_interface = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-interface", 0); + + dsim_config_dt.e_virtual_ch = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-virtual-ch", 0); + + dsim_config_dt.e_pixel_format = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-pixel-format", 0); + + dsim_config_dt.e_burst_mode = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-burst-mode", 0); + + dsim_config_dt.e_no_data_lane = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-no-data-lane", 0); + + dsim_config_dt.e_byte_clk = fdtdec_get_int(blob, node, + "samsung,dsim-config-e-byte-clk", 0); + + dsim_config_dt.hfp = fdtdec_get_int(blob, node, + "samsung,dsim-config-hfp", 0); + + dsim_config_dt.p = fdtdec_get_int(blob, node, + "samsung,dsim-config-p", 0); + dsim_config_dt.m = fdtdec_get_int(blob, node, + "samsung,dsim-config-m", 0); + dsim_config_dt.s = fdtdec_get_int(blob, node, + "samsung,dsim-config-s", 0); + + dsim_config_dt.pll_stable_time = fdtdec_get_int(blob, node, + "samsung,dsim-config-pll-stable-time", 0); + + dsim_config_dt.esc_clk = fdtdec_get_int(blob, node, + "samsung,dsim-config-esc-clk", 0); + + dsim_config_dt.stop_holding_cnt = fdtdec_get_int(blob, node, + "samsung,dsim-config-stop-holding-cnt", 0); + + dsim_config_dt.bta_timeout = fdtdec_get_int(blob, node, + "samsung,dsim-config-bta-timeout", 0); + + dsim_config_dt.rx_timeout = fdtdec_get_int(blob, node, + "samsung,dsim-config-rx-timeout", 0); + + mipi_lcd_device_dt.name = fdtdec_get_config_string(blob, + "samsung,dsim-device-name"); + + mipi_lcd_device_dt.id = fdtdec_get_int(blob, node, + "samsung,dsim-device-id", 0); + + mipi_lcd_device_dt.bus_id = fdtdec_get_int(blob, node, + "samsung,dsim-device-bus_id", 0); + + mipi_lcd_device_dt.reverse_panel = fdtdec_get_int(blob, node, + "samsung,dsim-device-reverse-panel", 0); + + return 0; +} + +void exynos_init_dsim_platform_data(vidinfo_t *vid) +{ + if (exynos_dsim_config_parse_dt(gd->fdt_blob)) + debug("Can't get proper dsim config.\n"); + + strcpy(dsim_platform_data_dt.lcd_panel_name, mipi_lcd_device_dt.name); + dsim_platform_data_dt.dsim_config = &dsim_config_dt; + dsim_platform_data_dt.mipi_power = mipi_power; + dsim_platform_data_dt.phy_enable = set_mipi_phy_ctrl; + dsim_platform_data_dt.lcd_panel_info = (void *)vid; + + mipi_lcd_device_dt.platform_data = (void *)&dsim_platform_data_dt; + exynos_mipi_dsi_register_lcd_device(&mipi_lcd_device_dt); + + dsim_pd = &dsim_platform_data_dt; +} +#endif |