mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
parent
aa004cf211
commit
55cfa22ac9
@ -13,22 +13,22 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <root/component.h>
|
||||
#include <os/ring_buffer.h>
|
||||
#include <os/static_root.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* device configuration */
|
||||
#include <pl11x_defs.h>
|
||||
#include <sp810_defs.h>
|
||||
#include <video_memory.h>
|
||||
|
||||
|
||||
/***********************************************
|
||||
@ -52,181 +52,164 @@ namespace Framebuffer
|
||||
FRAMEBUFFER_SIZE = SCR_WIDTH*SCR_HEIGHT*BYTES_PER_PIXEL,
|
||||
};
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
class Session_component;
|
||||
|
||||
Genode::Dataspace_capability _fb_ds_cap;
|
||||
Genode::Dataspace_client _fb_ds;
|
||||
Genode::addr_t _regs_base;
|
||||
Genode::addr_t _sys_regs_base;
|
||||
Timer::Connection _timer;
|
||||
using namespace Genode;
|
||||
class Main;
|
||||
}
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Bit definitions of the lcd control register
|
||||
*/
|
||||
CTRL_ENABLED = 1 << 0,
|
||||
CTRL_BPP16 = 4 << 1,
|
||||
CTRL_BPP16_565 = 6 << 1,
|
||||
CTRL_TFT = 1 << 5,
|
||||
CTRL_BGR = 1 << 8,
|
||||
CTRL_POWER = 1 << 11,
|
||||
CTRL_VCOMP = 1 << 12,
|
||||
class Framebuffer::Session_component : public Genode::Rpc_object<Framebuffer::Session>
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Bit definitions for CLCDC timing.
|
||||
*/
|
||||
CLCDC_IVS = 1 << 11,
|
||||
CLCDC_IHS = 1 << 12,
|
||||
CLCDC_BCD = 1 << 26,
|
||||
};
|
||||
Genode::Dataspace_capability _fb_ds_cap;
|
||||
Genode::Dataspace_client _fb_ds;
|
||||
Genode::addr_t _regs_base;
|
||||
Genode::addr_t _sys_regs_base;
|
||||
Timer::Connection _timer;
|
||||
|
||||
void sys_reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_sys_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
long sys_reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_sys_regs_base + sizeof(long)*reg); }
|
||||
|
||||
void reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
long reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_regs_base + sizeof(long)*reg); }
|
||||
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* Bit definitions of the lcd control register
|
||||
*/
|
||||
CTRL_ENABLED = 1 << 0,
|
||||
CTRL_BPP16 = 4 << 1,
|
||||
CTRL_BPP16_565 = 6 << 1,
|
||||
CTRL_TFT = 1 << 5,
|
||||
CTRL_BGR = 1 << 8,
|
||||
CTRL_POWER = 1 << 11,
|
||||
CTRL_VCOMP = 1 << 12,
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Bit definitions for CLCDC timing.
|
||||
*/
|
||||
Session_component(void *regs_base, void *sys_regs_base,
|
||||
Genode::Dataspace_capability fb_ds_cap)
|
||||
: _fb_ds_cap(fb_ds_cap), _fb_ds(_fb_ds_cap),
|
||||
_regs_base((Genode::addr_t)regs_base),
|
||||
_sys_regs_base((Genode::addr_t)sys_regs_base)
|
||||
{
|
||||
using namespace Genode;
|
||||
CLCDC_IVS = 1 << 11,
|
||||
CLCDC_IHS = 1 << 12,
|
||||
CLCDC_BCD = 1 << 26,
|
||||
};
|
||||
|
||||
uint32_t tim0 = (SCR_WIDTH/16 - 1) << 2
|
||||
| (HSYNC_LEN - 1) << 8
|
||||
| (RIGHT_MARGIN - 1) << 16
|
||||
| (LEFT_MARGIN - 1) << 24;
|
||||
uint32_t tim1 = (SCR_HEIGHT - 1)
|
||||
| (VSYNC_LEN - 1) << 10
|
||||
| LOWER_MARGIN << 16
|
||||
| UPPER_MARGIN << 24;
|
||||
uint32_t tim2 = ((SCR_WIDTH - 1) << 16)
|
||||
| CLCDC_IVS | CLCDC_IHS | CLCDC_BCD;
|
||||
uint32_t tim3 = 0;
|
||||
uint32_t ctrl = reg_read(PL11X_REG_CTRL);
|
||||
void sys_reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_sys_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
/* reset video if already enabled */
|
||||
if (ctrl & CTRL_POWER) {
|
||||
ctrl &= ~CTRL_POWER;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
}
|
||||
if (ctrl & CTRL_ENABLED) {
|
||||
ctrl &= ~CTRL_ENABLED;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
}
|
||||
long sys_reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_sys_regs_base + sizeof(long)*reg); }
|
||||
|
||||
ctrl = CTRL_BGR | CTRL_ENABLED | CTRL_TFT | CTRL_VCOMP | CTRL_BPP16_565;
|
||||
void reg_write(unsigned reg, long value) {
|
||||
*(volatile long *)(_regs_base + sizeof(long)*reg) = value; }
|
||||
|
||||
/* init color-lcd oscillator */
|
||||
sys_reg_write(SP810_REG_LOCK, 0xa05f);
|
||||
sys_reg_write(SP810_REG_OSCCLCD, 0x2c77);
|
||||
sys_reg_write(SP810_REG_LOCK, 0);
|
||||
long reg_read(unsigned reg) {
|
||||
return *(volatile long *)(_regs_base + sizeof(long)*reg); }
|
||||
|
||||
/* init video timing */
|
||||
reg_write(PL11X_REG_TIMING0, tim0);
|
||||
reg_write(PL11X_REG_TIMING1, tim1);
|
||||
reg_write(PL11X_REG_TIMING2, tim2);
|
||||
reg_write(PL11X_REG_TIMING3, tim3);
|
||||
public:
|
||||
|
||||
/* set framebuffer address and ctrl register */
|
||||
reg_write(PL11X_REG_UPBASE, _fb_ds.phys_addr());
|
||||
reg_write(PL11X_REG_LPBASE, 0);
|
||||
reg_write(PL11X_REG_IMSC, 0);
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Genode::Env &env,
|
||||
void *regs_base, void *sys_regs_base,
|
||||
Genode::Dataspace_capability fb_ds_cap)
|
||||
: _fb_ds_cap(fb_ds_cap), _fb_ds(_fb_ds_cap),
|
||||
_regs_base((Genode::addr_t)regs_base),
|
||||
_sys_regs_base((Genode::addr_t)sys_regs_base),
|
||||
_timer(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
uint32_t tim0 = (SCR_WIDTH/16 - 1) << 2
|
||||
| (HSYNC_LEN - 1) << 8
|
||||
| (RIGHT_MARGIN - 1) << 16
|
||||
| (LEFT_MARGIN - 1) << 24;
|
||||
uint32_t tim1 = (SCR_HEIGHT - 1)
|
||||
| (VSYNC_LEN - 1) << 10
|
||||
| LOWER_MARGIN << 16
|
||||
| UPPER_MARGIN << 24;
|
||||
uint32_t tim2 = ((SCR_WIDTH - 1) << 16)
|
||||
| CLCDC_IVS | CLCDC_IHS | CLCDC_BCD;
|
||||
uint32_t tim3 = 0;
|
||||
uint32_t ctrl = reg_read(PL11X_REG_CTRL);
|
||||
|
||||
/* reset video if already enabled */
|
||||
if (ctrl & CTRL_POWER) {
|
||||
ctrl &= ~CTRL_POWER;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
}
|
||||
if (ctrl & CTRL_ENABLED) {
|
||||
ctrl &= ~CTRL_ENABLED;
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
|
||||
/* power on */
|
||||
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability dataspace() override { return _fb_ds_cap; }
|
||||
ctrl = CTRL_BGR | CTRL_ENABLED | CTRL_TFT | CTRL_VCOMP | CTRL_BPP16_565;
|
||||
|
||||
Mode mode() const override { return Mode(SCR_WIDTH, SCR_HEIGHT, Mode::RGB565); }
|
||||
/* init color-lcd oscillator */
|
||||
sys_reg_write(SP810_REG_LOCK, 0xa05f);
|
||||
sys_reg_write(SP810_REG_OSCCLCD, 0x2c77);
|
||||
sys_reg_write(SP810_REG_LOCK, 0);
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
/* init video timing */
|
||||
reg_write(PL11X_REG_TIMING0, tim0);
|
||||
reg_write(PL11X_REG_TIMING1, tim1);
|
||||
reg_write(PL11X_REG_TIMING2, tim2);
|
||||
reg_write(PL11X_REG_TIMING3, tim3);
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
/* set framebuffer address and ctrl register */
|
||||
reg_write(PL11X_REG_UPBASE, _fb_ds.phys_addr());
|
||||
reg_write(PL11X_REG_LPBASE, 0);
|
||||
reg_write(PL11X_REG_IMSC, 0);
|
||||
reg_write(PL11X_REG_CTRL, ctrl);
|
||||
_timer.msleep(100);
|
||||
|
||||
void refresh(int x, int y, int w, int h) override { }
|
||||
};
|
||||
/* power on */
|
||||
reg_write(PL11X_REG_CTRL, ctrl | CTRL_POWER);
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability dataspace() override { return _fb_ds_cap; }
|
||||
|
||||
Mode mode() const override { return Mode(SCR_WIDTH, SCR_HEIGHT, Mode::RGB565); }
|
||||
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
void sync_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_timer.sigh(sigh);
|
||||
_timer.trigger_periodic(10*1000);
|
||||
}
|
||||
|
||||
void refresh(int x, int y, int w, int h) override { }
|
||||
};
|
||||
|
||||
|
||||
class Root : public Genode::Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
void *_lcd_regs_base;
|
||||
void *_sys_regs_base;
|
||||
Genode::Dataspace_capability _fb_ds_cap;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args) override {
|
||||
return new (md_alloc()) Session_component(_lcd_regs_base,
|
||||
_sys_regs_base,
|
||||
_fb_ds_cap); }
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Rpc_entrypoint *session_ep, Genode::Allocator *md_alloc,
|
||||
void *lcd_regs_base, void *sys_regs_base,
|
||||
Genode::Dataspace_capability fb_ds_cap)
|
||||
: Genode::Root_component<Session_component>(session_ep, md_alloc),
|
||||
_lcd_regs_base(lcd_regs_base), _sys_regs_base(sys_regs_base),
|
||||
_fb_ds_cap(fb_ds_cap) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main(int, char **)
|
||||
struct Framebuffer::Main
|
||||
{
|
||||
printf("--- pl11x framebuffer driver ---\n");
|
||||
Env &_env;
|
||||
Entrypoint &_ep;
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
/* locally map LCD control registers */
|
||||
Io_mem_connection lcd_io_mem(PL11X_LCD_PHYS, PL11X_LCD_SIZE);
|
||||
void *lcd_base = env()->rm_session()->attach(lcd_io_mem.dataspace());
|
||||
Io_mem_connection _lcd_io_mem { _env, PL11X_LCD_PHYS, PL11X_LCD_SIZE };
|
||||
void * _lcd_base { _env.rm().attach(_lcd_io_mem.dataspace()) };
|
||||
|
||||
/* locally map system control registers */
|
||||
Io_mem_connection sys_mem(SP810_PHYS, SP810_SIZE);
|
||||
void *sys_base = env()->rm_session()->attach(sys_mem.dataspace());
|
||||
Io_mem_connection _sys_mem { SP810_PHYS, SP810_SIZE };
|
||||
void * _sys_base { _env.rm().attach(_sys_mem.dataspace()) };
|
||||
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "fb_ep");
|
||||
Dataspace_capability _fb_ds_cap { _env.ram().alloc(Framebuffer::FRAMEBUFFER_SIZE) };
|
||||
Session_component _fb_session { _env, _lcd_base, _sys_base, _fb_ds_cap };
|
||||
Static_root<Session> _fb_root { _ep.manage(_fb_session) };
|
||||
|
||||
Dataspace_capability fb_ds_cap =
|
||||
Framebuffer::alloc_video_memory(Framebuffer::FRAMEBUFFER_SIZE);
|
||||
Main(Env &env) : _env(env), _ep(_env.ep())
|
||||
{
|
||||
log("--- pl11x framebuffer driver ---\n");
|
||||
|
||||
/*
|
||||
* Let the entry point serve the framebuffer and input root interfaces
|
||||
*/
|
||||
static Framebuffer::Root fb_root(&ep, env()->heap(), lcd_base, sys_base, fb_ds_cap);
|
||||
env()->parent()->announce(ep.manage(&fb_root));
|
||||
/* announce service */
|
||||
_env.parent().announce(_ep.manage(_fb_root));
|
||||
}
|
||||
};
|
||||
|
||||
sleep_forever();
|
||||
|
||||
return 0;
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Framebuffer::Main main(env);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = fb_drv
|
||||
REQUIRES = pl11x pbxa9
|
||||
SRC_CC = main.cc video_memory.cc
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* \brief PL11x video memory function for platform baseboard cortex-A9.
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-11-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
|
||||
#include <pl11x_defs.h>
|
||||
#include <video_memory.h>
|
||||
|
||||
Genode::Dataspace_capability Framebuffer::alloc_video_memory(Genode::size_t sz) {
|
||||
return Genode::env()->ram_session()->alloc(sz);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* \brief Video memory allocator.
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-11-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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__VIDEOMEM_ALLOCATOR_H_
|
||||
#define _INCLUDE__VIDEOMEM_ALLOCATOR_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
namespace Framebuffer {
|
||||
|
||||
Genode::Dataspace_capability alloc_video_memory(Genode::size_t size);
|
||||
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__VIDEOMEM_ALLOCATOR_H_ */
|
Loading…
Reference in New Issue
Block a user