From 92b31717651768c1400df86fffd8eac5f3866a7b Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 8 Oct 2013 18:04:45 +0200 Subject: [PATCH] platform_drv & exynos5: provide HDMI switches ref #796 --- .../platform/arndale/regulator/consts.h | 20 +++++---- os/src/drivers/platform/arndale/cmu.h | 41 ++++++++++++++++--- os/src/drivers/platform/arndale/main.cc | 2 + os/src/drivers/platform/arndale/pmu.h | 22 +++++++++- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/os/include/platform/arndale/regulator/consts.h b/os/include/platform/arndale/regulator/consts.h index 4e8af4d29..26231e327 100644 --- a/os/include/platform/arndale/regulator/consts.h +++ b/os/include/platform/arndale/regulator/consts.h @@ -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) diff --git a/os/src/drivers/platform/arndale/cmu.h b/os/src/drivers/platform/arndale/cmu.h index b8d84a3cb..d0a914f51 100644 --- a/os/src/drivers/platform/arndale/cmu.h +++ b/os/src/drivers/platform/arndale/cmu.h @@ -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(1); + Clk_gate_ip_disp1::access_t gd1 = read(); + Clk_gate_ip_disp1::Clk_mixer::set(gd1, 1); + Clk_gate_ip_disp1::Clk_hdmi::set(gd1, 1); + write(gd1); + write(1); + write(1); + write(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(0); write(0); write(0); - write(0); + write(0); write(0); write(0); write(0); diff --git a/os/src/drivers/platform/arndale/main.cc b/os/src/drivers/platform/arndale/main.cc index 8f3b08d16..3b5bc5570 100644 --- a/os/src/drivers/platform/arndale/main.cc +++ b/os/src/drivers/platform/arndale/main.cc @@ -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 */ diff --git a/os/src/drivers/platform/arndale/pmu.h b/os/src/drivers/platform/arndale/pmu.h index 7f82b30e3..f724642ee 100644 --- a/os/src/drivers/platform/arndale/pmu.h +++ b/os/src/drivers/platform/arndale/pmu.h @@ -57,7 +57,12 @@ class Pmu : public Regulator::Driver, struct Stat : Register::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() != 0) ; } + template + void _enable_domain() + { + if (read() == 7) + return; + write(7); + while (read() != 7) ; + } void _enable(unsigned long id) { @@ -111,6 +124,13 @@ class Pmu : public Regulator::Driver, case PWR_SATA : write(1); break; + case PWR_HDMI: { + _enable_domain(); + Hdmi_phy_control::access_t hpc = read(); + Hdmi_phy_control::Div_ratio::set(hpc, 150); + Hdmi_phy_control::Enable::set(hpc, 1); + write(hpc); + break; } default: PWRN("Unsupported for %s", names[id].name); }