Implement platform driver for i.MX53 platform

Move clock and reset controller functionality out of framebuffer driver
into platform driver.
This commit is contained in:
Stefan Kalkowski 2013-04-29 14:53:49 +02:00 committed by Norman Feske
parent d2f5deaf33
commit 4fe158a320
14 changed files with 434 additions and 123 deletions

View File

@ -46,6 +46,9 @@ namespace Genode
AIPS_1_MMIO_BASE = 0x53f00000,
AIPS_2_MMIO_BASE = 0x63f00000,
IOMUXC_BASE = 0x53fa8000,
IOMUXC_SIZE = 0x00004000,
IPU_ERR_IRQ = 10,
IPU_SYNC_IRQ = 11,
IPU_BASE = 0x18000000,

View File

@ -0,0 +1,22 @@
/*
* \brief Platform session capability type
* \author Stefan Kalkowski
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__CAPABILITY_H_
#define _INCLUDE__PLATFORM_SESSION__CAPABILITY_H_
#include <base/capability.h>
#include <platform_session/platform_session.h>
namespace Platform { typedef Genode::Capability<Session> Session_capability; }
#endif /* _INCLUDE__PLATFORM_SESSION__CAPABILITY_H_ */

View File

@ -0,0 +1,35 @@
/*
* \brief i.MX53 specific platform session client side
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__CLIENT_H_
#define _INCLUDE__PLATFORM_SESSION__CLIENT_H_
#include <base/capability.h>
#include <base/rpc.h>
#include <platform_session/platform_session.h>
namespace Platform {
struct Client : Genode::Rpc_client<Session>
{
explicit Client(Capability<Session> session)
: Genode::Rpc_client<Session>(session) { }
void enable(Device dev) { call<Rpc_enable>(dev); }
void disable(Device dev) { call<Rpc_disable>(dev); }
void clock_rate(Device dev, unsigned long rate) {
call<Rpc_clock_rate>(dev, rate); }
};
}
#endif /* _INCLUDE__PLATFORM_SESSION__CLIENT_H_ */

View File

@ -0,0 +1,37 @@
/*
* \brief Connection to platform service
* \author Stefan Kalkowski
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__CONNECTION_H_
#define _INCLUDE__PLATFORM_SESSION__CONNECTION_H_
#include <platform_session/client.h>
#include <util/arg_string.h>
#include <base/connection.h>
namespace Platform {
class Connection : public Genode::Connection<Session>,
public Client
{
public:
/**
* Constructor
*/
Connection()
: Genode::Connection<Session>(session("ram_quota=4K")),
Client(cap()) { }
};
}
#endif /* _INCLUDE__PLATFORM_SESSION__CONNECTION_H_ */

View File

@ -0,0 +1,47 @@
/*
* \brief i.MX53 specific platform session
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_
#define _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_
#include <base/capability.h>
#include <base/rpc.h>
namespace Platform {
struct Session : Genode::Session
{
enum Device { IPU };
static const char *service_name() { return "Platform"; }
virtual ~Session() { }
virtual void enable(Device dev) = 0;
virtual void disable(Device dev) = 0;
virtual void clock_rate(Device dev, unsigned long rate) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_enable, void, enable, Device);
GENODE_RPC(Rpc_disable, void, disable, Device);
GENODE_RPC(Rpc_clock_rate, void, clock_rate, Device, unsigned long);
GENODE_RPC_INTERFACE(Rpc_enable, Rpc_disable, Rpc_clock_rate);
};
}
#endif /* _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_ */

View File

@ -10,8 +10,9 @@ set build_components {
drivers/framebuffer drivers/pci drivers/input
}
lappend_if [have_spec usb] build_components drivers/usb
lappend_if [have_spec gpio] build_components drivers/gpio
lappend_if [have_spec usb] build_components drivers/usb
lappend_if [have_spec gpio] build_components drivers/gpio
lappend_if [have_spec imx53] build_components drivers/platform
build $build_components
@ -68,6 +69,14 @@ append_if [have_spec gpio] config {
<config/>
</start>}
append_if [have_spec imx53] config {
<start name="platform_drv">
<resource name="RAM" quantum="1M"/>
<provides><service name="Platform"/></provides>
<config/>
</start>
}
append_if [have_spec ps2] config {
<start name="ps2_drv">
<resource name="RAM" quantum="1M"/>
@ -116,6 +125,7 @@ lappend_if [have_spec ps2] boot_modules ps2_drv
lappend_if [have_spec framebuffer] boot_modules fb_drv
lappend_if [have_spec usb] boot_modules usb_drv
lappend_if [have_spec gpio] boot_modules gpio_drv
lappend_if [have_spec imx53] boot_modules platform_drv
build_boot_image $boot_modules

View File

@ -1,67 +0,0 @@
/*
* \brief Clock control module
* \author Nikolay Golikov <nik@ksyslabs.org>
* \date 2012-10-09
*/
/*
* Copyright (C) 2012 Ksys Labs LLC
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CCM_H_
#define _CCM_H_
/* Genode includes */
#include <util/mmio.h>
struct Ccm : Genode::Mmio
{
enum { IPU_CLK = 133000000 };
/**
* Control divider register
*/
struct Ccdr : Register<0x4, 32>
{
struct Ipu_hs_mask : Bitfield <21, 1> { };
};
/**
* Low power control register
*/
struct Clpcr : Register<0x54, 32>
{
struct Bypass_ipu_hs : Bitfield<18, 1> { };
};
/**
*
*/
struct Cccr5 : Register<0x7c, 32>
{
struct Ipu_clk_en : Bitfield<10, 2> { };
};
void ipu_clk_enable(void)
{
write<Cccr5::Ipu_clk_en>(3);
write<Ccdr::Ipu_hs_mask>(0);
write<Clpcr::Bypass_ipu_hs>(0);
}
void ipu_clk_disable(void)
{
write<Cccr5::Ipu_clk_en>(0);
write<Ccdr::Ipu_hs_mask>(1);
write<Clpcr::Bypass_ipu_hs>(1);
}
Ccm(Genode::addr_t const mmio_base) : Genode::Mmio(mmio_base) { }
};
#endif /* _CCM_H_ */

View File

@ -9,12 +9,11 @@
#include <os/attached_io_mem_dataspace.h>
#include <io_mem_session/connection.h>
#include <gpio_session/connection.h>
#include <platform_session/connection.h>
#include <util/mmio.h>
/* local includes */
#include <ipu.h>
#include <src.h>
#include <ccm.h>
namespace Framebuffer {
@ -27,18 +26,9 @@ class Framebuffer::Driver
{
private:
/* Clocks control module */
Attached_io_mem_dataspace _ccm_mmio;
Ccm _ccm;
/* System reset controller registers */
Attached_io_mem_dataspace _src_mmio;
Src _src;
/* Image processing unit memory */
Attached_io_mem_dataspace _ipu_mmio;
Platform::Connection _platform;
Attached_io_mem_dataspace _ipu_mmio; /* Image processing unit memory */
Ipu _ipu;
Gpio::Connection _gpio;
public:
@ -64,19 +54,13 @@ class Framebuffer::Driver
Driver()
: _ccm_mmio(Board_base::CCM_BASE, Board_base::CCM_SIZE),
_ccm((addr_t)_ccm_mmio.local_addr<void>()),
_src_mmio(Board_base::SRC_BASE, Board_base::SRC_SIZE),
_src((addr_t)_src_mmio.local_addr<void>()),
_ipu_mmio(Board_base::IPU_BASE, Board_base::IPU_SIZE),
: _ipu_mmio(Board_base::IPU_BASE, Board_base::IPU_SIZE),
_ipu((addr_t)_ipu_mmio.local_addr<void>()) { }
bool init(addr_t phys_base)
{
/* reset ipu over src */
_src.write<Src::Ctrl_reg::Ipu_rst>(1);
_ccm.ipu_clk_enable();
/* enable IPU via platform driver */
_platform.enable(Platform::Session::IPU);
_ipu.init(WIDTH, HEIGHT, WIDTH * BYTES_PER_PIXEL, phys_base);
@ -85,6 +69,5 @@ class Framebuffer::Driver
_gpio.direction_output(LCD_CONT_GPIO, true);
return true;
}
};

View File

@ -1,31 +0,0 @@
/*
* \brief System reset controller registers
* \author Nikolay Golikov <nik@ksyslabs.org>
* \date 2012-11-06
*/
/*
* Copyright (C) 2012 Ksys Labs LLC
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SRC_H_
#define _SRC_H_
/* Genode includes */
#include <util/mmio.h>
struct Src : Genode::Mmio
{
Src(Genode::addr_t const mmio_base) : Genode::Mmio(mmio_base) { }
struct Ctrl_reg : Register<0x0, 32>
{
struct Ipu_rst : Bitfield<3, 1> { };
};
};
#endif /* _SRC_H_ */

View File

@ -0,0 +1,71 @@
/*
* \brief Clock control module register description
* \author Nikolay Golikov <nik@ksyslabs.org>
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DRIVERS__PLATFORM__IMX53__CCM_H_
#define _DRIVERS__PLATFORM__IMX53__CCM_H_
/* Genode includes */
#include <util/mmio.h>
#include <drivers/board_base.h>
#include <os/attached_io_mem_dataspace.h>
class Ccm : public Genode::Attached_io_mem_dataspace,
Genode::Mmio
{
private:
/**
* Control divider register
*/
struct Ccdr : Register<0x4, 32>
{
struct Ipu_hs_mask : Bitfield <21, 1> { };
};
/**
* Low power control register
*/
struct Clpcr : Register<0x54, 32>
{
struct Bypass_ipu_hs : Bitfield<18, 1> { };
};
struct Cccr5 : Register<0x7c, 32>
{
struct Ipu_clk_en : Bitfield<10, 2> { };
};
public:
Ccm()
: Genode::Attached_io_mem_dataspace(Genode::Board_base::CCM_BASE,
Genode::Board_base::CCM_SIZE),
Genode::Mmio((Genode::addr_t)local_addr<void>()) {}
void ipu_clk_enable(void)
{
write<Cccr5::Ipu_clk_en>(3);
write<Ccdr::Ipu_hs_mask>(0);
write<Clpcr::Bypass_ipu_hs>(0);
}
void ipu_clk_disable(void)
{
write<Cccr5::Ipu_clk_en>(0);
write<Ccdr::Ipu_hs_mask>(1);
write<Clpcr::Bypass_ipu_hs>(1);
}
};
#endif /* _DRIVERS__PLATFORM__IMX53__CCM_H_ */

View File

@ -0,0 +1,33 @@
/*
* \brief IOMUX controller register description
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DRIVERS__PLATFORM__IMX53__IOMUX_H_
#define _DRIVERS__PLATFORM__IMX53__IOMUX_H_
/* Genode includes */
#include <util/mmio.h>
#include <drivers/board_base.h>
#include <os/attached_io_mem_dataspace.h>
class Iomux : public Genode::Attached_io_mem_dataspace,
Genode::Mmio
{
public:
Iomux()
: Genode::Attached_io_mem_dataspace(Genode::Board_base::IOMUXC_BASE,
Genode::Board_base::IOMUXC_SIZE),
Genode::Mmio((Genode::addr_t)local_addr<void>()) {}
};
#endif /* _DRIVERS__PLATFORM__IMX53__IOMUX_H_ */

View File

@ -0,0 +1,120 @@
/*
* \brief Driver for i.MX53 specific platform devices (clocks, power, etc.)
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/sleep.h>
#include <base/rpc_server.h>
#include <cap_session/connection.h>
#include <root/component.h>
#include <platform_session/platform_session.h>
#include <iomux.h>
#include <ccm.h>
#include <src.h>
namespace Platform {
class Session_component;
class Root;
}
class Platform::Session_component : public Genode::Rpc_object<Platform::Session>
{
private:
Iomux &_iomux; /* I/O multiplexer device */
Ccm &_ccm; /* clock control module */
Src &_src; /* system reset controller */
public:
/**
* Constructor
*/
Session_component(Iomux &iomux, Ccm &ccm, Src &src)
: _iomux(iomux), _ccm(ccm), _src(src) {}
/**********************************
** Platform session interface **
**********************************/
void enable(Device dev)
{
switch (dev) {
case Session::IPU:
_src.reset_ipu();
_ccm.ipu_clk_enable();
break;
default:
PWRN("Invalid device");
};
}
void disable(Device dev)
{
switch (dev) {
case Session::IPU:
_ccm.ipu_clk_disable();
break;
default:
PWRN("Invalid device");
};
}
void clock_rate(Device dev, unsigned long rate)
{
switch (dev) {
default:
PWRN("Invalid device");
};
}
};
class Platform::Root : public Genode::Root_component<Platform::Session_component>
{
private:
Iomux _iomux;
Ccm _ccm;
Src _src;
protected:
Session_component *_create_session(const char *args) {
return new (md_alloc()) Session_component(_iomux, _ccm, _src); }
public:
Root(Genode::Rpc_entrypoint *session_ep,
Genode::Allocator *md_alloc)
: Genode::Root_component<Session_component>(session_ep, md_alloc) { }
};
int main(int, char **)
{
using namespace Genode;
PINF("--- i.MX53 platform driver ---\n");
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, 4096, "imx53_plat_ep");
static Platform::Root plat_root(&ep, env()->heap());
env()->parent()->announce(ep.manage(&plat_root));
sleep_forever();
return 0;
}

View File

@ -0,0 +1,43 @@
/*
* \brief System reset controller register description
* \author Nikolay Golikov <nik@ksyslabs.org>
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2013-04-29
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DRIVERS__PLATFORM__IMX53__SRC_H_
#define _DRIVERS__PLATFORM__IMX53__SRC_H_
/* Genode includes */
#include <util/mmio.h>
#include <drivers/board_base.h>
#include <os/attached_io_mem_dataspace.h>
class Src : public Genode::Attached_io_mem_dataspace,
Genode::Mmio
{
private:
struct Ctrl_reg : Register<0x0, 32>
{
struct Ipu_rst : Bitfield<3, 1> { };
};
public:
Src()
: Genode::Attached_io_mem_dataspace(Genode::Board_base::SRC_BASE,
Genode::Board_base::SRC_SIZE),
Genode::Mmio((Genode::addr_t)local_addr<void>()) {}
void reset_ipu() { write<Ctrl_reg::Ipu_rst>(1); }
};
#endif /* _DRIVERS__PLATFORM__IMX53__SRC_H_ */

View File

@ -0,0 +1,5 @@
TARGET = platform_drv
REQUIRES = imx53
SRC_CC = main.cc
INC_DIR += ${PRG_DIR}
LIBS = base