Compare commits

...

8 Commits

Author SHA1 Message Date
Merlijn Wajer 40e80547b6 Forward port OLIMEX LIME2 Gbit ethernet patch 6 years ago
Merlijn Wajer 9064f824c5 The lime2 features a too large capacitor on the LDO3 output, which 6 years ago
Merlijn Wajer 73d5c9c3dd Some boards feature a capacitance on LDO3's output that is to large, 6 years ago
Merlijn Wajer 3d6bca513e The AXP209 has voltage rate control, or can set a slew rate, for LDO3. 6 years ago
Merlijn Wajer a1e0662a62 The AXP209 has a few 'magisc-ish' values that are better served with 6 years ago
Merlijn Wajer b5d91bd55f Use a define for the chip version mask on the axp209. 6 years ago
Merlijn Wajer a189450a5a Use the standard BIT() macro to define BITS. 6 years ago
Merlijn Wajer 1a82933368 When we set or clear a pmic_bus bit, we do a read-modify-write 6 years ago
  1. 6
      arch/arm/mach-sunxi/pmic_bus.c
  2. 2
      board/sunxi/gmac.c
  3. 1
      configs/A20-OLinuXino-Lime2_defconfig
  4. 11
      drivers/net/phy/micrel_ksz90x1.c
  5. 27
      drivers/net/phy/realtek.c
  6. 35
      drivers/net/phy/smsc.c
  7. 42
      drivers/power/Kconfig
  8. 59
      drivers/power/axp209.c
  9. 66
      include/axp209.h
  10. 3
      include/configs/sunxi-common.h

@ -102,6 +102,9 @@ int pmic_bus_setbits(u8 reg, u8 bits)
if (ret)
return ret;
if (val & bits)
return 0;
val |= bits;
return pmic_bus_write(reg, val);
}
@ -115,6 +118,9 @@ int pmic_bus_clrbits(u8 reg, u8 bits)
if (ret)
return ret;
if (!(val & bits))
return 0;
val &= ~bits;
return pmic_bus_write(reg, val);
}

@ -24,8 +24,6 @@ void eth_init_board(void)
#ifdef CONFIG_RGMII
setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII |
CCM_GMAC_CTRL_GPIT_RGMII);
setbits_le32(&ccm->gmac_clk_cfg,
CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY));
#else
setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII |
CCM_GMAC_CTRL_GPIT_MII);

@ -23,6 +23,7 @@ CONFIG_DFU_RAM=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_RGMII=y
CONFIG_SUN7I_GMAC=y
CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
CONFIG_AXP_ALDO3_VOLT=2800
CONFIG_AXP_ALDO4_VOLT=2800
CONFIG_SCSI=y

@ -16,6 +16,8 @@
#include <errno.h>
#include <micrel.h>
#include <phy.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
DECLARE_GLOBAL_DATA_PTR;
@ -103,7 +105,7 @@ static const struct ksz90x1_reg_field ksz9031_ctl_grp[] = {
};
static const struct ksz90x1_reg_field ksz9031_clk_grp[] = {
{ "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf }
{ "rxc-skew-ps", 5, 0, 0x7 }, { "txc-skew-ps", 5, 5, 0x17 }
};
static int ksz90x1_of_config_group(struct phy_device *phydev,
@ -334,6 +336,13 @@ static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
static int ksz9031_config(struct phy_device *phydev)
{
int ret;
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
#ifdef CONFIG_RGMII
setbits_le32(&ccm->gmac_clk_cfg,
CCM_GMAC_CTRL_TX_CLK_DELAY(4));
#endif
ret = ksz9031_of_config(phydev);
if (ret)

@ -11,6 +11,8 @@
#include <common.h>
#include <linux/bitops.h>
#include <phy.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#define PHY_RTL8211x_FORCE_MASTER BIT(1)
#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
@ -80,6 +82,9 @@ static int rtl8211e_probe(struct phy_device *phydev)
/* RealTek RTL8211x */
static int rtl8211x_config(struct phy_device *phydev)
{
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
/* mask interrupt at init; if the interrupt is
@ -88,6 +93,27 @@ static int rtl8211x_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER,
MIIM_RTL8211x_PHY_INTR_DIS);
/* Check if device is RTL8211CL or RTL8211E */
if(phydev->drv->uid == 0x1cc912) {
/* On RTL8211E TX delay must be 0 and
* phy must be forced to be master
*/
setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_DELAY(0));
unsigned int reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
/* force manual master/slave configuration */
reg |= MIIM_RTL8211x_CTRL1000T_MSCE;
/* force master mode */
reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
} else {
if(phydev->drv->uid == 0x1cc915) {
/* On RTL8211E make GMAC_TX_CLK_DELAY 2 */
setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_DELAY(2));
}
}
if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) {
unsigned int reg;
@ -114,6 +140,7 @@ static int rtl8211x_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
0);
}
/* read interrupt status just to clear it */
phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);

@ -11,6 +11,8 @@
* Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
*/
#include <miiphy.h>
#include <asm/gpio.h>
#include <asm/arch/gpio.h>
/* This code does not check the partner abilities. */
static int smsc_parse_status(struct phy_device *phydev)
@ -43,6 +45,30 @@ static int smsc_startup(struct phy_device *phydev)
return smsc_parse_status(phydev);
}
#if 1
static int olinuxino_smsc_startup(struct phy_device *phydev)
{
int ret;
ret = gpio_request(SUNXI_GPA(17), "lan8710-txerr");
if(ret)
return ret;
gpio_direction_output(SUNXI_GPA(17), 0);
ret = genphy_update_link(phydev);
if (ret)
return ret;
return genphy_parse_link(phydev);
}
static int olinuxino_smsc_shutdown(struct phy_device *phydev)
{
sunxi_gpio_set_cfgpin(SUNXI_GPA(17), SUNXI_GPIO_INPUT);
return 0;
}
#endif
static struct phy_driver lan8700_driver = {
.name = "SMSC LAN8700",
.uid = 0x0007c0c0,
@ -69,8 +95,13 @@ static struct phy_driver lan8710_driver = {
.mask = 0xffff0,
.features = PHY_BASIC_FEATURES,
.config = &genphy_config_aneg,
.startup = &genphy_startup,
.shutdown = &genphy_shutdown,
#if 1
.startup = &olinuxino_smsc_startup,
.shutdown = &olinuxino_smsc_shutdown,
#else
.startup = &genphy_startup,
.shutdown = &genphy_shutdown,
#endif
};
static struct phy_driver lan8740_driver = {

@ -197,6 +197,48 @@ config AXP_ALDO3_VOLT
On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be
3.0V.
choice
prompt "axp pmic (a)ldo3 voltage rate control"
depends on AXP209_POWER && (AXP_ALDO3_VOLT != 0)
default AXP_ALDO3_VOLT_SLOPE_NONE
---help---
The AXP can slowly ramp up voltage to reduce the inrush current when
changing voltages.
Note, this does not apply when enabeling/disableing LDO3. See
"axp pmic (a)ldo3 inrush quirk" below to enable a slew rate to limit
inrush current on broken board designs.
config AXP_ALDO3_VOLT_SLOPE_NONE
bool "No voltage slope"
---help---
Tries to reach the next voltage setting near instantaneous. Measurements
indicate that this is about 0.0167 V/uS.
config AXP_ALDO3_VOLT_SLOPE_16
bool "1.6 mV per uS"
---help---
Increases the voltage by 1.6 mV per uS until the final voltage has
been reached. Note that the scaling is in 25 mV steps however and thus
the slew rate is 25 mV/31.250 uS in reality.
config AXP_ALDO3_VOLT_SLOPE_08
bool "0.8 mV per uS"
---help---
Increases the voltage by 0.8 mV per uS until the final voltage has
been reached. Note that the scaling is in 25 mV steps however and thus
the slew rate is 25 mV/15.625 uS in reality. This is the slowest rate.
endchoice
config AXP_ALDO3_INRUSH_QUIRK
bool "axp pmic (a)ldo3 inrush quirk"
depends on AXP209_POWER
default n
---help---
The reference design denotes a value of 4.7 uF for the output capacitor
of LDO3. Some boards have to higher capacitance than that which causes
an inrush current and causes an AXP209 shutdown.
config AXP_ALDO4_VOLT
int "axp pmic (a)ldo4 voltage"
depends on AXP209_POWER

@ -10,6 +10,16 @@
#include <asm/arch/pmic_bus.h>
#include <axp_pmic.h>
#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_08
# define AXP209_VRC_SLOPE AXP209_VRC_LDO3_800uV_uS
#endif
#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_16
# define AXP209_VRC_SLOPE AXP209_VRC_LDO3_1600uV_uS
#endif
#if defined CONFIG_AXP_ALDO3_VOLT_SLOPE_NONE || !defined AXP209_VRC_SLOPE
# define AXP209_VRC_SLOPE 0x00
#endif
static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
{
if (mvolt < min)
@ -82,8 +92,7 @@ int axp_set_aldo2(unsigned int mvolt)
if (rc)
return rc;
/* LDO2 configuration is in upper 4 bits */
reg = (reg & 0x0f) | (cfg << 4);
reg |= AXP209_LDO24_LDO2_SET(reg, cfg);
rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
if (rc)
return rc;
@ -100,10 +109,46 @@ int axp_set_aldo3(unsigned int mvolt)
return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
AXP209_OUTPUT_CTRL_LDO3);
/*
* Some boards have trouble reaching the target voltage without causing
* great inrush currents. To prevent this, boards can enable a certain
* slope to ramp up voltage. Note, this only works when changing an
* already active power rail. When toggling power on, the AXP ramps up
* steeply at 0.0167 V/uS.
*/
rc = pmic_bus_read(AXP209_VRC_DCDC2_LDO3, &cfg);
cfg = AXP209_VRC_LDO3_SLOPE_SET(cfg, AXP209_VRC_SLOPE);
rc |= pmic_bus_write(AXP209_VRC_DCDC2_LDO3, cfg);
if (rc)
return rc;
/*
* On some boards, LDO3 has a to big capacitor installed. When
* turning on LDO3, this causes the AXP209 to shutdown on
* voltages over 1.9 volt. As a work around, we enable LDO3
* first with the lowest possible voltage. If this still causes
* high inrush currents, the voltage slope should be increased.
*/
#ifdef CONFIG_AXP_ALDO3_INRUSH_QUIRK
rc = pmic_bus_read(AXP209_OUTPUT_CTRL, &cfg);
if (rc)
return rc;
if (!(cfg & AXP209_OUTPUT_CTRL_LDO3)) {
rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, 0x0); /* 0.7 Volt */
mdelay(1);
rc |= pmic_bus_setbits(AXP209_OUTPUT_CTRL, AXP209_OUTPUT_CTRL_LDO3);
if (rc)
return rc;
}
#endif
if (mvolt == -1)
cfg = 0x80; /* determined by LDO3IN pin */
cfg = AXP209_LDO3_VOLTAGE_FROM_LDO3IN;
else
cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
cfg = AXP209_LDO3_VOLTAGE_SET(axp209_mvolt_to_cfg(mvolt, 700, 3500, 25));
rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, cfg);
if (rc)
@ -132,8 +177,7 @@ int axp_set_aldo4(unsigned int mvolt)
if (rc)
return rc;
/* LDO4 configuration is in lower 4 bits */
reg = (reg & 0xf0) | (cfg << 0);
reg |= AXP209_LDO24_LDO4_SET(reg, cfg);
rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
if (rc)
return rc;
@ -154,10 +198,13 @@ int axp_init(void)
if (rc)
return rc;
#if 0
/* Low 4 bits is chip version */
ver &= 0x0f;
if (ver != 0x1)
#endif
if ((ver & AXP209_CHIP_VERSION_MASK) != 0x1)
return -EINVAL;
/* Mask all interrupts */

@ -4,11 +4,14 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <linux/bitops.h>
enum axp209_reg {
AXP209_POWER_STATUS = 0x00,
AXP209_CHIP_VERSION = 0x03,
AXP209_OUTPUT_CTRL = 0x12,
AXP209_DCDC2_VOLTAGE = 0x23,
AXP209_VRC_DCDC2_LDO3 = 0x25,
AXP209_DCDC3_VOLTAGE = 0x27,
AXP209_LDO24_VOLTAGE = 0x28,
AXP209_LDO3_VOLTAGE = 0x29,
@ -21,29 +24,60 @@ enum axp209_reg {
AXP209_SHUTDOWN = 0x32,
};
#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0)
#define AXP209_POWER_STATUS_VBUS_USABLE (1 << 4)
#define AXP209_POWER_STATUS_ON_BY_DC BIT(0)
#define AXP209_POWER_STATUS_VBUS_USABLE BIT(4)
#define AXP209_CHIP_VERSION_MASK 0x0f
#define AXP209_OUTPUT_CTRL_EXTEN BIT(0)
#define AXP209_OUTPUT_CTRL_DCDC3 BIT(1)
#define AXP209_OUTPUT_CTRL_LDO2 BIT(2)
#define AXP209_OUTPUT_CTRL_LDO4 BIT(3)
#define AXP209_OUTPUT_CTRL_DCDC2 BIT(4)
#define AXP209_OUTPUT_CTRL_LDO3 BIT(6)
#define AXP209_VRC_LDO3_EN BIT(3)
#define AXP209_VRC_DCDC2_EN BIT(2)
#define AXP209_VRC_LDO3_800uV_uS (BIT(1) | AXP209_VRC_LDO3_EN)
#define AXP209_VRC_LDO3_1600uV_uS AXP209_VRC_LDO3_EN
#define AXP209_VRC_DCDC2_800uV_uS (BIT(0) | AXP209_VRC_DCDC2_EN)
#define AXP209_VRC_DCDC2_1600uV_uS AXP209_VRC_DCDC2_EN
#define AXP209_VRC_LDO3_MASK 0xa
#define AXP209_VRC_DCDC2_MASK 0x5
#define AXP209_VRC_DCDC2_SLOPE_SET(reg, cfg) \
(((reg) & ~AXP209_VRC_DCDC2_MASK) | \
((cfg) & AXP209_VRC_DCDC2_MASK))
#define AXP209_VRC_LDO3_SLOPE_SET(reg, cfg) \
(((reg) & ~AXP209_VRC_LDO3_MASK) | \
((cfg) & AXP209_VRC_LDO3_MASK))
#define AXP209_LDO24_LDO2_MASK 0xf0
#define AXP209_LDO24_LDO4_MASK 0x0f
#define AXP209_LDO24_LDO2_SET(reg, cfg) \
(((reg) & ~AXP209_LDO24_LDO2_MASK) | \
(((cfg) << 4) & AXP209_LDO24_LDO2_MASK))
#define AXP209_LDO24_LDO4_SET(reg, cfg) \
(((reg) & ~AXP209_LDO24_LDO4_MASK) | \
(((cfg) << 0) & AXP209_LDO24_LDO4_MASK))
#define AXP209_OUTPUT_CTRL_EXTEN (1 << 0)
#define AXP209_OUTPUT_CTRL_DCDC3 (1 << 1)
#define AXP209_OUTPUT_CTRL_LDO2 (1 << 2)
#define AXP209_OUTPUT_CTRL_LDO4 (1 << 3)
#define AXP209_OUTPUT_CTRL_DCDC2 (1 << 4)
#define AXP209_OUTPUT_CTRL_LDO3 (1 << 6)
#define AXP209_LDO3_VOLTAGE_FROM_LDO3IN BIT(7)
#define AXP209_LDO3_VOLTAGE_MASK 0x7f
#define AXP209_LDO3_VOLTAGE_SET(x) ((x) & AXP209_LDO3_VOLTAGE_MASK)
#define AXP209_IRQ5_PEK_UP (1 << 6)
#define AXP209_IRQ5_PEK_DOWN (1 << 5)
#define AXP209_IRQ5_PEK_UP BIT(6)
#define AXP209_IRQ5_PEK_DOWN BIT(5)
#define AXP209_POWEROFF (1 << 7)
#define AXP209_POWEROFF BIT(7)
/* For axp_gpio.c */
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)
#define AXP_POWER_STATUS_VBUS_PRESENT BIT(5)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x92
#define AXP_GPIO2_CTRL 0x93
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 4
#define AXP_GPIO_STATE_OFFSET 4

@ -294,6 +294,9 @@ extern int soft_i2c_gpio_scl;
#ifdef CONFIG_SUN7I_GMAC
#define CONFIG_MII /* MII PHY management */
#define CONFIG_PHY_REALTEK
#define CONFIG_PHY_MICREL
#define CONFIG_PHY_MICREL_KSZ9031
#define CONFIG_PHY_SMSC
#endif
#ifdef CONFIG_USB_EHCI_HCD

Loading…
Cancel
Save