uboot/board/samsung/universal_c210/universal.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *  Copyright (C) 2010 Samsung Electronics
   4 *  Minkyu Kang <mk7.kang@samsung.com>
   5 *  Kyungmin Park <kyungmin.park@samsung.com>
   6 */
   7
   8#include <common.h>
   9#include <env.h>
  10#include <log.h>
  11#include <spi.h>
  12#include <lcd.h>
  13#include <asm/global_data.h>
  14#include <asm/io.h>
  15#include <asm/gpio.h>
  16#include <asm/arch/adc.h>
  17#include <asm/arch/pinmux.h>
  18#include <asm/arch/watchdog.h>
  19#include <ld9040.h>
  20#include <linux/delay.h>
  21#include <power/pmic.h>
  22#include <usb.h>
  23#include <usb/dwc2_udc.h>
  24#include <asm/arch/cpu.h>
  25#include <power/max8998_pmic.h>
  26#include <libtizen.h>
  27#include <samsung/misc.h>
  28#include <usb_mass_storage.h>
  29#include <asm/mach-types.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33unsigned int board_rev;
  34static int init_pmic_lcd(void);
  35
  36u32 get_board_rev(void)
  37{
  38        return board_rev;
  39}
  40
  41int exynos_power_init(void)
  42{
  43        return init_pmic_lcd();
  44}
  45
  46static int get_hwrev(void)
  47{
  48        return board_rev & 0xFF;
  49}
  50
  51static unsigned short get_adc_value(int channel)
  52{
  53        struct s5p_adc *adc = (struct s5p_adc *)samsung_get_base_adc();
  54        unsigned short ret = 0;
  55        unsigned int reg;
  56        unsigned int loop = 0;
  57
  58        writel(channel & 0xF, &adc->adcmux);
  59        writel((1 << 14) | (49 << 6), &adc->adccon);
  60        writel(1000 & 0xffff, &adc->adcdly);
  61        writel(readl(&adc->adccon) | (1 << 16), &adc->adccon); /* 12 bit */
  62        udelay(10);
  63        writel(readl(&adc->adccon) | (1 << 0), &adc->adccon); /* Enable */
  64        udelay(10);
  65
  66        do {
  67                udelay(1);
  68                reg = readl(&adc->adccon);
  69        } while (!(reg & (1 << 15)) && (loop++ < 1000));
  70
  71        ret = readl(&adc->adcdat0) & 0xFFF;
  72
  73        return ret;
  74}
  75
  76static int adc_power_control(int on)
  77{
  78        struct udevice *dev;
  79        int ret;
  80        u8 reg;
  81
  82        ret = pmic_get("max8998-pmic", &dev);
  83        if (ret) {
  84                puts("Failed to get MAX8998!\n");
  85                return ret;
  86        }
  87
  88        reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
  89        if (on)
  90                reg |= MAX8998_LDO4;
  91        else
  92                reg &= ~MAX8998_LDO4;
  93
  94        ret = pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
  95        if (ret) {
  96                puts("MAX8998 LDO setting error\n");
  97                return -EINVAL;
  98        }
  99
 100        return 0;
 101}
 102
 103static unsigned int get_hw_revision(void)
 104{
 105        int hwrev, mode0, mode1;
 106
 107        adc_power_control(1);
 108
 109        mode0 = get_adc_value(1);               /* HWREV_MODE0 */
 110        mode1 = get_adc_value(2);               /* HWREV_MODE1 */
 111
 112        /*
 113         * XXX Always set the default hwrev as the latest board
 114         * ADC = (voltage) / 3.3 * 4096
 115         */
 116        hwrev = 3;
 117
 118#define IS_RANGE(x, min, max)   ((x) > (min) && (x) < (max))
 119        if (IS_RANGE(mode0, 80, 200) && IS_RANGE(mode1, 80, 200))
 120                hwrev = 0x0;            /* 0.01V        0.01V */
 121        if (IS_RANGE(mode0, 750, 1000) && IS_RANGE(mode1, 80, 200))
 122                hwrev = 0x1;            /* 610mV        0.01V */
 123        if (IS_RANGE(mode0, 1300, 1700) && IS_RANGE(mode1, 80, 200))
 124                hwrev = 0x2;            /* 1.16V        0.01V */
 125        if (IS_RANGE(mode0, 2000, 2400) && IS_RANGE(mode1, 80, 200))
 126                hwrev = 0x3;            /* 1.79V        0.01V */
 127#undef IS_RANGE
 128
 129        debug("mode0: %d, mode1: %d, hwrev 0x%x\n", mode0, mode1, hwrev);
 130
 131        adc_power_control(0);
 132
 133        return hwrev;
 134}
 135
 136static void check_hw_revision(void)
 137{
 138        int hwrev;
 139
 140        hwrev = get_hw_revision();
 141
 142        board_rev |= hwrev;
 143}
 144
 145#ifdef CONFIG_USB_GADGET
 146static int s5pc210_phy_control(int on)
 147{
 148        struct udevice *dev;
 149        int ret;
 150        u8 reg;
 151
 152        ret = pmic_get("max8998-pmic", &dev);
 153        if (ret) {
 154                puts("Failed to get MAX8998!\n");
 155                return ret;
 156        }
 157
 158        if (on) {
 159                reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
 160                reg |= MAX8998_SAFEOUT1;
 161                ret |= pmic_reg_write(dev,
 162                        MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);
 163
 164                reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
 165                reg |= MAX8998_LDO3;
 166                ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
 167
 168                reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
 169                reg |= MAX8998_LDO8;
 170                ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
 171
 172        } else {
 173                reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
 174                reg &= ~MAX8998_LDO8;
 175                ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
 176
 177                reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
 178                reg &= ~MAX8998_LDO3;
 179                ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
 180
 181                reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
 182                reg &= ~MAX8998_SAFEOUT1;
 183                ret |= pmic_reg_write(dev,
 184                        MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);
 185        }
 186
 187        if (ret) {
 188                puts("MAX8998 LDO setting error!\n");
 189                return -EINVAL;
 190        }
 191
 192        return 0;
 193}
 194
 195struct dwc2_plat_otg_data s5pc210_otg_data = {
 196        .phy_control = s5pc210_phy_control,
 197        .regs_phy = EXYNOS4_USBPHY_BASE,
 198        .regs_otg = EXYNOS4_USBOTG_BASE,
 199        .usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
 200        .usb_flags = PHY0_SLEEP,
 201};
 202#endif
 203
 204int board_usb_init(int index, enum usb_init_type init)
 205{
 206        debug("USB_udc_probe\n");
 207        return dwc2_udc_probe(&s5pc210_otg_data);
 208}
 209
 210int exynos_early_init_f(void)
 211{
 212        wdt_stop();
 213
 214        return 0;
 215}
 216
 217static int init_pmic_lcd(void)
 218{
 219        struct udevice *dev;
 220        unsigned char val;
 221        int ret = 0;
 222
 223        ret = pmic_get("max8998-pmic", &dev);
 224        if (ret) {
 225                puts("Failed to get MAX8998 for init_pmic_lcd()!\n");
 226                return ret;
 227        }
 228
 229        /* LDO7 1.8V */
 230        val = 0x02; /* (1800 - 1600) / 100; */
 231        ret |= pmic_reg_write(dev,  MAX8998_REG_LDO7, val);
 232
 233        /* LDO17 3.0V */
 234        val = 0xe; /* (3000 - 1600) / 100; */
 235        ret |= pmic_reg_write(dev,  MAX8998_REG_LDO17, val);
 236
 237        /* Disable unneeded regulators */
 238        /*
 239         * ONOFF1
 240         * Buck1 ON, Buck2 OFF, Buck3 ON, Buck4 ON
 241         * LDO2 ON, LDO3 OFF, LDO4 OFF, LDO5 ON
 242         */
 243        val = 0xB9;
 244        ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF1, val);
 245
 246        /* ONOFF2
 247         * LDO6 OFF, LDO7 ON, LDO8 OFF, LDO9 ON,
 248         * LDO10 OFF, LDO11 OFF, LDO12 OFF, LDO13 OFF
 249         */
 250        val = 0x50;
 251        ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF2, val);
 252
 253        /* ONOFF3
 254         * LDO14 OFF, LDO15 OFF, LGO16 OFF, LDO17 OFF
 255         * EPWRHOLD OFF, EBATTMON OFF, ELBCNFG2 OFF, ELBCNFG1 OFF
 256         */
 257        val = 0x00;
 258        ret |= pmic_reg_write(dev,  MAX8998_REG_ONOFF3, val);
 259
 260        if (ret) {
 261                puts("LCD pmic initialisation error!\n");
 262                return -EINVAL;
 263        }
 264
 265        return 0;
 266}
 267
 268void exynos_cfg_lcd_gpio(void)
 269{
 270        unsigned int i, f3_end = 4;
 271
 272        for (i = 0; i < 8; i++) {
 273                /* set GPF0,1,2[0:7] for RGB Interface and Data lines (32bit) */
 274                gpio_cfg_pin(EXYNOS4_GPIO_F00 + i, S5P_GPIO_FUNC(2));
 275                gpio_cfg_pin(EXYNOS4_GPIO_F10 + i, S5P_GPIO_FUNC(2));
 276                gpio_cfg_pin(EXYNOS4_GPIO_F20 + i, S5P_GPIO_FUNC(2));
 277                /* pull-up/down disable */
 278                gpio_set_pull(EXYNOS4_GPIO_F00 + i, S5P_GPIO_PULL_NONE);
 279                gpio_set_pull(EXYNOS4_GPIO_F10 + i, S5P_GPIO_PULL_NONE);
 280                gpio_set_pull(EXYNOS4_GPIO_F20 + i, S5P_GPIO_PULL_NONE);
 281
 282                /* drive strength to max (24bit) */
 283                gpio_set_drv(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_4X);
 284                gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
 285                gpio_set_drv(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_4X);
 286                gpio_set_rate(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_SLOW);
 287                gpio_set_drv(EXYNOS4_GPIO_F20 + i, S5P_GPIO_DRV_4X);
 288                gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
 289        }
 290
 291        for (i = EXYNOS4_GPIO_F30; i < (EXYNOS4_GPIO_F30 + f3_end); i++) {
 292                /* set GPF3[0:3] for RGB Interface and Data lines (32bit) */
 293                gpio_cfg_pin(i, S5P_GPIO_FUNC(2));
 294                /* pull-up/down disable */
 295                gpio_set_pull(i, S5P_GPIO_PULL_NONE);
 296                /* drive strength to max (24bit) */
 297                gpio_set_drv(i, S5P_GPIO_DRV_4X);
 298                gpio_set_rate(i, S5P_GPIO_DRV_SLOW);
 299        }
 300
 301        /* gpio pad configuration for LCD reset. */
 302        gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
 303        gpio_cfg_pin(EXYNOS4_GPIO_Y45, S5P_GPIO_OUTPUT);
 304}
 305
 306int mipi_power(void)
 307{
 308        return 0;
 309}
 310
 311void exynos_reset_lcd(void)
 312{
 313        gpio_set_value(EXYNOS4_GPIO_Y45, 1);
 314        udelay(10000);
 315        gpio_set_value(EXYNOS4_GPIO_Y45, 0);
 316        udelay(10000);
 317        gpio_set_value(EXYNOS4_GPIO_Y45, 1);
 318        udelay(100);
 319}
 320
 321void exynos_lcd_power_on(void)
 322{
 323        struct udevice *dev;
 324        int ret;
 325        u8 reg;
 326
 327        ret = pmic_get("max8998-pmic", &dev);
 328        if (ret) {
 329                puts("Failed to get MAX8998!\n");
 330                return;
 331        }
 332
 333        reg = pmic_reg_read(dev, MAX8998_REG_ONOFF3);
 334        reg |= MAX8998_LDO17;
 335        ret = pmic_reg_write(dev, MAX8998_REG_ONOFF3, reg);
 336        if (ret) {
 337                puts("MAX8998 LDO setting error\n");
 338                return;
 339        }
 340
 341        reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
 342        reg |= MAX8998_LDO7;
 343        ret = pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
 344        if (ret) {
 345                puts("MAX8998 LDO setting error\n");
 346                return;
 347        }
 348}
 349
 350void exynos_cfg_ldo(void)
 351{
 352        ld9040_cfg_ldo();
 353}
 354
 355void exynos_enable_ldo(unsigned int onoff)
 356{
 357        ld9040_enable_ldo(onoff);
 358}
 359
 360int exynos_init(void)
 361{
 362        gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
 363
 364        switch (get_hwrev()) {
 365        case 0:
 366                /*
 367                 * Set the low to enable LDO_EN
 368                 * But when you use the test board for eMMC booting
 369                 * you should set it HIGH since it removes the inverter
 370                 */
 371                /* MASSMEMORY_EN: XMDMDATA_6: GPE3[6] */
 372                gpio_request(EXYNOS4_GPIO_E36, "ldo_en");
 373                gpio_direction_output(EXYNOS4_GPIO_E36, 0);
 374                break;
 375        default:
 376                /*
 377                 * Default reset state is High and there's no inverter
 378                 * But set it as HIGH to ensure
 379                 */
 380                /* MASSMEMORY_EN: XMDMADDR_3: GPE1[3] */
 381                gpio_request(EXYNOS4_GPIO_E13, "massmemory_en");
 382                gpio_direction_output(EXYNOS4_GPIO_E13, 1);
 383                break;
 384        }
 385
 386        check_hw_revision();
 387        printf("HW Revision:\t0x%x\n", board_rev);
 388
 389        return 0;
 390}
 391
 392#ifdef CONFIG_LCD
 393void exynos_lcd_misc_init(vidinfo_t *vid)
 394{
 395#ifdef CONFIG_TIZEN
 396        get_tizen_logo_info(vid);
 397#endif
 398
 399        /* for LD9040. */
 400        vid->pclk_name = 1;     /* MPLL */
 401        vid->sclk_div = 1;
 402
 403        env_set("lcdinfo", "lcd=ld9040");
 404}
 405#endif
 406