diff --git a/os/include/platform/arndale/regulator/consts.h b/os/include/platform/arndale/regulator/consts.h
index 480771139..703256b06 100644
--- a/os/include/platform/arndale/regulator/consts.h
+++ b/os/include/platform/arndale/regulator/consts.h
@@ -22,6 +22,7 @@ namespace Regulator {
CLK_CPU,
CLK_SATA,
CLK_USB30,
+ CLK_MMC0,
PWR_SATA,
PWR_USB30,
MAX,
@@ -37,6 +38,7 @@ namespace Regulator {
{ CLK_CPU, "clock-cpu" },
{ CLK_SATA, "clock-sata" },
{ CLK_USB30, "clock-usb3.0" },
+ { CLK_MMC0, "clock-mmc0" },
{ PWR_SATA, "power-sata" },
{ PWR_USB30, "power-usb3.0" },
};
diff --git a/os/run/sd_card.run b/os/run/sd_card.run
index 762cb764d..2a58a6849 100644
--- a/os/run/sd_card.run
+++ b/os/run/sd_card.run
@@ -5,6 +5,7 @@
# generic components
set build_components {
core init
+ drivers/platform
drivers/timer
drivers/sd_card
test/block
@@ -36,6 +37,10 @@ set config {
+
+
+
+
@@ -61,6 +66,7 @@ install_config $config
set boot_modules {
core init
timer
+ platform_drv
sd_card_drv
test-block
}
diff --git a/os/src/drivers/platform/arndale/cmu.h b/os/src/drivers/platform/arndale/cmu.h
index a6ad0cffa..0f1276590 100644
--- a/os/src/drivers/platform/arndale/cmu.h
+++ b/os/src/drivers/platform/arndale/cmu.h
@@ -47,6 +47,7 @@ class Cmu : public Regulator::Driver,
struct P : Register::template Bitfield < 8, 6> { };
struct M : Register::template Bitfield <16, 10> { };
struct Locked : Register::template Bitfield <29, 1> { };
+ struct Enable : Register::template Bitfield <31, 1> { };
};
@@ -121,6 +122,11 @@ class Cmu : public Regulator::Driver,
}
};
+
+ /************************
+ ** CMU CORE registers **
+ ************************/
+
typedef Pll_lock<0x4000> Mpll_lock;
typedef Pll_con0<0x4100> Mpll_con0;
@@ -129,11 +135,25 @@ class Cmu : public Regulator::Driver,
struct Mux_mpll_sel : Bitfield<8, 1> { enum { XXTI, MPLL_FOUT_RGT }; };
};
+ struct Clk_gate_ip_acp : Register<0x8800, 32> { };
+ struct Clk_gate_ip_isp0 : Register<0xc800, 32> { };
+ struct Clk_gate_ip_isp1 : Register<0xc804, 32> { };
+ struct Clk_gate_sclk_isp : Register<0xc900, 32> { };
+
/***********************
** CMU TOP registers **
***********************/
+ typedef Pll_lock<0x10020> Cpll_lock;
+ typedef Pll_lock<0x10030> Epll_lock;
+ typedef Pll_lock<0x10040> Vpll_lock;
+ typedef Pll_lock<0x10050> Gpll_lock;
+ typedef Pll_con0<0x10120> Cpll_con0;
+ typedef Pll_con0<0x10130> Epll_con0;
+ typedef Pll_con0<0x10140> Vpll_con0;
+ typedef Pll_con0<0x10150> Gpll_con0;
+
struct Clk_src_top2 : Register<0x10218, 32>
{
struct Mux_mpll_user_sel : Bitfield<20, 1> { enum { XXTI, MOUT_MPLL}; };
@@ -149,6 +169,7 @@ class Cmu : public Regulator::Driver,
struct Clk_src_mask_fsys : Register<0x10340, 32>
{
+ struct Mmc0_mask : Bitfield<0, 1> { enum { MASK, UNMASK }; };
struct Sata_mask : Bitfield<24, 1> { enum { MASK, UNMASK }; };
struct Usbdrd30_mask : Bitfield<28, 1> { enum { MASK, UNMASK }; };
};
@@ -165,16 +186,35 @@ class Cmu : public Regulator::Driver,
struct Div_usbdrd30 : Bitfield<24, 1> {};
};
+ struct Clk_gate_ip_gscl : Register<0x10920, 32> { };
+ struct Clk_gate_ip_disp1 : Register<0x10928, 32> { };
+ struct Clk_gate_ip_mfc : Register<0x1092c, 32> { };
+ struct Clk_gate_ip_g3d : Register<0x10930, 32> { };
+ struct Clk_gate_ip_gen : Register<0x10934, 32> { };
+
struct Clk_gate_ip_fsys : Register<0x10944, 32>
{
struct Pdma0 : Bitfield<1, 1> { };
struct Pdma1 : Bitfield<2, 1> { };
struct Sata : Bitfield<6, 1> { };
- struct Usbdrd30 : Bitfield<19, 0> { };
+ struct Clk_sdmmc0 : Bitfield<12, 1> { };
+ struct Clk_usbhost20 : Bitfield<18, 1> { };
+ struct Usbdrd30 : Bitfield<19, 1> { };
struct Sata_phy_ctrl : Bitfield<24, 1> { };
struct Sata_phy_i2c : Bitfield<25, 1> { };
};
+ struct Clk_gate_ip_peric : Register<0x10950, 32>
+ {
+ struct Clk_uart2 : Bitfield<2, 1> { };
+ struct Clk_pwm : Bitfield<24, 1> { };
+ };
+
+ struct Clk_gate_block : Register<0x10980, 32>
+ {
+ struct Clk_gen : Bitfield<2, 1> { };
+ };
+
/*************************
** CMU CDREX registers **
@@ -240,9 +280,9 @@ class Cmu : public Regulator::Driver,
}
- /********************
- ** SATA functions **
- ********************/
+ /**********************
+ ** Device functions **
+ **********************/
void _sata_enable()
{
@@ -262,36 +302,13 @@ class Cmu : public Regulator::Driver,
write(1);
}
- void _sata_disable()
- {
- /* disable I2C for SATA */
- write(0);
-
- /* disable SATA and SATA Phy */
- write(0);
- write(0);
- write(0);
- }
-
- bool _sata_enabled()
- {
- return read() &&
- read() &&
- read();
- }
-
-
- /***********************
- ** USB 3.0 functions **
- ***********************/
-
void _usb30_enable()
{
/**
* set USBDRD30 clock to 66 MHz
* assuming 800 MHz from sclk_mpll_user, formula: sclk / (divider + 1)
*/
- write(11); /* */
+ write(11);
while (read()) ;
/* enable USBDRD30 clock */
@@ -299,16 +316,44 @@ class Cmu : public Regulator::Driver,
write(1);
}
- void _usb30_disable()
+ void _enable(Regulator_id id)
{
- write(0);
- write(0);
+ switch (id) {
+ case CLK_SATA:
+ _sata_enable();
+ break;
+ case CLK_USB30:
+ _usb30_enable();
+ break;
+ case CLK_MMC0:
+ write(1);
+ write(1);
+ break;
+ default:
+ PWRN("Unsupported for %s", names[id].name);
+ }
}
- bool _usb30_enabled()
+ void _disable(Regulator_id id)
{
- return read() &&
- read();
+ switch (id) {
+ case CLK_SATA:
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ break;
+ case CLK_USB30:
+ write(0);
+ write(0);
+ break;
+ case CLK_MMC0:
+ write(0);
+ write(0);
+ break;
+ default:
+ PWRN("Unsupported for %s", names[id].name);
+ }
}
public:
@@ -321,13 +366,31 @@ class Cmu : public Regulator::Driver,
Genode::Board_base::CMU_MMIO_SIZE),
_cpu_freq(CPU_FREQ_1600)
{
- _sata_disable();
- _usb30_disable();
+ /**
+ * Close certain clock gates by default (~ 0.7 Watt reduction)
+ */
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(Clk_gate_ip_peric::Clk_uart2::bits(1) |
+ Clk_gate_ip_peric::Clk_pwm::bits(1));
+ write(Clk_gate_block::Clk_gen::bits(1));
+
+ /**
+ * Set default CPU frequency
+ */
_cpu_clk_freq(_cpu_freq);
/**
- * Hard wiring of reference clocks
+ * Hard wiring of certain reference clocks
*/
write(Pll_div2_sel::Mpll_fout_sel::MPLL_FOUT_HALF);
write(Clk_src_core1::Mux_mpll_sel::MPLL_FOUT_RGT);
@@ -372,31 +435,25 @@ class Cmu : public Regulator::Driver,
void set_state(Regulator_id id, bool enable)
{
- switch (id) {
- case CLK_SATA:
- if (enable)
- _sata_enable();
- else
- _sata_disable();
- break;
- case CLK_USB30:
- if (enable)
- _usb30_enable();
- else
- _usb30_disable();
- break;
- default:
- PWRN("Unsupported for %s", names[id].name);
- }
+ if (enable)
+ _enable(id);
+ else
+ _disable(id);
}
bool state(Regulator_id id)
{
switch (id) {
case CLK_SATA:
- return _sata_enabled();
+ return read() &&
+ read() &&
+ read();
case CLK_USB30:
- return _usb30_enabled();
+ return read() &&
+ read();
+ case CLK_MMC0:
+ return read() &&
+ read();
default:
PWRN("Unsupported for %s", names[id].name);
}
diff --git a/os/src/drivers/platform/arndale/main.cc b/os/src/drivers/platform/arndale/main.cc
index c9ffc2054..422612ffa 100644
--- a/os/src/drivers/platform/arndale/main.cc
+++ b/os/src/drivers/platform/arndale/main.cc
@@ -31,6 +31,7 @@ struct Driver_factory : Regulator::Driver_factory
case Regulator::CLK_CPU:
case Regulator::CLK_SATA:
case Regulator::CLK_USB30:
+ case Regulator::CLK_MMC0:
return _cmu;
case Regulator::PWR_SATA:
case Regulator::PWR_USB30:
diff --git a/os/src/drivers/platform/arndale/pmu.h b/os/src/drivers/platform/arndale/pmu.h
index 1e6ce7ef6..1aa38a15e 100644
--- a/os/src/drivers/platform/arndale/pmu.h
+++ b/os/src/drivers/platform/arndale/pmu.h
@@ -27,16 +27,77 @@ class Pmu : public Regulator::Driver,
{
private:
- template
- struct Control : Register
+ template
+ struct Control : Register
{
- struct Enable : Register::template Bitfield<0, 1> { };
+ struct Enable : Register::template Bitfield<0, 1> { };
};
+ template
+ struct Configuration : Register
+ {
+ struct Local_pwr_cfg : Register::template Bitfield<0, 3> { };
+ };
+
+ template
+ struct Status : Register
+ {
+ struct Stat : Register::template Bitfield<0, 3> { };
+ };
+
+ template
+ struct Sysclk_configuration : Register
+ {
+ struct Local_pwr_cfg : Register::template Bitfield<0, 1> { };
+ };
+
+ template
+ struct Sysclk_status : Register
+ {
+ struct Stat : Register::template Bitfield<0, 1> { };
+ };
+
+ typedef Control<0x700> Hdmi_phy_control;
typedef Control<0x704> Usbdrd_phy_control;
typedef Control<0x708> Usbhost_phy_control;
+ typedef Control<0x70c> Efnand_phy_control;
+ typedef Control<0x718> Adc_phy_control;
+ typedef Control<0x71c> Mtcadc_phy_control;
+ typedef Control<0x720> Dptx_phy_control;
typedef Control<0x724> Sata_phy_control;
+ typedef Sysclk_configuration<0x2a40> Vpll_sysclk_configuration;
+ typedef Sysclk_status<0x2a44> Vpll_sysclk_status;
+ typedef Sysclk_configuration<0x2a60> Epll_sysclk_configuration;
+ typedef Sysclk_status<0x2a64> Epll_sysclk_status;
+ typedef Sysclk_configuration<0x2aa0> Cpll_sysclk_configuration;
+ typedef Sysclk_status<0x2aa4> Cpll_sysclk_status;
+ typedef Sysclk_configuration<0x2ac0> Gpll_sysclk_configuration;
+ typedef Sysclk_status<0x2ac4> Gpll_sysclk_status;
+
+ typedef Configuration<0x4000> Gscl_configuration;
+ typedef Status<0x4004> Gscl_status;
+ typedef Configuration<0x4020> Isp_configuration;
+ typedef Status<0x4024> Isp_status;
+ typedef Configuration<0x4040> Mfc_configuration;
+ typedef Status<0x4044> Mfc_status;
+ typedef Configuration<0x4060> G3d_configuration;
+ typedef Status<0x4064> G3d_status;
+ typedef Configuration<0x40A0> Disp1_configuration;
+ typedef Status<0x40A4> Disp1_status;
+ typedef Configuration<0x40C0> Mau_configuration;
+ typedef Status<0x40C4> Mau_status;
+
+
+ template
+ void _disable_domain()
+ {
+ if (read() == 0)
+ return;
+ write(0);
+ while (read() != 0) ;
+ }
+
/***********************
** USB 3.0 functions **
@@ -67,7 +128,29 @@ class Pmu : public Regulator::Driver,
* Constructor
*/
Pmu() : Genode::Attached_mmio(Genode::Board_base::PMU_MMIO_BASE,
- Genode::Board_base::PMU_MMIO_SIZE) { }
+ Genode::Board_base::PMU_MMIO_SIZE)
+ {
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+ write(0);
+
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+ _disable_domain();
+ }
/********************************
diff --git a/os/src/drivers/sd_card/exynos5/main.cc b/os/src/drivers/sd_card/exynos5/main.cc
index 7ee8145c1..641ed560d 100644
--- a/os/src/drivers/sd_card/exynos5/main.cc
+++ b/os/src/drivers/sd_card/exynos5/main.cc
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
/* local includes */
#include
@@ -48,7 +49,8 @@ int main(int argc, char **argv)
enum { STACK_SIZE = 8192 };
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
-
+ static Regulator::Connection mmc0_regulator(Regulator::CLK_MMC0);
+ mmc0_regulator.set_state(true);
static Block::Root block_root(&ep, env()->heap(), driver_factory);
env()->parent()->announce(ep.manage(&block_root));