exynos: generalize Exynos5 fb_drv for Exynos4/5

Fixes #1678
This commit is contained in:
Alexy Gallardo Segura 2015-09-11 01:32:28 -04:00 committed by Christian Helmuth
parent 24b1f269be
commit 49b3d520a9
10 changed files with 128 additions and 33 deletions

View File

@ -74,6 +74,20 @@ struct Genode::Exynos5
/* SD card */ /* SD card */
SDMMC0_IRQ = 107, SDMMC0_IRQ = 107,
/******************************
** HDMI memory map and irqs **
******************************/
/* Mixer base */
MIXER_BASE = 0x14450000,
/* HDMI base */
HDMI_BASE = 0x14530000,
/* I2C BASE */
I2C_BASE = 0x12ce0000,
/* I2C */ /* I2C */
I2C_HDMI_IRQ = 96, I2C_HDMI_IRQ = 96,
}; };

View File

@ -35,11 +35,46 @@ struct Genode::Board_base : Exynos4
/* power management unit */ /* power management unit */
PMU_MMIO_BASE = 0x10020000, PMU_MMIO_BASE = 0x10020000,
PMU_MMIO_SIZE = 0x5000, /* TODO Check the region size */
PMU_MMIO_SIZE = 0x5000, /* UART */
UART_1_MMIO_BASE = 0x13810000,
UART_1_IRQ = 85,
UART_1_CLOCK = 100000000, /* TODO Check SCLK_UART1 */
/* USB HOST interrupt */ UART_2_MMIO_BASE = 0x13820000,
UART_2_IRQ = 86,
UART_2_CLOCK = 100000000, /* TODO Check SCLK_UART2 */
MCT_IRQ_L0 = 28,
MCT_IRQ_L1 = 28,
MCT_IRQ_L2 = 28,
MCT_IRQ_L3 = 28,
TIMER_IRQ = 28,
/* USB IRQ */
USB_HOST20_IRQ = 102, USB_HOST20_IRQ = 102,
/******************************
** HDMI memory map and irqs **
******************************/
/* Mixer base */
MIXER_BASE = 0x12C10000,
/* HDMI base */
HDMI_BASE = 0x12D00000,
/* IC2 BASE*/
I2C_BASE = 0x138E0000,
/* HDMI IRQ*/
I2C_HDMI_IRQ = 125,
/* wether board provides security extension */
SECURITY_EXTENSION = 0, /* TODO Check this value */
}; };
}; };

View File

@ -7,7 +7,7 @@
# #
# denote specs that are fullfilled by this spec # denote specs that are fullfilled by this spec
SPECS += exynos exynos4 cortex_a9 usb SPECS += exynos exynos4 cortex_a9 usb framebuffer
# add repository relative paths # add repository relative paths
REP_INC_DIR += include/spec/odroid_x2 REP_INC_DIR += include/spec/odroid_x2

View File

@ -417,7 +417,7 @@ class Video_mixer : public Attached_mmio
/** /**
* Constructor * Constructor
*/ */
Video_mixer() : Attached_mmio(0x14450000, 0x10000) { } Video_mixer() : Attached_mmio(Genode::Board_base::MIXER_BASE, 0x10000) { }
/** /**
* Initialize mixer for displaying one graphical input fullscreen * Initialize mixer for displaying one graphical input fullscreen
@ -520,14 +520,16 @@ class Video_mixer : public Attached_mmio
cfg = read<Cfg>(); cfg = read<Cfg>();
switch (fb_height) { switch (fb_height) {
case 480: case 480:
Cfg::Hd_sd::set(cfg, 0); Cfg::Hd_sd::set(cfg, 1);
Cfg::Hd_mode::set(cfg, 1);
break; break;
case 576: case 576:
Cfg::Hd_sd::set(cfg, 0); Cfg::Hd_sd::set(cfg, 1);
Cfg::Hd_mode::set(cfg, 1);
break; break;
case 720: case 720:
Cfg::Hd_sd::set(cfg, 1); Cfg::Hd_sd::set(cfg, 1);
Cfg::Hd_mode::set(cfg, 0); Cfg::Hd_mode::set(cfg, 1);
break; break;
case 1080: case 1080:
Cfg::Hd_sd::set(cfg, 1); Cfg::Hd_sd::set(cfg, 1);
@ -577,7 +579,7 @@ class I2c_hdmi : public I2c_interface
* Constructor * Constructor
*/ */
I2c_hdmi() I2c_hdmi()
: I2c_interface(0x12ce0000, Genode::Board_base::I2C_HDMI_IRQ) { } : I2c_interface(Genode::Board_base::I2C_BASE, Genode::Board_base::I2C_HDMI_IRQ) { }
/** /**
* Stop HDMI PHY from operating * Stop HDMI PHY from operating
@ -960,7 +962,7 @@ class Hdmi : public Attached_mmio
* Constructor * Constructor
*/ */
Hdmi() Hdmi()
: Attached_mmio(0x14530000, 0xa0000), _i2c_hdmi() { } : Attached_mmio(Genode::Board_base::HDMI_BASE, 0xa0000), _i2c_hdmi() { }
/** /**
* Initialize HDMI controller for video output only * Initialize HDMI controller for video output only

View File

@ -1,5 +1,5 @@
TARGET = fb_drv TARGET = fb_drv
REQUIRES = exynos5 REQUIRES = exynos
SRC_CC += main.cc driver.cc SRC_CC += main.cc driver.cc
LIBS += base config server LIBS += base config server
INC_DIR += $(PRG_DIR) INC_DIR += $(PRG_DIR)

View File

@ -136,23 +136,14 @@ class Cmu : public Regulator::Driver,
typedef Pll_lock<0x0008> Mpll_lock; typedef Pll_lock<0x0008> Mpll_lock;
typedef Pll_con0<0x0108> Mpll_con0; typedef Pll_con0<0x0108> Mpll_con0;
struct Clk_src_dmc : Register<0x10200, 32>
{
struct Mux_mpll_sel : Bitfield<12, 1> { enum { XXTI, MPLL_FOUT_RGT }; };
};
struct Clk_gate_ip_acp : Register<0x0900, 32> { };
struct Clk_gate_ip_isp0 : Register<0x8800, 32> { };
struct Clk_gate_ip_isp1 : Register<0x8804, 32> { };
/*********************** /***********************
** CMU TOP registers ** ** CMU TOP registers **
***********************/ ***********************/
struct Clk_gate_ip_tv : Register<0x10928, 32>
{
struct Clk_mixer : Bitfield<1, 1> { };
struct Clk_hdmi : Bitfield<3, 1> { };
};
struct Clk_gate_ip_fsys : Register<0xC940, 32> struct Clk_gate_ip_fsys : Register<0xC940, 32>
{ {
@ -161,7 +152,27 @@ class Cmu : public Regulator::Driver,
}; };
struct Clk_src_tv : Register<0xC224, 32> /* old name Clk_src_disp1_0 */
{
struct Hdmi_sel : Bitfield<0, 1> { };
};
struct Clk_src_mask_tv : Register<0xC324, 32>
{
struct Hdmi_mask : Bitfield<0, 1> { };
};
struct Clk_gate_ip_peric : Register<0xC950, 32>
{
struct Clk_uart2 : Bitfield<2, 1> { };
struct Clk_i2chdmi : Bitfield<14, 1> { };
struct Clk_pwm : Bitfield<24, 1> { };
};
struct Clk_gate_block : Register<0xC970, 32>
{
struct Clk_tv : Bitfield<1, 1> { };
};
/******************* /*******************
** CPU functions ** ** CPU functions **
@ -245,6 +256,25 @@ class Cmu : public Regulator::Driver,
} }
/**********************
** Device functions **
**********************/
void _hdmi_enable()
{
write<Clk_gate_ip_peric::Clk_i2chdmi>(1);
Clk_gate_ip_tv::access_t gd1 = read<Clk_gate_ip_tv>();
Clk_gate_ip_tv::Clk_mixer::set(gd1, 1);
Clk_gate_ip_tv::Clk_hdmi::set(gd1, 1);
write<Clk_gate_ip_tv>(gd1);
write<Clk_gate_block::Clk_tv>(1);
write<Clk_src_mask_tv::Hdmi_mask>(1);
write<Clk_src_tv::Hdmi_sel>(1);
}
void _enable(Regulator_id id) void _enable(Regulator_id id)
{ {
switch (id) { switch (id) {
@ -253,6 +283,10 @@ class Cmu : public Regulator::Driver,
write<Clk_gate_ip_fsys::Usbdevice>(1); write<Clk_gate_ip_fsys::Usbdevice>(1);
return write<Clk_gate_ip_fsys::Usbhost20>(1); return write<Clk_gate_ip_fsys::Usbhost20>(1);
} }
case CLK_HDMI:
_hdmi_enable();
break;
default: default:
PWRN("Unsupported for %s", names[id].name); PWRN("Unsupported for %s", names[id].name);
} }
@ -281,23 +315,19 @@ class Cmu : public Regulator::Driver,
Genode::Board_base::CMU_MMIO_SIZE), Genode::Board_base::CMU_MMIO_SIZE),
_cpu_freq(CPU_FREQ_1400) _cpu_freq(CPU_FREQ_1400)
{ {
/** /**
* Close certain clock gates by default (~ 0.7 Watt reduction) * Close certain clock gates by default (~ 0.7 Watt reduction)
*/ */
write<Clk_gate_ip_fsys>(0); write<Clk_gate_ip_fsys>(0);
write<Clk_gate_ip_peric::Clk_uart2>(1);
write<Clk_gate_ip_peric::Clk_pwm>(1);
/** /**
* Set default CPU frequency * Set default CPU frequency
*/ */
_cpu_clk_freq(_cpu_freq); _cpu_clk_freq(_cpu_freq);
} }
/******************************** /********************************
** Regulator driver interface ** ** Regulator driver interface **
********************************/ ********************************/
@ -334,7 +364,6 @@ class Cmu : public Regulator::Driver,
bool state(Regulator_id id) bool state(Regulator_id id)
{ {
switch (id) { switch (id) {
case CLK_USB20: case CLK_USB20:
return read<Clk_gate_ip_fsys::Usbhost20>(); return read<Clk_gate_ip_fsys::Usbhost20>();

View File

@ -32,9 +32,14 @@ struct Driver_factory: Regulator::Driver_factory
switch (id) { switch (id) {
case Regulator::CLK_CPU: case Regulator::CLK_CPU:
case Regulator::CLK_USB20: case Regulator::CLK_USB20:
case Regulator::CLK_HDMI:
return _cmu; return _cmu;
case Regulator::PWR_USB20: case Regulator::PWR_USB20:
case Regulator::PWR_HDMI:
return _pmu; return _pmu;
default: default:
throw Root::Invalid_args(); /* invalid regulator */ throw Root::Invalid_args(); /* invalid regulator */
}; };

View File

@ -69,7 +69,6 @@ class Pmu : public Regulator::Driver,
typedef Control<0x0708> Usbhost_phy1_control; typedef Control<0x0708> Usbhost_phy1_control;
typedef Control<0x70c> Usbhost_phy2_control; typedef Control<0x70c> Usbhost_phy2_control;
void _enable(unsigned long id) void _enable(unsigned long id)
{ {
switch (id) { switch (id) {
@ -78,6 +77,13 @@ class Pmu : public Regulator::Driver,
write<Usbhost_phy1_control::Enable>(1); write<Usbhost_phy1_control::Enable>(1);
write<Usbhost_phy2_control::Enable>(1); write<Usbhost_phy2_control::Enable>(1);
break; break;
case PWR_HDMI: {
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: default:
PWRN("Unsupported for %s", names[id].name); PWRN("Unsupported for %s", names[id].name);
} }
@ -91,6 +97,9 @@ class Pmu : public Regulator::Driver,
write<Usbhost_phy1_control::Enable>(0); write<Usbhost_phy1_control::Enable>(0);
write<Usbhost_phy2_control::Enable>(0); write<Usbhost_phy2_control::Enable>(0);
break; break;
case PWR_HDMI:
write<Hdmi_phy_control::Enable>(0);
break;
default: default:
PWRN("Unsupported for %s", names[id].name); PWRN("Unsupported for %s", names[id].name);
} }
@ -104,9 +113,10 @@ class Pmu : public Regulator::Driver,
Pmu() : Genode::Attached_mmio(Genode::Board_base::PMU_MMIO_BASE, Pmu() : Genode::Attached_mmio(Genode::Board_base::PMU_MMIO_BASE,
Genode::Board_base::PMU_MMIO_SIZE) Genode::Board_base::PMU_MMIO_SIZE)
{ {
write<Usbdrd_phy_control ::Enable>(0); write<Usbdrd_phy_control::Enable>(0);
write<Usbhost_phy1_control::Enable>(0); write<Usbhost_phy1_control::Enable>(0);
write<Usbhost_phy2_control::Enable>(0); write<Usbhost_phy2_control::Enable>(0);
write<Hdmi_phy_control::Enable>(0);
} }