platform_drv & exynos5: provide HDMI switches

ref #796
This commit is contained in:
Martin Stein 2013-10-08 18:04:45 +02:00 committed by Christian Helmuth
parent f14213b5f4
commit 92b3171765
4 changed files with 71 additions and 14 deletions

View File

@ -24,9 +24,11 @@ namespace Regulator {
CLK_USB30,
CLK_USB20,
CLK_MMC0,
CLK_HDMI,
PWR_SATA,
PWR_USB30,
PWR_USB20,
PWR_HDMI,
MAX,
INVALID
};
@ -37,14 +39,16 @@ namespace Regulator {
};
Regulator_name names[] = {
{ 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" },
{ CLK_CPU, "clock-cpu" },
{ CLK_SATA, "clock-sata" },
{ CLK_USB30, "clock-usb3.0" },
{ CLK_USB20, "clock-usb2.0" },
{ CLK_MMC0, "clock-mmc0" },
{ CLK_HDMI, "clock-hdmi" },
{ PWR_SATA, "power-sata" },
{ PWR_USB30, "power-usb3.0" },
{ PWR_USB20, "power-usb2.0" },
{ PWR_HDMI, "power-hdmi"},
};
Regulator_id regulator_id_by_name(const char * name)

View File

@ -187,7 +187,11 @@ class Cmu : public Regulator::Driver,
};
struct Clk_gate_ip_gscl : Register<0x10920, 32> { };
struct Clk_gate_ip_disp1 : Register<0x10928, 32> { };
struct Clk_gate_ip_disp1 : Register<0x10928, 32>
{
struct Clk_mixer : Bitfield<5, 1> { };
struct Clk_hdmi : Bitfield<6, 1> { };
};
struct Clk_gate_ip_mfc : Register<0x1092c, 32> { };
struct Clk_gate_ip_g3d : Register<0x10930, 32> { };
struct Clk_gate_ip_gen : Register<0x10934, 32> { };
@ -204,15 +208,27 @@ class Cmu : public Regulator::Driver,
struct Sata_phy_i2c : Bitfield<25, 1> { };
};
struct Clk_src_disp1_0 : Register<0x1022c, 32>
{
struct Hdmi_sel : Bitfield<20, 1> { };
};
struct Clk_src_mask_disp1_0 : Register<0x1032c, 32>
{
struct Hdmi_mask : Bitfield<20, 1> { };
};
struct Clk_gate_ip_peric : Register<0x10950, 32>
{
struct Clk_uart2 : Bitfield<2, 1> { };
struct Clk_pwm : Bitfield<24, 1> { };
struct Clk_uart2 : Bitfield<2, 1> { };
struct Clk_i2chdmi : Bitfield<14, 1> { };
struct Clk_pwm : Bitfield<24, 1> { };
};
struct Clk_gate_block : Register<0x10980, 32>
{
struct Clk_gen : Bitfield<2, 1> { };
struct Clk_disp1 : Bitfield<5, 1> { };
struct Clk_gen : Bitfield<2, 1> { };
};
@ -320,6 +336,18 @@ class Cmu : public Regulator::Driver,
** Device functions **
**********************/
void _hdmi_enable()
{
write<Clk_gate_ip_peric::Clk_i2chdmi>(1);
Clk_gate_ip_disp1::access_t gd1 = read<Clk_gate_ip_disp1>();
Clk_gate_ip_disp1::Clk_mixer::set(gd1, 1);
Clk_gate_ip_disp1::Clk_hdmi::set(gd1, 1);
write<Clk_gate_ip_disp1>(gd1);
write<Clk_gate_block::Clk_disp1>(1);
write<Clk_src_mask_disp1_0::Hdmi_mask>(1);
write<Clk_src_disp1_0::Hdmi_sel>(1);
}
void _sata_enable()
{
/* enable I2C for SATA */
@ -358,6 +386,9 @@ class Cmu : public Regulator::Driver,
case CLK_SATA:
_sata_enable();
break;
case CLK_HDMI:
_hdmi_enable();
break;
case CLK_USB30:
_usb30_enable();
break;
@ -413,7 +444,7 @@ class Cmu : public Regulator::Driver,
write<Clk_gate_ip_isp0>(0);
write<Clk_gate_ip_isp1>(0);
write<Clk_gate_sclk_isp>(0);
write<Clk_gate_ip_gscl>(0);
write<Clk_gate_ip_gscl>(0);
write<Clk_gate_ip_disp1>(0);
write<Clk_gate_ip_mfc>(0);
write<Clk_gate_ip_g3d>(0);

View File

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

View File

@ -57,7 +57,12 @@ class Pmu : public Regulator::Driver,
struct Stat : Register<OFFSET, 32>::template Bitfield<0, 1> { };
};
typedef Control<0x700> Hdmi_phy_control;
struct Hdmi_phy_control : Register<0x700, 32>
{
struct Enable : Bitfield<0, 1> { };
struct Div_ratio : Bitfield<16, 10> { };
};
typedef Control<0x704> Usbdrd_phy_control;
typedef Control<0x708> Usbhost_phy_control;
typedef Control<0x70c> Efnand_phy_control;
@ -98,6 +103,14 @@ class Pmu : public Regulator::Driver,
while (read<typename S::Stat>() != 0) ;
}
template <typename C, typename S>
void _enable_domain()
{
if (read<typename S::Stat>() == 7)
return;
write<typename C::Local_pwr_cfg>(7);
while (read<typename S::Stat>() != 7) ;
}
void _enable(unsigned long id)
{
@ -111,6 +124,13 @@ class Pmu : public Regulator::Driver,
case PWR_SATA :
write<Sata_phy_control::Enable>(1);
break;
case PWR_HDMI: {
_enable_domain<Disp1_configuration, Disp1_status>();
Hdmi_phy_control::access_t hpc = read<Hdmi_phy_control>();
Hdmi_phy_control::Div_ratio::set(hpc, 150);
Hdmi_phy_control::Enable::set(hpc, 1);
write<Hdmi_phy_control>(hpc);
break; }
default:
PWRN("Unsupported for %s", names[id].name);
}