blob: 4e8565d92d49b6c010844dec50a731c03facb472 [file] [log] [blame]
/*
* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*/
/* Implementation of per-board power management function */
#include <common.h>
#include <errno.h>
#include <i2c.h>
#include <spl.h>
#include <asm/arch/clock.h>
#include <asm/arch-tegra/sys_proto.h>
#include <asm-generic/gpio.h>
#include <cros/common.h>
#include <cros/power_management.h>
#include <power/as3722.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* This file is directly copied from cros/tegra114/power_management.c.
* All functions here need to be fleshed out and verified for Tegra124.
*/
#define PMIC_I2C_BUS 0x00
#define PMIC_I2C_DEVICE_ADDRESS 0x40 /* AS3722 PMIC */
#define PMIC_RESET_CTRL 0x36 /* AS3722 PMIC ResetControl */
int is_processor_reset(void)
{
return spl_was_boot_source();
}
static int pmic_set_bit(int reg, int bit, int value)
{
struct udevice *pmic;
uint8_t byte;
int ret;
ret = as3722_get(&pmic);
if (ret)
return -ENOENT;
ret = dm_i2c_read(pmic, reg, &byte, sizeof(byte));
if (ret) {
VBDEBUG("i2c_read fail: reg=%02x\n", reg);
return ret;
}
if (value)
byte |= 1 << bit;
else
byte &= ~(1 << bit);
ret = dm_i2c_write(pmic, reg, &byte, sizeof(byte));
if (ret) {
VBDEBUG("i2c_write fail: reg=%02x\n", reg);
return ret;
}
return 0;
}
/* This function never returns */
void cold_reboot(void)
{
const void *blob = gd->fdt_blob;
struct gpio_desc desc;
int ret, node;
VBDEBUG("cold_reboot\n");
mdelay(100);
node = fdt_path_offset(blob, "/config");
ret = gpio_request_by_name_nodev(blob, node, "reset-gpio", 0, &desc,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret && ret != -ENOENT)
VBDEBUG("cold_reboot: reset failed: %d\n", ret);
VBDEBUG("gpio reset %d\n", ret);
mdelay(100);
/* Set force-reset bit in PMIC reg 0x36 */
if (!pmic_set_bit(PMIC_RESET_CTRL, 0, 1)) {
/* Wait for 10 ms. If not rebootting, go to endless loop */
mdelay(10);
}
printf("Please press cold reboot button\n");
while (1)
;
}
/* This function never returns */
void power_off(void)
{
VBDEBUG("power_off\n");
mdelay(100);
/* Set shut-down bit in PMIC reg 0x36*/
if (!pmic_set_bit(PMIC_RESET_CTRL, 1, 1)) {
/* Wait for 10 ms. If not powering off, go to endless loop */
mdelay(10);
}
printf("Please unplug the power cable and battery\n");
while (1)
;
}