Commit 02c19243 authored by Kevin Hilman's avatar Kevin Hilman

Merge ../../omap/pristine

parents 5cc90896 0af779e2
...@@ -84,11 +84,10 @@ config MACH_OMAP_PALMTE ...@@ -84,11 +84,10 @@ config MACH_OMAP_PALMTE
bool "Palm Tungsten E" bool "Palm Tungsten E"
depends on ARCH_OMAP1 && ARCH_OMAP15XX depends on ARCH_OMAP1 && ARCH_OMAP15XX
help help
Support for the Palm Tungsten E PDA. Currently only the LCD panel Support for the Palm Tungsten E PDA. To boot the kernel, you'll
is supported. To boot the kernel, you'll need a PalmOS compatible need a PalmOS compatible bootloader; check out
bootloader; check out http://palmtelinux.sourceforge.net for more http://palmtelinux.sourceforge.net/ for more information.
informations. Say Y here if you have this PDA model, say N otherwise.
Say Y here if you have such a PDA, say NO otherwise.
config MACH_NOKIA770 config MACH_NOKIA770
bool "Nokia 770" bool "Nokia 770"
...@@ -179,5 +178,3 @@ config OMAP_ARM_30MHZ ...@@ -179,5 +178,3 @@ config OMAP_ARM_30MHZ
help help
Enable 30MHz clock for OMAP CPU. If unsure, say N. Enable 30MHz clock for OMAP CPU. If unsure, say N.
source "arch/arm/plat-omap/dsp/Kconfig"
...@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MPU_TIMER) += time.o ...@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PM) += pm.o sleep.o
# DSP
obj-$(CONFIG_OMAP_DSP) += mailbox.o
led-y := leds.o led-y := leds.o
# Specific board support # Specific board support
...@@ -37,4 +40,3 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o ...@@ -37,4 +40,3 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
obj-$(CONFIG_LEDS) += $(led-y) obj-$(CONFIG_LEDS) += $(led-y)
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <asm/arch/aic23.h> #include <asm/arch/aic23.h>
#include <asm/arch/gpio.h> #include <asm/arch/gpio.h>
#include "../plat-omap/dsp/dsp_common.h"
static void __init omap_nokia770_init_irq(void) static void __init omap_nokia770_init_irq(void)
{ {
/* On Nokia 770, the SleepX signal is masked with an /* On Nokia 770, the SleepX signal is masked with an
...@@ -149,6 +151,7 @@ static struct omap_board_config_kernel nokia770_config[] = { ...@@ -149,6 +151,7 @@ static struct omap_board_config_kernel nokia770_config[] = {
{ OMAP_TAG_MMC, &nokia770_mmc_config }, { OMAP_TAG_MMC, &nokia770_mmc_config },
}; };
#if defined(CONFIG_OMAP_DSP)
/* /*
* audio power control * audio power control
*/ */
...@@ -209,7 +212,8 @@ static void nokia770_audio_pwr_down(void) ...@@ -209,7 +212,8 @@ static void nokia770_audio_pwr_down(void)
schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */ schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
} }
void nokia770_audio_pwr_up_request(int stage) static int
nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage)
{ {
down(&audio_pwr_sem); down(&audio_pwr_sem);
if (audio_pwr_state == -1) if (audio_pwr_state == -1)
...@@ -217,9 +221,11 @@ void nokia770_audio_pwr_up_request(int stage) ...@@ -217,9 +221,11 @@ void nokia770_audio_pwr_up_request(int stage)
/* force audio_pwr_state = 0, even if it was 1. */ /* force audio_pwr_state = 0, even if it was 1. */
audio_pwr_state = 0; audio_pwr_state = 0;
up(&audio_pwr_sem); up(&audio_pwr_sem);
return 0;
} }
void nokia770_audio_pwr_down_request(int stage) static int
nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
{ {
down(&audio_pwr_sem); down(&audio_pwr_sem);
switch (stage) { switch (stage) {
...@@ -235,7 +241,38 @@ void nokia770_audio_pwr_down_request(int stage) ...@@ -235,7 +241,38 @@ void nokia770_audio_pwr_down_request(int stage)
break; break;
} }
up(&audio_pwr_sem); up(&audio_pwr_sem);
return 0;
}
static struct dsp_kfunc_device nokia770_audio_device = {
.name = "audio",
.type = DSP_KFUNC_DEV_TYPE_AUDIO,
.enable = nokia770_audio_pwr_up_request,
.disable = nokia770_audio_pwr_down_request,
};
static __init int omap_dsp_init(void)
{
int ret;
dspxor_ck = clk_get(0, "dspxor_ck");
if (IS_ERR(dspxor_ck)) {
printk(KERN_ERR "couldn't acquire dspxor_ck\n");
return PTR_ERR(dspxor_ck);
}
ret = dsp_kfunc_device_register(&nokia770_audio_device);
if (ret) {
printk(KERN_ERR
"KFUNC device registration faild: %s\n",
nokia770_audio_device.name);
goto out;
}
return 0;
out:
return ret;
} }
#endif /* CONFIG_OMAP_DSP */
static void __init omap_nokia770_init(void) static void __init omap_nokia770_init(void)
{ {
...@@ -247,9 +284,7 @@ static void __init omap_nokia770_init(void) ...@@ -247,9 +284,7 @@ static void __init omap_nokia770_init(void)
omap_board_config = nokia770_config; omap_board_config = nokia770_config;
omap_board_config_size = ARRAY_SIZE(nokia770_config); omap_board_config_size = ARRAY_SIZE(nokia770_config);
omap_serial_init(); omap_serial_init();
omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request; omap_dsp_init();
omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
dspxor_ck = clk_get(0, "dspxor_ck");
} }
static void __init omap_nokia770_map_io(void) static void __init omap_nokia770_map_io(void)
......
...@@ -17,27 +17,117 @@ ...@@ -17,27 +17,117 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/input.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/notifier.h> #include <linux/mtd/mtd.h>
#include <linux/clk.h> #include <linux/mtd/partitions.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/arch/gpio.h> #include <asm/arch/gpio.h>
#include <asm/arch/mux.h> #include <asm/arch/mux.h>
#include <asm/arch/usb.h> #include <asm/arch/usb.h>
#include <asm/arch/tc.h>
#include <asm/arch/dma.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
#include <asm/arch/irda.h>
#include <asm/arch/keypad.h>
#include <asm/arch/common.h> #include <asm/arch/common.h>
static void __init omap_generic_init_irq(void) static void __init omap_palmte_init_irq(void)
{ {
omap1_init_common_hw(); omap1_init_common_hw();
omap_init_irq(); omap_init_irq();
omap_gpio_init();
} }
static int palmte_keymap[] = {
KEY(0, 0, KEY_F1),
KEY(0, 1, KEY_F2),
KEY(0, 2, KEY_F3),
KEY(0, 3, KEY_F4),
KEY(0, 4, KEY_POWER),
KEY(1, 0, KEY_LEFT),
KEY(1, 1, KEY_DOWN),
KEY(1, 2, KEY_UP),
KEY(1, 3, KEY_RIGHT),
KEY(1, 4, KEY_CENTER),
0,
};
static struct omap_kp_platform_data palmte_kp_data = {
.rows = 8,
.cols = 8,
.keymap = palmte_keymap,
.rep = 1,
};
static struct resource palmte_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
.end = INT_KEYBOARD,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device palmte_kp_device = {
.name = "omap-keypad",
.id = -1,
.dev = {
.platform_data = &palmte_kp_data,
},
.num_resources = ARRAY_SIZE(palmte_kp_resources),
.resource = palmte_kp_resources,
};
static struct mtd_partition palmte_rom_partitions[] = {
/* PalmOS "Small ROM", contains the bootloader and the debugger */
{
.name = "smallrom",
.offset = 0,
.size = 0xa000,
.mask_flags = MTD_WRITEABLE,
},
/* PalmOS "Big ROM", a filesystem with all the OS code and data */
{
.name = "bigrom",
.offset = SZ_128K,
/*
* 0x5f0000 bytes big in the multi-language ("EFIGS") version,
* 0x7b0000 bytes in the English-only ("enUS") version.
*/
.size = 0x7b0000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct flash_platform_data palmte_rom_data = {
.map_name = "map_rom",
.width = 2,
.parts = palmte_rom_partitions,
.nr_parts = ARRAY_SIZE(palmte_rom_partitions),
};
static struct resource palmte_rom_resource = {
.start = OMAP_CS0_PHYS,
.end = OMAP_CS0_PHYS + SZ_8M - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device palmte_rom_device = {
.name = "omapflash",
.id = -1,
.dev = {
.platform_data = &palmte_rom_data,
},
.num_resources = 1,
.resource = &palmte_rom_resource,
};
static struct platform_device palmte_lcd_device = { static struct platform_device palmte_lcd_device = {
.name = "lcd_palmte", .name = "lcd_palmte",
.id = -1, .id = -1,
...@@ -55,24 +145,54 @@ static struct platform_device palmte_backlight_device = { ...@@ -55,24 +145,54 @@ static struct platform_device palmte_backlight_device = {
}, },
}; };
static struct omap_irda_config palmte_irda_config = {
.transceiver_cap = IR_SIRMODE,
.rx_channel = OMAP_DMA_UART3_RX,
.tx_channel = OMAP_DMA_UART3_TX,
.dest_start = UART3_THR,
.src_start = UART3_RHR,
.tx_trigger = 0,
.rx_trigger = 0,
};
static struct resource palmte_irda_resources[] = {
[0] = {
.start = INT_UART3,
.end = INT_UART3,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device palmte_irda_device = {
.name = "omapirda",
.id = -1,
.dev = {
.platform_data = &palmte_irda_config,
},
.num_resources = ARRAY_SIZE(palmte_irda_resources),
.resource = palmte_irda_resources,
};
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&palmte_rom_device,
&palmte_kp_device,
&palmte_lcd_device, &palmte_lcd_device,
&palmte_backlight_device, &palmte_backlight_device,
&palmte_irda_device,
}; };
static struct omap_usb_config palmte_usb_config __initdata = { static struct omap_usb_config palmte_usb_config __initdata = {
.register_dev = 1, .register_dev = 1, /* Mini-B only receptacle */
.hmc_mode = 0, .hmc_mode = 0,
.pins[0] = 3, .pins[0] = 2,
}; };
static struct omap_mmc_config palmte_mmc_config __initdata = { static struct omap_mmc_config palmte_mmc_config __initdata = {
.mmc [0] = { .mmc[0] = {
.enabled = 1, .enabled = 1,
.wire4 = 1, .wp_pin = PALMTE_MMC_WP_GPIO,
.wp_pin = OMAP_MPUIO(3), .power_pin = PALMTE_MMC_POWER_GPIO,
.power_pin = -1, .switch_pin = PALMTE_MMC_SWITCH_GPIO,
.switch_pin = -1,
}, },
}; };
...@@ -80,21 +200,99 @@ static struct omap_lcd_config palmte_lcd_config __initdata = { ...@@ -80,21 +200,99 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
.ctrl_name = "internal", .ctrl_name = "internal",
}; };
static struct omap_uart_config palmte_uart_config __initdata = {
.enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
};
static struct omap_board_config_kernel palmte_config[] = { static struct omap_board_config_kernel palmte_config[] = {
{ OMAP_TAG_USB, &palmte_usb_config }, { OMAP_TAG_USB, &palmte_usb_config },
{ OMAP_TAG_MMC, &palmte_mmc_config }, { OMAP_TAG_MMC, &palmte_mmc_config },
{ OMAP_TAG_LCD, &palmte_lcd_config }, { OMAP_TAG_LCD, &palmte_lcd_config },
{ OMAP_TAG_UART, &palmte_uart_config },
}; };
static void __init omap_generic_init(void) /* Periodically check for changes on important input pins */
struct timer_list palmte_pin_timer;
int prev_power, prev_headphones;
static void palmte_pin_handler(unsigned long data) {
int power, headphones;
power = !omap_get_gpio_datain(PALMTE_DC_GPIO);
headphones = omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO);
if (power && !prev_power)
printk(KERN_INFO "PM: cable connected\n");
else if (!power && prev_power)
printk(KERN_INFO "PM: cable disconnected\n");
if (headphones && !prev_headphones) {
/* Headphones connected, disable speaker */
omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 0);
printk(KERN_INFO "PM: speaker off\n");
} else if (!headphones && prev_headphones) {
/* Headphones unplugged, re-enable speaker */
omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 1);
printk(KERN_INFO "PM: speaker on\n");
}
prev_power = power;
prev_headphones = headphones;
mod_timer(&palmte_pin_timer, jiffies + msecs_to_jiffies(500));
}
static void __init palmte_gpio_setup(void)
{
/* Set TSC2102 PINTDAV pin as input */
if (omap_request_gpio(PALMTE_PINTDAV_GPIO)) {
printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
return;
}
omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1);
/* Monitor cable-connected signals */
if (omap_request_gpio(PALMTE_DC_GPIO) ||
omap_request_gpio(PALMTE_USB_OR_DC_GPIO) ||
omap_request_gpio(PALMTE_USBDETECT_GPIO)) {
printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
return;
}
omap_set_gpio_direction(PALMTE_DC_GPIO, 1);
omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO, 1);
omap_set_gpio_direction(PALMTE_USBDETECT_GPIO, 1);
/* Set speaker-enable pin as output */
if (omap_request_gpio(PALMTE_SPEAKER_GPIO)) {
printk(KERN_ERR "Could not reserve speaker GPIO!\n");
return;
}
omap_set_gpio_direction(PALMTE_SPEAKER_GPIO, 0);
/* Monitor the headphones-connected signal */
if (omap_request_gpio(PALMTE_HEADPHONES_GPIO)) {
printk(KERN_ERR "Could not reserve headphones signal GPIO!\n");
return;
}
omap_set_gpio_direction(PALMTE_HEADPHONES_GPIO, 1);
prev_power = omap_get_gpio_datain(PALMTE_DC_GPIO);
prev_headphones = !omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO);
setup_timer(&palmte_pin_timer, palmte_pin_handler, 0);
palmte_pin_handler(0);
}
static void __init omap_palmte_init(void)
{ {
omap_board_config = palmte_config; omap_board_config = palmte_config;
omap_board_config_size = ARRAY_SIZE(palmte_config); omap_board_config_size = ARRAY_SIZE(palmte_config);
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
omap_serial_init();
palmte_gpio_setup();
} }
static void __init omap_generic_map_io(void) static void __init omap_palmte_map_io(void)
{ {
omap1_map_common_io(); omap1_map_common_io();
} }
...@@ -103,8 +301,8 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") ...@@ -103,8 +301,8 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
.phys_io = 0xfff00000, .phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100, .boot_params = 0x10000100,
.map_io = omap_generic_map_io, .map_io = omap_palmte_map_io,
.init_irq = omap_generic_init_irq, .init_irq = omap_palmte_init_irq,
.init_machine = omap_generic_init, .init_machine = omap_palmte_init,
.timer = &omap_timer, .timer = &omap_timer,
MACHINE_END MACHINE_END
...@@ -496,7 +496,7 @@ static int omap1_clk_enable_generic(struct clk *clk) ...@@ -496,7 +496,7 @@ static int omap1_clk_enable_generic(struct clk *clk)
} }
} }
return 0; return;
} }
static void omap1_clk_disable_generic(struct clk *clk) static void omap1_clk_disable_generic(struct clk *clk)
...@@ -630,8 +630,6 @@ static void __init omap1_clk_disable_unused(struct clk *clk) ...@@ -630,8 +630,6 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
clk->disable(clk); clk->disable(clk);
printk(" done\n"); printk(" done\n");
return 0;
} }
#else #else
...@@ -656,6 +654,7 @@ int __init omap1_clk_init(void) ...@@ -656,6 +654,7 @@ int __init omap1_clk_init(void)
/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
reg = omap_readw(SOFT_REQ_REG) & (1 << 4); reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
omap_writew(reg, SOFT_REQ_REG); omap_writew(reg, SOFT_REQ_REG);
if (!cpu_is_omap15xx())
omap_writew(0, SOFT_REQ_REG2); omap_writew(0, SOFT_REQ_REG2);
clk_init(&omap1_clk_functions); clk_init(&omap1_clk_functions);
......
...@@ -61,6 +61,45 @@ static void omap_init_rtc(void) ...@@ -61,6 +61,45 @@ static void omap_init_rtc(void)
static inline void omap_init_rtc(void) {} static inline void omap_init_rtc(void) {}
#endif #endif
#if defined(CONFIG_OMAP_DSP)
#if defined(CONFIG_ARCH_OMAP1510)
# define OMAP1_MBOX_SIZE 0x23
# define INT_DSP_MAILBOX1 INT_1510_DSP_MAILBOX1
#elif defined(CONFIG_ARCH_OMAP16XX)
# define OMAP1_MBOX_SIZE 0x2f
# define INT_DSP_MAILBOX1 INT_1610_DSP_MAILBOX1
#endif
#define OMAP1_MBOX_BASE IO_ADDRESS(OMAP16XX_MAILBOX_BASE)
static struct resource mbox_resources[] = {
{
.start = OMAP1_MBOX_BASE,
.end = OMAP1_MBOX_BASE + OMAP1_MBOX_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_DSP_MAILBOX1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mbox_device = {
.name = "mailbox",
.id = -1,
.num_resources = ARRAY_SIZE(mbox_resources),
.resource = mbox_resources,
};
static inline void omap_init_mbox(void)
{
platform_device_register(&mbox_device);
}
#else
static inline void omap_init_mbox(void) { }
#endif
#if defined(CONFIG_OMAP_STI) #if defined(CONFIG_OMAP_STI)
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
...@@ -125,6 +164,8 @@ static int __init omap1_init_devices(void) ...@@ -125,6 +164,8 @@ static int __init omap1_init_devices(void)
/* please keep these calls, and their implementations above, /* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through. * in alphabetical order so they're easier to sort through.
*/ */
omap_init_mbox();
omap_init_rtc(); omap_init_rtc();
omap_init_sti(); omap_init_sti();
......
...@@ -238,7 +238,7 @@ void __init omap_init_irq(void) ...@@ -238,7 +238,7 @@ void __init omap_init_irq(void)
if (cpu_is_omap730()) if (cpu_is_omap730())
omap_unmask_irq(INT_730_IH2_IRQ); omap_unmask_irq(INT_730_IH2_IRQ);
else if (cpu_is_omap1510()) else if (cpu_is_omap15xx())
omap_unmask_irq(INT_1510_IH2_IRQ); omap_unmask_irq(INT_1510_IH2_IRQ);
else if (cpu_is_omap16xx()) else if (cpu_is_omap16xx())
omap_unmask_irq(INT_1610_IH2_IRQ); omap_unmask_irq(INT_1610_IH2_IRQ);
......
/*
* Mailbox reservation modules for DSP
*
* Copyright (C) 2006 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/resource.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/arch/mailbox.h>
#include <asm/arch/irqs.h>
#include <asm/io.h>
#define MAILBOX_ARM2DSP1 0x00
#define MAILBOX_ARM2DSP1b 0x04
#define MAILBOX_DSP2ARM1 0x08
#define MAILBOX_DSP2ARM1b 0x0c
#define MAILBOX_DSP2ARM2 0x10
#define MAILBOX_DSP2ARM2b 0x14
#define MAILBOX_ARM2DSP1_Flag 0x18
#define MAILBOX_DSP2ARM1_Flag 0x1c
#define MAILBOX_DSP2ARM2_Flag 0x20
unsigned long mbox_base;
struct omap_mbox1_fifo {
unsigned long cmd;
unsigned long data;
unsigned long flag;
};
struct omap_mbox1_priv {
struct omap_mbox1_fifo tx_fifo;
struct omap_mbox1_fifo rx_fifo;
};
static inline int mbox_read_reg(unsigned int reg)
{
return __raw_readw(mbox_base + reg);
}
static inline void mbox_write_reg(unsigned int val, unsigned int reg)
{
__raw_writew(val, mbox_base + reg);
}
/* msg */
static inline mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
{
struct omap_mbox1_fifo *fifo =
&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
mbox_msg_t msg;
msg = mbox_read_reg(fifo->data);
msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
return msg;
}
static inline void
omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
{
struct omap_mbox1_fifo *fifo =
&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
mbox_write_reg(msg & 0xffff, fifo->data);
mbox_write_reg(msg >> 16, fifo->cmd);
}
static inline int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
{
return 0;
}
static inline int omap1_mbox_fifo_full(struct omap_mbox *mbox)
{
struct omap_mbox1_fifo *fifo =
&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
return (mbox_read_reg(fifo->flag));
}
/* irq */
static inline void
omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
if (irq == IRQ_RX)
enable_irq(mbox->irq);
}
static inline void
omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
if (irq == IRQ_RX)
disable_irq(mbox->irq);
}
static inline int
omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
if (irq == IRQ_TX)
return 0;
return 1;
}
struct omap_mbox_ops omap1_mbox_ops = {
.fifo_read = omap1_mbox_fifo_read,
.fifo_write = omap1_mbox_fifo_write,
.fifo_empty = omap1_mbox_fifo_empty,
.fifo_full = omap1_mbox_fifo_full,
.enable_irq = omap1_mbox_enable_irq,
.disable_irq = omap1_mbox_disable_irq,
.is_irq = omap1_mbox_is_irq,
};
/* FIXME: the following struct should be created automatically by the user id */
/* DSP */
static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
.tx_fifo = {
.cmd = MAILBOX_ARM2DSP1b,
.data = MAILBOX_ARM2DSP1,
.flag = MAILBOX_ARM2DSP1_Flag,
},
.rx_fifo = {
.cmd = MAILBOX_DSP2ARM1b,
.data = MAILBOX_DSP2ARM1,
.flag = MAILBOX_DSP2ARM1_Flag,
},
};
struct omap_mbox mbox_dsp_info = {
.name = "DSP",
.ops = &omap1_mbox_ops,
.priv = &omap1_mbox_dsp_priv,
};
static int __init omap1_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0;
if (pdev->num_resources != 2) {
dev_err(&pdev->dev, "invalid number of resources: %d\n",
pdev->num_resources);
return -ENODEV;
}
/* MBOX base */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid mem resource\n");
return -ENODEV;
}
mbox_base = res->start;
/* DSP IRQ */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
return -ENODEV;
}
mbox_dsp_info.irq = res->start;
ret = omap_mbox_register(&mbox_dsp_info);
return ret;
}
static int omap1_mbox_remove(struct platform_device *pdev)
{
omap_mbox_unregister(&mbox_dsp_info);
return 0;
}
static struct platform_driver omap1_mbox_driver = {
.probe = omap1_mbox_probe,
.remove = omap1_mbox_remove,
.driver = {
.name = "mailbox",
},
};
static int __init omap1_mbox_init(void)
{
return platform_driver_register(&omap1_mbox_driver);
}
static void __exit omap1_mbox_exit(void)
{
platform_driver_unregister(&omap1_mbox_driver);
}
module_init(omap1_mbox_init);
module_exit(omap1_mbox_exit);
MODULE_LICENSE("GPL");
...@@ -256,6 +256,7 @@ void omap_pm_suspend(void) ...@@ -256,6 +256,7 @@ void omap_pm_suspend(void)
tps65010_set_led(LED1, OFF); tps65010_set_led(LED1, OFF);
} }
if (!cpu_is_omap15xx())
omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
/* /*
...@@ -434,6 +435,7 @@ void omap_pm_suspend(void) ...@@ -434,6 +435,7 @@ void omap_pm_suspend(void)
MPUI1610_RESTORE(OMAP_IH2_3_MIR); MPUI1610_RESTORE(OMAP_IH2_3_MIR);
} }
if (!cpu_is_omap15xx())
omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
/* /*
......
...@@ -11,8 +11,10 @@ obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o ...@@ -11,8 +11,10 @@ obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
# DSP
obj-$(CONFIG_OMAP_DSP) += mailbox.o
# Specific board support # Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "memory.h" #include "memory.h"
#include "clock.h" #include "clock.h"
#undef DEBUG
//#define DOWN_VARIABLE_DPLL 1 /* Experimental */ //#define DOWN_VARIABLE_DPLL 1 /* Experimental */
static struct prcm_config *curr_prcm_set; static struct prcm_config *curr_prcm_set;
...@@ -81,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk) ...@@ -81,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk)
propagate_rate(clk); propagate_rate(clk);
} }
static void omap2_set_osc_ck(int enable)
{
if (enable)
PRCM_CLKSRC_CTRL &= ~(0x3 << 3);
else
PRCM_CLKSRC_CTRL |= 0x3 << 3;
}
/* Enable an APLL if off */ /* Enable an APLL if off */
static void omap2_clk_fixed_enable(struct clk *clk) static void omap2_clk_fixed_enable(struct clk *clk)
{ {
...@@ -106,9 +116,51 @@ static void omap2_clk_fixed_enable(struct clk *clk) ...@@ -106,9 +116,51 @@ static void omap2_clk_fixed_enable(struct clk *clk)
while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */ while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */
++i; ++i;
udelay(1); udelay(1);
if (i == 100000) if (i == 100000) {
printk(KERN_ERR "Clock %s didn't lock\n", clk->name);
break;
}
}
}
static void omap2_clk_wait_ready(struct clk *clk)
{
unsigned long reg, other_reg, st_reg;
u32 bit;
int i;
reg = (unsigned long) clk->enable_reg;
if (reg == (unsigned long) &CM_FCLKEN1_CORE ||
reg == (unsigned long) &CM_FCLKEN2_CORE)
other_reg = (reg & ~0xf0) | 0x10;
else if (reg == (unsigned long) &CM_ICLKEN1_CORE ||
reg == (unsigned long) &CM_ICLKEN2_CORE)
other_reg = (reg & ~0xf0) | 0x00;
else
return;
/* No check for DSS or cam clocks */
if ((reg & 0x0f) == 0) {
if (clk->enable_bit <= 1 || clk->enable_bit == 31)
return;
}
/* Check if both functional and interface clocks
* are running. */
bit = 1 << clk->enable_bit;
if (!(__raw_readl(other_reg) & bit))
return;
st_reg = (other_reg & ~0xf0) | 0x20;
i = 0;
while (!(__raw_readl(st_reg) & bit)) {
i++;
if (i == 100000) {
printk(KERN_ERR "Timeout enabling clock %s\n", clk->name);
break; break;
} }
}
if (i)
pr_debug("Clock %s stable after %d loops\n", clk->name, i);
} }
/* Enables clock without considering parent dependencies or use count /* Enables clock without considering parent dependencies or use count
...@@ -121,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk) ...@@ -121,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk)
if (clk->flags & ALWAYS_ENABLED) if (clk->flags & ALWAYS_ENABLED)
return 0; return 0;
if (unlikely(clk == &osc_ck)) {
omap2_set_osc_ck(1);
return 0;
}
if (unlikely(clk->enable_reg == 0)) { if (unlikely(clk->enable_reg == 0)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n", printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name); clk->name);
...@@ -137,6 +194,8 @@ static int _omap2_clk_enable(struct clk * clk) ...@@ -137,6 +194,8 @@ static int _omap2_clk_enable(struct clk * clk)
__raw_writel(regval32, clk->enable_reg); __raw_writel(regval32, clk->enable_reg);
wmb(); wmb();
omap2_clk_wait_ready(clk);
return 0; return 0;
} }
...@@ -158,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk) ...@@ -158,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk)
{ {
u32 regval32; u32 regval32;
if (unlikely(clk == &osc_ck)) {
omap2_set_osc_ck(0);
return;
}
if (clk->enable_reg == 0) if (clk->enable_reg == 0)
return; return;
...@@ -1094,6 +1158,12 @@ int __init omap2_clk_init(void) ...@@ -1094,6 +1158,12 @@ int __init omap2_clk_init(void)
*/ */
clk_enable(&sync_32k_ick); clk_enable(&sync_32k_ick);
clk_enable(&omapctrl_ick); clk_enable(&omapctrl_ick);
/* Force the APLLs always active. The clocks are idled
* automatically by hardware. */
clk_enable(&apll96_ck);
clk_enable(&apll54_ck);
if (cpu_is_omap2430()) if (cpu_is_omap2430())
clk_enable(&sdrc_ick); clk_enable(&sdrc_ick);
......
...@@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ ...@@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
.name = "osc_ck", .name = "osc_ck",
.rate = 26000000, /* fixed up in clock init */ .rate = 26000000, /* fixed up in clock init */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, RATE_FIXED | RATE_PROPAGATES,
}; };
/* With out modem likely 12MHz, with modem likely 13MHz */ /* With out modem likely 12MHz, with modem likely 13MHz */
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -67,6 +66,40 @@ static void omap_init_i2c(void) {} ...@@ -67,6 +66,40 @@ static void omap_init_i2c(void) {}
#endif #endif
#if defined(CONFIG_OMAP_DSP)
#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
static struct resource mbox_resources[] = {
{
.start = OMAP2_MBOX_BASE,
.end = OMAP2_MBOX_BASE + 0x11f,
.flags = IORESOURCE_MEM,
},
{
.start = INT_24XX_MAIL_U0_MPU,
.flags = IORESOURCE_IRQ,
},
{
.start = INT_24XX_MAIL_U3_MPU,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device mbox_device = {
.name = "mailbox",
.id = -1,
.num_resources = ARRAY_SIZE(mbox_resources),
.resource = mbox_resources,
};
static inline void omap_init_mbox(void)
{
platform_device_register(&mbox_device);
}
#else
static inline void omap_init_mbox(void) { }
#endif
#if defined(CONFIG_OMAP_STI) #if defined(CONFIG_OMAP_STI)
#define OMAP2_STI_BASE IO_ADDRESS(0x48068000) #define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
...@@ -174,10 +207,10 @@ static int __init omap2_init_devices(void) ...@@ -174,10 +207,10 @@ static int __init omap2_init_devices(void)
* in alphabetical order so they're easier to sort through. * in alphabetical order so they're easier to sort through.
*/ */
omap_init_i2c(); omap_init_i2c();
omap_init_mbox();
omap_init_mcspi(); omap_init_mcspi();
omap_init_sti(); omap_init_sti();
return 0; return 0;
} }
arch_initcall(omap2_init_devices); arch_initcall(omap2_init_devices);
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
extern void omap_sram_init(void); extern void omap_sram_init(void);
extern int omap2_clk_init(void); extern int omap2_clk_init(void);
extern void omap2_check_revision(void); extern void omap2_check_revision(void);
extern void omap2_init_memory(void);
extern void gpmc_init(void); extern void gpmc_init(void);
/* /*
...@@ -44,6 +45,24 @@ static struct map_desc omap2_io_desc[] __initdata = { ...@@ -44,6 +45,24 @@ static struct map_desc omap2_io_desc[] __initdata = {
.pfn = __phys_to_pfn(L4_24XX_PHYS), .pfn = __phys_to_pfn(L4_24XX_PHYS),
.length = L4_24XX_SIZE, .length = L4_24XX_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
},
{
.virtual = DSP_MEM_24XX_VIRT,
.pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
.length = DSP_MEM_24XX_SIZE,
.type = MT_DEVICE
},
{
.virtual = DSP_IPI_24XX_VIRT,
.pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS),
.length = DSP_IPI_24XX_SIZE,
.type = MT_DEVICE
},
{
.virtual = DSP_MMU_24XX_VIRT,
.pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS),
.length = DSP_MMU_24XX_SIZE,
.type = MT_DEVICE
} }
}; };
...@@ -67,5 +86,6 @@ void __init omap2_init_common_hw(void) ...@@ -67,5 +86,6 @@ void __init omap2_init_common_hw(void)
{ {
omap2_mux_init(); omap2_mux_init();
omap2_clk_init(); omap2_clk_init();
omap2_init_memory();
gpmc_init(); gpmc_init();
} }
...@@ -37,7 +37,7 @@ static struct omap_irq_bank { ...@@ -37,7 +37,7 @@ static struct omap_irq_bank {
} __attribute__ ((aligned(4))) irq_banks[] = { } __attribute__ ((aligned(4))) irq_banks[] = {
{ {
/* MPU INTC */ /* MPU INTC */
.base_reg = OMAP24XX_IC_BASE, .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE),
.nr_irqs = 96, .nr_irqs = 96,
}, { }, {
/* XXX: DSP INTC */ /* XXX: DSP INTC */
...@@ -47,7 +47,7 @@ static struct omap_irq_bank { ...@@ -47,7 +47,7 @@ static struct omap_irq_bank {
/* XXX: FIQ and additional INTC support (only MPU at the moment) */ /* XXX: FIQ and additional INTC support (only MPU at the moment) */
static void omap_ack_irq(unsigned int irq) static void omap_ack_irq(unsigned int irq)
{ {
omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
} }
static void omap_mask_irq(unsigned int irq) static void omap_mask_irq(unsigned int irq)
...@@ -60,7 +60,7 @@ static void omap_mask_irq(unsigned int irq) ...@@ -60,7 +60,7 @@ static void omap_mask_irq(unsigned int irq)
irq %= 32; irq %= 32;
} }
omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
} }
static void omap_unmask_irq(unsigned int irq) static void omap_unmask_irq(unsigned int irq)
...@@ -73,7 +73,7 @@ static void omap_unmask_irq(unsigned int irq) ...@@ -73,7 +73,7 @@ static void omap_unmask_irq(unsigned int irq)
irq %= 32; irq %= 32;
} }
omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
} }
static void omap_mask_ack_irq(unsigned int irq) static void omap_mask_ack_irq(unsigned int irq)
...@@ -93,17 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) ...@@ -93,17 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
{ {
unsigned long tmp; unsigned long tmp;
tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff; tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff;
printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx " printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
"(revision %ld.%ld) with %d interrupts\n", "(revision %ld.%ld) with %d interrupts\n",
bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG); tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG);
tmp |= 1 << 1; /* soft reset */ tmp |= 1 << 1; /* soft reset */
omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG); __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
/* Wait for reset to complete */; /* Wait for reset to complete */;
/* Enable autoidle */
__raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG);
} }
void __init omap_init_irq(void) void __init omap_init_irq(void)
......
/*
* Mailbox reservation modules for OMAP2
*
* Copyright (C) 2006 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
* and Paul Mundt <paul.mundt@nokia.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <asm/arch/mailbox.h>
#include <asm/arch/irqs.h>
#include <asm/io.h>
#define MAILBOX_REVISION 0x00
#define MAILBOX_SYSCONFIG 0x10
#define MAILBOX_SYSSTATUS 0x14
#define MAILBOX_MESSAGE_0 0x40
#define MAILBOX_MESSAGE_1 0x44
#define MAILBOX_MESSAGE_2 0x48
#define MAILBOX_MESSAGE_3 0x4c
#define MAILBOX_MESSAGE_4 0x50
#define MAILBOX_MESSAGE_5 0x54
#define MAILBOX_FIFOSTATUS_0 0x80
#define MAILBOX_FIFOSTATUS_1 0x84
#define MAILBOX_FIFOSTATUS_2 0x88
#define MAILBOX_FIFOSTATUS_3 0x8c
#define MAILBOX_FIFOSTATUS_4 0x90
#define MAILBOX_FIFOSTATUS_5 0x94
#define MAILBOX_MSGSTATUS_0 0xc0
#define MAILBOX_MSGSTATUS_1 0xc4
#define MAILBOX_MSGSTATUS_2 0xc8
#define MAILBOX_MSGSTATUS_3 0xcc
#define MAILBOX_MSGSTATUS_4 0xd0
#define MAILBOX_MSGSTATUS_5 0xd4
#define MAILBOX_IRQSTATUS_0 0x100
#define MAILBOX_IRQENABLE_0 0x104
#define MAILBOX_IRQSTATUS_1 0x108
#define MAILBOX_IRQENABLE_1 0x10c
#define MAILBOX_IRQSTATUS_2 0x110
#define MAILBOX_IRQENABLE_2 0x114
#define MAILBOX_IRQSTATUS_3 0x118
#define MAILBOX_IRQENABLE_3 0x11c
unsigned long mbox_base;
#define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1))
#define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n)))
struct omap_mbox2_fifo {
unsigned long msg;
unsigned long fifo_stat;
unsigned long msg_stat;
};
struct omap_mbox2_priv {
struct omap_mbox2_fifo tx_fifo;
struct omap_mbox2_fifo rx_fifo;
unsigned long irqenable;
unsigned long irqstatus;
u32 newmsg_bit;
u32 notfull_bit;
};
struct clk *mbox_ick_handle;
static inline unsigned int mbox_read_reg(unsigned int reg)
{
return __raw_readl(mbox_base + reg);
}
static inline void mbox_write_reg(unsigned int val, unsigned int reg)
{
__raw_writel(val, mbox_base + reg);
}
/* Mailbox H/W preparations */
static inline int omap2_mbox_startup(struct omap_mbox *mbox)
{
unsigned int l;
mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
if (IS_ERR(mbox_ick_handle)) {
printk("Could not get mailboxes_ick\n");
return -ENODEV;
}
clk_enable(mbox_ick_handle);
/* set smart-idle & autoidle */
l = mbox_read_reg(MAILBOX_SYSCONFIG);
l |= 0x00000011;
mbox_write_reg(l, MAILBOX_SYSCONFIG);
return 0;
}
static inline void omap2_mbox_shutdown(struct omap_mbox *mbox)
{
clk_disable(mbox_ick_handle);
clk_put(mbox_ick_handle);
}
/* Mailbox FIFO handle functions */
static inline mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
{
struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
return (mbox_msg_t) mbox_read_reg(fifo->msg);
}
static inline void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
{
struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
mbox_write_reg(msg, fifo->msg);
}
static inline int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
{
struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
return (mbox_read_reg(fifo->msg_stat) == 0);
}
static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox)
{
struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
return (mbox_read_reg(fifo->fifo_stat));
}
/* Mailbox IRQ handle functions */
static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
l = mbox_read_reg(p->irqenable);
l |= bit;
mbox_write_reg(l, p->irqenable);
}
static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
l = mbox_read_reg(p->irqenable);
l &= ~bit;
mbox_write_reg(l, p->irqenable);
}
static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
mbox_write_reg(bit, p->irqstatus);
}
static inline int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
{
struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
u32 enable = mbox_read_reg(p->irqenable);
u32 status = mbox_read_reg(p->irqstatus);
return (enable & status & bit);
}
struct omap_mbox_ops omap2_mbox_ops = {
.type = OMAP_MBOX_TYPE2,
.startup = omap2_mbox_startup,
.shutdown = omap2_mbox_shutdown,
.fifo_read = omap2_mbox_fifo_read,
.fifo_write = omap2_mbox_fifo_write,
.fifo_empty = omap2_mbox_fifo_empty,
.fifo_full = omap2_mbox_fifo_full,
.enable_irq = omap2_mbox_enable_irq,
.disable_irq = omap2_mbox_disable_irq,
.ack_irq = omap2_mbox_ack_irq,
.is_irq = omap2_mbox_is_irq,
};
/*
* MAILBOX 0: ARM -> DSP,
* MAILBOX 1: ARM <- DSP.
* MAILBOX 2: ARM -> IVA,
* MAILBOX 3: ARM <- IVA.
*/
/* FIXME: the following structs should be filled automatically by the user id */
/* DSP */
static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE_0,
.fifo_stat = MAILBOX_FIFOSTATUS_0,
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE_1,
.msg_stat = MAILBOX_MSGSTATUS_1,
},
.irqenable = MAILBOX_IRQENABLE_0,
.irqstatus = MAILBOX_IRQSTATUS_0,
.notfull_bit = MAILBOX_IRQ_NOTFULL(0),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
};
static struct omap_mbox mbox_dsp_info = {
.name = "dsp",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_dsp_priv,
};
/* IVA */
static struct omap_mbox2_priv omap2_mbox_iva_priv = {
.tx_fifo = {
.msg = MAILBOX_MESSAGE_2,
.fifo_stat = MAILBOX_FIFOSTATUS_2,
},
.rx_fifo = {
.msg = MAILBOX_MESSAGE_3,
.msg_stat = MAILBOX_MSGSTATUS_3,
},
.irqenable = MAILBOX_IRQENABLE_3,
.irqstatus = MAILBOX_IRQSTATUS_3,
.notfull_bit = MAILBOX_IRQ_NOTFULL(2),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
};
static struct omap_mbox mbox_iva_info = {
.name = "iva",
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_iva_priv,
};
static int __init omap2_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0;
if (pdev->num_resources != 3) {
dev_err(&pdev->dev, "invalid number of resources: %d\n",
pdev->num_resources);
return -ENODEV;
}
/* MBOX base */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid mem resource\n");
return -ENODEV;
}
mbox_base = res->start;
/* DSP IRQ */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
return -ENODEV;
}
mbox_dsp_info.irq = res->start;
ret = omap_mbox_register(&mbox_dsp_info);
/* IVA IRQ */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
if (unlikely(!res)) {
dev_err(&pdev->dev, "invalid irq resource\n");
return -ENODEV;
}
mbox_iva_info.irq = res->start;
ret = omap_mbox_register(&mbox_iva_info);
return ret;
}
static int omap2_mbox_remove(struct platform_device *pdev)
{
omap_mbox_unregister(&mbox_dsp_info);
return 0;
}
static struct platform_driver omap2_mbox_driver = {
.probe = omap2_mbox_probe,
.remove = omap2_mbox_remove,
.driver = {
.name = "mailbox",
},
};
int __init omap2_mbox_init(void)
{
return platform_driver_register(&omap2_mbox_driver);
}
static void __exit omap2_mbox_exit(void)
{
platform_driver_unregister(&omap2_mbox_driver);
}
module_init(omap2_mbox_init);
module_exit(omap2_mbox_exit);
MODULE_LICENSE("GPL");
...@@ -30,6 +30,38 @@ ...@@ -30,6 +30,38 @@
#include "prcm-regs.h" #include "prcm-regs.h"
#include "memory.h" #include "memory.h"
#define SMS_BASE 0x68008000
#define SMS_SYSCONFIG 0x010
#define SDRC_BASE 0x68009000
#define SDRC_SYSCONFIG 0x010
#define SDRC_SYSSTATUS 0x014
static const u32 sms_base = IO_ADDRESS(SMS_BASE);
static const u32 sdrc_base = IO_ADDRESS(SDRC_BASE);
static inline void sms_write_reg(int idx, u32 val)
{
__raw_writel(val, sms_base + idx);
}
static inline u32 sms_read_reg(int idx)
{
return __raw_readl(sms_base + idx);
}
static inline void sdrc_write_reg(int idx, u32 val)
{
__raw_writel(val, sdrc_base + idx);
}
static inline u32 sdrc_read_reg(int idx)
{
return __raw_readl(sdrc_base + idx);
}
static struct memory_timings mem_timings; static struct memory_timings mem_timings;
u32 omap2_memory_get_slow_dll_ctrl(void) u32 omap2_memory_get_slow_dll_ctrl(void)
...@@ -99,3 +131,19 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) ...@@ -99,3 +131,19 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
/* 90 degree phase for anything below 133Mhz + disable DLL filter */ /* 90 degree phase for anything below 133Mhz + disable DLL filter */
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
} }
void __init omap2_init_memory(void)
{
u32 l;
l = sms_read_reg(SMS_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sms_write_reg(SMS_SYSCONFIG, l);
l = sdrc_read_reg(SDRC_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sdrc_write_reg(SDRC_SYSCONFIG, l);
}
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h> #include <linux/clk.h>
......
...@@ -84,7 +84,7 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p) ...@@ -84,7 +84,7 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
serial_write_reg(p, UART_OMAP_MDR1, 0x07); serial_write_reg(p, UART_OMAP_MDR1, 0x07);
serial_write_reg(p, UART_OMAP_SCR, 0x08); serial_write_reg(p, UART_OMAP_SCR, 0x08);
serial_write_reg(p, UART_OMAP_MDR1, 0x00); serial_write_reg(p, UART_OMAP_MDR1, 0x00);
serial_write_reg(p, UART_OMAP_SYSC, 0x01); serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
} }
void __init omap_serial_init() void __init omap_serial_init()
......
...@@ -172,6 +172,8 @@ config OMAP_SERIAL_WAKE ...@@ -172,6 +172,8 @@ config OMAP_SERIAL_WAKE
to data on the serial RX line. This allows you to wake the to data on the serial RX line. This allows you to wake the
system from serial console. system from serial console.
source "arch/arm/plat-omap/dsp/Kconfig"
endmenu endmenu
endif endif
...@@ -26,4 +26,4 @@ obj-$(CONFIG_OMAP_COMPONENT_VERSION) += component-version.o ...@@ -26,4 +26,4 @@ obj-$(CONFIG_OMAP_COMPONENT_VERSION) += component-version.o
obj-$(CONFIG_OMAP_GPIO_SWITCH) += gpio-switch.o obj-$(CONFIG_OMAP_GPIO_SWITCH) += gpio-switch.o
# DSP subsystem # DSP subsystem
obj-y += dsp/ obj-$(CONFIG_OMAP_DSP) += dsp/ mailbox.o
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/version.h> #include <linux/version.h>
#include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -28,12 +27,47 @@ ...@@ -28,12 +27,47 @@
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
LIST_HEAD(clocks); static LIST_HEAD(clocks);
DEFINE_SPINLOCK(clockfw_lock);
static DEFINE_MUTEX(clocks_mutex); static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
static struct clk_functions *arch_clock; static struct clk_functions *arch_clock;
#ifdef CONFIG_PM_DEBUG
static void print_parents(struct clk *clk)
{
struct clk *p;
int printed = 0;
list_for_each_entry(p, &clocks, node) {
if (p->parent == clk && p->usecount) {
if (!clk->usecount && !printed) {
printk("MISMATCH: %s\n", clk->name);
printed = 1;
}
printk("\t%-15s\n", p->name);
}
}
}
void clk_print_usecounts(void)
{
unsigned long flags;
struct clk *p;
spin_lock_irqsave(&clockfw_lock, flags);
list_for_each_entry(p, &clocks, node) {
if (p->usecount)
printk("%-15s: %d\n", p->name, p->usecount);
print_parents(p);
}
spin_unlock_irqrestore(&clockfw_lock, flags);
}
#endif
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* Standard clock functions defined in include/linux/clk.h * Standard clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/ *-------------------------------------------------------------------------*/
...@@ -101,6 +135,7 @@ void clk_disable(struct clk *clk) ...@@ -101,6 +135,7 @@ void clk_disable(struct clk *clk)
return; return;
spin_lock_irqsave(&clockfw_lock, flags); spin_lock_irqsave(&clockfw_lock, flags);
BUG_ON(clk->usecount == 0);
if (arch_clock->clk_disable) if (arch_clock->clk_disable)
arch_clock->clk_disable(clk); arch_clock->clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags); spin_unlock_irqrestore(&clockfw_lock, flags);
......
...@@ -25,6 +25,70 @@ ...@@ -25,6 +25,70 @@
#include <asm/arch/gpio.h> #include <asm/arch/gpio.h>
#include <asm/arch/menelaus.h> #include <asm/arch/menelaus.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
#include "../plat-omap/dsp/dsp_common.h"
static struct dsp_platform_data dsp_pdata = {
.kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list),
};
static struct resource omap_dsp_resources[] = {
{
.name = "dsp_mmu",
.start = -1,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device omap_dsp_device = {
.name = "dsp",
.id = -1,
.num_resources = ARRAY_SIZE(omap_dsp_resources),
.resource = omap_dsp_resources,
.dev = {
.platform_data = &dsp_pdata,
},
};
static inline void omap_init_dsp(void)
{
struct resource *res;
int irq;
if (cpu_is_omap15xx())
irq = INT_1510_DSP_MMU;
else if (cpu_is_omap16xx())
irq = INT_1610_DSP_MMU;
else if (cpu_is_omap24xx())
irq = INT_24XX_DSP_MMU;
res = platform_get_resource_byname(&omap_dsp_device,
IORESOURCE_IRQ, "dsp_mmu");
res->start = irq;
platform_device_register(&omap_dsp_device);
}
int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
{
static DEFINE_MUTEX(dsp_pdata_lock);
mutex_init(&kdev->lock);
mutex_lock(&dsp_pdata_lock);
list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
mutex_unlock(&dsp_pdata_lock);
return 0;
}
EXPORT_SYMBOL(dsp_kfunc_device_register);
#else
static inline void omap_init_dsp(void) { }
#endif /* CONFIG_OMAP_DSP */
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
#define OMAP1_I2C_BASE 0xfffb3800 #define OMAP1_I2C_BASE 0xfffb3800
...@@ -432,6 +496,7 @@ static int __init omap_init_devices(void) ...@@ -432,6 +496,7 @@ static int __init omap_init_devices(void)
/* please keep these calls, and their implementations above, /* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through. * in alphabetical order so they're easier to sort through.
*/ */
omap_init_dsp();
omap_init_i2c(); omap_init_i2c();
omap_init_kp(); omap_init_kp();
omap_init_mmc(); omap_init_mmc();
...@@ -442,4 +507,3 @@ static int __init omap_init_devices(void) ...@@ -442,4 +507,3 @@ static int __init omap_init_devices(void)
return 0; return 0;
} }
arch_initcall(omap_init_devices); arch_initcall(omap_init_devices);
...@@ -930,10 +930,17 @@ static int omap2_dma_handle_ch(int ch) ...@@ -930,10 +930,17 @@ static int omap2_dma_handle_ch(int ch)
u32 status = OMAP_DMA_CSR_REG(ch); u32 status = OMAP_DMA_CSR_REG(ch);
u32 val; u32 val;
if (!status) if (!status) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch);
return 0; return 0;
if (unlikely(dma_chan[ch].dev_id == -1)) }
if (unlikely(dma_chan[ch].dev_id == -1)) {
if (printk_ratelimit())
printk(KERN_WARNING "IRQ %04x for non-allocated DMA"
"channel %d\n", status, ch);
return 0; return 0;
}
if (unlikely(status & OMAP_DMA_DROP_IRQ)) if (unlikely(status & OMAP_DMA_DROP_IRQ))
printk(KERN_INFO printk(KERN_INFO
"DMA synchronization event drop occurred with device " "DMA synchronization event drop occurred with device "
...@@ -969,11 +976,15 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id, ...@@ -969,11 +976,15 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id,
int i; int i;
val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
if (val == 0) {
for (i = 1; i <= OMAP_LOGICAL_DMA_CH_COUNT; i++) { if (printk_ratelimit())
int active = val & (1 << (i - 1)); printk(KERN_WARNING "Spurious DMA IRQ\n");
if (active) return IRQ_HANDLED;
omap2_dma_handle_ch(i - 1); }
for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) {
if (val & 1)
omap2_dma_handle_ch(i);
val >>= 1;
} }
return IRQ_HANDLED; return IRQ_HANDLED;
......
config OMAP_DSP config OMAP_DSP
tristate "OMAP DSP driver (DSP Gateway)" tristate "OMAP DSP driver (DSP Gateway)"
depends on ARCH_OMAP15XX || ARCH_OMAP16XX depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP24XX
help help
This enables OMAP DSP driver, DSP Gateway. This enables OMAP DSP driver, DSP Gateway.
......
This diff is collapsed.
This diff is collapsed.
/* /*
* linux/arch/arm/mach-omap/dsp/dsp_common.h * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* Header for OMAP DSP driver static part * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2002-2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/06/13: DSP Gateway version 3.3
*/ */
#ifndef DRIVER_DSP_COMMON_H
#define DRIVER_DSP_COMMON_H
#include "hardware_dsp.h" #include "hardware_dsp.h"
#define DSPSPACE_SIZE 0x1000000 #define DSPSPACE_SIZE 0x1000000
...@@ -36,48 +36,41 @@ ...@@ -36,48 +36,41 @@
do { omap_writel(omap_readl(r) | (b), (r)); } while(0) do { omap_writel(omap_readl(r) | (b), (r)); } while(0)
#define omap_clr_bit_regl(b,r) \ #define omap_clr_bit_regl(b,r) \
do { omap_writel(omap_readl(r) & ~(b), (r)); } while(0) do { omap_writel(omap_readl(r) & ~(b), (r)); } while(0)
#define omap_set_bits_regl(val,mask,r) \
do { omap_writel((omap_readl(r) & ~(mask)) | (val), (r)); } while(0)
#define dspword_to_virt(dw) ((void *)(dspmem_base + ((dw) << 1))) #define dspword_to_virt(dw) ((void *)(dspmem_base + ((dw) << 1)))
#define dspbyte_to_virt(db) ((void *)(dspmem_base + (db))) #define dspbyte_to_virt(db) ((void *)(dspmem_base + (db)))
#define virt_to_dspword(va) (((unsigned long)(va) - dspmem_base) >> 1) #define virt_to_dspword(va) \
#define virt_to_dspbyte(va) ((unsigned long)(va) - dspmem_base) ((dsp_long_t)(((unsigned long)(va) - dspmem_base) >> 1))
#define virt_to_dspbyte(va) \
((dsp_long_t)((unsigned long)(va) - dspmem_base))
#define is_dsp_internal_mem(va) \ #define is_dsp_internal_mem(va) \
(((unsigned long)(va) >= dspmem_base) && \ (((unsigned long)(va) >= dspmem_base) && \
((unsigned long)(va) < dspmem_base + dspmem_size)) ((unsigned long)(va) < dspmem_base + dspmem_size))
#define is_dspbyte_internal_mem(db) ((db) < dspmem_size) #define is_dspbyte_internal_mem(db) ((db) < dspmem_size)
#define is_dspword_internal_mem(dw) (((dw) << 1) < dspmem_size) #define is_dspword_internal_mem(dw) (((dw) << 1) < dspmem_size)
#ifdef CONFIG_ARCH_OMAP1
/* /*
* MPUI byteswap/wordswap on/off * MPUI byteswap/wordswap on/off
* default setting: wordswap = all, byteswap = APIMEM only * default setting: wordswap = all, byteswap = APIMEM only
*/ */
#define mpui_wordswap_on() \ #define mpui_wordswap_on() \
do { \ omap_set_bits_regl(MPUI_CTRL_WORDSWAP_ALL, MPUI_CTRL_WORDSWAP_MASK, \
omap_writel( \ MPUI_CTRL)
(omap_readl(MPUI_CTRL) & ~MPUI_CTRL_WORDSWAP_MASK) | \
MPUI_CTRL_WORDSWAP_ALL, MPUI_CTRL); \
} while(0)
#define mpui_wordswap_off() \ #define mpui_wordswap_off() \
do { \ omap_set_bits_regl(MPUI_CTRL_WORDSWAP_NONE, MPUI_CTRL_WORDSWAP_MASK, \
omap_writel( \ MPUI_CTRL)
(omap_readl(MPUI_CTRL) & ~MPUI_CTRL_WORDSWAP_MASK) | \
MPUI_CTRL_WORDSWAP_NONE, MPUI_CTRL); \
} while(0)
#define mpui_byteswap_on() \ #define mpui_byteswap_on() \
do { \ omap_set_bits_regl(MPUI_CTRL_BYTESWAP_API, MPUI_CTRL_BYTESWAP_MASK, \
omap_writel( \ MPUI_CTRL)
(omap_readl(MPUI_CTRL) & ~MPUI_CTRL_BYTESWAP_MASK) | \
MPUI_CTRL_BYTESWAP_API, MPUI_CTRL); \
} while(0)
#define mpui_byteswap_off() \ #define mpui_byteswap_off() \
do { \ omap_set_bits_regl(MPUI_CTRL_BYTESWAP_NONE, MPUI_CTRL_BYTESWAP_MASK, \
omap_writel( \ MPUI_CTRL)
(omap_readl(MPUI_CTRL) & ~MPUI_CTRL_BYTESWAP_MASK) | \
MPUI_CTRL_BYTESWAP_NONE, MPUI_CTRL); \
} while(0)
/* /*
* TC wordswap on / off * TC wordswap on / off
...@@ -88,11 +81,7 @@ ...@@ -88,11 +81,7 @@
TC_ENDIANISM); \ TC_ENDIANISM); \
} while(0) } while(0)
#define tc_noswap() \ #define tc_noswap() omap_clr_bit_regl(TC_ENDIANISM_EN, TC_ENDIANISM)
do { \
omap_writel(omap_readl(TC_ENDIANISM) & ~TC_ENDIANISM_EN, \
TC_ENDIANISM); \
} while(0)
/* /*
* enable priority registers, EMIF, MPUI control logic * enable priority registers, EMIF, MPUI control logic
...@@ -101,32 +90,120 @@ ...@@ -101,32 +90,120 @@
#define __dsp_disable() omap_clr_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1) #define __dsp_disable() omap_clr_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1)
#define __dsp_run() omap_set_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1) #define __dsp_run() omap_set_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
#define __dsp_reset() omap_clr_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1) #define __dsp_reset() omap_clr_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
#endif /* CONFIG_ARCH_OMAP1 */
#ifdef CONFIG_ARCH_OMAP2
/*
* PRCM / IPI control logic
*/
#define RSTCTRL_RST1_DSP 0x00000001
#define RSTCTRL_RST2_DSP 0x00000002
#define __dsp_core_enable() \
do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST1_DSP; } while (0)
#define __dsp_core_disable() \
do { RM_RSTCTRL_DSP |= RSTCTRL_RST1_DSP; } while (0)
#define __dsp_per_enable() \
do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST2_DSP; } while (0)
#define __dsp_per_disable() \
do { RM_RSTCTRL_DSP |= RSTCTRL_RST2_DSP; } while (0)
#endif /* CONFIG_ARCH_OMAP2 */
typedef u32 dsp_long_t; /* must have ability to carry TADD_ABORTADR */
#if defined(CONFIG_ARCH_OMAP1)
extern struct clk *dsp_ck_handle; extern struct clk *dsp_ck_handle;
extern struct clk *api_ck_handle; extern struct clk *api_ck_handle;
extern unsigned long dspmem_base, dspmem_size, #elif defined(CONFIG_ARCH_OMAP2)
extern struct clk *dsp_fck_handle;
extern struct clk *dsp_ick_handle;
#endif
extern dsp_long_t dspmem_base, dspmem_size,
daram_base, daram_size, daram_base, daram_size,
saram_base, saram_size; saram_base, saram_size;
enum e_cpustat { enum cpustat_e {
CPUSTAT_RESET = 0, CPUSTAT_RESET = 0,
CPUSTAT_GBL_IDLE = 1, #ifdef CONFIG_ARCH_OMAP1
CPUSTAT_CPU_IDLE = 2, CPUSTAT_GBL_IDLE,
CPUSTAT_RUN = 3 CPUSTAT_CPU_IDLE,
#endif
CPUSTAT_RUN,
CPUSTAT_MAX
}; };
#define cpustat_name(stat) \ int dsp_set_rstvect(dsp_long_t adr);
((stat == CPUSTAT_RESET) ? "RESET" :\ dsp_long_t dsp_get_rstvect(void);
(stat == CPUSTAT_GBL_IDLE) ? "GBL_IDLE" :\ #ifdef CONFIG_ARCH_OMAP1
(stat == CPUSTAT_CPU_IDLE) ? "CPU_IDLE" :\ void dsp_set_idle_boot_base(dsp_long_t adr, size_t size);
(stat == CPUSTAT_RUN) ? "RUN" :\ void dsp_reset_idle_boot_base(void);
"unknown") #endif
void dsp_cpustat_request(enum cpustat_e req);
int dsp_set_rstvect(unsigned long adr); enum cpustat_e dsp_cpustat_get_stat(void);
void dsp_set_idle_boot_base(unsigned long adr, size_t size); u16 dsp_cpustat_get_icrmask(void);
void dsp_cpustat_request(enum e_cpustat req); void dsp_cpustat_set_icrmask(u16 mask);
enum e_cpustat dsp_cpustat_get_stat(void); #ifdef CONFIG_ARCH_OMAP1
unsigned short dsp_cpustat_get_icrmask(void);
void dsp_cpustat_set_icrmask(unsigned short mask);
void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void)); void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void));
void dsp_unregister_mem_cb(void); void dsp_unregister_mem_cb(void);
#endif
#if defined(CONFIG_ARCH_OMAP1)
static inline void dsp_clk_autoidle(void) {}
#elif defined(CONFIG_ARCH_OMAP2)
static inline void dsp_clk_autoidle(void)
{
/*XXX should be handled in mach-omap[1,2] XXX*/
PM_PWSTCTRL_DSP = (1 << 18) | (1 << 0);
CM_AUTOIDLE_DSP |= (1 << 1);
CM_CLKSTCTRL_DSP |= (1 << 0);
}
#endif
struct dsp_kfunc_device {
char *name;
struct clk *fck;
struct clk *ick;;
struct mutex lock;
int enabled;
int type;
#define DSP_KFUNC_DEV_TYPE_COMMON 1
#define DSP_KFUNC_DEV_TYPE_AUDIO 2
struct list_head entry;
int (*probe)(struct dsp_kfunc_device *);
int (*remove)(struct dsp_kfunc_device *);
int (*enable)(struct dsp_kfunc_device *, int);
int (*disable)(struct dsp_kfunc_device *, int);
};
extern int dsp_kfunc_device_register(struct dsp_kfunc_device *);
struct dsp_platform_data {
struct list_head kdev_list;
};
struct omap_dsp {
struct mutex lock;
int enabled; /* stored peripheral status */
int mmu_irq;
struct omap_mbox *mbox;
struct device *dev;
struct list_head *kdev_list;
int initialized;
};
#if defined(CONFIG_ARCH_OMAP1)
#define command_dvfs_stop(m) (0)
#define command_dvfs_start(m) (0)
#elif defined(CONFIG_ARCH_OMAP2)
#define command_dvfs_stop(m) \
(((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_STOP))
#define command_dvfs_start(m) \
(((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_START))
#endif
extern struct omap_dsp *omap_dsp;
extern int dsp_late_init(void);
#endif /* DRIVER_DSP_COMMON_H */
This diff is collapsed.
This diff is collapsed.
/* /*
* linux/arch/arm/mach-omap/dsp/dsp_ctl_core.c * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* OMAP DSP control devices core driver * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2004,2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/07/26: DSP Gateway version 3.3
*/ */
#include <linux/module.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/arch/dsp.h> #include "dsp.h"
#include "hardware_dsp.h"
#define CTL_MINOR 0 #define CTL_MINOR 0
#define MEM_MINOR 1 #define MEM_MINOR 1
...@@ -45,6 +40,20 @@ extern struct file_operations dsp_ctl_fops, ...@@ -45,6 +40,20 @@ extern struct file_operations dsp_ctl_fops,
static int dsp_ctl_core_open(struct inode *inode, struct file *file) static int dsp_ctl_core_open(struct inode *inode, struct file *file)
{ {
static DEFINE_MUTEX(open_lock);
int ret = 0;
mutex_lock_interruptible(&open_lock);
if (omap_dsp->initialized == 0) {
ret = dsp_late_init();
if (ret != 0) {
mutex_unlock(&open_lock);
return ret;
}
omap_dsp->initialized = 1;
}
mutex_unlock(&open_lock);
switch (iminor(inode)) { switch (iminor(inode)) {
case CTL_MINOR: case CTL_MINOR:
file->f_op = &dsp_ctl_fops; file->f_op = &dsp_ctl_fops;
...@@ -86,7 +95,6 @@ int __init dsp_ctl_core_init(void) ...@@ -86,7 +95,6 @@ int __init dsp_ctl_core_init(void)
{ {
int retval; int retval;
int i; int i;
struct class_device *cdev;
retval = register_chrdev(OMAP_DSP_CTL_MAJOR, "dspctl", retval = register_chrdev(OMAP_DSP_CTL_MAJOR, "dspctl",
&dsp_ctl_core_fops); &dsp_ctl_core_fops);
...@@ -99,7 +107,7 @@ int __init dsp_ctl_core_init(void) ...@@ -99,7 +107,7 @@ int __init dsp_ctl_core_init(void)
dsp_ctl_class = class_create(THIS_MODULE, "dspctl"); dsp_ctl_class = class_create(THIS_MODULE, "dspctl");
for (i = 0; i < ARRAY_SIZE(dev_list); i++) { for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
cdev = class_device_create(dsp_ctl_class, NULL, class_device_create(dsp_ctl_class, NULL,
MKDEV(OMAP_DSP_CTL_MAJOR, MKDEV(OMAP_DSP_CTL_MAJOR,
dev_list[i].minor), dev_list[i].minor),
NULL, dev_list[i].devname); NULL, dev_list[i].devname);
......
/*
* This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
*
* Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
*
* Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/*
* mailbox command: 0x00 - 0x7f
* when a driver wants to use mailbox, it must reserve mailbox commands here.
*/
#define MBOX_CMD_DSP_WDSND 0x10
#define MBOX_CMD_DSP_WDREQ 0x11
#define MBOX_CMD_DSP_BKSND 0x20
#define MBOX_CMD_DSP_BKREQ 0x21
#define MBOX_CMD_DSP_BKYLD 0x23
#define MBOX_CMD_DSP_BKSNDP 0x24
#define MBOX_CMD_DSP_BKREQP 0x25
#define MBOX_CMD_DSP_TCTL 0x30
#define MBOX_CMD_DSP_TCTLDATA 0x31
#define MBOX_CMD_DSP_POLL 0x32
#define MBOX_CMD_DSP_WDT 0x50
#define MBOX_CMD_DSP_RUNLEVEL 0x51
#define MBOX_CMD_DSP_PM 0x52
#define MBOX_CMD_DSP_SUSPEND 0x53
#define MBOX_CMD_DSP_KFUNC 0x54
#define MBOX_CMD_DSP_TCFG 0x60
#define MBOX_CMD_DSP_TADD 0x62
#define MBOX_CMD_DSP_TDEL 0x63
#define MBOX_CMD_DSP_TSTOP 0x65
#define MBOX_CMD_DSP_DSPCFG 0x70
#define MBOX_CMD_DSP_REGRW 0x72
#define MBOX_CMD_DSP_GETVAR 0x74
#define MBOX_CMD_DSP_SETVAR 0x75
#define MBOX_CMD_DSP_ERR 0x78
#define MBOX_CMD_DSP_DBG 0x79
/*
* DSP mailbox protocol definitions
*/
#define MBPROT_REVISION 0x0019
#define TCTL_TINIT 0x0000
#define TCTL_TEN 0x0001
#define TCTL_TDIS 0x0002
#define TCTL_TCLR 0x0003
#define TCTL_TCLR_FORCE 0x0004
#define RUNLEVEL_USER 0x01
#define RUNLEVEL_SUPER 0x0e
#define RUNLEVEL_RECOVERY 0x10
#define PM_DISABLE 0x00
#define PM_ENABLE 0x01
#define KFUNC_FBCTL 0x00
#define KFUNC_POWER 0x01
#define FBCTL_UPD 0x0000
#define FBCTL_ENABLE 0x0002
#define FBCTL_DISABLE 0x0003
/* KFUNC_POWER */
#define AUDIO_PWR_UP 0x0000 /* ARM(exe/ack) <-> DSP(req) */
#define AUDIO_PWR_DOWN 0x0001 /* ARM(exe) <- DSP(req) */
#define AUDIO_PWR_DOWN1 AUDIO_PWR_DOWN
#define AUDIO_PWR_DOWN2 0x0002
#define DSP_PWR_UP 0x0003 /* ARM(exe/snd) -> DSP(exe) */
#define DSP_PWR_DOWN 0x0004 /* ARM(exe) <- DSP(req) */
#define DVFS_START 0x0006 /* ARM(req) <-> DSP(exe/ack)*/
#define DVFS_STOP 0x0007 /* ARM(req) -> DSP(exe) */
#define TDEL_SAFE 0x0000
#define TDEL_KILL 0x0001
#define DSPCFG_REQ 0x00
#define DSPCFG_SYSADRH 0x28
#define DSPCFG_SYSADRL 0x29
#define DSPCFG_PROTREV 0x70
#define DSPCFG_ABORT 0x78
#define DSPCFG_LAST 0x80
#define REGRW_MEMR 0x00
#define REGRW_MEMW 0x01
#define REGRW_IOR 0x02
#define REGRW_IOW 0x03
#define REGRW_DATA 0x04
#define VARID_ICRMASK 0x00
#define VARID_LOADINFO 0x01
#define TTYP_ARCV 0x0001
#define TTYP_ASND 0x0002
#define TTYP_BKMD 0x0004
#define TTYP_BKDM 0x0008
#define TTYP_PVMD 0x0010
#define TTYP_PVDM 0x0020
#define EID_BADTID 0x10
#define EID_BADTCN 0x11
#define EID_BADBID 0x20
#define EID_BADCNT 0x21
#define EID_NOTLOCKED 0x22
#define EID_STVBUF 0x23
#define EID_BADADR 0x24
#define EID_BADTCTL 0x30
#define EID_BADPARAM 0x50
#define EID_FATAL 0x58
#define EID_NOMEM 0xc0
#define EID_NORES 0xc1
#define EID_IPBFULL 0xc2
#define EID_WDT 0xd0
#define EID_TASKNOTRDY 0xe0
#define EID_TASKBSY 0xe1
#define EID_TASKERR 0xef
#define EID_BADCFGTYP 0xf0
#define EID_DEBUG 0xf8
#define EID_BADSEQ 0xfe
#define EID_BADCMD 0xff
#define TNM_LEN 16
#define TID_FREE 0xff
#define TID_ANON 0xfe
#define BID_NULL 0xffff
#define BID_PVT 0xfffe
This diff is collapsed.
/* /*
* linux/arch/arm/mach-omap/dsp/error.c * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* OMAP DSP error detection I/F device driver * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2002-2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/03/11: DSP Gateway version 3.3
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h>
#include <linux/major.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include "dsp_mbcmd.h"
#include <asm/ioctls.h>
#include <asm/arch/dsp.h>
#include "dsp.h" #include "dsp.h"
/*
* value seen through read()
*/
#define DSP_ERR_WDT 0x00000001
#define DSP_ERR_MMU 0x00000002
static unsigned long errval;
static DECLARE_WAIT_QUEUE_HEAD(err_wait_q); static DECLARE_WAIT_QUEUE_HEAD(err_wait_q);
static unsigned long errcode;
static int errcnt; static int errcnt;
static unsigned short wdtval; /* FIXME: read through ioctl */ static u16 wdtval; /* FIXME: read through ioctl */
static unsigned long mmu_fadr; /* FIXME: read through ioctl */ static u32 mmu_fadr; /* FIXME: read through ioctl */
/* /*
* DSP error detection device file operations * DSP error detection device file operations
*/ */
static ssize_t dsp_err_read(struct file *file, char *buf, size_t count, static ssize_t dsp_err_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
unsigned long flags; unsigned long flags;
...@@ -71,7 +70,7 @@ static ssize_t dsp_err_read(struct file *file, char *buf, size_t count, ...@@ -71,7 +70,7 @@ static ssize_t dsp_err_read(struct file *file, char *buf, size_t count,
} }
local_irq_save(flags); local_irq_save(flags);
status = copy_to_user(buf, &errcode, 4); status = copy_to_user(buf, &errval, 4);
if (status) { if (status) {
local_irq_restore(flags); local_irq_restore(flags);
return -EFAULT; return -EFAULT;
...@@ -100,90 +99,108 @@ struct file_operations dsp_err_fops = { ...@@ -100,90 +99,108 @@ struct file_operations dsp_err_fops = {
}; };
/* /*
* DSP MMU * set / clear functions
*/ */
void dsp_err_mmu_set(unsigned long adr)
/* DSP MMU */
static void dsp_err_mmu_set(unsigned long arg)
{ {
disable_irq(INT_DSP_MMU); disable_irq(omap_dsp->mmu_irq);
errcode |= OMAP_DSP_ERRDT_MMU; mmu_fadr = (u32)arg;
errcnt++;
mmu_fadr = adr;
wake_up_interruptible(&err_wait_q);
} }
void dsp_err_mmu_clear(void) static void dsp_err_mmu_clr(void)
{ {
errcode &= ~OMAP_DSP_ERRDT_MMU; enable_irq(omap_dsp->mmu_irq);
enable_irq(INT_DSP_MMU);
} }
int dsp_err_mmu_isset(void) /* WDT */
static void dsp_err_wdt_set(unsigned long arg)
{ {
return (errcode & OMAP_DSP_ERRDT_MMU) ? 1 : 0; wdtval = (u16)arg;
} }
/* /*
* WDT * error code handler
*/ */
void dsp_err_wdt_clear(void) static struct {
unsigned long val;
void (*set)(unsigned long arg);
void (*clr)(void);
} dsp_err_desc[ERRCODE_MAX] = {
[ERRCODE_MMU] = { DSP_ERR_MMU, dsp_err_mmu_set, dsp_err_mmu_clr },
[ERRCODE_WDT] = { DSP_ERR_WDT, dsp_err_wdt_set, NULL },
};
void dsp_err_set(enum errcode_e code, unsigned long arg)
{ {
errcode &= ~OMAP_DSP_ERRDT_WDT; if (dsp_err_desc[code].set != NULL)
dsp_err_desc[code].set(arg);
errval |= dsp_err_desc[code].val;
errcnt++;
wake_up_interruptible(&err_wait_q);
}
void dsp_err_clear(enum errcode_e code)
{
errval &= ~dsp_err_desc[code].val;
if (dsp_err_desc[code].clr != NULL)
dsp_err_desc[code].clr();
} }
int dsp_err_wdt_isset(void) int dsp_err_isset(enum errcode_e code)
{ {
return (errcode & OMAP_DSP_ERRDT_WDT) ? 1 : 0; return (errval & dsp_err_desc[code].val) ? 1 : 0;
} }
/* /*
* functions called from mailbox1 interrupt routine * functions called from mailbox interrupt routine
*/ */
static void mbx1_err_wdt(unsigned short data) static void mbox_err_wdt(u16 data)
{ {
errcode |= OMAP_DSP_ERRDT_WDT; dsp_err_set(DSP_ERR_WDT, (unsigned long)data);
errcnt++;
wdtval = data;
wake_up_interruptible(&err_wait_q);
} }
#ifdef OLD_BINARY_SUPPORT #ifdef OLD_BINARY_SUPPORT
/* v3.3 obsolete */ /* v3.3 obsolete */
void mbx1_wdt(struct mbcmd *mb) void mbox_wdt(struct mbcmd *mb)
{ {
mbx1_err_wdt(mb->data); mbox_err_wdt(mb->data);
} }
#endif #endif
extern void mbx1_err_ipbfull(void); extern void mbox_err_ipbfull(void);
extern void mbx1_err_fatal(unsigned char tid); extern void mbox_err_fatal(u8 tid);
void mbx1_err(struct mbcmd *mb) void mbox_err(struct mbcmd *mb)
{ {
unsigned char eid = mb->cmd_l; u8 eid = mb->cmd_l;
char *eidnm = subcmd_name(mb); char *eidnm = subcmd_name(mb);
unsigned char tid; u8 tid;
if (eidnm) { if (eidnm) {
printk(KERN_WARNING printk(KERN_WARNING
"mbx: ERR from DSP (%s): 0x%04x\n", eidnm, mb->data); "mbox: ERR from DSP (%s): 0x%04x\n", eidnm, mb->data);
} else { } else {
printk(KERN_WARNING printk(KERN_WARNING
"mbx: ERR from DSP (unknown EID=%02x): %04x\n", "mbox: ERR from DSP (unknown EID=%02x): %04x\n",
eid, mb->data); eid, mb->data);
} }
switch (eid) { switch (eid) {
case OMAP_DSP_EID_IPBFULL: case EID_IPBFULL:
mbx1_err_ipbfull(); mbox_err_ipbfull();
break; break;
case OMAP_DSP_EID_FATAL: case EID_FATAL:
tid = mb->data & 0x00ff; tid = mb->data & 0x00ff;
mbx1_err_fatal(tid); mbox_err_fatal(tid);
break; break;
case OMAP_DSP_EID_WDT: case EID_WDT:
mbx1_err_wdt(mb->data); mbox_err_wdt(mb->data);
break; break;
} }
} }
...@@ -193,11 +210,14 @@ void mbx1_err(struct mbcmd *mb) ...@@ -193,11 +210,14 @@ void mbx1_err(struct mbcmd *mb)
*/ */
void dsp_err_start(void) void dsp_err_start(void)
{ {
enum errcode_e i;
for (i = 0; i < ERRCODE_MAX; i++) {
if (dsp_err_isset(i))
dsp_err_clear(i);
}
errcnt = 0; errcnt = 0;
if (dsp_err_wdt_isset())
dsp_err_wdt_clear();
if (dsp_err_mmu_isset())
dsp_err_mmu_clear();
} }
void dsp_err_stop(void) void dsp_err_stop(void)
......
/* /*
* linux/arch/arm/mach-omap/dsp/fifo.h * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* FIFO buffer operators * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2002-2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/02/24: DSP Gateway version 3.3
*/ */
struct fifo_struct { struct fifo_struct {
...@@ -53,8 +50,10 @@ static inline int init_fifo(struct fifo_struct *fifo, size_t sz) ...@@ -53,8 +50,10 @@ static inline int init_fifo(struct fifo_struct *fifo, size_t sz)
static inline void free_fifo(struct fifo_struct *fifo) static inline void free_fifo(struct fifo_struct *fifo)
{ {
spin_lock(&fifo->lock); spin_lock(&fifo->lock);
if (fifo->buf == NULL) if (fifo->buf == NULL) {
spin_unlock(&fifo->lock);
return; return;
}
kfree(fifo->buf); kfree(fifo->buf);
fifo->buf = NULL; fifo->buf = NULL;
...@@ -87,25 +86,17 @@ static inline int realloc_fifo(struct fifo_struct *fifo, size_t sz) ...@@ -87,25 +86,17 @@ static inline int realloc_fifo(struct fifo_struct *fifo, size_t sz)
kfree(fifo->buf); kfree(fifo->buf);
/* alloc */ /* alloc */
if ((fifo->buf = kmalloc(sz, GFP_KERNEL)) == NULL) { ret = alloc_fifo(fifo, sz);
fifo->sz = 0;
ret = -ENOMEM;
goto out;
}
fifo->sz = sz;
fifo->cnt = 0;
fifo->wp = 0;
out: out:
spin_unlock(&fifo->lock); spin_unlock(&fifo->lock);
return ret; return ret;
} }
static inline void write_word_to_fifo(struct fifo_struct *fifo, static inline void write_word_to_fifo(struct fifo_struct *fifo, u16 word)
unsigned short word)
{ {
spin_lock(&fifo->lock); spin_lock(&fifo->lock);
*(unsigned short *)&fifo->buf[fifo->wp] = word; *(u16 *)&fifo->buf[fifo->wp] = word;
if ((fifo->wp += 2) == fifo->sz) if ((fifo->wp += 2) == fifo->sz)
fifo->wp = 0; fifo->wp = 0;
if ((fifo->cnt += 2) > fifo->sz) if ((fifo->cnt += 2) > fifo->sz)
......
/* /*
* linux/arch/arm/mach-omap/dsp/hardware_dsp.h * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* Register bit definitions for DSP driver * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2002-2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/05/30: DSP Gateway version 3.3
*/ */
#ifndef __OMAP_DSP_HARDWARE_DSP_H #ifndef __OMAP_DSP_HARDWARE_DSP_H
#define __OMAP_DSP_HARDWARE_DSP_H #define __OMAP_DSP_HARDWARE_DSP_H
#ifdef CONFIG_ARCH_OMAP15XX #ifdef CONFIG_ARCH_OMAP1
#define OMAP1510_DARAM_BASE 0xe0000000 #include "omap1_dsp.h"
#define OMAP1510_DARAM_SIZE 0x10000
#define OMAP1510_SARAM_BASE 0xe0010000
#define OMAP1510_SARAM_SIZE 0x18000
#endif #endif
#ifdef CONFIG_ARCH_OMAP16XX #ifdef CONFIG_ARCH_OMAP2
#define OMAP16XX_DARAM_BASE 0xe0000000 #include "omap2_dsp.h"
#define OMAP16XX_DARAM_SIZE 0x10000
#define OMAP16XX_SARAM_BASE 0xe0010000
#define OMAP16XX_SARAM_SIZE 0x18000
#endif #endif
/*
* MAJOR device number: !! allocated arbitrary !!
*/
#define OMAP_DSP_CTL_MAJOR 96
#define OMAP_DSP_TASK_MAJOR 97
/*
* Reset Control
*/
#define ARM_RSTCT1_SW_RST 0x0008
#define ARM_RSTCT1_DSP_RST 0x0004
#define ARM_RSTCT1_DSP_EN 0x0002
#define ARM_RSTCT1_ARM_RST 0x0001
/*
* MPUI
*/
#define MPUI_CTRL_WORDSWAP_MASK 0x00600000
#define MPUI_CTRL_WORDSWAP_ALL 0x00000000
#define MPUI_CTRL_WORDSWAP_NONAPI 0x00200000
#define MPUI_CTRL_WORDSWAP_API 0x00400000
#define MPUI_CTRL_WORDSWAP_NONE 0x00600000
#define MPUI_CTRL_AP_MASK 0x001c0000
#define MPUI_CTRL_AP_MDH 0x00000000
#define MPUI_CTRL_AP_MHD 0x00040000
#define MPUI_CTRL_AP_DMH 0x00080000
#define MPUI_CTRL_AP_HMD 0x000c0000
#define MPUI_CTRL_AP_DHM 0x00100000
#define MPUI_CTRL_AP_HDM 0x00140000
#define MPUI_CTRL_BYTESWAP_MASK 0x00030000
#define MPUI_CTRL_BYTESWAP_NONE 0x00000000
#define MPUI_CTRL_BYTESWAP_NONAPI 0x00010000
#define MPUI_CTRL_BYTESWAP_ALL 0x00020000
#define MPUI_CTRL_BYTESWAP_API 0x00030000
#define MPUI_CTRL_TIMEOUT_MASK 0x0000ff00
#define MPUI_CTRL_APIF_HNSTB_DIV_MASK 0x000000f0
#define MPUI_CTRL_S_NABORT_GL 0x00000008
#define MPUI_CTRL_S_NABORT_32BIT 0x00000004
#define MPUI_CTRL_EN_TIMEOUT 0x00000002
#define MPUI_CTRL_HF_MCUCLK 0x00000001
#define MPUI_DSP_BOOT_CONFIG_DIRECT 0x00000000
#define MPUI_DSP_BOOT_CONFIG_PSD_DIRECT 0x00000001
#define MPUI_DSP_BOOT_CONFIG_IDLE 0x00000002
#define MPUI_DSP_BOOT_CONFIG_DL16 0x00000003
#define MPUI_DSP_BOOT_CONFIG_DL32 0x00000004
#define MPUI_DSP_BOOT_CONFIG_MPUI 0x00000005
#define MPUI_DSP_BOOT_CONFIG_INTERNAL 0x00000006
/*
* DSP boot mode
* direct: 0xffff00
* pseudo direct: 0x080000
* MPUI: branch 0x010000
* internel: branch 0x024000
*/
#define DSP_BOOT_ADR_DIRECT 0xffff00
#define DSP_BOOT_ADR_PSD_DIRECT 0x080000
#define DSP_BOOT_ADR_MPUI 0x010000
#define DSP_BOOT_ADR_INTERNAL 0x024000
/*
* TC
*/
#define TC_ENDIANISM_SWAP 0x00000002
#define TC_ENDIANISM_SWAP_WORD 0x00000002
#define TC_ENDIANISM_SWAP_BYTE 0x00000000
#define TC_ENDIANISM_EN 0x00000001
/*
* DSP MMU
*/
#define DSPMMU_BASE (0xfffed200)
#define DSPMMU_PREFETCH (DSPMMU_BASE + 0x00)
#define DSPMMU_WALKING_ST (DSPMMU_BASE + 0x04)
#define DSPMMU_CNTL (DSPMMU_BASE + 0x08)
#define DSPMMU_FAULT_AD_H (DSPMMU_BASE + 0x0c)
#define DSPMMU_FAULT_AD_L (DSPMMU_BASE + 0x10)
#define DSPMMU_FAULT_ST (DSPMMU_BASE + 0x14)
#define DSPMMU_IT_ACK (DSPMMU_BASE + 0x18)
#define DSPMMU_TTB_H (DSPMMU_BASE + 0x1c)
#define DSPMMU_TTB_L (DSPMMU_BASE + 0x20)
#define DSPMMU_LOCK (DSPMMU_BASE + 0x24)
#define DSPMMU_LD_TLB (DSPMMU_BASE + 0x28)
#define DSPMMU_CAM_H (DSPMMU_BASE + 0x2c)
#define DSPMMU_CAM_L (DSPMMU_BASE + 0x30)
#define DSPMMU_RAM_H (DSPMMU_BASE + 0x34)
#define DSPMMU_RAM_L (DSPMMU_BASE + 0x38)
#define DSPMMU_GFLUSH (DSPMMU_BASE + 0x3c)
#define DSPMMU_FLUSH_ENTRY (DSPMMU_BASE + 0x40)
#define DSPMMU_READ_CAM_H (DSPMMU_BASE + 0x44)
#define DSPMMU_READ_CAM_L (DSPMMU_BASE + 0x48)
#define DSPMMU_READ_RAM_H (DSPMMU_BASE + 0x4c)
#define DSPMMU_READ_RAM_L (DSPMMU_BASE + 0x50)
#define DSPMMU_CNTL_BURST_16MNGT_EN 0x0020
#define DSPMMU_CNTL_WTL_EN 0x0004
#define DSPMMU_CNTL_MMU_EN 0x0002
#define DSPMMU_CNTL_RESET_SW 0x0001
#define DSPMMU_FAULT_AD_H_DP 0x0100
#define DSPMMU_FAULT_AD_H_ADR_MASK 0x00ff
#define DSPMMU_FAULT_ST_PREF 0x0008
#define DSPMMU_FAULT_ST_PERM 0x0004
#define DSPMMU_FAULT_ST_TLB_MISS 0x0002
#define DSPMMU_FAULT_ST_TRANS 0x0001
#define DSPMMU_IT_ACK_IT_ACK 0x0001
#define DSPMMU_LOCK_BASE_MASK 0xfc00
#define DSPMMU_LOCK_BASE_SHIFT 10
#define DSPMMU_LOCK_VICTIM_MASK 0x03f0
#define DSPMMU_LOCK_VICTIM_SHIFT 4
#define DSPMMU_CAM_H_VA_TAG_H_MASK 0x0003
#define DSPMMU_CAM_L_VA_TAG_L1_MASK 0xc000
#define DSPMMU_CAM_L_VA_TAG_L2_MASK_1MB 0x0000
#define DSPMMU_CAM_L_VA_TAG_L2_MASK_64KB 0x3c00
#define DSPMMU_CAM_L_VA_TAG_L2_MASK_4KB 0x3fc0
#define DSPMMU_CAM_L_VA_TAG_L2_MASK_1KB 0x3ff0
#define DSPMMU_CAM_L_P 0x0008
#define DSPMMU_CAM_L_V 0x0004
#define DSPMMU_CAM_L_SLST_MASK 0x0003
#define DSPMMU_CAM_L_SLST_1MB 0x0000
#define DSPMMU_CAM_L_SLST_64KB 0x0001
#define DSPMMU_CAM_L_SLST_4KB 0x0002
#define DSPMMU_CAM_L_SLST_1KB 0x0003
#define DSPMMU_RAM_L_RAM_LSB_MASK 0xfc00
#define DSPMMU_RAM_L_AP_MASK 0x0300
#define DSPMMU_RAM_L_AP_NA 0x0000
#define DSPMMU_RAM_L_AP_RO 0x0200
#define DSPMMU_RAM_L_AP_FA 0x0300
#define DSPMMU_GFLUSH_GFLUSH 0x0001
#define DSPMMU_FLUSH_ENTRY_FLUSH_ENTRY 0x0001
#define DSPMMU_LD_TLB_RD 0x0002
#define DSPMMU_LD_TLB_LD 0x0001
/*
* Mailbox
*/
#define MAILBOX_BASE (0xfffcf000)
#define MAILBOX_ARM2DSP1 (MAILBOX_BASE + 0x00)
#define MAILBOX_ARM2DSP1b (MAILBOX_BASE + 0x04)
#define MAILBOX_DSP2ARM1 (MAILBOX_BASE + 0x08)
#define MAILBOX_DSP2ARM1b (MAILBOX_BASE + 0x0c)
#define MAILBOX_DSP2ARM2 (MAILBOX_BASE + 0x10)
#define MAILBOX_DSP2ARM2b (MAILBOX_BASE + 0x14)
#define MAILBOX_ARM2DSP1_Flag (MAILBOX_BASE + 0x18)
#define MAILBOX_DSP2ARM1_Flag (MAILBOX_BASE + 0x1c)
#define MAILBOX_DSP2ARM2_Flag (MAILBOX_BASE + 0x20)
/*
* DSP ICR
*/
#define DSPREG_ICR_RESERVED_BITS 0xffc0
#define DSPREG_ICR_EMIF_IDLE_DOMAIN 0x0020
#define DSPREG_ICR_DPLL_IDLE_DOMAIN 0x0010
#define DSPREG_ICR_PER_IDLE_DOMAIN 0x0008
#define DSPREG_ICR_CACHE_IDLE_DOMAIN 0x0004
#define DSPREG_ICR_DMA_IDLE_DOMAIN 0x0002
#define DSPREG_ICR_CPU_IDLE_DOMAIN 0x0001
#endif /* __OMAP_DSP_HARDWARE_DSP_H */ #endif /* __OMAP_DSP_HARDWARE_DSP_H */
/*
* This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
*
* Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
*
* Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/*
* for /dev/dspctl/ctl
*/
#define DSPCTL_IOCTL_RESET 1
#define DSPCTL_IOCTL_RUN 2
#define DSPCTL_IOCTL_SETRSTVECT 3
#ifdef CONFIG_ARCH_OMAP1
#define DSPCTL_IOCTL_CPU_IDLE 4
#define DSPCTL_IOCTL_MPUI_WORDSWAP_ON 5
#define DSPCTL_IOCTL_MPUI_WORDSWAP_OFF 6
#define DSPCTL_IOCTL_MPUI_BYTESWAP_ON 7
#define DSPCTL_IOCTL_MPUI_BYTESWAP_OFF 8
#define DSPCTL_IOCTL_GBL_IDLE 9
#endif /* CONFIG_ARCH_OMAP1 */
#define DSPCTL_IOCTL_DSPCFG 10
#define DSPCTL_IOCTL_DSPUNCFG 11
#define DSPCTL_IOCTL_TASKCNT 12
#define DSPCTL_IOCTL_POLL 13
#define DSPCTL_IOCTL_REGMEMR 40
#define DSPCTL_IOCTL_REGMEMW 41
#define DSPCTL_IOCTL_REGIOR 42
#define DSPCTL_IOCTL_REGIOW 43
#define DSPCTL_IOCTL_GETVAR 44
#define DSPCTL_IOCTL_SETVAR 45
#define DSPCTL_IOCTL_RUNLEVEL 50
#define DSPCTL_IOCTL_SUSPEND 51
#define DSPCTL_IOCTL_RESUME 52
#ifdef CONFIG_OMAP_DSP_FBEXPORT
#define DSPCTL_IOCTL_FBEN 53
#define DSPCTL_IOCTL_FBDIS 54
#endif /* CONFIG_OMAP_DSP_FBEXPORT */
#define DSPCTL_IOCTL_MBSEND 99
struct omap_dsp_mailbox_cmd {
__u16 cmd;
__u16 data;
};
struct omap_dsp_reginfo {
__u16 adr;
__u16 val;
};
struct omap_dsp_varinfo {
__u8 varid;
__u16 val[0];
};
/*
* for taskdev
* (ioctls below should be >= 0x10000)
*/
#define TASK_IOCTL_BFLSH 0x10000
#define TASK_IOCTL_SETBSZ 0x10001
#define TASK_IOCTL_LOCK 0x10002
#define TASK_IOCTL_UNLOCK 0x10003
#define TASK_IOCTL_GETNAME 0x10004
/*
* for /dev/dspctl/mem
*/
#define MEM_IOCTL_EXMAP 1
#define MEM_IOCTL_EXUNMAP 2
#define MEM_IOCTL_EXMAP_FLUSH 3
#define MEM_IOCTL_FBEXPORT 5
#ifdef CONFIG_ARCH_OMAP1
#define MEM_IOCTL_MMUITACK 7
#endif
#define MEM_IOCTL_MMUINIT 9
#define MEM_IOCTL_KMEM_RESERVE 11
#define MEM_IOCTL_KMEM_RELEASE 12
struct omap_dsp_mapinfo {
__u32 dspadr;
__u32 size;
};
/*
* for /dev/dspctl/twch
*/
#define TWCH_IOCTL_MKDEV 1
#define TWCH_IOCTL_RMDEV 2
#define TWCH_IOCTL_TADD 11
#define TWCH_IOCTL_TDEL 12
#define TWCH_IOCTL_TKILL 13
struct omap_dsp_taddinfo {
__u8 minor;
__u32 taskadr;
};
#define TADD_ABORTADR 0xffffffff
/* /*
* linux/arch/arm/mach-omap/dsp/ipbuf.c * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* IPBUF handler * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2002-2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2005/06/06: DSP Gateway version 3.3
*/ */
#include <linux/init.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/device.h> #include <linux/device.h>
#include <asm/signal.h> #include <linux/interrupt.h>
#include <asm/arch/dsp.h> #include <asm/arch/mailbox.h>
#include "dsp_mbcmd.h"
#include "dsp.h" #include "dsp.h"
#include "ipbuf.h" #include "ipbuf.h"
struct ipbuf **ipbuf; static struct ipbuf_head *g_ipbuf;
struct ipbcfg ipbcfg; struct ipbcfg ipbcfg;
struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad; struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad;
static struct ipblink ipb_free = IPBLINK_INIT; static struct ipblink ipb_free = IPBLINK_INIT;
static int ipbuf_sys_hold_mem_active; static int ipbuf_sys_hold_mem_active;
static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
char *buf);
static struct device_attribute dev_attr_ipbuf = __ATTR_RO(ipbuf);
void ipbuf_stop(void) void ipbuf_stop(void)
{ {
int i; int i;
device_remove_file(omap_dsp->dev, &dev_attr_ipbuf);
spin_lock(&ipb_free.lock); spin_lock(&ipb_free.lock);
INIT_IPBLINK(&ipb_free); RESET_IPBLINK(&ipb_free);
spin_unlock(&ipb_free.lock); spin_unlock(&ipb_free.lock);
ipbcfg.ln = 0; ipbcfg.ln = 0;
if (ipbuf) { if (g_ipbuf) {
kfree(ipbuf); kfree(g_ipbuf);
ipbuf = NULL; g_ipbuf = NULL;
} }
for (i = 0; i < ipbuf_sys_hold_mem_active; i++) { for (i = 0; i < ipbuf_sys_hold_mem_active; i++) {
dsp_mem_disable((void *)daram_base); dsp_mem_disable((void *)daram_base);
...@@ -59,9 +60,9 @@ void ipbuf_stop(void) ...@@ -59,9 +60,9 @@ void ipbuf_stop(void)
ipbuf_sys_hold_mem_active = 0; ipbuf_sys_hold_mem_active = 0;
} }
int ipbuf_config(unsigned short ln, unsigned short lsz, void *base) int ipbuf_config(u16 ln, u16 lsz, void *base)
{ {
unsigned long lsz_byte = ((unsigned long)lsz) << 1; size_t lsz_byte = ((size_t)lsz) << 1;
size_t size; size_t size;
int ret = 0; int ret = 0;
int i; int i;
...@@ -79,8 +80,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base) ...@@ -79,8 +80,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
if (dsp_address_validate(base, size, "global ipbuf") < 0) if (dsp_address_validate(base, size, "global ipbuf") < 0)
return -EINVAL; return -EINVAL;
ipbuf = kmalloc(sizeof(void *) * ln, GFP_KERNEL); g_ipbuf = kmalloc(sizeof(struct ipbuf_head) * ln, GFP_KERNEL);
if (ipbuf == NULL) { if (g_ipbuf == NULL) {
printk(KERN_ERR printk(KERN_ERR
"omapdsp: memory allocation for ipbuf failed.\n"); "omapdsp: memory allocation for ipbuf failed.\n");
return -ENOMEM; return -ENOMEM;
...@@ -90,7 +91,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base) ...@@ -90,7 +91,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
top = base + (sizeof(struct ipbuf) + lsz_byte) * i; top = base + (sizeof(struct ipbuf) + lsz_byte) * i;
btm = base + (sizeof(struct ipbuf) + lsz_byte) * (i+1) - 1; btm = base + (sizeof(struct ipbuf) + lsz_byte) * (i+1) - 1;
ipbuf[i] = (struct ipbuf *)top; g_ipbuf[i].p = (struct ipbuf *)top;
g_ipbuf[i].bid = i;
if (((unsigned long)top & 0xfffe0000) != if (((unsigned long)top & 0xfffe0000) !=
((unsigned long)btm & 0xfffe0000)) { ((unsigned long)btm & 0xfffe0000)) {
/* /*
...@@ -99,7 +101,7 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base) ...@@ -99,7 +101,7 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
*/ */
printk(KERN_ERR printk(KERN_ERR
"omapdsp: ipbuf[%d] crosses 64k-word boundary!\n" "omapdsp: ipbuf[%d] crosses 64k-word boundary!\n"
" @0x%p, size=0x%08lx\n", i, top, lsz_byte); " @0x%p, size=0x%08x\n", i, top, lsz_byte);
ret = -EINVAL; ret = -EINVAL;
goto free_out; goto free_out;
} }
...@@ -115,15 +117,17 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base) ...@@ -115,15 +117,17 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
" %d words * %d lines at 0x%p.\n", " %d words * %d lines at 0x%p.\n",
ipbcfg.lsz, ipbcfg.ln, ipbcfg.base); ipbcfg.lsz, ipbcfg.ln, ipbcfg.base);
device_create_file(omap_dsp->dev, &dev_attr_ipbuf);
return ret; return ret;
free_out: free_out:
kfree(ipbuf); kfree(g_ipbuf);
ipbuf = NULL; g_ipbuf = NULL;
return ret; return ret;
} }
int ipbuf_sys_config(void *p, enum arm_dsp_dir dir) int ipbuf_sys_config(void *p, arm_dsp_dir_t dir)
{ {
char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D"; char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D";
...@@ -158,7 +162,7 @@ int ipbuf_sys_config(void *p, enum arm_dsp_dir dir) ...@@ -158,7 +162,7 @@ int ipbuf_sys_config(void *p, enum arm_dsp_dir dir)
return 0; return 0;
} }
int ipbuf_p_validate(void *p, enum arm_dsp_dir dir) int ipbuf_p_validate(void *p, arm_dsp_dir_t dir)
{ {
char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D"; char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D";
...@@ -175,57 +179,60 @@ int ipbuf_p_validate(void *p, enum arm_dsp_dir dir) ...@@ -175,57 +179,60 @@ int ipbuf_p_validate(void *p, enum arm_dsp_dir dir)
/* /*
* Global IPBUF operations * Global IPBUF operations
*/ */
unsigned short get_free_ipbuf(unsigned char tid) struct ipbuf_head *bid_to_ipbuf(u16 bid)
{ {
unsigned short bid; return &g_ipbuf[bid];
}
struct ipbuf_head *get_free_ipbuf(u8 tid)
{
struct ipbuf_head *ipb_h;
if (dsp_mem_enable_ipbuf() < 0) if (dsp_mem_enable_ipbuf() < 0)
return OMAP_DSP_BID_NULL; return NULL;
spin_lock(&ipb_free.lock); spin_lock(&ipb_free.lock);
if (ipblink_empty(&ipb_free)) { if (ipblink_empty(&ipb_free)) {
/* FIXME: wait on queue when not available. */ /* FIXME: wait on queue when not available. */
bid = OMAP_DSP_BID_NULL; ipb_h = NULL;
goto out; goto out;
} }
bid = ipb_free.top; ipb_h = &g_ipbuf[ipb_free.top];
ipbuf[bid]->la = tid; /* lock */ ipb_h->p->la = tid; /* lock */
ipblink_del_top(&ipb_free, ipbuf); __ipblink_del_top(&ipb_free);
out: out:
spin_unlock(&ipb_free.lock); spin_unlock(&ipb_free.lock);
dsp_mem_disable_ipbuf(); dsp_mem_disable_ipbuf();
return bid; return ipb_h;
} }
void release_ipbuf(unsigned short bid) void release_ipbuf(struct ipbuf_head *ipb_h)
{ {
if (ipbuf[bid]->la == OMAP_DSP_TID_FREE) { if (ipb_h->p->la == TID_FREE) {
printk(KERN_WARNING printk(KERN_WARNING
"omapdsp: attempt to release unlocked IPBUF[%d].\n", "omapdsp: attempt to release unlocked IPBUF[%d].\n",
bid); ipb_h->bid);
/* /*
* FIXME: re-calc bsycnt * FIXME: re-calc bsycnt
*/ */
return; return;
} }
ipbuf[bid]->la = OMAP_DSP_TID_FREE; ipb_h->p->la = TID_FREE;
ipbuf[bid]->sa = OMAP_DSP_TID_FREE; ipb_h->p->sa = TID_FREE;
spin_lock(&ipb_free.lock); ipblink_add_tail(&ipb_free, ipb_h->bid);
ipblink_add_tail(&ipb_free, bid, ipbuf);
spin_unlock(&ipb_free.lock);
} }
static int try_yld(unsigned short bid) static int try_yld(struct ipbuf_head *ipb_h)
{ {
int status; int status;
ipbuf[bid]->sa = OMAP_DSP_TID_ANON; ipb_h->p->sa = TID_ANON;
status = dsp_mbsend(MBCMD(BKYLD), 0, bid); status = mbcompose_send(BKYLD, 0, ipb_h->bid);
if (status < 0) { if (status < 0) {
/* DSP is busy and ARM keeps this line. */ /* DSP is busy and ARM keeps this line. */
release_ipbuf(bid); release_ipbuf(ipb_h);
return status; return status;
} }
...@@ -239,12 +246,11 @@ static int try_yld(unsigned short bid) ...@@ -239,12 +246,11 @@ static int try_yld(unsigned short bid)
static void do_balance_ipbuf(void) static void do_balance_ipbuf(void)
{ {
while (ipbcfg.bsycnt <= ipbcfg.ln / 4) { while (ipbcfg.bsycnt <= ipbcfg.ln / 4) {
unsigned short bid; struct ipbuf_head *ipb_h;
bid = get_free_ipbuf(OMAP_DSP_TID_ANON); if ((ipb_h = get_free_ipbuf(TID_ANON)) == NULL)
if (bid == OMAP_DSP_BID_NULL)
return; return;
if (try_yld(bid) < 0) if (try_yld(ipb_h) < 0)
return; return;
} }
} }
...@@ -258,31 +264,31 @@ void balance_ipbuf(void) ...@@ -258,31 +264,31 @@ void balance_ipbuf(void)
} }
/* for process context */ /* for process context */
void unuse_ipbuf(unsigned short bid) void unuse_ipbuf(struct ipbuf_head *ipb_h)
{ {
if (ipbcfg.bsycnt > ipbcfg.ln / 4) { if (ipbcfg.bsycnt > ipbcfg.ln / 4) {
/* we don't have enough IPBUF lines. let's keep it. */ /* we don't have enough IPBUF lines. let's keep it. */
release_ipbuf(bid); release_ipbuf(ipb_h);
} else { } else {
/* we have enough IPBUF lines. let's return this line to DSP. */ /* we have enough IPBUF lines. let's return this line to DSP. */
ipbuf[bid]->la = OMAP_DSP_TID_ANON; ipb_h->p->la = TID_ANON;
try_yld(bid); try_yld(ipb_h);
balance_ipbuf(); balance_ipbuf();
} }
} }
/* for interrupt context */ /* for interrupt context */
void unuse_ipbuf_nowait(unsigned short bid) void unuse_ipbuf_nowait(struct ipbuf_head *ipb_h)
{ {
release_ipbuf(bid); release_ipbuf(ipb_h);
balance_ipbuf(); balance_ipbuf();
} }
/* /*
* functions called from mailbox1 interrupt routine * functions called from mailbox interrupt routine
*/ */
void mbx1_err_ipbfull(void) void mbox_err_ipbfull(void)
{ {
ipbcfg.cnt_full++; ipbcfg.cnt_full++;
} }
...@@ -294,12 +300,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr, ...@@ -294,12 +300,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
int len = 0; int len = 0;
unsigned short bid; u16 bid;
for (bid = 0; bid < ipbcfg.ln; bid++) { for (bid = 0; bid < ipbcfg.ln; bid++) {
unsigned short la = ipbuf[bid]->la; struct ipbuf_head *ipb_h = &g_ipbuf[bid];
unsigned short ld = ipbuf[bid]->ld; u16 la = ipb_h->p->la;
unsigned short c = ipbuf[bid]->c; u16 ld = ipb_h->p->ld;
u16 c = ipb_h->p->c;
if (len > PAGE_SIZE - 100) { if (len > PAGE_SIZE - 100) {
len += sprintf(buf + len, "out of buffer.\n"); len += sprintf(buf + len, "out of buffer.\n");
...@@ -307,13 +314,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr, ...@@ -307,13 +314,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
} }
len += sprintf(buf + len, "ipbuf[%d]: adr = 0x%p\n", len += sprintf(buf + len, "ipbuf[%d]: adr = 0x%p\n",
bid, ipbuf[bid]); bid, ipb_h->p);
if (la == OMAP_DSP_TID_FREE) { if (la == TID_FREE) {
len += sprintf(buf + len, len += sprintf(buf + len,
" DSPtask[%d]->Linux " " DSPtask[%d]->Linux "
"(already read and now free for Linux)\n", "(already read and now free for Linux)\n",
ld); ld);
} else if (ld == OMAP_DSP_TID_FREE) { } else if (ld == TID_FREE) {
len += sprintf(buf + len, len += sprintf(buf + len,
" Linux->DSPtask[%d] " " Linux->DSPtask[%d] "
"(already read and now free for DSP)\n", "(already read and now free for DSP)\n",
...@@ -333,7 +340,7 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr, ...@@ -333,7 +340,7 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
len += sprintf(buf + len, "\nFree IPBUF link: "); len += sprintf(buf + len, "\nFree IPBUF link: ");
spin_lock(&ipb_free.lock); spin_lock(&ipb_free.lock);
ipblink_for_each(bid, &ipb_free, ipbuf) { ipblink_for_each(bid, &ipb_free) {
len += sprintf(buf + len, "%d ", bid); len += sprintf(buf + len, "%d ", bid);
} }
spin_unlock(&ipb_free.lock); spin_unlock(&ipb_free.lock);
...@@ -344,5 +351,3 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr, ...@@ -344,5 +351,3 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
finish: finish:
return len; return len;
} }
struct device_attribute dev_attr_ipbuf = __ATTR_RO(ipbuf);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* /*
* linux/arch/arm/mach-omap/dsp/uaccess_dsp.S * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
* *
* user memory access functions for DSP driver * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
* *
* Copyright (C) 2004,2005 Nokia Corporation * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
* *
* Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
* *
* This program is free software; you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but
* it under the terms of the GNU General Public License as published by * WITHOUT ANY WARRANTY; without even the implied warranty of
* the Free Software Foundation; either version 2 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* (at your option) any later version. * General Public License for more details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
* *
* 2004/06/29: DSP Gateway version 3.3
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -202,7 +202,8 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, ...@@ -202,7 +202,8 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
omap_32k_timer_ack_irq(); omap_32k_timer_ack_irq();
now = omap_32k_sync_timer_read(); now = omap_32k_sync_timer_read();
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { while ((signed long)(now - omap_32k_last_tick)
>= OMAP_32K_TICKS_PER_HZ) {
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
timer_tick(regs); timer_tick(regs);
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment