Commit 96d928ed authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xtensa-20150416' of git://github.com/czankel/xtensa-linux

Pull Xtensa updates from Chris Zankel:

 - fix linker script transformation for .text / .text.fixup

 - wire bpf and execveat syscalls

 - provide __NR_sync_file_range2 instead of __NR_sync_file_range, as
   that's what xtensa uses.

 - make xtfpgs LCD driver functional and configurable.  This fixes
   hardware lockup on KC705/ML605 boot

 - add audio subsystem bits to xtfpga DTS and provide sample KC705
   config with audio features enabled

 - add CY7C67300 USB controller support to XTFPGA

 - fix locking issues in ISS network driver

 - document PIC and MX interrupt distributor device tree bindings

* tag 'xtensa-20150416' of git://github.com/czankel/xtensa-linux:
  xtensa: xtfpga: add CY7C67300 USB controller support
  irqchip: xtensa-pic: xtensa-mx: document DT bindings
  xtensa: ISS: fix locking in TAP network adapter
  xtensa: Fix fix linker script transformation for .text / .text.fixup
  xtensa: provide __NR_sync_file_range2 instead of __NR_sync_file_range
  xtensa: wire bpf and execveat syscalls
  xtensa: xtfpga: fix hardware lockup caused by LCD driver
  xtensa: xtfpga: provide defconfig with audio subsystem
  xtensa: xtfpga: add audio card to xtfpga DTS
parents e076b7c1 2ba9268d
* Xtensa Interrupt Distributor and Programmable Interrupt Controller (MX)
Required properties:
- compatible: Should be "cdns,xtensa-mx".
Remaining properties have exact same meaning as in Xtensa PIC
(see cdns,xtensa-pic.txt).
Examples:
pic: pic {
compatible = "cdns,xtensa-mx";
/* one cell: internal irq number,
* two cells: second cell == 0: internal irq number
* second cell == 1: external irq number
*/
#interrupt-cells = <2>;
interrupt-controller;
};
* Xtensa built-in Programmable Interrupt Controller (PIC)
Required properties:
- compatible: Should be "cdns,xtensa-pic".
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: The number of cells to define the interrupts.
It may be either 1 or 2.
When it's 1, the first cell is the internal IRQ number.
When it's 2, the first cell is the IRQ number, and the second cell
specifies whether it's internal (0) or external (1).
Periferals are usually connected to a fixed external IRQ, but for different
core variants it may be mapped to different internal IRQ.
IRQ sensitivity and priority are fixed for each core variant and may not be
changed at runtime.
Examples:
pic: pic {
compatible = "cdns,xtensa-pic";
/* one cell: internal irq number,
* two cells: second cell == 0: internal irq number
* second cell == 1: external irq number
*/
#interrupt-cells = <2>;
interrupt-controller;
};
...@@ -428,6 +428,36 @@ config DEFAULT_MEM_SIZE ...@@ -428,6 +428,36 @@ config DEFAULT_MEM_SIZE
If unsure, leave the default value here. If unsure, leave the default value here.
config XTFPGA_LCD
bool "Enable XTFPGA LCD driver"
depends on XTENSA_PLATFORM_XTFPGA
default n
help
There's a 2x16 LCD on most of XTFPGA boards, kernel may output
progress messages there during bootup/shutdown. It may be useful
during board bringup.
If unsure, say N.
config XTFPGA_LCD_BASE_ADDR
hex "XTFPGA LCD base address"
depends on XTFPGA_LCD
default "0x0d0c0000"
help
Base address of the LCD controller inside KIO region.
Different boards from XTFPGA family have LCD controller at different
addresses. Please consult prototyping user guide for your board for
the correct address. Wrong address here may lead to hardware lockup.
config XTFPGA_LCD_8BIT_ACCESS
bool "Use 8-bit access to XTFPGA LCD"
depends on XTFPGA_LCD
default n
help
LCD may be connected with 4- or 8-bit interface, 8-bit access may
only be used with 8-bit interface. Please consult prototyping user
guide for your board for the correct interface width.
endmenu endmenu
menu "Executable file formats" menu "Executable file formats"
......
...@@ -40,6 +40,12 @@ osc: main-oscillator { ...@@ -40,6 +40,12 @@ osc: main-oscillator {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
}; };
clk54: clk54 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <54000000>;
};
}; };
soc { soc {
...@@ -65,5 +71,63 @@ enet0: ethoc@0d030000 { ...@@ -65,5 +71,63 @@ enet0: ethoc@0d030000 {
local-mac-address = [00 50 c2 13 6f 00]; local-mac-address = [00 50 c2 13 6f 00];
clocks = <&osc>; clocks = <&osc>;
}; };
i2s0: xtfpga-i2s@0d080000 {
#sound-dai-cells = <0>;
compatible = "cdns,xtfpga-i2s";
reg = <0x0d080000 0x40>;
interrupts = <2 1>; /* external irq 2 */
clocks = <&cdce706 4>;
};
i2c0: i2c-master@0d090000 {
compatible = "opencores,i2c-ocores";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0d090000 0x20>;
reg-shift = <2>;
reg-io-width = <1>;
interrupts = <4 1>;
clocks = <&osc>;
cdce706: clock-synth@69 {
compatible = "ti,cdce706";
#clock-cells = <1>;
reg = <0x69>;
clocks = <&clk54>;
clock-names = "clk_in0";
};
};
spi0: spi-master@0d0a0000 {
compatible = "cdns,xtfpga-spi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0d0a0000 0xc>;
tlv320aic23: sound-codec@0 {
#sound-dai-cells = <0>;
compatible = "tlv320aic23";
reg = <0>;
spi-max-frequency = <12500000>;
};
};
};
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0>;
};
simple-audio-card,codec {
sound-dai = <&tlv320aic23>;
simple-audio-card,bitclock-master = <0>;
simple-audio-card,frame-master = <0>;
clocks = <&cdce706 4>;
};
}; };
}; };
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_FHANDLE=y
CONFIG_IRQ_DOMAIN_DEBUG=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_MEMCG=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS_ALL=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_XTENSA_VARIANT_CUSTOM=y
CONFIG_XTENSA_VARIANT_CUSTOM_NAME="test_kc705_hifi"
CONFIG_XTENSA_UNALIGNED_USER=y
CONFIG_PREEMPT=y
CONFIG_HIGHMEM=y
# CONFIG_PCI is not set
CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"
CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="kc705"
# CONFIG_COMPACTION is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_MTD=y
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_ARC is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_SAMSUNG is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_MARVELL_PHY=y
# CONFIG_WLAN is not set
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_OCORES=y
CONFIG_SPI=y
CONFIG_SPI_XTENSA_XTFPGA=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_XTFPGA_I2S=y
CONFIG_SND_SOC_TLV320AIC23_SPI=y
CONFIG_SND_SIMPLE_CARD=y
# CONFIG_USB_SUPPORT is not set
CONFIG_COMMON_CLK_CDCE706=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_FANOTIFY=y
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UBIFS_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_NFS_SWAP=y
CONFIG_ROOT_NFS=y
CONFIG_SUNRPC_DEBUG=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_STACKTRACE=y
CONFIG_RCU_TRACE=y
# CONFIG_FTRACE is not set
# CONFIG_S32C1I_SELFTEST is not set
CONFIG_CRYPTO_ANSI_CPRNG=y
...@@ -715,7 +715,7 @@ __SYSCALL(323, sys_process_vm_writev, 6) ...@@ -715,7 +715,7 @@ __SYSCALL(323, sys_process_vm_writev, 6)
__SYSCALL(324, sys_name_to_handle_at, 5) __SYSCALL(324, sys_name_to_handle_at, 5)
#define __NR_open_by_handle_at 325 #define __NR_open_by_handle_at 325
__SYSCALL(325, sys_open_by_handle_at, 3) __SYSCALL(325, sys_open_by_handle_at, 3)
#define __NR_sync_file_range 326 #define __NR_sync_file_range2 326
__SYSCALL(326, sys_sync_file_range2, 6) __SYSCALL(326, sys_sync_file_range2, 6)
#define __NR_perf_event_open 327 #define __NR_perf_event_open 327
__SYSCALL(327, sys_perf_event_open, 5) __SYSCALL(327, sys_perf_event_open, 5)
...@@ -749,8 +749,12 @@ __SYSCALL(337, sys_seccomp, 3) ...@@ -749,8 +749,12 @@ __SYSCALL(337, sys_seccomp, 3)
__SYSCALL(338, sys_getrandom, 3) __SYSCALL(338, sys_getrandom, 3)
#define __NR_memfd_create 339 #define __NR_memfd_create 339
__SYSCALL(339, sys_memfd_create, 2) __SYSCALL(339, sys_memfd_create, 2)
#define __NR_bpf 340
__SYSCALL(340, sys_bpf, 3)
#define __NR_execveat 341
__SYSCALL(341, sys_execveat, 5)
#define __NR_syscall_count 340 #define __NR_syscall_count 342
/* /*
* sysxtensa syscall handler * sysxtensa syscall handler
......
...@@ -29,6 +29,7 @@ AFLAGS_head.o += -mtext-section-literals ...@@ -29,6 +29,7 @@ AFLAGS_head.o += -mtext-section-literals
sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \
-e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \
-e 's/\*(\(\.text .*\))/*(.literal \1)/g' \
-e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
quiet_cmd__cpp_lds_S = LDS $@ quiet_cmd__cpp_lds_S = LDS $@
......
...@@ -349,8 +349,8 @@ static void iss_net_timer(unsigned long priv) ...@@ -349,8 +349,8 @@ static void iss_net_timer(unsigned long priv)
{ {
struct iss_net_private *lp = (struct iss_net_private *)priv; struct iss_net_private *lp = (struct iss_net_private *)priv;
spin_lock(&lp->lock);
iss_net_poll(); iss_net_poll();
spin_lock(&lp->lock);
mod_timer(&lp->timer, jiffies + lp->timer_val); mod_timer(&lp->timer, jiffies + lp->timer_val);
spin_unlock(&lp->lock); spin_unlock(&lp->lock);
} }
...@@ -361,7 +361,7 @@ static int iss_net_open(struct net_device *dev) ...@@ -361,7 +361,7 @@ static int iss_net_open(struct net_device *dev)
struct iss_net_private *lp = netdev_priv(dev); struct iss_net_private *lp = netdev_priv(dev);
int err; int err;
spin_lock(&lp->lock); spin_lock_bh(&lp->lock);
err = lp->tp.open(lp); err = lp->tp.open(lp);
if (err < 0) if (err < 0)
...@@ -376,9 +376,11 @@ static int iss_net_open(struct net_device *dev) ...@@ -376,9 +376,11 @@ static int iss_net_open(struct net_device *dev)
while ((err = iss_net_rx(dev)) > 0) while ((err = iss_net_rx(dev)) > 0)
; ;
spin_lock(&opened_lock); spin_unlock_bh(&lp->lock);
spin_lock_bh(&opened_lock);
list_add(&lp->opened_list, &opened); list_add(&lp->opened_list, &opened);
spin_unlock(&opened_lock); spin_unlock_bh(&opened_lock);
spin_lock_bh(&lp->lock);
init_timer(&lp->timer); init_timer(&lp->timer);
lp->timer_val = ISS_NET_TIMER_VALUE; lp->timer_val = ISS_NET_TIMER_VALUE;
...@@ -387,7 +389,7 @@ static int iss_net_open(struct net_device *dev) ...@@ -387,7 +389,7 @@ static int iss_net_open(struct net_device *dev)
mod_timer(&lp->timer, jiffies + lp->timer_val); mod_timer(&lp->timer, jiffies + lp->timer_val);
out: out:
spin_unlock(&lp->lock); spin_unlock_bh(&lp->lock);
return err; return err;
} }
...@@ -395,7 +397,7 @@ static int iss_net_close(struct net_device *dev) ...@@ -395,7 +397,7 @@ static int iss_net_close(struct net_device *dev)
{ {
struct iss_net_private *lp = netdev_priv(dev); struct iss_net_private *lp = netdev_priv(dev);
netif_stop_queue(dev); netif_stop_queue(dev);
spin_lock(&lp->lock); spin_lock_bh(&lp->lock);
spin_lock(&opened_lock); spin_lock(&opened_lock);
list_del(&opened); list_del(&opened);
...@@ -405,18 +407,17 @@ static int iss_net_close(struct net_device *dev) ...@@ -405,18 +407,17 @@ static int iss_net_close(struct net_device *dev)
lp->tp.close(lp); lp->tp.close(lp);
spin_unlock(&lp->lock); spin_unlock_bh(&lp->lock);
return 0; return 0;
} }
static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct iss_net_private *lp = netdev_priv(dev); struct iss_net_private *lp = netdev_priv(dev);
unsigned long flags;
int len; int len;
netif_stop_queue(dev); netif_stop_queue(dev);
spin_lock_irqsave(&lp->lock, flags); spin_lock_bh(&lp->lock);
len = lp->tp.write(lp, &skb); len = lp->tp.write(lp, &skb);
...@@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); pr_err("%s: %s failed(%d)\n", dev->name, __func__, len);
} }
spin_unlock_irqrestore(&lp->lock, flags); spin_unlock_bh(&lp->lock);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_device *dev, void *addr) ...@@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_device *dev, void *addr)
if (!is_valid_ether_addr(hwaddr->sa_data)) if (!is_valid_ether_addr(hwaddr->sa_data))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
spin_lock(&lp->lock); spin_lock_bh(&lp->lock);
memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
spin_unlock(&lp->lock); spin_unlock_bh(&lp->lock);
return 0; return 0;
} }
...@@ -520,11 +521,11 @@ static int iss_net_configure(int index, char *init) ...@@ -520,11 +521,11 @@ static int iss_net_configure(int index, char *init)
*lp = (struct iss_net_private) { *lp = (struct iss_net_private) {
.device_list = LIST_HEAD_INIT(lp->device_list), .device_list = LIST_HEAD_INIT(lp->device_list),
.opened_list = LIST_HEAD_INIT(lp->opened_list), .opened_list = LIST_HEAD_INIT(lp->opened_list),
.lock = __SPIN_LOCK_UNLOCKED(lp.lock),
.dev = dev, .dev = dev,
.index = index, .index = index,
}; };
spin_lock_init(&lp->lock);
/* /*
* If this name ends up conflicting with an existing registered * If this name ends up conflicting with an existing registered
* netdevice, that is OK, register_netdev{,ice}() will notice this * netdevice, that is OK, register_netdev{,ice}() will notice this
......
...@@ -6,4 +6,5 @@ ...@@ -6,4 +6,5 @@
# #
# Note 2! The CFLAGS definitions are in the main makefile... # Note 2! The CFLAGS definitions are in the main makefile...
obj-y = setup.o lcd.o obj-y += setup.o
obj-$(CONFIG_XTFPGA_LCD) += lcd.o
...@@ -40,9 +40,6 @@ ...@@ -40,9 +40,6 @@
/* UART */ /* UART */
#define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) #define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020)
/* LCD instruction and data addresses. */
#define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000))
#define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004))
/* Misc. */ /* Misc. */
#define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) #define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000)
...@@ -62,4 +59,7 @@ ...@@ -62,4 +59,7 @@
/* 5*rx buffs + 5*tx buffs */ /* 5*rx buffs + 5*tx buffs */
#define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600)
#define C67X00_PADDR (XCHAL_KIO_PADDR + 0x0D0D0000)
#define C67X00_SIZE 0x10
#define C67X00_IRQ 5
#endif /* __XTENSA_XTAVNET_HARDWARE_H */ #endif /* __XTENSA_XTAVNET_HARDWARE_H */
...@@ -11,10 +11,25 @@ ...@@ -11,10 +11,25 @@
#ifndef __XTENSA_XTAVNET_LCD_H #ifndef __XTENSA_XTAVNET_LCD_H
#define __XTENSA_XTAVNET_LCD_H #define __XTENSA_XTAVNET_LCD_H
#ifdef CONFIG_XTFPGA_LCD
/* Display string STR at position POS on the LCD. */ /* Display string STR at position POS on the LCD. */
void lcd_disp_at_pos(char *str, unsigned char pos); void lcd_disp_at_pos(char *str, unsigned char pos);
/* Shift the contents of the LCD display left or right. */ /* Shift the contents of the LCD display left or right. */
void lcd_shiftleft(void); void lcd_shiftleft(void);
void lcd_shiftright(void); void lcd_shiftright(void);
#else
static inline void lcd_disp_at_pos(char *str, unsigned char pos)
{
}
static inline void lcd_shiftleft(void)
{
}
static inline void lcd_shiftright(void)
{
}
#endif
#endif #endif
/* /*
* Driver for the LCD display on the Tensilica LX60 Board. * Driver for the LCD display on the Tensilica XTFPGA board family.
* http://www.mytechcorp.com/cfdata/productFile/File1/MOC-16216B-B-A0A04.pdf
* *
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2001, 2006 Tensilica Inc. * Copyright (C) 2001, 2006 Tensilica Inc.
* Copyright (C) 2015 Cadence Design Systems Inc.
*/ */
/* #include <linux/delay.h>
*
* FIXME: this code is from the examples from the LX60 user guide.
*
* The lcd_pause function does busy waiting, which is probably not
* great. Maybe the code could be changed to use kernel timers, or
* change the hardware to not need to wait.
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <platform/hardware.h> #include <platform/hardware.h>
#include <platform/lcd.h> #include <platform/lcd.h>
#include <linux/delay.h>
#define LCD_PAUSE_ITERATIONS 4000 /* LCD instruction and data addresses. */
#define LCD_INSTR_ADDR ((char *)IOADDR(CONFIG_XTFPGA_LCD_BASE_ADDR))
#define LCD_DATA_ADDR (LCD_INSTR_ADDR + 4)
#define LCD_CLEAR 0x1 #define LCD_CLEAR 0x1
#define LCD_DISPLAY_ON 0xc #define LCD_DISPLAY_ON 0xc
/* 8bit and 2 lines display */ /* 8bit and 2 lines display */
#define LCD_DISPLAY_MODE8BIT 0x38 #define LCD_DISPLAY_MODE8BIT 0x38
#define LCD_DISPLAY_MODE4BIT 0x28
#define LCD_DISPLAY_POS 0x80 #define LCD_DISPLAY_POS 0x80
#define LCD_SHIFT_LEFT 0x18 #define LCD_SHIFT_LEFT 0x18
#define LCD_SHIFT_RIGHT 0x1c #define LCD_SHIFT_RIGHT 0x1c
static void lcd_put_byte(u8 *addr, u8 data)
{
#ifdef CONFIG_XTFPGA_LCD_8BIT_ACCESS
ACCESS_ONCE(*addr) = data;
#else
ACCESS_ONCE(*addr) = data & 0xf0;
ACCESS_ONCE(*addr) = (data << 4) & 0xf0;
#endif
}
static int __init lcd_init(void) static int __init lcd_init(void)
{ {
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
mdelay(5); mdelay(5);
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
udelay(200); udelay(200);
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
udelay(50);
#ifndef CONFIG_XTFPGA_LCD_8BIT_ACCESS
ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE4BIT;
udelay(50);
lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_MODE4BIT);
udelay(50); udelay(50);
*LCD_INSTR_ADDR = LCD_DISPLAY_ON; #endif
lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_ON);
udelay(50); udelay(50);
*LCD_INSTR_ADDR = LCD_CLEAR; lcd_put_byte(LCD_INSTR_ADDR, LCD_CLEAR);
mdelay(10); mdelay(10);
lcd_disp_at_pos("XTENSA LINUX", 0); lcd_disp_at_pos("XTENSA LINUX", 0);
return 0; return 0;
...@@ -52,10 +65,10 @@ static int __init lcd_init(void) ...@@ -52,10 +65,10 @@ static int __init lcd_init(void)
void lcd_disp_at_pos(char *str, unsigned char pos) void lcd_disp_at_pos(char *str, unsigned char pos)
{ {
*LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_POS | pos);
udelay(100); udelay(100);
while (*str != 0) { while (*str != 0) {
*LCD_DATA_ADDR = *str; lcd_put_byte(LCD_DATA_ADDR, *str);
udelay(200); udelay(200);
str++; str++;
} }
...@@ -63,13 +76,13 @@ void lcd_disp_at_pos(char *str, unsigned char pos) ...@@ -63,13 +76,13 @@ void lcd_disp_at_pos(char *str, unsigned char pos)
void lcd_shiftleft(void) void lcd_shiftleft(void)
{ {
*LCD_INSTR_ADDR = LCD_SHIFT_LEFT; lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_LEFT);
udelay(50); udelay(50);
} }
void lcd_shiftright(void) void lcd_shiftright(void)
{ {
*LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_RIGHT);
udelay(50); udelay(50);
} }
......
...@@ -189,6 +189,7 @@ void __init platform_calibrate_ccount(void) ...@@ -189,6 +189,7 @@ void __init platform_calibrate_ccount(void)
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/if.h> #include <linux/if.h>
#include <net/ethoc.h> #include <net/ethoc.h>
#include <linux/usb/c67x00.h>
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* Ethernet -- OpenCores Ethernet MAC (ethoc driver) * Ethernet -- OpenCores Ethernet MAC (ethoc driver)
...@@ -232,6 +233,38 @@ static struct platform_device ethoc_device = { ...@@ -232,6 +233,38 @@ static struct platform_device ethoc_device = {
}, },
}; };
/*----------------------------------------------------------------------------
* USB Host/Device -- Cypress CY7C67300
*/
static struct resource c67x00_res[] = {
[0] = { /* register space */
.start = C67X00_PADDR,
.end = C67X00_PADDR + C67X00_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[1] = { /* IRQ number */
.start = C67X00_IRQ,
.end = C67X00_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct c67x00_platform_data c67x00_pdata = {
.sie_config = C67X00_SIE1_HOST | C67X00_SIE2_UNUSED,
.hpi_regstep = 4,
};
static struct platform_device c67x00_device = {
.name = "c67x00",
.id = -1,
.num_resources = ARRAY_SIZE(c67x00_res),
.resource = c67x00_res,
.dev = {
.platform_data = &c67x00_pdata,
},
};
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
* UART * UART
*/ */
...@@ -268,6 +301,7 @@ static struct platform_device xtavnet_uart = { ...@@ -268,6 +301,7 @@ static struct platform_device xtavnet_uart = {
/* platform devices */ /* platform devices */
static struct platform_device *platform_devices[] __initdata = { static struct platform_device *platform_devices[] __initdata = {
&ethoc_device, &ethoc_device,
&c67x00_device,
&xtavnet_uart, &xtavnet_uart,
}; };
......
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