summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-03-13 18:32:26 +0100
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-03-13 18:32:26 +0100
commit63f347ec4ca94e3b57c6c719e4acaec81b61dc7a (patch)
tree9391d740c7646cb7808acd6a14d00e6f42cf4fec /drivers
parent08798026f24bd7c706e70372f8c323f0702c9a15 (diff)
parentb627eb461bb281a00b543e72e74edc197b5f7b5e (diff)
downloadu-boot-imx-63f347ec4ca94e3b57c6c719e4acaec81b61dc7a.zip
u-boot-imx-63f347ec4ca94e3b57c6c719e4acaec81b61dc7a.tar.gz
u-boot-imx-63f347ec4ca94e3b57c6c719e4acaec81b61dc7a.tar.bz2
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dfu/dfu.c6
-rw-r--r--drivers/mmc/s5p_sdhci.c129
-rw-r--r--drivers/video/exynos_fb.c12
-rw-r--r--drivers/video/exynos_mipi_dsi.c96
4 files changed, 242 insertions, 1 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 07011e9..56e69fd 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)
{
@@ -377,6 +378,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)
@@ -394,11 +397,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/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/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