Add regulators for EHCI controller on Arndale

Fix #780
This commit is contained in:
Stefan Kalkowski 2013-06-24 17:54:16 +02:00
parent 059bf1c576
commit ae49f6216d
5 changed files with 59 additions and 39 deletions

View File

@ -125,6 +125,13 @@ static void arndale_ehci_init()
{
enum Gpio_offset { D1 = 0x180, X3 = 0xc60 };
/* enable USB3 clock and power up */
Regulator::Connection reg_clk(Regulator::CLK_USB20);
reg_clk.state(true);
Regulator::Connection reg_pwr(Regulator::PWR_USB20);
reg_pwr.state(true);
/* reset hub via GPIO */
Io_mem_connection io_gpio(GPIO_BASE, 0x1000);
addr_t gpio_base = (addr_t)env()->rm_session()->attach(io_gpio.dataspace());

View File

@ -22,9 +22,11 @@ namespace Regulator {
CLK_CPU,
CLK_SATA,
CLK_USB30,
CLK_USB20,
CLK_MMC0,
PWR_SATA,
PWR_USB30,
PWR_USB20,
MAX,
INVALID
};
@ -38,9 +40,11 @@ namespace Regulator {
{ CLK_CPU, "clock-cpu" },
{ CLK_SATA, "clock-sata" },
{ CLK_USB30, "clock-usb3.0" },
{ CLK_USB20, "clock-usb2.0" },
{ CLK_MMC0, "clock-mmc0" },
{ PWR_SATA, "power-sata" },
{ PWR_USB30, "power-usb3.0" },
{ PWR_USB20, "power-usb2.0" },
};
Regulator_id regulator_id_by_name(const char * name)

View File

@ -197,8 +197,8 @@ class Cmu : public Regulator::Driver,
struct Pdma0 : Bitfield<1, 1> { };
struct Pdma1 : Bitfield<2, 1> { };
struct Sata : Bitfield<6, 1> { };
struct Clk_sdmmc0 : Bitfield<12, 1> { };
struct Clk_usbhost20 : Bitfield<18, 1> { };
struct Sdmmc0 : Bitfield<12, 1> { };
struct Usbhost20 : Bitfield<18, 1> { };
struct Usbdrd30 : Bitfield<19, 1> { };
struct Sata_phy_ctrl : Bitfield<24, 1> { };
struct Sata_phy_i2c : Bitfield<25, 1> { };
@ -361,8 +361,10 @@ class Cmu : public Regulator::Driver,
case CLK_USB30:
_usb30_enable();
break;
case CLK_USB20:
return write<Clk_gate_ip_fsys::Usbhost20>(1);
case CLK_MMC0:
write<Clk_gate_ip_fsys::Clk_sdmmc0>(1);
write<Clk_gate_ip_fsys::Sdmmc0>(1);
write<Clk_src_mask_fsys::Mmc0_mask>(1);
break;
default:
@ -383,8 +385,10 @@ class Cmu : public Regulator::Driver,
write<Clk_gate_ip_fsys::Usbdrd30>(0);
write<Clk_src_mask_fsys::Usbdrd30_mask>(0);
break;
case CLK_USB20:
return write<Clk_gate_ip_fsys::Usbhost20>(0);
case CLK_MMC0:
write<Clk_gate_ip_fsys::Clk_sdmmc0>(0);
write<Clk_gate_ip_fsys::Sdmmc0>(0);
write<Clk_src_mask_fsys::Mmc0_mask>(0);
break;
default:
@ -483,8 +487,10 @@ class Cmu : public Regulator::Driver,
case CLK_USB30:
return read<Clk_gate_ip_fsys::Usbdrd30>() &&
read<Clk_src_mask_fsys::Usbdrd30_mask>();
case CLK_USB20:
return read<Clk_gate_ip_fsys::Usbhost20>();
case CLK_MMC0:
return read<Clk_gate_ip_fsys::Clk_sdmmc0>() &&
return read<Clk_gate_ip_fsys::Sdmmc0>() &&
read<Clk_src_mask_fsys::Mmc0_mask>();
default:
PWRN("Unsupported for %s", names[id].name);

View File

@ -31,10 +31,12 @@ struct Driver_factory : Regulator::Driver_factory
case Regulator::CLK_CPU:
case Regulator::CLK_SATA:
case Regulator::CLK_USB30:
case Regulator::CLK_USB20:
case Regulator::CLK_MMC0:
return _cmu;
case Regulator::PWR_SATA:
case Regulator::PWR_USB30:
case Regulator::PWR_USB20:
return _pmu;
default:
throw Root::Invalid_args(); /* invalid regulator */

View File

@ -99,27 +99,38 @@ class Pmu : public Regulator::Driver,
}
/***********************
** USB 3.0 functions **
***********************/
void _usb30_enable()
void _enable(unsigned long id)
{
write<Usbdrd_phy_control::Enable>(1);
write<Usbhost_phy_control::Enable>(1);
switch (id) {
case PWR_USB30:
write<Usbdrd_phy_control::Enable>(1);
break;
case PWR_USB20:
write<Usbhost_phy_control::Enable>(1);
break;
case PWR_SATA :
write<Sata_phy_control::Enable>(1);
break;
default:
PWRN("Unsupported for %s", names[id].name);
}
}
void _usb30_disable()
void _disable(unsigned long id)
{
write<Usbdrd_phy_control::Enable>(0);
write<Usbhost_phy_control::Enable>(0);
}
bool _usb30_enabled()
{
return read<Usbdrd_phy_control::Enable>() &&
read<Usbhost_phy_control::Enable>();
switch (id) {
case PWR_USB30:
write<Usbdrd_phy_control::Enable>(0);
break;
case PWR_USB20:
write<Usbhost_phy_control::Enable>(0);
break;
case PWR_SATA :
write<Sata_phy_control::Enable>(0);
break;
default:
PWRN("Unsupported for %s", names[id].name);
}
}
public:
@ -176,29 +187,19 @@ class Pmu : public Regulator::Driver,
void state(Regulator_id id, bool enable)
{
switch (id) {
case PWR_USB30:
if (enable)
_usb30_enable();
else
_usb30_disable();
break;
case PWR_SATA :
if (enable)
write<Sata_phy_control::Enable>(1);
else
write<Sata_phy_control::Enable>(0);
break;
default:
PWRN("Unsupported for %s", names[id].name);
}
if (enable)
_enable(id);
else
_disable(id);
}
bool state(Regulator_id id)
{
switch (id) {
case PWR_USB30:
return _usb30_enabled();
return read<Usbdrd_phy_control::Enable>();
case PWR_USB20:
return read<Usbhost_phy_control::Enable>();
case PWR_SATA:
return read<Sata_phy_control::Enable>();
default: