forked from Minki/linux
Merge master.kernel.org:/home/rmk/linux-2.6-arm
This commit is contained in:
commit
435d444a53
93
Documentation/arm/Samsung-S3C24XX/USB-Host.txt
Normal file
93
Documentation/arm/Samsung-S3C24XX/USB-Host.txt
Normal file
@ -0,0 +1,93 @@
|
||||
S3C24XX USB Host support
|
||||
========================
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This document details the S3C2410/S3C2440 in-built OHCI USB host support.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Enable at least the following kernel options:
|
||||
|
||||
menuconfig:
|
||||
|
||||
Device Drivers --->
|
||||
USB support --->
|
||||
<*> Support for Host-side USB
|
||||
<*> OHCI HCD support
|
||||
|
||||
|
||||
.config:
|
||||
CONFIG_USB
|
||||
CONFIG_USB_OHCI_HCD
|
||||
|
||||
|
||||
Once these options are configured, the standard set of USB device
|
||||
drivers can be configured and used.
|
||||
|
||||
|
||||
Board Support
|
||||
-------------
|
||||
|
||||
The driver attaches to a platform device, which will need to be
|
||||
added by the board specific support file in linux/arch/arm/mach-s3c2410,
|
||||
such as mach-bast.c or mach-smdk2410.c
|
||||
|
||||
The platform device's platform_data field is only needed if the
|
||||
board implements extra power control or over-current monitoring.
|
||||
|
||||
The OHCI driver does not ensure the state of the S3C2410's MISCCTRL
|
||||
register, so if both ports are to be used for the host, then it is
|
||||
the board support file's responsibility to ensure that the second
|
||||
port is configured to be connected to the OHCI core.
|
||||
|
||||
|
||||
Platform Data
|
||||
-------------
|
||||
|
||||
See linux/include/asm-arm/arch-s3c2410/usb-control.h for the
|
||||
descriptions of the platform device data. An implementation
|
||||
can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
|
||||
|
||||
The `struct s3c2410_hcd_info` contains a pair of functions
|
||||
that get called to enable over-current detection, and to
|
||||
control the port power status.
|
||||
|
||||
The ports are numbered 0 and 1.
|
||||
|
||||
power_control:
|
||||
|
||||
Called to enable or disable the power on the port.
|
||||
|
||||
enable_oc:
|
||||
|
||||
Called to enable or disable the over-current monitoring.
|
||||
This should claim or release the resources being used to
|
||||
check the power condition on the port, such as an IRQ.
|
||||
|
||||
report_oc:
|
||||
|
||||
The OHCI driver fills this field in for the over-current code
|
||||
to call when there is a change to the over-current state on
|
||||
an port. The ports argument is a bitmask of 1 bit per port,
|
||||
with bit X being 1 for an over-current on port X.
|
||||
|
||||
The function s3c2410_usb_report_oc() has been provided to
|
||||
ensure this is called correctly.
|
||||
|
||||
port[x]:
|
||||
|
||||
This is struct describes each port, 0 or 1. The platform driver
|
||||
should set the flags field of each port to S3C_HCDFLG_USED if
|
||||
the port is enabled.
|
||||
|
||||
|
||||
|
||||
Document Author
|
||||
---------------
|
||||
|
||||
Ben Dooks, (c) 2005 Simtec Electronics
|
@ -1,6 +1,6 @@
|
||||
/* linux/arch/arm/mach-s3c2410/usb-simtec.c
|
||||
*
|
||||
* Copyright (c) 2004 Simtec Electronics
|
||||
* Copyright (c) 2004,2005 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
*
|
||||
* http://www.simtec.co.uk/products/EB2410ITX/
|
||||
@ -14,6 +14,8 @@
|
||||
* Modifications:
|
||||
* 14-Sep-2004 BJD Created
|
||||
* 18-Oct-2004 BJD Cleanups, and added code to report OC cleared
|
||||
* 09-Aug-2005 BJD Renamed s3c2410_report_oc to s3c2410_usb_report_oc
|
||||
* 09-Aug-2005 BJD Ports powered only if both are enabled
|
||||
*/
|
||||
|
||||
#define DEBUG
|
||||
@ -47,13 +49,19 @@
|
||||
* designed boards.
|
||||
*/
|
||||
|
||||
static unsigned int power_state[2];
|
||||
|
||||
static void
|
||||
usb_simtec_powercontrol(int port, int to)
|
||||
{
|
||||
pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
|
||||
|
||||
if (port == 1)
|
||||
s3c2410_gpio_setpin(S3C2410_GPB4, to ? 0:1);
|
||||
power_state[port] = to;
|
||||
|
||||
if (power_state[0] && power_state[1])
|
||||
s3c2410_gpio_setpin(S3C2410_GPB4, 0);
|
||||
else
|
||||
s3c2410_gpio_setpin(S3C2410_GPB4, 1);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
@ -63,10 +71,10 @@ usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs)
|
||||
|
||||
if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
|
||||
pr_debug("usb_simtec: over-current irq (oc detected)\n");
|
||||
s3c2410_report_oc(info, 3);
|
||||
s3c2410_usb_report_oc(info, 3);
|
||||
} else {
|
||||
pr_debug("usb_simtec: over-current irq (oc cleared)\n");
|
||||
s3c2410_report_oc(info, 0);
|
||||
s3c2410_usb_report_oc(info, 0);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -383,6 +383,7 @@ static void __init build_mem_type_table(void)
|
||||
{
|
||||
struct cachepolicy *cp;
|
||||
unsigned int cr = get_cr();
|
||||
unsigned int user_pgprot;
|
||||
int cpu_arch = cpu_architecture();
|
||||
int i;
|
||||
|
||||
@ -408,6 +409,9 @@ static void __init build_mem_type_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
cp = &cache_policies[cachepolicy];
|
||||
user_pgprot = cp->pte;
|
||||
|
||||
/*
|
||||
* ARMv6 and above have extended page tables.
|
||||
*/
|
||||
@ -426,11 +430,18 @@ static void __init build_mem_type_table(void)
|
||||
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||
|
||||
/*
|
||||
* Mark the device area as "shared device"
|
||||
*/
|
||||
mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
|
||||
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
|
||||
}
|
||||
|
||||
cp = &cache_policies[cachepolicy];
|
||||
/*
|
||||
* User pages need to be mapped with the ASID
|
||||
* (iow, non-global)
|
||||
*/
|
||||
user_pgprot |= L_PTE_ASID;
|
||||
}
|
||||
|
||||
if (cpu_arch >= CPU_ARCH_ARMv5) {
|
||||
mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
|
||||
@ -448,7 +459,7 @@ static void __init build_mem_type_table(void)
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned long v = pgprot_val(protection_map[i]);
|
||||
v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte;
|
||||
v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
|
||||
protection_map[i] = __pgprot(v);
|
||||
}
|
||||
|
||||
|
@ -111,12 +111,6 @@ ENTRY(cpu_v6_switch_mm)
|
||||
mcr p15, 0, r1, c13, c0, 1 @ set context ID
|
||||
mov pc, lr
|
||||
|
||||
#define nG (1 << 11)
|
||||
#define APX (1 << 9)
|
||||
#define AP1 (1 << 5)
|
||||
#define AP0 (1 << 4)
|
||||
#define XN (1 << 0)
|
||||
|
||||
/*
|
||||
* cpu_v6_set_pte(ptep, pte)
|
||||
*
|
||||
@ -139,24 +133,24 @@ ENTRY(cpu_v6_switch_mm)
|
||||
ENTRY(cpu_v6_set_pte)
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0x00000ff0
|
||||
bic r2, r1, #0x000007f0
|
||||
bic r2, r2, #0x00000003
|
||||
orr r2, r2, #AP0 | 2
|
||||
orr r2, r2, #PTE_EXT_AP0 | 2
|
||||
|
||||
tst r1, #L_PTE_WRITE
|
||||
tstne r1, #L_PTE_DIRTY
|
||||
orreq r2, r2, #APX
|
||||
orreq r2, r2, #PTE_EXT_APX
|
||||
|
||||
tst r1, #L_PTE_USER
|
||||
orrne r2, r2, #AP1 | nG
|
||||
tstne r2, #APX
|
||||
bicne r2, r2, #APX | AP0
|
||||
orrne r2, r2, #PTE_EXT_AP1
|
||||
tstne r2, #PTE_EXT_APX
|
||||
bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
|
||||
|
||||
tst r1, #L_PTE_YOUNG
|
||||
biceq r2, r2, #APX | AP1 | AP0
|
||||
biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
|
||||
|
||||
@ tst r1, #L_PTE_EXEC
|
||||
@ orreq r2, r2, #XN
|
||||
@ orreq r2, r2, #PTE_EXT_XN
|
||||
|
||||
tst r1, #L_PTE_PRESENT
|
||||
moveq r2, #0
|
||||
|
@ -717,6 +717,9 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
|
||||
DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
|
||||
DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
|
||||
|
||||
/* enable LCD controller clock */
|
||||
pxa_set_cken(CKEN16_LCD, 1);
|
||||
|
||||
/* Sequence from 11.7.10 */
|
||||
LCCR3 = fbi->reg_lccr3;
|
||||
LCCR2 = fbi->reg_lccr2;
|
||||
@ -750,6 +753,9 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
|
||||
|
||||
schedule_timeout(20 * HZ / 1000);
|
||||
remove_wait_queue(&fbi->ctrlr_wait, &wait);
|
||||
|
||||
/* disable LCD controller clock */
|
||||
pxa_set_cken(CKEN16_LCD, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1299,8 +1305,6 @@ int __init pxafb_probe(struct device *dev)
|
||||
ret = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
/* enable LCD controller clock */
|
||||
pxa_set_cken(CKEN16_LCD, 1);
|
||||
|
||||
ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
|
||||
if (ret) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
* Changelog:
|
||||
* 11-Sep-2004 BJD Created file
|
||||
* 21-Sep-2004 BJD Updated port info
|
||||
* 09-Aug-2005 BJD Renamed s3c2410_report_oc s3c2410_usb_report_oc
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_USBCONTROL_H
|
||||
@ -35,7 +36,7 @@ struct s3c2410_hcd_info {
|
||||
void (*report_oc)(struct s3c2410_hcd_info *, int ports);
|
||||
};
|
||||
|
||||
static void inline s3c2410_report_oc(struct s3c2410_hcd_info *info, int ports)
|
||||
static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
|
||||
{
|
||||
if (info->report_oc != NULL) {
|
||||
(info->report_oc)(info, ports);
|
||||
|
@ -188,12 +188,18 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
||||
/*
|
||||
* - extended small page/tiny page
|
||||
*/
|
||||
#define PTE_EXT_XN (1 << 0) /* v6 */
|
||||
#define PTE_EXT_AP_MASK (3 << 4)
|
||||
#define PTE_EXT_AP0 (1 << 4)
|
||||
#define PTE_EXT_AP1 (2 << 4)
|
||||
#define PTE_EXT_AP_UNO_SRO (0 << 4)
|
||||
#define PTE_EXT_AP_UNO_SRW (1 << 4)
|
||||
#define PTE_EXT_AP_URO_SRW (2 << 4)
|
||||
#define PTE_EXT_AP_URW_SRW (3 << 4)
|
||||
#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
|
||||
#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
|
||||
#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
|
||||
#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
|
||||
#define PTE_EXT_APX (1 << 9) /* v6 */
|
||||
#define PTE_EXT_SHARED (1 << 10) /* v6 */
|
||||
#define PTE_EXT_NG (1 << 11) /* v6 */
|
||||
|
||||
/*
|
||||
* - small page
|
||||
@ -224,6 +230,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
||||
#define L_PTE_WRITE (1 << 5)
|
||||
#define L_PTE_EXEC (1 << 6)
|
||||
#define L_PTE_DIRTY (1 << 7)
|
||||
#define L_PTE_SHARED (1 << 10) /* shared between CPUs (v6) */
|
||||
#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user