uboot/board/samsung/trats/trats.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2011 Samsung Electronics
   4 * Heungjun Kim <riverful.kim@samsung.com>
   5 * Kyungmin Park <kyungmin.park@samsung.com>
   6 * Donghwa Lee <dh09.lee@samsung.com>
   7 */
   8
   9#include <common.h>
  10#include <lcd.h>
  11#include <asm/io.h>
  12#include <asm/gpio.h>
  13#include <asm/arch/cpu.h>
  14#include <asm/arch/pinmux.h>
  15#include <asm/arch/clock.h>
  16#include <asm/arch/mipi_dsim.h>
  17#include <asm/arch/watchdog.h>
  18#include <asm/arch/power.h>
  19#include <power/pmic.h>
  20#include <usb/dwc2_udc.h>
  21#include <power/max8997_pmic.h>
  22#include <power/max8997_muic.h>
  23#include <power/battery.h>
  24#include <power/max17042_fg.h>
  25#include <power/pmic.h>
  26#include <libtizen.h>
  27#include <usb.h>
  28#include <usb_mass_storage.h>
  29
  30#include "setup.h"
  31
  32unsigned int board_rev;
  33
  34#ifdef CONFIG_REVISION_TAG
  35u32 get_board_rev(void)
  36{
  37        return board_rev;
  38}
  39#endif
  40
  41static void check_hw_revision(void);
  42struct dwc2_plat_otg_data s5pc210_otg_data;
  43
  44int exynos_init(void)
  45{
  46        check_hw_revision();
  47        printf("HW Revision:\t0x%x\n", board_rev);
  48
  49        return 0;
  50}
  51
  52#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
  53static void trats_low_power_mode(void)
  54{
  55        struct exynos4_clock *clk =
  56            (struct exynos4_clock *)samsung_get_base_clock();
  57        struct exynos4_power *pwr =
  58            (struct exynos4_power *)samsung_get_base_power();
  59
  60        /* Power down CORE1 */
  61        /* LOCAL_PWR_CFG [1:0] 0x3 EN, 0x0 DIS */
  62        writel(0x0, &pwr->arm_core1_configuration);
  63
  64        /* Change the APLL frequency */
  65        /* ENABLE (1 enable) | LOCKED (1 locked)  */
  66        /* [31]              | [29]               */
  67        /* FSEL      | MDIV          | PDIV            | SDIV */
  68        /* [27]      | [25:16]       | [13:8]          | [2:0]      */
  69        writel(0xa0c80604, &clk->apll_con0);
  70
  71        /* Change CPU0 clock divider */
  72        /* CORE2_RATIO  | APLL_RATIO   | PCLK_DBG_RATIO | ATB_RATIO  */
  73        /* [30:28]      | [26:24]      | [22:20]        | [18:16]    */
  74        /* PERIPH_RATIO | COREM1_RATIO | COREM0_RATIO   | CORE_RATIO */
  75        /* [14:12]      | [10:8]       | [6:4]          | [2:0]      */
  76        writel(0x00000100, &clk->div_cpu0);
  77
  78        /* CLK_DIV_STAT_CPU0 - wait until clock gets stable (0 = stable) */
  79        while (readl(&clk->div_stat_cpu0) & 0x1111111)
  80                continue;
  81
  82        /* Change clock divider ratio for DMC */
  83        /* DMCP_RATIO                  | DMCD_RATIO  */
  84        /* [22:20]                     | [18:16]     */
  85        /* DMC_RATIO | DPHY_RATIO | ACP_PCLK_RATIO   | ACP_RATIO */
  86        /* [14:12]   | [10:8]     | [6:4]            | [2:0]     */
  87        writel(0x13113117, &clk->div_dmc0);
  88
  89        /* CLK_DIV_STAT_DMC0 - wait until clock gets stable (0 = stable) */
  90        while (readl(&clk->div_stat_dmc0) & 0x11111111)
  91                continue;
  92
  93        /* Turn off unnecessary power domains */
  94        writel(0x0, &pwr->xxti_configuration);  /* XXTI */
  95        writel(0x0, &pwr->cam_configuration);   /* CAM */
  96        writel(0x0, &pwr->tv_configuration);    /* TV */
  97        writel(0x0, &pwr->mfc_configuration);   /* MFC */
  98        writel(0x0, &pwr->g3d_configuration);   /* G3D */
  99        writel(0x0, &pwr->gps_configuration);   /* GPS */
 100        writel(0x0, &pwr->gps_alive_configuration);     /* GPS_ALIVE */
 101
 102        /* Turn off unnecessary clocks */
 103        writel(0x0, &clk->gate_ip_cam); /* CAM */
 104        writel(0x0, &clk->gate_ip_tv);          /* TV */
 105        writel(0x0, &clk->gate_ip_mfc); /* MFC */
 106        writel(0x0, &clk->gate_ip_g3d); /* G3D */
 107        writel(0x0, &clk->gate_ip_image);       /* IMAGE */
 108        writel(0x0, &clk->gate_ip_gps); /* GPS */
 109}
 110#endif
 111
 112int exynos_power_init(void)
 113{
 114#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
 115        int chrg, ret;
 116        struct power_battery *pb;
 117        struct pmic *p_fg, *p_chrg, *p_muic, *p_bat;
 118
 119        /*
 120         * For PMIC/MUIC the I2C bus is named as I2C5, but it is connected
 121         * to logical I2C adapter 0
 122         *
 123         * The FUEL_GAUGE is marked as I2C9 on the schematic, but connected
 124         * to logical I2C adapter 1
 125         */
 126        ret = power_fg_init(I2C_9);
 127        ret |= power_muic_init(I2C_5);
 128        ret |= power_bat_init(0);
 129        if (ret)
 130                return ret;
 131
 132        p_fg = pmic_get("MAX17042_FG");
 133        if (!p_fg) {
 134                puts("MAX17042_FG: Not found\n");
 135                return -ENODEV;
 136        }
 137
 138        p_chrg = pmic_get("MAX8997_PMIC");
 139        if (!p_chrg) {
 140                puts("MAX8997_PMIC: Not found\n");
 141                return -ENODEV;
 142        }
 143
 144        p_muic = pmic_get("MAX8997_MUIC");
 145        if (!p_muic) {
 146                puts("MAX8997_MUIC: Not found\n");
 147                return -ENODEV;
 148        }
 149
 150        p_bat = pmic_get("BAT_TRATS");
 151        if (!p_bat) {
 152                puts("BAT_TRATS: Not found\n");
 153                return -ENODEV;
 154        }
 155
 156        p_fg->parent =  p_bat;
 157        p_chrg->parent = p_bat;
 158        p_muic->parent = p_bat;
 159
 160        p_bat->low_power_mode = trats_low_power_mode;
 161        p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
 162
 163        pb = p_bat->pbat;
 164        chrg = p_muic->chrg->chrg_type(p_muic);
 165        debug("CHARGER TYPE: %d\n", chrg);
 166
 167        if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
 168                puts("No battery detected\n");
 169                return 0;
 170        }
 171
 172        p_fg->fg->fg_battery_check(p_fg, p_bat);
 173
 174        if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
 175                puts("CHARGE Battery !\n");
 176#endif
 177
 178        return 0;
 179}
 180
 181static unsigned int get_hw_revision(void)
 182{
 183        int hwrev = 0;
 184        char str[10];
 185        int i;
 186
 187        /* hw_rev[3:0] == GPE1[3:0] */
 188        for (i = 0; i < 4; i++) {
 189                int pin = i + EXYNOS4_GPIO_E10;
 190
 191                sprintf(str, "hw_rev%d", i);
 192                gpio_request(pin, str);
 193                gpio_cfg_pin(pin, S5P_GPIO_INPUT);
 194                gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
 195        }
 196
 197        udelay(1);
 198
 199        for (i = 0; i < 4; i++)
 200                hwrev |= (gpio_get_value(EXYNOS4_GPIO_E10 + i) << i);
 201
 202        debug("hwrev 0x%x\n", hwrev);
 203
 204        return hwrev;
 205}
 206
 207static void check_hw_revision(void)
 208{
 209        int hwrev;
 210
 211        hwrev = get_hw_revision();
 212
 213        board_rev |= hwrev;
 214}
 215
 216
 217#ifdef CONFIG_USB_GADGET
 218static int s5pc210_phy_control(int on)
 219{
 220        struct udevice *dev;
 221        int reg, ret;
 222
 223        ret = pmic_get("max8997-pmic", &dev);
 224        if (ret)
 225                return ret;
 226
 227        if (on) {
 228                reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL);
 229                reg |= ENSAFEOUT1;
 230                ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg);
 231                if (ret) {
 232                        puts("MAX8997 setting error!\n");
 233                        return ret;
 234                }
 235                reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL);
 236                reg |= EN_LDO;
 237                ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg);
 238                if (ret) {
 239                        puts("MAX8997 setting error!\n");
 240                        return ret;
 241                }
 242                reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL);
 243                reg |= EN_LDO;
 244                ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg);
 245                if (ret) {
 246                        puts("MAX8997 setting error!\n");
 247                        return ret;
 248                }
 249        } else {
 250                reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL);
 251                reg &= DIS_LDO;
 252                ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg);
 253                if (ret) {
 254                        puts("MAX8997 setting error!\n");
 255                        return ret;
 256                }
 257                reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL);
 258                reg &= DIS_LDO;
 259                ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg);
 260                if (ret) {
 261                        puts("MAX8997 setting error!\n");
 262                        return ret;
 263                }
 264                reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL);
 265                reg &= ~ENSAFEOUT1;
 266                ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg);
 267                if (ret) {
 268                        puts("MAX8997 setting error!\n");
 269                        return ret;
 270                }
 271
 272        }
 273
 274        return 0;
 275}
 276
 277struct dwc2_plat_otg_data s5pc210_otg_data = {
 278        .phy_control    = s5pc210_phy_control,
 279        .regs_phy       = EXYNOS4_USBPHY_BASE,
 280        .regs_otg       = EXYNOS4_USBOTG_BASE,
 281        .usb_phy_ctrl   = EXYNOS4_USBPHY_CONTROL,
 282        .usb_flags      = PHY0_SLEEP,
 283};
 284
 285int board_usb_init(int index, enum usb_init_type init)
 286{
 287        debug("USB_udc_probe\n");
 288        return dwc2_udc_probe(&s5pc210_otg_data);
 289}
 290
 291int g_dnl_board_usb_cable_connected(void)
 292{
 293#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
 294        struct pmic *muic = pmic_get("MAX8997_MUIC");
 295        if (!muic)
 296                return 0;
 297
 298        return !!muic->chrg->chrg_type(muic);
 299#else
 300        return false;
 301#endif
 302
 303}
 304#endif
 305
 306static void pmic_reset(void)
 307{
 308        gpio_direction_output(EXYNOS4_GPIO_X07, 1);
 309        gpio_set_pull(EXYNOS4_GPIO_X27, S5P_GPIO_PULL_NONE);
 310}
 311
 312static void board_clock_init(void)
 313{
 314        struct exynos4_clock *clk =
 315                (struct exynos4_clock *)samsung_get_base_clock();
 316
 317        writel(CLK_SRC_CPU_VAL, (unsigned int)&clk->src_cpu);
 318        writel(CLK_SRC_TOP0_VAL, (unsigned int)&clk->src_top0);
 319        writel(CLK_SRC_FSYS_VAL, (unsigned int)&clk->src_fsys);
 320        writel(CLK_SRC_PERIL0_VAL, (unsigned int)&clk->src_peril0);
 321
 322        writel(CLK_DIV_CPU0_VAL, (unsigned int)&clk->div_cpu0);
 323        writel(CLK_DIV_CPU1_VAL, (unsigned int)&clk->div_cpu1);
 324        writel(CLK_DIV_DMC0_VAL, (unsigned int)&clk->div_dmc0);
 325        writel(CLK_DIV_DMC1_VAL, (unsigned int)&clk->div_dmc1);
 326        writel(CLK_DIV_LEFTBUS_VAL, (unsigned int)&clk->div_leftbus);
 327        writel(CLK_DIV_RIGHTBUS_VAL, (unsigned int)&clk->div_rightbus);
 328        writel(CLK_DIV_TOP_VAL, (unsigned int)&clk->div_top);
 329        writel(CLK_DIV_FSYS1_VAL, (unsigned int)&clk->div_fsys1);
 330        writel(CLK_DIV_FSYS2_VAL, (unsigned int)&clk->div_fsys2);
 331        writel(CLK_DIV_FSYS3_VAL, (unsigned int)&clk->div_fsys3);
 332        writel(CLK_DIV_PERIL0_VAL, (unsigned int)&clk->div_peril0);
 333        writel(CLK_DIV_PERIL3_VAL, (unsigned int)&clk->div_peril3);
 334
 335        writel(PLL_LOCKTIME, (unsigned int)&clk->apll_lock);
 336        writel(PLL_LOCKTIME, (unsigned int)&clk->mpll_lock);
 337        writel(PLL_LOCKTIME, (unsigned int)&clk->epll_lock);
 338        writel(PLL_LOCKTIME, (unsigned int)&clk->vpll_lock);
 339        writel(APLL_CON1_VAL, (unsigned int)&clk->apll_con1);
 340        writel(APLL_CON0_VAL, (unsigned int)&clk->apll_con0);
 341        writel(MPLL_CON1_VAL, (unsigned int)&clk->mpll_con1);
 342        writel(MPLL_CON0_VAL, (unsigned int)&clk->mpll_con0);
 343        writel(EPLL_CON1_VAL, (unsigned int)&clk->epll_con1);
 344        writel(EPLL_CON0_VAL, (unsigned int)&clk->epll_con0);
 345        writel(VPLL_CON1_VAL, (unsigned int)&clk->vpll_con1);
 346        writel(VPLL_CON0_VAL, (unsigned int)&clk->vpll_con0);
 347
 348        writel(CLK_GATE_IP_CAM_VAL, (unsigned int)&clk->gate_ip_cam);
 349        writel(CLK_GATE_IP_VP_VAL, (unsigned int)&clk->gate_ip_tv);
 350        writel(CLK_GATE_IP_MFC_VAL, (unsigned int)&clk->gate_ip_mfc);
 351        writel(CLK_GATE_IP_G3D_VAL, (unsigned int)&clk->gate_ip_g3d);
 352        writel(CLK_GATE_IP_IMAGE_VAL, (unsigned int)&clk->gate_ip_image);
 353        writel(CLK_GATE_IP_LCD0_VAL, (unsigned int)&clk->gate_ip_lcd0);
 354        writel(CLK_GATE_IP_LCD1_VAL, (unsigned int)&clk->gate_ip_lcd1);
 355        writel(CLK_GATE_IP_FSYS_VAL, (unsigned int)&clk->gate_ip_fsys);
 356        writel(CLK_GATE_IP_GPS_VAL, (unsigned int)&clk->gate_ip_gps);
 357        writel(CLK_GATE_IP_PERIL_VAL, (unsigned int)&clk->gate_ip_peril);
 358        writel(CLK_GATE_IP_PERIR_VAL, (unsigned int)&clk->gate_ip_perir);
 359        writel(CLK_GATE_BLOCK_VAL, (unsigned int)&clk->gate_block);
 360}
 361
 362static void board_power_init(void)
 363{
 364        struct exynos4_power *pwr =
 365                (struct exynos4_power *)samsung_get_base_power();
 366
 367        /* PS HOLD */
 368        writel(EXYNOS4_PS_HOLD_CON_VAL, (unsigned int)&pwr->ps_hold_control);
 369
 370        /* Set power down */
 371        writel(0, (unsigned int)&pwr->cam_configuration);
 372        writel(0, (unsigned int)&pwr->tv_configuration);
 373        writel(0, (unsigned int)&pwr->mfc_configuration);
 374        writel(0, (unsigned int)&pwr->g3d_configuration);
 375        writel(0, (unsigned int)&pwr->lcd1_configuration);
 376        writel(0, (unsigned int)&pwr->gps_configuration);
 377        writel(0, (unsigned int)&pwr->gps_alive_configuration);
 378
 379        /* It is necessary to power down core 1 */
 380        /* to successfully boot CPU1 in kernel */
 381        writel(0, (unsigned int)&pwr->arm_core1_configuration);
 382}
 383
 384static void exynos_uart_init(void)
 385{
 386        /* UART_SEL GPY4[7] (part2) at EXYNOS4 */
 387        gpio_request(EXYNOS4_GPIO_Y47, "uart_sel");
 388        gpio_set_pull(EXYNOS4_GPIO_Y47, S5P_GPIO_PULL_UP);
 389        gpio_direction_output(EXYNOS4_GPIO_Y47, 1);
 390}
 391
 392int exynos_early_init_f(void)
 393{
 394        wdt_stop();
 395        pmic_reset();
 396        board_clock_init();
 397        exynos_uart_init();
 398        board_power_init();
 399
 400        return 0;
 401}
 402
 403void exynos_reset_lcd(void)
 404{
 405        gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
 406        gpio_direction_output(EXYNOS4_GPIO_Y45, 1);
 407        udelay(10000);
 408        gpio_direction_output(EXYNOS4_GPIO_Y45, 0);
 409        udelay(10000);
 410        gpio_direction_output(EXYNOS4_GPIO_Y45, 1);
 411}
 412
 413int lcd_power(void)
 414{
 415#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
 416        int ret = 0;
 417        struct pmic *p = pmic_get("MAX8997_PMIC");
 418        if (!p)
 419                return -ENODEV;
 420
 421        if (pmic_probe(p))
 422                return 0;
 423
 424        /* LDO15 voltage: 2.2v */
 425        ret |= pmic_reg_write(p, MAX8997_REG_LDO15CTRL, 0x1c | EN_LDO);
 426        /* LDO13 voltage: 3.0v */
 427        ret |= pmic_reg_write(p, MAX8997_REG_LDO13CTRL, 0x2c | EN_LDO);
 428
 429        if (ret) {
 430                puts("MAX8997 LDO setting error!\n");
 431                return -1;
 432        }
 433#endif
 434        return 0;
 435}
 436
 437int mipi_power(void)
 438{
 439#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
 440        int ret = 0;
 441        struct pmic *p = pmic_get("MAX8997_PMIC");
 442        if (!p)
 443                return -ENODEV;
 444
 445        if (pmic_probe(p))
 446                return 0;
 447
 448        /* LDO3 voltage: 1.1v */
 449        ret |= pmic_reg_write(p, MAX8997_REG_LDO3CTRL, 0x6 | EN_LDO);
 450        /* LDO4 voltage: 1.8v */
 451        ret |= pmic_reg_write(p, MAX8997_REG_LDO4CTRL, 0x14 | EN_LDO);
 452
 453        if (ret) {
 454                puts("MAX8997 LDO setting error!\n");
 455                return -1;
 456        }
 457#endif
 458        return 0;
 459}
 460
 461#ifdef CONFIG_LCD
 462void exynos_lcd_misc_init(vidinfo_t *vid)
 463{
 464#ifdef CONFIG_TIZEN
 465        get_tizen_logo_info(vid);
 466#endif
 467#ifdef CONFIG_S6E8AX0
 468        s6e8ax0_init();
 469        env_set("lcdinfo", "lcd=s6e8ax0");
 470#endif
 471}
 472#endif
 473