Merge branch 'master' of git://git.denx.de/u-boot-samsung
[platform/kernel/u-boot.git] / board / BuR / common / common.c
index 23a98e4..e8c6401 100644 (file)
@@ -3,7 +3,7 @@
  *
  * common board functions for B&R boards
  *
- * Copyright (C) 2013 Hannes Petermaier <oe5hpm@oevsv.at>
+ * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at>
  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
  *
  * SPDX-License-Identifier:    GPL-2.0+
@@ -12,7 +12,6 @@
 #include <version.h>
 #include <common.h>
 #include <errno.h>
-#include <spl.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/omap.h>
@@ -34,6 +33,7 @@
 #include "bur_common.h"
 #include "../../../drivers/video/am335x-fb.h"
 #include <nand.h>
+#include <fdt_simplefb.h>
 
 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 
@@ -47,11 +47,80 @@ DECLARE_GLOBAL_DATA_PTR;
 /* --------------------------------------------------------------------------*/
 #if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \
        !defined(CONFIG_SPL_BUILD)
+void lcdbacklight(int on)
+{
+#ifdef CONFIG_USE_FDT
+       if (gd->fdt_blob == NULL) {
+               printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
+               return;
+       }
+       unsigned int driver = FDTPROP(PATHINF, "brightdrv");
+       unsigned int bright = FDTPROP(PATHINF, "brightdef");
+       unsigned int pwmfrq = FDTPROP(PATHINF, "brightfdim");
+#else
+       unsigned int driver = getenv_ulong("ds1_bright_drv", 16, 0UL);
+       unsigned int bright = getenv_ulong("ds1_bright_def", 10, 50);
+       unsigned int pwmfrq = getenv_ulong("ds1_pwmfreq", 10, ~0UL);
+#endif
+       unsigned int tmp;
+       struct gptimer *timerhw;
+
+       if (on)
+               bright = bright != ~0UL ? bright : 50;
+       else
+               bright = 0;
+
+       switch (driver) {
+       case 2:
+               timerhw = (struct gptimer *)DM_TIMER5_BASE;
+               break;
+       default:
+               timerhw = (struct gptimer *)DM_TIMER6_BASE;
+       }
+
+       switch (driver) {
+       case 0: /* PMIC LED-Driver */
+               /* brightness level */
+               tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
+                                  TPS65217_WLEDCTRL2, bright, 0xFF);
+               /* current sink */
+               tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
+                                  TPS65217_WLEDCTRL1,
+                                  bright != 0 ? 0x0A : 0x02,
+                                  0xFF);
+               break;
+       case 1:
+       case 2: /* PWM using timer */
+               if (pwmfrq != ~0UL) {
+                       timerhw->tiocp_cfg = TCFG_RESET;
+                       udelay(10);
+                       while (timerhw->tiocp_cfg & TCFG_RESET)
+                               ;
+                       tmp = ~0UL-(V_OSCK/pwmfrq);     /* bottom value */
+                       timerhw->tldr = tmp;
+                       timerhw->tcrr = tmp;
+                       tmp = tmp + ((V_OSCK/pwmfrq)/100) * bright;
+                       timerhw->tmar = tmp;
+                       timerhw->tclr = (TCLR_PT | (2 << TCLR_TRG_SHIFT) |
+                                       TCLR_CE | TCLR_AR | TCLR_ST);
+               } else {
+                       puts("invalid pwmfrq in env/dtb! skip PWM-setup.\n");
+               }
+               break;
+       default:
+               puts("no suitable backlightdriver in env/dtb!\n");
+               break;
+       }
+}
+
 int load_lcdtiming(struct am335x_lcdpanel *panel)
 {
        struct am335x_lcdpanel pnltmp;
 #ifdef CONFIG_USE_FDT
        u32 dtbprop;
+       char buf[32];
+       const char *nodep = 0;
+       int nodeoff;
 
        if (gd->fdt_blob == NULL) {
                printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
@@ -97,6 +166,25 @@ int load_lcdtiming(struct am335x_lcdpanel *panel)
        dtbprop = FDTPROP(PATHTIM, "de-active");
        if (dtbprop == 0)
                pnltmp.pol |= DE_INVERT;
+
+       nodeoff = fdt_path_offset(gd->fdt_blob, "/factory-settings");
+       if (nodeoff >= 0) {
+               nodep = fdt_getprop(gd->fdt_blob, nodeoff, "rotation", NULL);
+               if (nodep != 0) {
+                       if (strcmp(nodep, "cw") == 0)
+                               panel_info.vl_rot = 1;
+                       else if (strcmp(nodep, "ud") == 0)
+                               panel_info.vl_rot = 2;
+                       else if (strcmp(nodep, "ccw") == 0)
+                               panel_info.vl_rot = 3;
+                       else
+                               panel_info.vl_rot = 0;
+               }
+       } else {
+               puts("no 'factory-settings / rotation' in dtb!\n");
+       }
+       snprintf(buf, sizeof(buf), "fbcon=rotate:%d", panel_info.vl_rot);
+       setenv("optargs_rot", buf);
 #else
        pnltmp.hactive = getenv_ulong("ds1_hactive", 10, ~0UL);
        pnltmp.vactive = getenv_ulong("ds1_vactive", 10, ~0UL);
@@ -111,6 +199,7 @@ int load_lcdtiming(struct am335x_lcdpanel *panel)
        pnltmp.pol = getenv_ulong("ds1_pol", 16, ~0UL);
        pnltmp.pup_delay = getenv_ulong("ds1_pupdelay", 10, ~0UL);
        pnltmp.pon_delay = getenv_ulong("ds1_tondelay", 10, ~0UL);
+       panel_info.vl_rot = getenv_ulong("ds1_rotation", 10, 0);
 #endif
        if (
           ~0UL == (pnltmp.hactive) ||
@@ -170,18 +259,18 @@ static int load_devicetree(void)
        }
 #ifdef CONFIG_NAND
        dtbsize = 0x20000;
-       rc = nand_read_skip_bad(&nand_info[0], 0x40000, (size_t *)&dtbsize,
+       rc = nand_read_skip_bad(nand_info[0], 0x40000, (size_t *)&dtbsize,
                                NULL, 0x20000, (u_char *)dtbaddr);
 #else
        char *dtbname = getenv("dtb");
        char *dtbdev = getenv("dtbdev");
-       char *dtppart = getenv("dtbpart");
-       if (!dtbdev || !dtbdev || !dtbname) {
+       char *dtbpart = getenv("dtbpart");
+       if (!dtbdev || !dtbpart || !dtbname) {
                printf("%s: <dtbdev>/<dtbpart>/<dtb> missing.\n", __func__);
                return -1;
        }
 
-       if (fs_set_blk_dev(dtbdev, dtppart, FS_TYPE_EXT)) {
+       if (fs_set_blk_dev(dtbdev, dtbpart, FS_TYPE_EXT)) {
                puts("load_devicetree: set_blk_dev failed.\n");
                return -1;
        }
@@ -281,6 +370,32 @@ int ft_board_setup(void *blob, bd_t *bd)
                puts("set bootloader version 'bl-version' prop. not in dtb!\n");
                return -1;
        }
+       /*
+        * if no simplefb is requested through environment, we don't set up
+        * one, instead we turn off backlight.
+        */
+       if (getenv_ulong("simplefb", 10, 0) == 0) {
+               lcdbacklight(0);
+               return 0;
+       }
+       /* Setup simplefb devicetree node, also adapt memory-node,
+        * upper limit for kernel e.g. linux is memtop-framebuffer alligned
+        * to a full megabyte.
+        */
+       u64 start = gd->bd->bi_dram[0].start;
+       u64 size = (gd->fb_base - start) & ~0xFFFFF;
+       int rc = fdt_fixup_memory_banks(blob, &start, &size, 1);
+
+       if (rc) {
+               puts("cannot setup simplefb: Error reserving memory!\n");
+               return rc;
+       }
+       rc = lcd_dt_simplefb_enable_existing_node(blob);
+       if (rc) {
+               puts("cannot setup simplefb: error enabling simplefb node!\n");
+               return rc;
+       }
+
        return 0;
 }
 #else
@@ -389,55 +504,8 @@ void lcd_ctrl_init(void *lcdbase)
 
 void lcd_enable(void)
 {
-#ifdef CONFIG_USE_FDT
-       if (gd->fdt_blob == NULL) {
-               printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
-               return;
-       }
-       unsigned int driver = FDTPROP(PATHINF, "brightdrv");
-       unsigned int bright = FDTPROP(PATHINF, "brightdef");
-       unsigned int pwmfrq = FDTPROP(PATHINF, "brightfdim");
-#else
-       unsigned int driver = getenv_ulong("ds1_bright_drv", 16, 0UL);
-       unsigned int bright = getenv_ulong("ds1_bright_def", 10, 50);
-       unsigned int pwmfrq = getenv_ulong("ds1_pwmfreq", 10, ~0UL);
-#endif
-       unsigned int tmp;
-       struct gptimer *const timerhw = (struct gptimer *)DM_TIMER6_BASE;
-
-       bright = bright != ~0UL ? bright : 50;
-
-       switch (driver) {
-       case 0: /* PMIC LED-Driver */
-               /* brightness level */
-               tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
-                                  TPS65217_WLEDCTRL2, bright, 0xFF);
-               /* turn on light */
-               tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
-                                  TPS65217_WLEDCTRL1, 0x0A, 0xFF);
-               break;
-       case 1: /* PWM using timer6 */
-               if (pwmfrq != ~0UL) {
-                       timerhw->tiocp_cfg = TCFG_RESET;
-                       udelay(10);
-                       while (timerhw->tiocp_cfg & TCFG_RESET)
-                               ;
-                       tmp = ~0UL-(V_OSCK/pwmfrq);     /* bottom value */
-                       timerhw->tldr = tmp;
-                       timerhw->tcrr = tmp;
-                       tmp = tmp + ((V_OSCK/pwmfrq)/100) * bright;
-                       timerhw->tmar = tmp;
-                       timerhw->tclr = (TCLR_PT | (2 << TCLR_TRG_SHIFT) |
-                                       TCLR_CE | TCLR_AR | TCLR_ST);
-               } else {
-                       puts("invalid pwmfrq in env/dtb! skip PWM-setup.\n");
-               }
-               break;
-       default:
-               puts("no suitable backlightdriver in env/dtb!\n");
-               break;
-       }
        br_summaryscreen();
+       lcdbacklight(1);
 }
 #elif CONFIG_SPL_BUILD
 #else
@@ -571,8 +639,7 @@ static struct cpsw_platform_data cpsw_data = {
 };
 #endif /* CONFIG_DRIVER_TI_CPSW, ... */
 
-#if defined(CONFIG_DRIVER_TI_CPSW)
-
+#if defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)
 int board_eth_init(bd_t *bis)
 {
        int rv = 0;
@@ -589,8 +656,6 @@ int board_eth_init(bd_t *bis)
        mac_addr[4] = mac_lo & 0xFF;
        mac_addr[5] = (mac_lo & 0xFF00) >> 8;
 
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
-       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
        if (!getenv("ethaddr")) {
                #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USE_FDT)
                printf("<ethaddr> not set. trying DTB ... ");
@@ -616,14 +681,18 @@ int board_eth_init(bd_t *bis)
                printf("Error %d registering CPSW switch\n", rv);
                return 0;
        }
-#endif /* CONFIG_DRIVER_TI_CPSW, ... */
        return rv;
 }
-#endif /* CONFIG_DRIVER_TI_CPSW */
-#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
+#endif /* defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD) */
+#if defined(CONFIG_MMC)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(1, 0, 0, -1, -1);
+       int rc = 0;
+
+       rc |= omap_mmc_init(0, 0, 0, -1, -1);
+       rc |= omap_mmc_init(1, 0, 0, -1, -1);
+
+       return rc;
 }
 #endif
 int overwrite_console(void)