uboot/board/BuR/common/common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * common.c
   4 *
   5 * common board functions for B&R boards
   6 *
   7 * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at>
   8 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
   9 *
  10 */
  11#include <log.h>
  12#include <version.h>
  13#include <common.h>
  14#include <env.h>
  15#include <fdtdec.h>
  16#include <i2c.h>
  17#include <lcd.h>
  18#include <asm/global_data.h>
  19#include <linux/delay.h>
  20#include "bur_common.h"
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24/* --------------------------------------------------------------------------*/
  25#if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \
  26        !defined(CONFIG_DM_VIDEO) && !defined(CONFIG_SPL_BUILD)
  27#include <asm/arch/hardware.h>
  28#include <asm/arch/cpu.h>
  29#include <asm/gpio.h>
  30#include <power/tps65217.h>
  31#include "../../../drivers/video/ti/am335x-fb.h"
  32
  33void lcdbacklight(int on)
  34{
  35        unsigned int driver = env_get_ulong("ds1_bright_drv", 16, 0UL);
  36        unsigned int bright = env_get_ulong("ds1_bright_def", 10, 50);
  37        unsigned int pwmfrq = env_get_ulong("ds1_pwmfreq", 10, ~0UL);
  38        unsigned int tmp;
  39        struct gptimer *timerhw;
  40
  41        if (on)
  42                bright = bright != ~0UL ? bright : 50;
  43        else
  44                bright = 0;
  45
  46        switch (driver) {
  47        case 2:
  48                timerhw = (struct gptimer *)DM_TIMER5_BASE;
  49                break;
  50        default:
  51                timerhw = (struct gptimer *)DM_TIMER6_BASE;
  52        }
  53
  54        switch (driver) {
  55        case 0: /* PMIC LED-Driver */
  56                /* brightness level */
  57                tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
  58                                   TPS65217_WLEDCTRL2, bright, 0xFF);
  59                /* current sink */
  60                tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
  61                                   TPS65217_WLEDCTRL1,
  62                                   bright != 0 ? 0x0A : 0x02,
  63                                   0xFF);
  64                break;
  65        case 1:
  66        case 2: /* PWM using timer */
  67                if (pwmfrq != ~0UL) {
  68                        timerhw->tiocp_cfg = TCFG_RESET;
  69                        udelay(10);
  70                        while (timerhw->tiocp_cfg & TCFG_RESET)
  71                                ;
  72                        tmp = ~0UL-(V_OSCK/pwmfrq);     /* bottom value */
  73                        timerhw->tldr = tmp;
  74                        timerhw->tcrr = tmp;
  75                        tmp = tmp + ((V_OSCK/pwmfrq)/100) * bright;
  76                        timerhw->tmar = tmp;
  77                        timerhw->tclr = (TCLR_PT | (2 << TCLR_TRG_SHIFT) |
  78                                        TCLR_CE | TCLR_AR | TCLR_ST);
  79                } else {
  80                        puts("invalid pwmfrq in env/dtb! skip PWM-setup.\n");
  81                }
  82                break;
  83        default:
  84                puts("no suitable backlightdriver in env/dtb!\n");
  85                break;
  86        }
  87}
  88
  89int load_lcdtiming(struct am335x_lcdpanel *panel)
  90{
  91        struct am335x_lcdpanel pnltmp;
  92
  93        pnltmp.hactive = env_get_ulong("ds1_hactive", 10, ~0UL);
  94        pnltmp.vactive = env_get_ulong("ds1_vactive", 10, ~0UL);
  95        pnltmp.bpp = env_get_ulong("ds1_bpp", 10, ~0UL);
  96        pnltmp.hfp = env_get_ulong("ds1_hfp", 10, ~0UL);
  97        pnltmp.hbp = env_get_ulong("ds1_hbp", 10, ~0UL);
  98        pnltmp.hsw = env_get_ulong("ds1_hsw", 10, ~0UL);
  99        pnltmp.vfp = env_get_ulong("ds1_vfp", 10, ~0UL);
 100        pnltmp.vbp = env_get_ulong("ds1_vbp", 10, ~0UL);
 101        pnltmp.vsw = env_get_ulong("ds1_vsw", 10, ~0UL);
 102        pnltmp.pxl_clk = env_get_ulong("ds1_pxlclk", 10, ~0UL);
 103        pnltmp.pol = env_get_ulong("ds1_pol", 16, ~0UL);
 104        pnltmp.pup_delay = env_get_ulong("ds1_pupdelay", 10, ~0UL);
 105        pnltmp.pon_delay = env_get_ulong("ds1_tondelay", 10, ~0UL);
 106        panel_info.vl_rot = env_get_ulong("ds1_rotation", 10, 0);
 107
 108        if (
 109           ~0UL == (pnltmp.hactive) ||
 110           ~0UL == (pnltmp.vactive) ||
 111           ~0UL == (pnltmp.bpp) ||
 112           ~0UL == (pnltmp.hfp) ||
 113           ~0UL == (pnltmp.hbp) ||
 114           ~0UL == (pnltmp.hsw) ||
 115           ~0UL == (pnltmp.vfp) ||
 116           ~0UL == (pnltmp.vbp) ||
 117           ~0UL == (pnltmp.vsw) ||
 118           ~0UL == (pnltmp.pxl_clk) ||
 119           ~0UL == (pnltmp.pol) ||
 120           ~0UL == (pnltmp.pup_delay) ||
 121           ~0UL == (pnltmp.pon_delay)
 122           ) {
 123                puts("lcd-settings in env/dtb incomplete!\n");
 124                printf("display-timings:\n"
 125                        "================\n"
 126                        "hactive: %d\n"
 127                        "vactive: %d\n"
 128                        "bpp    : %d\n"
 129                        "hfp    : %d\n"
 130                        "hbp    : %d\n"
 131                        "hsw    : %d\n"
 132                        "vfp    : %d\n"
 133                        "vbp    : %d\n"
 134                        "vsw    : %d\n"
 135                        "pxlclk : %d\n"
 136                        "pol    : 0x%08x\n"
 137                        "pondly : %d\n",
 138                        pnltmp.hactive, pnltmp.vactive, pnltmp.bpp,
 139                        pnltmp.hfp, pnltmp.hbp, pnltmp.hsw,
 140                        pnltmp.vfp, pnltmp.vbp, pnltmp.vsw,
 141                        pnltmp.pxl_clk, pnltmp.pol, pnltmp.pon_delay);
 142
 143                return -1;
 144        }
 145        debug("lcd-settings in env complete, taking over.\n");
 146        memcpy((void *)panel,
 147               (void *)&pnltmp,
 148               sizeof(struct am335x_lcdpanel));
 149
 150        return 0;
 151}
 152
 153static void br_summaryscreen_printenv(char *prefix,
 154                                       char *name, char *altname,
 155                                       char *suffix)
 156{
 157        char *envval = env_get(name);
 158        if (0 != envval) {
 159                lcd_printf("%s %s %s", prefix, envval, suffix);
 160        } else if (0 != altname) {
 161                envval = env_get(altname);
 162                if (0 != envval)
 163                        lcd_printf("%s %s %s", prefix, envval, suffix);
 164        } else {
 165                lcd_printf("\n");
 166        }
 167}
 168
 169void br_summaryscreen(void)
 170{
 171        br_summaryscreen_printenv(" - B&R -", "br_orderno", 0, "-\n");
 172        br_summaryscreen_printenv(" Serial/Rev :", "br_serial", 0, "\n");
 173        br_summaryscreen_printenv(" MAC1       :", "br_mac1", "ethaddr", "\n");
 174        br_summaryscreen_printenv(" MAC2       :", "br_mac2", 0, "\n");
 175        lcd_puts(" Bootloader : " PLAIN_VERSION "\n");
 176        lcd_puts("\n");
 177}
 178
 179void lcdpower(int on)
 180{
 181        u32 pin, swval, i;
 182        char buf[16] = { 0 };
 183
 184        pin = env_get_ulong("ds1_pwr", 16, ~0UL);
 185
 186        if (pin == ~0UL) {
 187                puts("no pwrpin in dtb/env, cannot powerup display!\n");
 188                return;
 189        }
 190
 191        for (i = 0; i < 3; i++) {
 192                if (pin != 0) {
 193                        snprintf(buf, sizeof(buf), "ds1_pwr#%d", i);
 194                        if (gpio_request(pin & 0x7F, buf) != 0) {
 195                                printf("%s: not able to request gpio %s",
 196                                       __func__, buf);
 197                                continue;
 198                        }
 199                        swval = pin & 0x80 ? 0 : 1;
 200                        if (on)
 201                                gpio_direction_output(pin & 0x7F, swval);
 202                        else
 203                                gpio_direction_output(pin & 0x7F, !swval);
 204
 205                        debug("switched pin %d to %d\n", pin & 0x7F, swval);
 206                }
 207                pin >>= 8;
 208        }
 209}
 210
 211vidinfo_t       panel_info = {
 212                .vl_col = 1366, /*
 213                                 * give full resolution for allocating enough
 214                                 * memory
 215                                 */
 216                .vl_row = 768,
 217                .vl_bpix = 5,
 218                .priv = 0
 219};
 220
 221void lcd_ctrl_init(void *lcdbase)
 222{
 223        struct am335x_lcdpanel lcd_panel;
 224
 225        memset(&lcd_panel, 0, sizeof(struct am335x_lcdpanel));
 226        if (load_lcdtiming(&lcd_panel) != 0)
 227                return;
 228
 229        lcd_panel.panel_power_ctrl = &lcdpower;
 230
 231        if (0 != am335xfb_init(&lcd_panel))
 232                printf("ERROR: failed to initialize video!");
 233        /*
 234         * modifiy panel info to 'real' resolution, to operate correct with
 235         * lcd-framework.
 236         */
 237        panel_info.vl_col = lcd_panel.hactive;
 238        panel_info.vl_row = lcd_panel.vactive;
 239
 240        lcd_set_flush_dcache(1);
 241}
 242
 243void lcd_enable(void)
 244{
 245        br_summaryscreen();
 246        lcdbacklight(1);
 247}
 248#endif /* CONFIG_LCD */
 249
 250int ft_board_setup(void *blob, struct bd_info *bd)
 251{
 252        int nodeoffset;
 253
 254        nodeoffset = fdt_path_offset(blob, "/factory-settings");
 255        if (nodeoffset < 0) {
 256                printf("%s: cannot find /factory-settings, trying /fset\n",
 257                       __func__);
 258                nodeoffset = fdt_path_offset(blob, "/fset");
 259                if (nodeoffset < 0) {
 260                        printf("%s: cannot find /fset.\n", __func__);
 261                        return 0;
 262                }
 263        }
 264
 265        if (fdt_setprop(blob, nodeoffset, "bl-version",
 266                        PLAIN_VERSION, strlen(PLAIN_VERSION)) != 0) {
 267                printf("%s: no 'bl-version' prop in fdt!\n", __func__);
 268                return 0;
 269        }
 270        return 0;
 271}
 272
 273int brdefaultip_setup(int bus, int chip)
 274{
 275        int rc;
 276        struct udevice *i2cdev;
 277        u8 u8buf = 0;
 278        char defip[256] = { 0 };
 279
 280        rc = i2c_get_chip_for_busnum(bus, chip, 2, &i2cdev);
 281        if (rc != 0) {
 282                printf("WARN: cannot probe baseboard EEPROM!\n");
 283                return -1;
 284        }
 285
 286        rc = dm_i2c_read(i2cdev, 0, &u8buf, 1);
 287        if (rc != 0) {
 288                printf("WARN: cannot read baseboard EEPROM!\n");
 289                return -1;
 290        }
 291
 292        if (u8buf != 0xFF)
 293                snprintf(defip, sizeof(defip),
 294                         "if test -r ${ipaddr}; then; else setenv ipaddr 192.168.60.%d; setenv serverip 192.168.60.254; setenv gatewayip 192.168.60.254; setenv netmask 255.255.255.0; fi;",
 295                         u8buf);
 296        else
 297                strncpy(defip,
 298                        "if test -r ${ipaddr}; then; else setenv ipaddr 192.168.60.1; setenv serverip 192.168.60.254; setenv gatewayip 192.168.60.254; setenv netmask 255.255.255.0; fi;",
 299                        sizeof(defip));
 300
 301        env_set("brdefaultip", defip);
 302        env_set_hex("board_id", u8buf);
 303
 304        return 0;
 305}
 306
 307int overwrite_console(void)
 308{
 309        return 1;
 310}
 311
 312#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_AM33XX)
 313#include <asm/arch/hardware.h>
 314#include <asm/arch/omap.h>
 315#include <asm/arch/clock.h>
 316#include <asm/arch/sys_proto.h>
 317#include <power/tps65217.h>
 318
 319static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 320
 321void pmicsetup(u32 mpupll, unsigned int bus)
 322{
 323        int mpu_vdd;
 324        int usb_cur_lim;
 325
 326        if (power_tps65217_init(bus)) {
 327                printf("WARN: cannot setup PMIC 0x24 @ bus #%d, not found!.\n",
 328                       bus);
 329                return;
 330        }
 331
 332        /* Get the frequency which is defined by device fuses */
 333        dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
 334        printf("detected max. frequency: %d - ", dpll_mpu_opp100.m);
 335
 336        if (0 != mpupll) {
 337                dpll_mpu_opp100.m = mpupll;
 338                printf("retuning MPU-PLL to: %d MHz.\n", dpll_mpu_opp100.m);
 339        } else {
 340                puts("ok.\n");
 341        }
 342        /*
 343         * Increase USB current limit to 1300mA or 1800mA and set
 344         * the MPU voltage controller as needed.
 345         */
 346        if (dpll_mpu_opp100.m == MPUPLL_M_1000) {
 347                usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA;
 348                mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
 349        } else {
 350                usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA;
 351                mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
 352        }
 353
 354        if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_POWER_PATH,
 355                               usb_cur_lim, TPS65217_USB_INPUT_CUR_LIMIT_MASK))
 356                puts("tps65217_reg_write failure\n");
 357
 358        /* Set DCDC3 (CORE) voltage to 1.125V */
 359        if (tps65217_voltage_update(TPS65217_DEFDCDC3,
 360                                    TPS65217_DCDC_VOLT_SEL_1125MV)) {
 361                puts("tps65217_voltage_update failure\n");
 362                return;
 363        }
 364
 365        /* Set CORE Frequencies to OPP100 */
 366        do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
 367
 368        /* Set DCDC2 (MPU) voltage */
 369        if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
 370                puts("tps65217_voltage_update failure\n");
 371                return;
 372        }
 373
 374        /* Set LDO3 to 1.8V */
 375        if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
 376                               TPS65217_DEFLS1,
 377                               TPS65217_LDO_VOLTAGE_OUT_1_8,
 378                               TPS65217_LDO_MASK))
 379                puts("tps65217_reg_write failure\n");
 380        /* Set LDO4 to 3.3V */
 381        if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
 382                               TPS65217_DEFLS2,
 383                               TPS65217_LDO_VOLTAGE_OUT_3_3,
 384                               TPS65217_LDO_MASK))
 385                puts("tps65217_reg_write failure\n");
 386
 387        /* Set MPU Frequency to what we detected now that voltages are set */
 388        do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
 389        /* Set PWR_EN bit in Status Register */
 390        tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
 391                           TPS65217_STATUS, TPS65217_PWR_OFF, TPS65217_PWR_OFF);
 392}
 393
 394void set_uart_mux_conf(void)
 395{
 396        enable_uart0_pin_mux();
 397}
 398
 399void set_mux_conf_regs(void)
 400{
 401        enable_board_pin_mux();
 402}
 403
 404#endif /* CONFIG_SPL_BUILD && CONFIG_AM33XX */
 405