hw: unify irq enumeration for Raspberri Pi

By now, the enumeration of peripheral interrupts on Raspberry Pi 1 was
different in between base-hw kernel and Fiasco.OC. Therefore, hacks were
needed in every driver to request the correct interrupt number dependent
on the kernel. Before reproducing the same in the platform driver for rpi,
we can more easily use the same enumeration with base-hw.

Ref #3864
This commit is contained in:
Stefan Kalkowski 2020-08-21 13:00:04 +02:00 committed by Norman Feske
parent 7ba31d4447
commit 5f5ad41ad3
11 changed files with 22 additions and 103 deletions

View File

@ -76,25 +76,16 @@ Board::Pic::Pic()
bool Board::Pic::take_request(unsigned &irq) bool Board::Pic::take_request(unsigned &irq)
{ {
/* read basic IRQ status mask */
uint32_t const p = read<Irq_pending_basic>();
/* read GPU IRQ status mask */ /* read GPU IRQ status mask */
uint32_t const p1 = read<Irq_pending_gpu_1>(), uint32_t const p1 = read<Irq_pending_gpu_1>(),
p2 = read<Irq_pending_gpu_2>(); p2 = read<Irq_pending_gpu_2>();
if (Irq_pending_basic::Timer::get(p)) {
irq = Irq_pending_basic::Timer::SHIFT;
return true;
}
/* search for lowest set bit in pending masks */ /* search for lowest set bit in pending masks */
for (unsigned i = 0; i < NR_OF_IRQ; i++) { for (unsigned i = 0; i < NR_OF_IRQ; i++) {
if (!_is_pending(i, p1, p2)) if (!_is_pending(i, p1, p2))
continue; continue;
irq = Board::GPU_IRQ_BASE + i; irq = i;
/* handle SOF interrupts locally, filter from the user land */ /* handle SOF interrupts locally, filter from the user land */
if (irq == Board::DWC_IRQ) if (irq == Board::DWC_IRQ)
@ -118,23 +109,15 @@ void Board::Pic::mask()
void Board::Pic::unmask(unsigned const i, unsigned) void Board::Pic::unmask(unsigned const i, unsigned)
{ {
if (i < 8) if (i < 32) { write<Irq_enable_gpu_1>(1 << i); }
write<Irq_enable_basic>(1 << i); else { write<Irq_enable_gpu_2>(1 << (i - 32)); }
else if (i < 32 + 8)
write<Irq_enable_gpu_1>(1 << (i - 8));
else
write<Irq_enable_gpu_2>(1 << (i - 8 - 32));
} }
void Board::Pic::mask(unsigned const i) void Board::Pic::mask(unsigned const i)
{ {
if (i < 8) if (i < 32) { write<Irq_disable_gpu_1>(1 << i); }
write<Irq_disable_basic>(1 << i); else { write<Irq_disable_gpu_2>(1 << (i - 32)); }
else if (i < 32 + 8)
write<Irq_disable_gpu_1>(1 << (i - 8));
else
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
} }

View File

@ -25,14 +25,7 @@ namespace Rpi {
MMIO_0_BASE = 0x20000000, MMIO_0_BASE = 0x20000000,
MMIO_0_SIZE = 0x02000000, MMIO_0_SIZE = 0x02000000,
/* SYSTEM_TIMER_IRQ = 1,
* IRQ numbers 0..7 refer to the basic IRQs.
* IRQ numbers 8..39 refer to GPU IRQs 0..31.
* IRQ numbers 40..71 refer to GPU IRQs 32..63.
*/
GPU_IRQ_BASE = 8,
SYSTEM_TIMER_IRQ = GPU_IRQ_BASE + 1,
SYSTEM_TIMER_MMIO_BASE = 0x20003000, SYSTEM_TIMER_MMIO_BASE = 0x20003000,
SYSTEM_TIMER_MMIO_SIZE = 0x1000, SYSTEM_TIMER_MMIO_SIZE = 0x1000,
SYSTEM_TIMER_CLOCK = 1000000, SYSTEM_TIMER_CLOCK = 1000000,
@ -56,11 +49,8 @@ namespace Rpi {
USB_DWC_OTG_BASE = 0x20980000, USB_DWC_OTG_BASE = 0x20980000,
USB_DWC_OTG_SIZE = 0x20000, USB_DWC_OTG_SIZE = 0x20000,
/* timer */
TIMER_IRQ = 0,
/* USB host controller */ /* USB host controller */
DWC_IRQ = 17, DWC_IRQ = 9,
/* SD card */ /* SD card */
SDHCI_BASE = MMIO_0_BASE + 0x300000, SDHCI_BASE = MMIO_0_BASE + 0x300000,

View File

@ -1,5 +0,0 @@
SRC_CC += dwc_irq.cc
vpath % $(REP_DIR)/src/lib/rpi_usb
CC_CXX_WARN_STRICT =

View File

@ -1,4 +1,4 @@
LIB_MK := lib/import/import-usb_include.mk lib/mk/usb_include.mk lib/mk/rpi_usb.mk \ LIB_MK := lib/import/import-usb_include.mk lib/mk/usb_include.mk \
lib/import/import-usb_arch_include.mk \ lib/import/import-usb_arch_include.mk \
$(foreach SPEC,x86_32 x86_64 arm,lib/mk/spec/$(SPEC)/lx_kit_setjmp.mk) $(foreach SPEC,x86_32 x86_64 arm,lib/mk/spec/$(SPEC)/lx_kit_setjmp.mk)
@ -6,8 +6,7 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/dde_linux)
MIRROR_FROM_REP_DIR := $(LIB_MK) \ MIRROR_FROM_REP_DIR := $(LIB_MK) \
src/drivers/usb \ src/drivers/usb \
src/include src/lx_kit \ src/include src/lx_kit
$(shell cd $(REP_DIR); find src/lib/rpi_usb -type f)
MIRROR_FROM_PORT_DIR := $(shell cd $(PORT_DIR); find src/lib/usb -type f | grep -v ".git") MIRROR_FROM_PORT_DIR := $(shell cd $(PORT_DIR); find src/lib/usb -type f | grep -v ".git")
MIRROR_FROM_PORT_DIR := $(filter-out $(MIRROR_FROM_REP_DIR),$(MIRROR_FROM_PORT_DIR)) MIRROR_FROM_PORT_DIR := $(filter-out $(MIRROR_FROM_REP_DIR),$(MIRROR_FROM_PORT_DIR))

View File

@ -28,8 +28,6 @@
using namespace Genode; using namespace Genode;
unsigned dwc_irq(Genode::Env&);
/************************************************ /************************************************
** Resource info passed to the dwc_otg driver ** ** Resource info passed to the dwc_otg driver **
@ -38,6 +36,7 @@ unsigned dwc_irq(Genode::Env&);
enum { enum {
DWC_BASE = 0x20980000, DWC_BASE = 0x20980000,
DWC_SIZE = 0x20000, DWC_SIZE = 0x20000,
DWC_IRQ = 9,
}; };
@ -155,11 +154,10 @@ extern "C" int module_smsc95xx_driver_init();
void platform_hcd_init(Env &env, Services *services) void platform_hcd_init(Env &env, Services *services)
{ {
unsigned irq = dwc_irq(env);
static resource _dwc_otg_resource[] = static resource _dwc_otg_resource[] =
{ {
{ DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM }, { DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM },
{ irq, irq, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ } { DWC_IRQ, DWC_IRQ, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ }
}; };
/* enable USB power */ /* enable USB power */

View File

@ -47,5 +47,3 @@ vpath %.c $(LX_CONTRIB_DIR)/drivers/net/usb
# enable C++11 support # enable C++11 support
CC_CXX_OPT += -std=gnu++11 CC_CXX_OPT += -std=gnu++11
LIBS += rpi_usb

View File

@ -28,8 +28,6 @@
using namespace Genode; using namespace Genode;
unsigned dwc_irq(Genode::Env&);
/************************************************ /************************************************
** Resource info passed to the dwc_otg driver ** ** Resource info passed to the dwc_otg driver **
@ -38,6 +36,7 @@ unsigned dwc_irq(Genode::Env&);
enum { enum {
DWC_BASE = 0x20980000, DWC_BASE = 0x20980000,
DWC_SIZE = 0x20000, DWC_SIZE = 0x20000,
DWC_IRQ = 9,
}; };
@ -50,11 +49,10 @@ extern bool fiq_enable, fiq_fsm_enable;
void platform_hcd_init(Genode::Env &env, Services *services) void platform_hcd_init(Genode::Env &env, Services *services)
{ {
unsigned irq = dwc_irq(env);
static resource _dwc_otg_resource[] = static resource _dwc_otg_resource[] =
{ {
{ DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM }, { DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM },
{ irq, irq, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ } { DWC_IRQ, DWC_IRQ, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ }
}; };
/* enable USB power */ /* enable USB power */

View File

@ -46,5 +46,3 @@ INC_DIR += $(LX_CONTRIB_DIR)/drivers/usb/host/dwc_common_port \
$(REP_DIR)/src/lib/usb_host/spec/arm $(REP_DIR)/src/lib/usb_host/spec/arm
vpath %.c $(LX_CONTRIB_DIR)/drivers/usb/host vpath %.c $(LX_CONTRIB_DIR)/drivers/usb/host
LIBS += rpi_usb

View File

@ -1,24 +0,0 @@
/*
* \brief USB: DWC-OTG RaspberryPI Interrupt
* \author Stefan Kalkowski
* \date 2019-04-16
*/
#include <base/attached_rom_dataspace.h>
#include <drivers/defs/rpi.h>
#include <util/string.h>
unsigned dwc_irq(Genode::Env &env)
{
using namespace Genode;
static Attached_rom_dataspace rom(env, "platform_info");
static unsigned offset = 0;
try {
String<32> kernel_name =
rom.xml().sub_node("kernel").attribute_value("name", String<32>());
if (kernel_name == "hw") offset += Rpi::GPU_IRQ_BASE;
} catch (...) { }
return offset + 9;
}

View File

@ -54,10 +54,15 @@ class Gpio::Rpi_driver : public Driver
}); });
} }
Rpi_driver(Genode::Env &env, unsigned irq_offset) void _invalid_gpio(unsigned gpio) {
Genode::error("invalid GPIO pin number ", gpio); }
public:
Rpi_driver(Genode::Env &env)
: :
_reg(env, Rpi::GPIO_CONTROLLER_BASE, 0, Rpi::GPIO_CONTROLLER_SIZE), _reg(env, Rpi::GPIO_CONTROLLER_BASE, 0, Rpi::GPIO_CONTROLLER_SIZE),
_irq(env, IRQ + irq_offset), _irq(env, IRQ),
_dispatcher(env.ep(), *this, &Rpi_driver::_handle), _dispatcher(env.ep(), *this, &Rpi_driver::_handle),
_async(false) _async(false)
{ {
@ -65,11 +70,6 @@ class Gpio::Rpi_driver : public Driver
_irq.ack_irq(); _irq.ack_irq();
} }
void _invalid_gpio(unsigned gpio) {
Genode::error("invalid GPIO pin number ", gpio); }
public:
void set_async_events(bool async) { _async = async; } void set_async_events(bool async) { _async = async; }
void set_func(unsigned gpio, Reg::Function function) void set_func(unsigned gpio, Reg::Function function)
@ -80,8 +80,6 @@ class Gpio::Rpi_driver : public Driver
_reg.set_gpio_function(gpio, function); _reg.set_gpio_function(gpio, function);
} }
static Rpi_driver& factory(Genode::Env &env);
/****************************** /******************************
** Driver interface ** ** Driver interface **

View File

@ -26,25 +26,11 @@
#include "driver.h" #include "driver.h"
Gpio::Rpi_driver& Gpio::Rpi_driver::factory(Genode::Env &env)
{
unsigned irq_offset = 0;
static Genode::Attached_rom_dataspace rom { env, "platform_info" };
try {
String<32> kernel_name =
rom.xml().sub_node("kernel").attribute_value("name", String<32>());
if (kernel_name == "hw") irq_offset += Rpi::GPU_IRQ_BASE;
} catch (...) { }
static Rpi_driver driver(env, irq_offset);
return driver;
}
struct Main struct Main
{ {
Genode::Env &env; Genode::Env &env;
Genode::Sliced_heap sliced_heap; Genode::Sliced_heap sliced_heap;
Gpio::Rpi_driver &driver; Gpio::Rpi_driver driver;
Gpio::Root root; Gpio::Root root;
Genode::Attached_rom_dataspace config_rom { env, "config" }; Genode::Attached_rom_dataspace config_rom { env, "config" };
@ -53,7 +39,7 @@ struct Main
: :
env(env), env(env),
sliced_heap(env.ram(), env.rm()), sliced_heap(env.ram(), env.rm()),
driver(Gpio::Rpi_driver::factory(env)), driver(env),
root(&env.ep().rpc_ep(), &sliced_heap, driver) root(&env.ep().rpc_ep(), &sliced_heap, driver)
{ {
using namespace Genode; using namespace Genode;