ryu: Enhance pmic access functions

1. Add page address, an i2c address, into register address table
2. Add pmic read function
3. Add more registers and setting values.

BRANCH=none
BUG=chrome-os-partner:31936
TEST=build and test on ryu

Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>

Change-Id: Ieef0737205b20add3ff8990f62dd8585a4e8c557
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 6dcf42c299e25023991be331b724acd0fd9f32c2
Original-Change-Id: I227b3e9390e6fc020707d4730c19945760df6ca2
Original-Reviewed-on: https://chromium-review.googlesource.com/226902
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Original-Commit-Queue: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Tested-by: Jimmy Zhang <jimmzhang@nvidia.com>
Reviewed-on: http://review.coreboot.org/9420
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Jimmy Zhang 2014-10-31 18:26:11 -07:00 committed by Patrick Georgi
parent 58901b6b66
commit ae272297aa
3 changed files with 89 additions and 41 deletions

View File

@ -27,30 +27,38 @@
#include "pmic.h"
#include "reset.h"
/* A44/Ryu has a TI 65913 PMIC on bus 4 (PWR_I2C) */
enum {
TI65913_I2C_ADDR = 0x58
};
#define PAGE_ADDR(reg) ((reg >> 8) & 0xff)
#define PAGE_OFFSET(reg) (reg & 0xff)
struct ti65913_init_reg {
u8 reg;
u16 reg;
u8 val;
u8 delay;
};
static struct ti65913_init_reg init_list[] = {
//TODO(twarren@nvidia.com): Add slams back to defaults
// {TI65913_SMPS12_CTRL, 0x01, 0},
// {TI65913_SMPS12_VOLTAGE, 0x38, 0},
// {TI65913_SMPS12_CTRL, 0x01, 1},
//etc.
};
void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int delay)
int pmic_read_reg(unsigned bus, uint16_t reg, uint8_t *data)
{
if (i2c_writeb(bus, TI65913_I2C_ADDR, reg, val)) {
printk(BIOS_ERR, "%s: reg = 0x%02X, value = 0x%02X failed!\n",
__func__, reg, val);
if (i2c_readb(bus, PAGE_ADDR(reg), PAGE_OFFSET(reg), data)) {
printk(BIOS_ERR, "%s: page = 0x%02X, reg = 0x%02X failed!\n",
__func__, PAGE_ADDR(reg), PAGE_OFFSET(reg));
return -1;
}
return 0;
}
void pmic_write_reg(unsigned bus, uint16_t reg, uint8_t val, int delay)
{
if (i2c_writeb(bus, PAGE_ADDR(reg), PAGE_OFFSET(reg), val)) {
printk(BIOS_ERR, "%s: page = 0x%02X, reg = 0x%02X, "
"value = 0x%02X failed!\n",
__func__, PAGE_ADDR(reg), PAGE_OFFSET(reg), val);
/* Reset the SoC on any PMIC write error */
cpu_reset();
} else {
@ -71,14 +79,12 @@ static void pmic_slam_defaults(unsigned bus)
void pmic_init(unsigned bus)
{
/* Don't need to set up VDD_CORE - already done - by EC ?? */
/* Restore PMIC POR defaults, in case kernel changed 'em */
pmic_slam_defaults(bus);
/* A44: Set VDD_CPU to 1.0V. */
pmic_write_reg(bus, TI65913_SMPS12_CTRL, 0x01, 1);
pmic_write_reg(bus, TI65913_SMPS12_VOLTAGE, 0x38, 0);
pmic_write_reg(bus, TI65913_SMPS12_CTRL, 0x01, 1);
printk(BIOS_DEBUG, "PMIC init done\n");
}

View File

@ -22,41 +22,47 @@
#include <stdint.h>
/* A44/Ryu has a TI 65913 PMIC */
/* A44/Ryu has a TI 65913 PMIC on bus 4 (PWR_I2C) */
enum {
TI65913_SMPS12_CTRL = 0x20,
TI65913_I2C_ADDR_PAGE1 = 0x58,
TI65913_I2C_ADDR_PAGE2 = 0x59
};
enum {
/* Registers in PAGE1 */
TI65913_SMPS12_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x20,
TI65913_SMPS12_TSTEP,
TI65913_SMPS12_FORCE,
TI65913_SMPS12_VOLTAGE,
TI65913_SMPS3_CTRL,
TI65913_SMPS3_VOLTAGE = 0x27,
TI65913_SMPS3_VOLTAGE = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x27,
TI65913_SMPS45_CTRL = 0x28,
TI65913_SMPS45_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x28,
TI65913_SMPS45_TSTEP,
TI65913_SMPS45_FORCE,
TI65913_SMPS45_VOLTAGE,
TI65913_SMPS6_CTRL = 0x2C,
TI65913_SMPS6_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x2C,
TI65913_SMPS6_TSTEP,
TI65913_SMPS6_FORCE,
TI65913_SMPS6_VOLTAGE,
TI65913_SMPS7_CTRL = 0x30,
TI65913_SMPS7_VOLTAGE = 0x33,
TI65913_SMPS7_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x30,
TI65913_SMPS7_VOLTAGE = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x33,
TI65913_SMPS8_CTRL = 0x34,
TI65913_SMPS8_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x34,
TI65913_SMPS8_TSTEP,
TI65913_SMPS8_FORCE,
TI65913_SMPS8_VOLTAGE,
TI65913_SMPS9_CTRL = 0x38,
TI65913_SMPS9_VOLTAGE = 0x3B,
TI65913_SMPS9_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x38,
TI65913_SMPS9_VOLTAGE = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x3B,
TI65913_SMPS10_CTRL = 0x3C,
TI65913_SMPS10_STATUS = 0x3F,
TI65913_SMPS10_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x3C,
TI65913_SMPS10_STATUS = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x3F,
TI65913_LDO1_CTRL = 0x50,
TI65913_LDO1_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x50,
TI65913_LDO1_VOLTAGE,
TI65913_LDO2_CTRL,
TI65913_LDO2_VOLTAGE,
@ -75,24 +81,55 @@ enum {
TI65913_LDO9_CTRL,
TI65913_LDO9_VOLTAGE,
TI65913_LDOLN_CTRL = 0x62,
TI65913_LDOLN_VOLTAGE = 0x63,
TI65913_LDOUSB_CTRL = 0x64,
TI65913_LDOUSB_VOLTAGE = 0x65,
TI65913_LDOLN_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x62,
TI65913_LDOLN_VOLTAGE,
TI65913_LDOUSB_CTRL,
TI65913_LDOUSB_VOLTAGE,
TI65913_LDO_CTRL = 0x6A,
TI65913_LDO_PD_CTRL1 = 0x6B,
TI65913_LDO_PD_CTRL2 = 0x6C,
TI65913_LDO_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x6A,
TI65913_LDO_PD_CTRL1,
TI65913_LDO_PD_CTRL2,
TI65913_LDO_SHORT_STATUS1 = 0x6D,
TI65913_LDO_SHORT_STATUS2 = 0x6E,
TI65913_LDO_SHORT_STATUS1 = (TI65913_I2C_ADDR_PAGE1 << 8) | 0x6D,
TI65913_LDO_SHORT_STATUS2,
TI65913_CLK32KGAUDIO_CTRL = 0xD5,
TI65913_CLK32KGAUDIO_CTRL = (TI65913_I2C_ADDR_PAGE1 << 8) | 0xD5,
TI65913_PRIMARY_SECONDARY_PAD2 = 0xFB,
TI65913_PAD2 = (TI65913_I2C_ADDR_PAGE1 << 8) | 0xFB,
/* Registers in PAGE2 */
TI65913_GPIO_DATA_IN = (TI65913_I2C_ADDR_PAGE2 << 8) | 0x80,
TI65913_GPIO_DATA_DIR,
TI65913_GPIO_DATA_OUT,
};
void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int delay);
/* Voltage selection */
enum {
VSEL_1200 = 0x07,
};
/*
* TI65913_LDO5_CTRL
* TI65913_CLK32KGAUDIO_CTRL
*/
#define TI65913_MODE_ACTIVE_ON (1 << 0)
/*
* select PRIMARY or SECONDARY function on PAD2
*/
#define PAD2_GPIO_6_PRIMARY(data) \
((data) & ~(1 << 3)) /* clear bit 3 */
#define PAD2_GPIO_5_SEC_CLK32KGAUDIO(data) \
(((data) & ~(0x03 << 1)) | (0x01 << 1)) /* bit 2:1 = 01 */
/* TI65913_GPIO_DATA_DIR */
#define TI65913_GPIO_6_OUTPUT (1 << 6)
/* TI65913_GPIO_DATA_OUT */
#define TI65913_GPIO_6_HIGH (1 << 6)
int pmic_read_reg(unsigned bus, uint16_t reg, uint8_t *data);
void pmic_write_reg(unsigned bus, uint16_t reg, uint8_t val, int delay);
void pmic_init(unsigned bus);
#endif /* __MAINBOARD_GOOGLE_RUSH_RYU_PMIC_H__ */

View File

@ -19,6 +19,7 @@
#include <delay.h>
#include <soc/addressmap.h>
#include <device/i2c.h>
#include <soc/clock.h>
#include <soc/funitcfg.h>
#include <soc/nvidia/tegra/i2c.h>
@ -67,6 +68,7 @@ static const struct funit_cfg funits[] = {
static void lte_modem_init(void)
{
int mdm_det;
uint8_t data;
/* A LTE modem is present if MDM_DET is pulled down by the modem */
mdm_det = gpio_get(MDM_DET);
@ -76,8 +78,11 @@ static void lte_modem_init(void)
printk(BIOS_DEBUG, "Found LTE modem\n");
/* Enable PMIC CLK32KGAUDIO to drive CLK_MDM_32K */
pmic_write_reg(I2CPWR_BUS, TI65913_PRIMARY_SECONDARY_PAD2, 0x02, 0);
pmic_write_reg(I2CPWR_BUS, TI65913_CLK32KGAUDIO_CTRL, 0x01, 0);
pmic_read_reg(I2CPWR_BUS, TI65913_PAD2, &data);
pmic_write_reg(I2CPWR_BUS, TI65913_PAD2,
PAD2_GPIO_5_SEC_CLK32KGAUDIO(data), 0);
pmic_write_reg(I2CPWR_BUS, TI65913_CLK32KGAUDIO_CTRL,
TI65913_MODE_ACTIVE_ON, 0);
/* FULL_CARD_POWER_OFF# (A44: MODEM_PWR_ON) and RESET#
* (A44: MODEM_RESET) of the LTE modem are actively low and initially