M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
if PLAT_VERSATILE
config PLAT_VERSATILE_CLCD
bool
config PLAT_VERSATILE_FPGA_IRQ
bool
config PLAT_VERSATILE_LEDS
def_bool y if LEDS_CLASS
depends on ARCH_REALVIEW || ARCH_VERSATILE
config PLAT_VERSATILE_SCHED_CLOCK
def_bool y
endif
+6
View File
@@ -0,0 +1,6 @@
obj-y := clock.o
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+182
View File
@@ -0,0 +1,182 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <plat/clcd.h>
static struct clcd_panel vga = {
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
.bpp = 16,
};
static struct clcd_panel xvga = {
.mode = {
.name = "XVGA",
.refresh = 60,
.xres = 1024,
.yres = 768,
.pixclock = 15748,
.left_margin = 152,
.right_margin = 48,
.upper_margin = 23,
.lower_margin = 3,
.hsync_len = 104,
.vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
.bpp = 16,
};
/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
static struct clcd_panel sanyo_tm38qv67a02a = {
.mode = {
.name = "Sanyo TM38QV67A02A",
.refresh = 116,
.xres = 320,
.yres = 240,
.pixclock = 100000,
.left_margin = 6,
.right_margin = 6,
.upper_margin = 5,
.lower_margin = 5,
.hsync_len = 6,
.vsync_len = 6,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
static struct clcd_panel sanyo_2_5_in = {
.mode = {
.name = "Sanyo QVGA Portrait",
.refresh = 116,
.xres = 240,
.yres = 320,
.pixclock = 100000,
.left_margin = 20,
.right_margin = 10,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 10,
.vsync_len = 2,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
static struct clcd_panel epson_l2f50113t00 = {
.mode = {
.name = "Epson L2F50113T00",
.refresh = 390,
.xres = 176,
.yres = 220,
.pixclock = 62500,
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 0,
.hsync_len = 3,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
static struct clcd_panel *panels[] = {
&vga,
&xvga,
&sanyo_tm38qv67a02a,
&sanyo_2_5_in,
&epson_l2f50113t00,
};
struct clcd_panel *versatile_clcd_get_panel(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(panels); i++)
if (strcmp(panels[i]->mode.name, name) == 0)
break;
if (i < ARRAY_SIZE(panels))
return panels[i];
pr_err("CLCD: couldn't get parameters for panel %s\n", name);
return NULL;
}
int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
{
dma_addr_t dma;
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
&dma, GFP_KERNEL);
if (!fb->fb.screen_base) {
pr_err("CLCD: unable to map framebuffer\n");
return -ENOMEM;
}
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = framesize;
return 0;
}
int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma,
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
void versatile_clcd_remove_dma(struct clcd_fb *fb)
{
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
}
+74
View File
@@ -0,0 +1,74 @@
/*
* linux/arch/arm/plat-versatile/clock.c
*
* Copyright (C) 2004 ARM Limited.
* Written by Deep Blue Solutions Limited.
*
* 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.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <asm/hardware/icst.h>
#include <mach/clkdev.h>
int clk_enable(struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
long ret = -EIO;
if (clk->ops && clk->ops->round)
ret = clk->ops->round(clk, rate);
return ret;
}
EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret = -EIO;
if (clk->ops && clk->ops->set)
ret = clk->ops->set(clk, rate);
return ret;
}
EXPORT_SYMBOL(clk_set_rate);
long icst_clk_round(struct clk *clk, unsigned long rate)
{
struct icst_vco vco;
vco = icst_hz_to_vco(clk->params, rate);
return icst_hz(clk->params, vco);
}
EXPORT_SYMBOL(icst_clk_round);
int icst_clk_set(struct clk *clk, unsigned long rate)
{
struct icst_vco vco;
vco = icst_hz_to_vco(clk->params, rate);
clk->rate = icst_hz(clk->params, vco);
clk->ops->setvco(clk, vco);
return 0;
}
EXPORT_SYMBOL(icst_clk_set);
+72
View File
@@ -0,0 +1,72 @@
/*
* Support for Versatile FPGA-based IRQ controllers
*/
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/mach/irq.h>
#include <plat/fpga-irq.h>
#define IRQ_STATUS 0x00
#define IRQ_RAW_STATUS 0x04
#define IRQ_ENABLE_SET 0x08
#define IRQ_ENABLE_CLEAR 0x0c
static void fpga_irq_mask(struct irq_data *d)
{
struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
u32 mask = 1 << (d->irq - f->irq_start);
writel(mask, f->base + IRQ_ENABLE_CLEAR);
}
static void fpga_irq_unmask(struct irq_data *d)
{
struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
u32 mask = 1 << (d->irq - f->irq_start);
writel(mask, f->base + IRQ_ENABLE_SET);
}
static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
{
struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
u32 status = readl(f->base + IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(irq, desc);
return;
}
do {
irq = ffs(status) - 1;
status &= ~(1 << irq);
generic_handle_irq(irq + f->irq_start);
} while (status);
}
void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
{
unsigned int i;
f->chip.irq_ack = fpga_irq_mask;
f->chip.irq_mask = fpga_irq_mask;
f->chip.irq_unmask = fpga_irq_unmask;
if (parent_irq != -1) {
irq_set_handler_data(parent_irq, f);
irq_set_chained_handler(parent_irq, fpga_irq_handle);
}
for (i = 0; i < 32; i++) {
if (valid & (1 << i)) {
unsigned int irq = f->irq_start + i;
irq_set_chip_data(irq, f);
irq_set_chip_and_handler(irq, &f->chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
}
+41
View File
@@ -0,0 +1,41 @@
/*
* linux/arch/arm/plat-versatile/headsmp.S
*
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
*
* 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.
*/
#include <linux/linkage.h>
#include <linux/init.h>
__INIT
/*
* Realview/Versatile Express specific entry point for secondary CPUs.
* This provides a "holding pen" into which all secondary cores are held
* until we're ready for them to initialise.
*/
ENTRY(versatile_secondary_startup)
mrc p15, 0, r0, c0, c0, 5
and r0, r0, #15
adr r4, 1f
ldmia r4, {r5, r6}
sub r4, r4, r5
add r6, r6, r4
pen: ldr r7, [r6]
cmp r7, r0
bne pen
/*
* we've been released from the holding pen: secondary_stack
* should now contain the SVC stack for this core
*/
b secondary_startup
.align
1: .long .
.long pen_release
ENDPROC(versatile_secondary_startup)
@@ -0,0 +1,9 @@
#ifndef PLAT_CLCD_H
#define PLAT_CLCD_H
struct clcd_panel *versatile_clcd_get_panel(const char *);
int versatile_clcd_setup_dma(struct clcd_fb *, unsigned long);
int versatile_clcd_mmap_dma(struct clcd_fb *, struct vm_area_struct *);
void versatile_clcd_remove_dma(struct clcd_fb *);
#endif
@@ -0,0 +1,15 @@
#ifndef PLAT_CLOCK_H
#define PLAT_CLOCK_H
#include <asm/hardware/icst.h>
struct clk_ops {
long (*round)(struct clk *, unsigned long);
int (*set)(struct clk *, unsigned long);
void (*setvco)(struct clk *, struct icst_vco);
};
int icst_clk_set(struct clk *, unsigned long);
long icst_clk_round(struct clk *, unsigned long);
#endif
@@ -0,0 +1,12 @@
#ifndef PLAT_FPGA_IRQ_H
#define PLAT_FPGA_IRQ_H
struct fpga_irq_data {
void __iomem *base;
unsigned int irq_start;
struct irq_chip chip;
};
void fpga_irq_init(int, u32, struct fpga_irq_data *);
#endif
@@ -0,0 +1,6 @@
#ifndef ARM_PLAT_SCHED_CLOCK_H
#define ARM_PLAT_SCHED_CLOCK_H
void versatile_sched_clock_init(void __iomem *, unsigned long);
#endif
+103
View File
@@ -0,0 +1,103 @@
/*
* Driver for the 8 user LEDs found on the RealViews and Versatiles
* Based on DaVinci's DM365 board code
*
* License terms: GNU General Public License (GPL) version 2
* Author: Linus Walleij <triad@df.lth.se>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#ifdef VERSATILE_SYS_BASE
#define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
#endif
#ifdef REALVIEW_SYS_BASE
#define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
#endif
struct versatile_led {
struct led_classdev cdev;
u8 mask;
};
/*
* The triggers lines up below will only be used if the
* LED triggers are compiled in.
*/
static const struct {
const char *name;
const char *trigger;
} versatile_leds[] = {
{ "versatile:0", "heartbeat", },
{ "versatile:1", "mmc0", },
{ "versatile:2", },
{ "versatile:3", },
{ "versatile:4", },
{ "versatile:5", },
{ "versatile:6", },
{ "versatile:7", },
};
static void versatile_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct versatile_led *led = container_of(cdev,
struct versatile_led, cdev);
u32 reg = readl(LEDREG);
if (b != LED_OFF)
reg |= led->mask;
else
reg &= ~led->mask;
writel(reg, LEDREG);
}
static enum led_brightness versatile_led_get(struct led_classdev *cdev)
{
struct versatile_led *led = container_of(cdev,
struct versatile_led, cdev);
u32 reg = readl(LEDREG);
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
static int __init versatile_leds_init(void)
{
int i;
/* All ON */
writel(0xff, LEDREG);
for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) {
struct versatile_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = versatile_leds[i].name;
led->cdev.brightness_set = versatile_led_set;
led->cdev.brightness_get = versatile_led_get;
led->cdev.default_trigger = versatile_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(versatile_leds_init);
+106
View File
@@ -0,0 +1,106 @@
/*
* linux/arch/arm/plat-versatile/platsmp.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* 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.
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include <asm/hardware/gic.h>
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);
/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
/*
* Set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);
/*
* This is really belt and braces; we hold unintended secondary
* CPUs in the holding pen until we're ready for them. However,
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
write_pen_release(cpu_logical_map(cpu));
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
gic_raise_softirq(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;
udelay(10);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);
return pen_release != -1 ? -ENOSYS : 0;
}
@@ -0,0 +1,41 @@
/*
* linux/arch/arm/plat-versatile/sched-clock.c
*
* Copyright (C) 1999 - 2003 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/sched_clock.h>
#include <plat/sched_clock.h>
static void __iomem *ctr;
static u32 notrace versatile_read_sched_clock(void)
{
if (ctr)
return readl(ctr);
return 0;
}
void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
{
ctr = reg;
setup_sched_clock(versatile_read_sched_clock, 32, rate);
}