1
0
mirror of https://git.yoctoproject.org/meta-ti synced 2026-01-12 01:20:20 +00:00

TI BSP: add support for the OMAP4430 pandaboard

Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
Koen Kooi
2011-01-12 16:02:15 +01:00
parent 675866afcb
commit 5e33c64e08
12 changed files with 3778 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
#@TYPE: Machine
#@NAME: OMAP4430 Panda
#@DESCRIPTION: Machine configuration for the OMAP4430 Panda
require conf/machine/include/omap3.inc
EXTRA_IMAGEDEPENDS = "x-load u-boot-sakoman "
XLOAD_MACHINE = "omap4430panda_config"
XLOAD_LOAD_ADDRESS = 0x40304350
PREFERRED_PROVIDER_virtual/bootloader = "u-boot-sakoman"
UBOOT_MACHINE = "omap4_panda_config"
PREFERRED_PROVIDER_virtual/kernel = "linux-omap4"
PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
XSERVER = "xserver-xorg \
xserver-xorg-extension-dri \
xserver-xorg-extension-dri2 \
xserver-xorg-extension-glx \
xf86-input-evdev \
xf86-input-mouse \
xf86-input-tslib \
xf86-video-fbdev \
xf86-input-keyboard"
GUI_MACHINE_CLASS = "bigscreen"
IMAGE_FSTYPES += "tar.bz2"
SERIAL_CONSOLE = "115200 ttyO2"
MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
MACHINE_FEATURES = "kernel26 alsa apm ext2 screen touchscreen usbgadget usbhost vfat"

View File

@@ -0,0 +1,150 @@
From 694125c6684f8bafbf5c4502659f1322fae33af2 Mon Sep 17 00:00:00 2001
From: Rob Clark <rob@ti.com>
Date: Sat, 10 Jul 2010 18:03:16 -0500
Subject: [PATCH 1/8] tiler: avoid lock-ups due to unmapped DMM entries
Due to the address remapping done for 2d buffers, when a 2d buffer is
allocated by userspace, it is possible that only partial pages map to
valid physical pages of memory. But the MMU can only protect accesses
to invalid addresses on the granualarity of full pages. Which results
in the inconvenient situation where access to a perfectly valid address
(from the point of view of a userspace process's memory map) can lock
up the processor.
To protect against this, a single dummy page is allocated at boot time
and mapped in to the entire DMM space. When actual buffers are alloc'd,
the mapping is replaced with the actual pages allocated for the buffer.
And when the actual TILER buffer is freed, the mappings are set back to
the dummy page.
As a result, there is no longer the need for a clear() function in DMM.
Instead the clear operation is simply remapping DMM entries back to the
dummy page.
As an added advantage, now pages are properly unmapped from DMM when
TILER buffers are freed, avoiding the potential to corrupt pages that
where previously allocated for TILER buffers.
---
drivers/media/video/dmm/tmm.h | 12 ------------
drivers/media/video/dmm/tmm_pat.c | 1 -
drivers/media/video/tiler/tiler.c | 27 ++++++++++++++++++++++++++-
3 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/media/video/dmm/tmm.h b/drivers/media/video/dmm/tmm.h
index deaeca5..b86dbc3 100644
--- a/drivers/media/video/dmm/tmm.h
+++ b/drivers/media/video/dmm/tmm.h
@@ -27,7 +27,6 @@ struct tmm {
u32 *(*get) (struct tmm *tmm, s32 num_pages);
void (*free) (struct tmm *tmm, u32 *pages);
s32 (*map) (struct tmm *tmm, struct pat_area area, u32 page_pa);
- void (*clear) (struct tmm *tmm, struct pat_area area);
void (*deinit) (struct tmm *tmm);
};
@@ -68,17 +67,6 @@ s32 tmm_map(struct tmm *tmm, struct pat_area area, u32 page_pa)
}
/**
- * Clears the physical address translator.
- * @param area PAT area
- */
-static inline
-void tmm_clear(struct tmm *tmm, struct pat_area area)
-{
- if (tmm && tmm->clear && tmm->pvt)
- tmm->clear(tmm, area);
-}
-
-/**
* Checks whether tiler memory manager supports mapping
*/
static inline
diff --git a/drivers/media/video/dmm/tmm_pat.c b/drivers/media/video/dmm/tmm_pat.c
index 4ee59bd..c9c9aa5 100644
--- a/drivers/media/video/dmm/tmm_pat.c
+++ b/drivers/media/video/dmm/tmm_pat.c
@@ -316,7 +316,6 @@ struct tmm *tmm_pat_init(u32 pat_id)
tmm->get = tmm_pat_get_pages;
tmm->free = tmm_pat_free_pages;
tmm->map = tmm_pat_map;
- tmm->clear = NULL; /* not yet supported */
return tmm;
}
diff --git a/drivers/media/video/tiler/tiler.c b/drivers/media/video/tiler/tiler.c
index 1c117eb..9ce065c 100644
--- a/drivers/media/video/tiler/tiler.c
+++ b/drivers/media/video/tiler/tiler.c
@@ -125,6 +125,9 @@ static struct tmm *tmm[TILER_FORMATS];
static u32 *dmac_va;
static dma_addr_t dmac_pa;
+static u32 *dummy_mem;
+static u32 dummy_pa;
+
#define TCM(fmt) tcm[(fmt) - TILFMT_8BIT]
#define TCM_SS(ssptr) TCM(TILER_GET_ACC_MODE(ssptr))
#define TCM_SET(fmt, i) tcm[(fmt) - TILFMT_8BIT] = i
@@ -410,6 +413,7 @@ static void clear_pat(struct tmm *tmm, struct tcm_area *area)
{
struct pat_area p_area = {0};
struct tcm_area slice, area_s;
+ int i;
tcm_for_each_slice(slice, *area, area_s) {
p_area.x0 = slice.p0.x;
@@ -417,7 +421,11 @@ static void clear_pat(struct tmm *tmm, struct tcm_area *area)
p_area.x1 = slice.p1.x;
p_area.y1 = slice.p1.y;
- tmm_clear(tmm, p_area);
+ for (i = 0; i<tcm_sizeof(slice); i++) {
+ dmac_va[i] = dummy_pa;
+ }
+
+ tmm_map(tmm, p_area, dmac_pa);
}
}
@@ -1467,6 +1475,8 @@ static void __exit tiler_exit(void)
kfree(tiler_device);
device_destroy(tilerdev_class, MKDEV(tiler_major, tiler_minor));
class_destroy(tilerdev_class);
+
+ free_pages_exact(dummy_mem, PAGE_SIZE);
}
static s32 tiler_open(struct inode *ip, struct file *filp)
@@ -1509,6 +1519,7 @@ static s32 __init tiler_init(void)
struct tcm_pt div_pt;
struct tcm *sita = NULL;
struct tmm *tmm_pat = NULL;
+ struct tcm_area area = {0};
if (!cpu_is_omap44xx())
return 0;
@@ -1583,6 +1594,20 @@ static s32 __init tiler_init(void)
BLOCKING_INIT_NOTIFIER_HEAD(&tiler_device->notifier);
id = 0xda7a000;
+ /* Dummy page for filling unused entries in dmm (dmac_va):
+ */
+ dummy_mem = alloc_pages_exact(PAGE_SIZE, GFP_KERNEL);
+ dummy_pa = virt_to_phys(dummy_mem);
+
+ /* clear the entire dmm space:
+ */
+ area.tcm = sita;
+ area.p0.x = 0;
+ area.p0.y = 0;
+ area.p1.x = TILER_WIDTH - 1;
+ area.p1.y = TILER_HEIGHT - 1;
+ clear_pat(tmm_pat, &area);
+
error:
/* TODO: error handling for device registration */
if (r) {
--
1.6.6.1

View File

@@ -0,0 +1,29 @@
From 0752e20ce23c68183503ac1d7cc5efc66f8cda1d Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Mon, 13 Oct 2008 20:32:16 +0100
Subject: [PATCH 2/8] ARM: Add prompt for CONFIG_ALIGNMENT_TRAP
This adds a prompt text for CONFIG_ALIGNMENT_TRAP, thus making it
visible in make *config.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
arch/arm/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4432566..4940c98 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1361,7 +1361,7 @@ config LEDS_CPU
will overrule the CPU usage LED.
config ALIGNMENT_TRAP
- bool
+ bool "Enable alignment trap"
depends on CPU_CP15_MMU
default y if !ARCH_EBSA110
select HAVE_PROC_CPU if PROC_FS
--
1.6.6.1

View File

@@ -0,0 +1,31 @@
From 8d8ae376807b2f104dcbcea19263ccecbd10feb8 Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Sat, 28 Mar 2009 13:21:55 +0000
Subject: [PATCH 3/8] ARM: Print warning on alignment trap in kernel mode
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
arch/arm/mm/alignment.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 6f98c35..1cda537 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -760,6 +760,13 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
ai_sys += 1;
+ printk("Alignment trap in kernel: %s (%d) PC=0x%08lx Instr=0x%0*lx "
+ "Address=0x%08lx FSR 0x%03x\n", current->comm,
+ task_pid_nr(current), instrptr,
+ thumb_mode(regs) ? 4 : 8,
+ thumb_mode(regs) ? tinstr : instr,
+ addr, fsr);
+
fixup:
regs->ARM_pc += isize;
--
1.6.6.1

View File

@@ -0,0 +1,219 @@
From e0a1a2019cac127f3cd86ea65f623c2c56970dcb Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 10 Nov 2009 00:39:21 +0000
Subject: [PATCH 4/8] ARM: Expose some CPU control registers via sysfs
This creates sysfs files under /sys/devices/system/cpu/cpuN
exposing the values of the control register, auxiliary control
register, L2 cache auxiliary control register, and PMON registers.
Writing to the files allows setting the value of bits which are
safe to change at any time.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
arch/arm/Kconfig | 5 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/sysfs_v7.c | 163 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/kernel/sysfs_v7.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4940c98..f7f8ddc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1402,6 +1402,11 @@ config CC_STACKPROTECTOR
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.
+config CPU_V7_SYSFS
+ bool
+ depends on CPU_V7 && SYSFS
+ default y
+
endmenu
menu "Boot options"
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 26d302c..bbebeec 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
+obj-$(CONFIG_CPU_V7_SYSFS) += sysfs_v7.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
diff --git a/arch/arm/kernel/sysfs_v7.c b/arch/arm/kernel/sysfs_v7.c
new file mode 100644
index 0000000..0e492db
--- /dev/null
+++ b/arch/arm/kernel/sysfs_v7.c
@@ -0,0 +1,163 @@
+/*
+ * linux/arch/arm/kernel/sysfs.c
+ *
+ * Copyright (C) 2008 Mans Rullgard
+ *
+ * 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/kernel.h>
+#include <linux/cpu.h>
+#include <linux/sysdev.h>
+#include <linux/fs.h>
+
+#define SETBITS(val, bits, new) \
+ do { \
+ val &= ~bits; \
+ val |= new & bits; \
+ } while (0)
+
+#define SHOW_REG(name, opc1, crn, crm, opc2) \
+static ssize_t name##_show(struct sys_device *dev, \
+ struct sysdev_attribute *attr, \
+ char *buf) \
+{ \
+ unsigned val; \
+ asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
+ return snprintf(buf, PAGE_SIZE, "%08x\n", val); \
+}
+
+#define STORE_REG(name, opc1, crn, crm, opc2, bits) \
+static ssize_t name##_store(struct sys_device *dev, \
+ struct sysdev_attribute *attr, \
+ const char *buf, size_t size) \
+{ \
+ char *end; \
+ unsigned new = simple_strtoul(buf, &end, 0); \
+ unsigned val; \
+ \
+ if (end == buf) \
+ return -EINVAL; \
+ \
+ asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
+ SETBITS(val, bits, new); \
+ asm ("mcr p15,"#opc1", %0,"#crn","#crm","#opc2 :: "r"(val)); \
+ \
+ if (*end == '\n') \
+ end++; \
+ return end - buf; \
+}
+
+#define RD_REG(name, opc1, crn, crm, opc2) \
+ SHOW_REG(name, opc1, crn, crm, opc2) \
+ static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, NULL)
+
+#define RDWR_REG(name, opc1, crn, crm, opc2, bits) \
+ SHOW_REG(name, opc1, crn, crm, opc2) \
+ STORE_REG(name, opc1, crn, crm, opc2, bits) \
+ static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, name##_store)
+
+RDWR_REG(control, 0, c1, c0, 0, 0x802);
+
+SHOW_REG(aux_ctl, 0, c1, c0, 1)
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static ssize_t aux_ctl_store(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ char *end;
+ unsigned new = simple_strtoul(buf, &end, 0);
+ unsigned val;
+
+ if (end == buf)
+ return -EINVAL;
+
+ asm ("mrc p15, 0, %0, c1, c0, 1" : "=r"(val));
+ SETBITS(val, 0xff8, new);
+ val &= ~2;
+ asm ("mov r0, %0 \n\t"
+ "mov r12, #3 \n\t"
+ "smc #0 \n\t"
+ :: "r"(val) : "r0", "r12");
+
+ return end - buf;
+}
+#define AUX_WR S_IWUSR
+#else
+#define aux_ctl_store NULL
+#define AUX_WR 0
+#endif
+
+static SYSDEV_ATTR(aux_control, S_IRUGO|AUX_WR, aux_ctl_show, aux_ctl_store);
+
+SHOW_REG(l2_aux_ctl, 1, c9, c0, 2)
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static ssize_t l2_aux_ctl_store(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ char *end;
+ unsigned new = simple_strtoul(buf, &end, 0);
+ unsigned val;
+
+ if (end == buf)
+ return -EINVAL;
+
+ asm ("mrc p15, 1, %0, c9, c0, 2" : "=r"(val));
+ SETBITS(val, 0xbc00000, new);
+ asm ("mov r0, %0 \n\t"
+ "mov r12, #2 \n\t"
+ "smc #0 \n\t"
+ :: "r"(val) : "r0", "r12");
+
+ return end - buf;
+}
+#define L2AUX_WR S_IWUSR
+#else
+#define l2_aux_ctl_store NULL
+#define L2AUX_WR 0
+#endif
+
+static SYSDEV_ATTR(l2_aux_control, S_IRUGO|L2AUX_WR,
+ l2_aux_ctl_show, l2_aux_ctl_store);
+
+RDWR_REG(pmon_pmnc, 0, c9, c12, 0, 0x3f)
+RDWR_REG(pmon_cntens, 0, c9, c12, 1, 0xffffffff)
+RDWR_REG(pmon_cntenc, 0, c9, c12, 2, 0xffffffff)
+RDWR_REG(pmon_ccnt, 0, c9, c13, 0, 0xffffffff)
+RDWR_REG(pmon_useren, 0, c9, c14, 0, 1)
+RDWR_REG(pmon_intens, 0, c9, c14, 1, 0xffffffff)
+RDWR_REG(pmon_intenc, 0, c9, c14, 2, 0xffffffff)
+
+#define REG_ATTR(sysdev, name) \
+ do { \
+ int err = sysfs_create_file(&sysdev->kobj, &name.attr); \
+ WARN_ON(err != 0); \
+ } while (0)
+
+static int __init cpu_sysfs_init(void)
+{
+ struct sys_device *sysdev;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ sysdev = get_cpu_sysdev(cpu);
+ REG_ATTR(sysdev, attr_control);
+ REG_ATTR(sysdev, attr_aux_control);
+ REG_ATTR(sysdev, attr_l2_aux_control);
+ REG_ATTR(sysdev, attr_pmon_pmnc);
+ REG_ATTR(sysdev, attr_pmon_cntens);
+ REG_ATTR(sysdev, attr_pmon_cntenc);
+ REG_ATTR(sysdev, attr_pmon_ccnt);
+ REG_ATTR(sysdev, attr_pmon_useren);
+ REG_ATTR(sysdev, attr_pmon_intens);
+ REG_ATTR(sysdev, attr_pmon_intenc);
+ }
+
+ return 0;
+}
+device_initcall(cpu_sysfs_init);
--
1.6.6.1

View File

@@ -0,0 +1,48 @@
From 85abaca878cc8c0a70e636975e05650012ec4bb2 Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 10 Nov 2009 00:41:54 +0000
Subject: [PATCH 5/8] ARM: Add option to allow userspace PLE access
This adds a Kconfig option to allow userspace to access the L2 preload
engine (PLE) found in Cortex-A8 and A9.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
arch/arm/kernel/head.S | 4 ++++
arch/arm/mm/Kconfig | 8 ++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf9..659ec9e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -172,6 +172,10 @@ __enable_mmu:
#ifdef CONFIG_CPU_ICACHE_DISABLE
bic r0, r0, #CR_I
#endif
+#ifdef CONFIG_USER_L2_PLE
+ mov r5, #3
+ mcr p15, 0, r5, c11, c1, 0
+#endif
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index bad0d73..4a337ab 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -853,3 +853,11 @@ config ARCH_HAS_BARRIERS
help
This option allows the use of custom mandatory barriers
included via the mach/barriers.h file.
+
+config USER_L2_PLE
+ bool "Enable userspace access to the L2 PLE"
+ depends on CPU_V7
+ default n
+ help
+ Enable userspace access to the L2 preload engine (PLE) available
+ in Cortex-A series ARM processors.
--
1.6.6.1

View File

@@ -0,0 +1,49 @@
From 47cb7627876fdc6a6b90eb86dc77705a6df0072a Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Tue, 10 Nov 2009 00:52:56 +0000
Subject: [PATCH 6/8] ARM: Add option to allow userspace access to performance counters
This adds an option to allow userspace access to the performance monitor
registers of the Cortex-A8.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
arch/arm/mm/Kconfig | 7 +++++++
arch/arm/mm/proc-v7.S | 6 ++++++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4a337ab..a49ff8b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -861,3 +861,10 @@ config USER_L2_PLE
help
Enable userspace access to the L2 preload engine (PLE) available
in Cortex-A series ARM processors.
+
+config USER_PMON
+ bool "Enable userspace access to performance counters"
+ depends on CPU_V7
+ default n
+ help
+ Enable userpsace access to the performance monitor registers.
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c1c3fe0..bd10c28 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -276,6 +276,12 @@ __v7_setup:
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
#endif
+
+#ifdef CONFIG_USER_PMON
+ mov r0, #1
+ mcr p15, 0, r0, c9, c14, 0
+#endif
+
adr r5, v7_crval
ldmia r5, {r5, r6}
#ifdef CONFIG_CPU_ENDIAN_BE8
--
1.6.6.1

View File

@@ -0,0 +1,26 @@
From 4223359216dc16d70ac0aced7078e66602500d66 Mon Sep 17 00:00:00 2001
From: Mans Rullgard <mans@mansr.com>
Date: Sat, 30 Oct 2010 15:36:06 +0100
Subject: [PATCH 7/8] OMAP4: do not force-select options which are not required
---
arch/arm/plat-omap/Kconfig | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7bfaeb8..934fe64 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -39,9 +39,6 @@ config ARCH_OMAP4
select CPU_V7
select ARM_GIC
select ARM_ERRATA_720789
- select ARM_THUMB
- select ARM_THUMBEE
- select DEVTMPFS
select UNIX
select USB_ARCH_HAS_EHCI
endchoice
--
1.6.6.1

View File

@@ -0,0 +1,203 @@
From b3f993f02eb4cf2018c78fb5b9cd5f220fda9589 Mon Sep 17 00:00:00 2001
From: Shravan Suryanarayana <shravan.s@ti.com>
Date: Wed, 22 Dec 2010 09:42:43 +0100
Subject: [PATCH 8/8] omap4: pandaboard: add support for DVI output
---
arch/arm/mach-omap2/board-omap4panda.c | 45 +++++++++++++++++++++++++++++++-
drivers/video/omap2/dss/dispc.c | 6 ++++
drivers/video/omap2/dss/dpi.c | 3 --
drivers/video/omap2/dss/dss.c | 37 ++++++++++++++++++++++++-
4 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 1f6d59e..323daa6 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -47,6 +47,7 @@
#include <plat/hwspinlock.h>
#include <plat/opp_twl_tps.h>
#include "hsmmc.h"
+#include "mux.h"
#define GPIO_HUB_POWER 1
#define GPIO_HUB_NRESET_39 39
@@ -55,6 +56,8 @@
#define GPIO_BOARD_ID1 101
#define GPIO_BOARD_ID2 171
+#define PANDA_DVI_CHIP_ENABLE_GPIO 0
+
static int board_revision;
/* wl127x BT, FM, GPS connectivity chip */
@@ -134,16 +137,45 @@ static struct omap_dss_device panda_hdmi_device = {
.channel = OMAP_DSS_CHANNEL_DIGIT,
};
+static int panda_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 1);
+ gpio_direction_output(dssdev->reset_gpio, 1);
+
+ return 0;
+}
+
+static void panda_disable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 0);
+ gpio_direction_output(dssdev->reset_gpio, 0);
+}
+
+static struct omap_dss_device panda_dvi_device = {
+ .name = "dvi",
+ .driver_name = "generic_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .platform_enable = panda_enable_dvi,
+ .platform_disable = panda_disable_dvi,
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+ .reset_gpio = PANDA_DVI_CHIP_ENABLE_GPIO,
+};
+
static struct omap_dss_device *panda_dss_devices[] = {
&panda_hdmi_device,
+ &panda_dvi_device,
};
static struct omap_dss_board_info panda_dss_data = {
.num_devices = ARRAY_SIZE(panda_dss_devices),
.devices = panda_dss_devices,
- .default_device = &panda_hdmi_device,
+ .default_device = &panda_hdmi_device,
};
+
static struct platform_device *panda_devices[] __initdata = {
&leds_gpio,
&sdp4430_hdmi_audio_device,
@@ -158,6 +190,16 @@ static void __init omap4_display_init(void)
/* Turning on DSI PHY Mux*/
__raw_writel(dsimux, phymux_base+0x618);
dsimux = __raw_readl(phymux_base+0x618);
+
+ int r = 0;
+ omap_mux_init_gpio(panda_dvi_device.reset_gpio, OMAP_PULL_UP | OMAP_PULL_ENA | OMAP_MUX_MODE3);
+ r = gpio_request(panda_dvi_device.reset_gpio, "DVI reset");
+ if (r) {
+ printk(KERN_ERR "failed to get DVI reset GPIO\n");
+ return;
+ }
+ gpio_direction_output(panda_dvi_device.reset_gpio, 0);
+
}
#else
@@ -207,6 +249,7 @@ static struct omap2_hsmmc_info mmc[] = {
.mmc = 1,
.wires = 8,
.gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
},
{
.mmc = 5,
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 42dfb1f..06f1989 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3818,6 +3818,12 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
else
dispc_write_reg(DISPC_DIVISOR,
FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
+
+ // DISPC_DIVISOR1 is actually mapped to DISPC_DIVISOR memory block (see #define at the beginning of this file);
+ // We need to write the value 1 (as opposed to default value 4); otherwise, we can't hit the pixel clock needed for
+ // higher resolutions and will have a stairstep / tearing display
+ dispc_write_reg(DISPC_DIVISOR1, FLD_VAL(1, 23, 16) | FLD_VAL(1, 7, 0));
+
enable_clocks(0);
}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 33e046e..29bffef 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -97,9 +97,6 @@ static int dpi_set_dispc_clk(enum omap_channel channel, bool is_tft,
struct dispc_clock_info dispc_cinfo;
int r;
- if (cpu_is_omap44xx()) /*TODO Check this */
- return 0;
-
r = dss_calc_clock_div(is_tft, pck_req, &dss_cinfo, &dispc_cinfo);
if (r)
return r;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index a69b754..2eff8f8 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -136,7 +136,7 @@ void dss_restore_context(void)
bool dss_get_mainclk_state()
{
- return dss.mainclk_state;
+ return true;
}
/*
@@ -501,9 +501,24 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
int match = 0;
int min_fck_per_pck;
- prate = dss_get_dpll4_rate();
+// prate = dss_get_dpll4_rate();
fck = dss_clk_get_rate(DSS_CLK_FCK1);
+
+ if (!cpu_is_omap44xx()) {
+ prate = dss_get_dpll4_rate();
+ } else {
+ /* Linux ARM clk framework issue currently all DPLL lock frequency
+ * multipliers are not configured properly. Hence multiplying by
+ * 2 to get the right pixel clock dividers.
+ *
+ * TODO: Need to change this once appropriate patches are added
+ * to clock framework.
+ */
+ fck *= 2;
+ }
+
+
if (req_pck == dss.cache_req_pck &&
((cpu_is_omap34xx() && prate == dss.cache_prate) ||
dss.cache_dss_cinfo.fck == fck)) {
@@ -575,6 +590,24 @@ retry:
goto found;
}
}
+ } else if (cpu_is_omap44xx()) {
+ struct dispc_clock_info cur_dispc;
+ /* we can not change fclk on OMAP4 */
+
+ dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
+ match = 1;
+
+ if (abs(cur_dispc.pck - req_pck) < abs(best_dispc.pck - req_pck)) {
+ best_dss.fck = fck;
+ best_dss.fck_div = 1;
+
+ best_dispc = cur_dispc;
+
+ if (cur_dispc.pck == req_pck)
+ goto found;
+ }
+
+
} else {
BUG();
}
--
1.6.6.1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
COMPATIBLE_MACHINE = "omap4430-panda"
require multi-kernel.inc
CORTEXA8FIXUP = "no"
SRCREV = "35528f5b0481485654a6577306f7a80d9e6a5cf5"
SRC_URI = "git://dev.omapzoom.org/pub/scm/integration/kernel-ubuntu.git;protocol=git;branch=ti-ubuntu-L24.11 \
file://0001-tiler-avoid-lock-ups-due-to-unmapped-DMM-entries.patch \
file://0002-ARM-Add-prompt-for-CONFIG_ALIGNMENT_TRAP.patch \
file://0003-ARM-Print-warning-on-alignment-trap-in-kernel-mode.patch \
file://0004-ARM-Expose-some-CPU-control-registers-via-sysfs.patch \
file://0005-ARM-Add-option-to-allow-userspace-PLE-access.patch \
file://0006-ARM-Add-option-to-allow-userspace-access-to-performa.patch \
file://0007-OMAP4-do-not-force-select-options-which-are-not-requ.patch \
file://0008-omap4-pandaboard-add-support-for-DVI-output.patch \
file://defconfig"
S = "${WORKDIR}/git"

View File

@@ -0,0 +1,18 @@
require u-boot.inc
FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/u-boot-sakoman-git/"
SRCREV = "261733408a27d14590cf3ec6b596461808050e32"
PV = "2010.12+${PR}+git${SRCREV}"
SRC_URI = "git://www.sakoman.com/git/u-boot.git;branch=omap4-exp;protocol=git \
"
S = "${WORKDIR}/git"
do_compile () {
unset LDFLAGS
unset CFLAGS
unset CPPFLAGS
oe_runmake all
}