Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
cb86ae95
Commit
cb86ae95
authored
Jul 22, 2010
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.infradead.org/users/cbou/linux-cns3xxx
into devel-stable
parents
14764b01
23f5cace
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
596 additions
and
56 deletions
+596
-56
arch/arm/Kconfig
arch/arm/Kconfig
+2
-1
arch/arm/mach-cns3xxx/Makefile
arch/arm/mach-cns3xxx/Makefile
+2
-1
arch/arm/mach-cns3xxx/cns3420vb.c
arch/arm/mach-cns3xxx/cns3420vb.c
+4
-0
arch/arm/mach-cns3xxx/devices.c
arch/arm/mach-cns3xxx/devices.c
+111
-0
arch/arm/mach-cns3xxx/devices.h
arch/arm/mach-cns3xxx/devices.h
+20
-0
arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
+45
-46
arch/arm/mach-cns3xxx/pcie.c
arch/arm/mach-cns3xxx/pcie.c
+389
-0
arch/arm/mach-cns3xxx/pm.c
arch/arm/mach-cns3xxx/pm.c
+23
-8
No files found.
arch/arm/Kconfig
View file @
cb86ae95
...
@@ -301,6 +301,7 @@ config ARCH_CNS3XXX
...
@@ -301,6 +301,7 @@ config ARCH_CNS3XXX
select CPU_V6
select CPU_V6
select GENERIC_CLOCKEVENTS
select GENERIC_CLOCKEVENTS
select ARM_GIC
select ARM_GIC
select PCI_DOMAINS if PCI
help
help
Support for Cavium Networks CNS3XXX platform.
Support for Cavium Networks CNS3XXX platform.
...
@@ -1061,7 +1062,7 @@ config ISA_DMA_API
...
@@ -1061,7 +1062,7 @@ config ISA_DMA_API
bool
bool
config PCI
config PCI
bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
|| ARCH_CNS3XXX
help
help
Find out whether you have a PCI motherboard. PCI is the name of a
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
bus system, i.e. the way the CPU talks to the other stuff inside
...
...
arch/arm/mach-cns3xxx/Makefile
View file @
cb86ae95
obj-$(CONFIG_ARCH_CNS3XXX)
+=
core.o pm.o
obj-$(CONFIG_ARCH_CNS3XXX)
+=
core.o pm.o devices.o
obj-$(CONFIG_PCI)
+=
pcie.o
obj-$(CONFIG_MACH_CNS3420VB)
+=
cns3420vb.o
obj-$(CONFIG_MACH_CNS3420VB)
+=
cns3420vb.o
arch/arm/mach-cns3xxx/cns3420vb.c
View file @
cb86ae95
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include <mach/cns3xxx.h>
#include <mach/cns3xxx.h>
#include <mach/irqs.h>
#include <mach/irqs.h>
#include "core.h"
#include "core.h"
#include "devices.h"
/*
/*
* NOR Flash
* NOR Flash
...
@@ -117,6 +118,9 @@ static void __init cns3420_init(void)
...
@@ -117,6 +118,9 @@ static void __init cns3420_init(void)
{
{
platform_add_devices
(
cns3420_pdevs
,
ARRAY_SIZE
(
cns3420_pdevs
));
platform_add_devices
(
cns3420_pdevs
,
ARRAY_SIZE
(
cns3420_pdevs
));
cns3xxx_ahci_init
();
cns3xxx_sdhci_init
();
pm_power_off
=
cns3xxx_power_off
;
pm_power_off
=
cns3xxx_power_off
;
}
}
...
...
arch/arm/mach-cns3xxx/devices.c
0 → 100644
View file @
cb86ae95
/*
* CNS3xxx common devices
*
* Copyright 2008 Cavium Networks
* Scott Shu
* Copyright 2010 MontaVista Software, LLC.
* Anton Vorontsov <avorontsov@mvista.com>
*
* This file 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/io.h>
#include <linux/init.h>
#include <linux/compiler.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <mach/cns3xxx.h>
#include <mach/irqs.h>
#include "core.h"
#include "devices.h"
/*
* AHCI
*/
static
struct
resource
cns3xxx_ahci_resource
[]
=
{
[
0
]
=
{
.
start
=
CNS3XXX_SATA2_BASE
,
.
end
=
CNS3XXX_SATA2_BASE
+
CNS3XXX_SATA2_SIZE
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_CNS3XXX_SATA
,
.
end
=
IRQ_CNS3XXX_SATA
,
.
flags
=
IORESOURCE_IRQ
,
},
};
static
u64
cns3xxx_ahci_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
platform_device
cns3xxx_ahci_pdev
=
{
.
name
=
"ahci"
,
.
id
=
0
,
.
resource
=
cns3xxx_ahci_resource
,
.
num_resources
=
ARRAY_SIZE
(
cns3xxx_ahci_resource
),
.
dev
=
{
.
dma_mask
=
&
cns3xxx_ahci_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
},
};
void
__init
cns3xxx_ahci_init
(
void
)
{
u32
tmp
;
tmp
=
__raw_readl
(
MISC_SATA_POWER_MODE
);
tmp
|=
0x1
<<
16
;
/* Disable SATA PHY 0 from SLUMBER Mode */
tmp
|=
0x1
<<
17
;
/* Disable SATA PHY 1 from SLUMBER Mode */
__raw_writel
(
tmp
,
MISC_SATA_POWER_MODE
);
/* Enable SATA PHY */
cns3xxx_pwr_power_up
(
0x1
<<
PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0
);
cns3xxx_pwr_power_up
(
0x1
<<
PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1
);
/* Enable SATA Clock */
cns3xxx_pwr_clk_en
(
0x1
<<
PM_CLK_GATE_REG_OFFSET_SATA
);
/* De-Asscer SATA Reset */
cns3xxx_pwr_soft_rst
(
CNS3XXX_PWR_SOFTWARE_RST
(
SATA
));
platform_device_register
(
&
cns3xxx_ahci_pdev
);
}
/*
* SDHCI
*/
static
struct
resource
cns3xxx_sdhci_resources
[]
=
{
[
0
]
=
{
.
start
=
CNS3XXX_SDIO_BASE
,
.
end
=
CNS3XXX_SDIO_BASE
+
SZ_4K
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
IRQ_CNS3XXX_SDIO
,
.
end
=
IRQ_CNS3XXX_SDIO
,
.
flags
=
IORESOURCE_IRQ
,
},
};
static
struct
platform_device
cns3xxx_sdhci_pdev
=
{
.
name
=
"sdhci-cns3xxx"
,
.
id
=
0
,
.
num_resources
=
ARRAY_SIZE
(
cns3xxx_sdhci_resources
),
.
resource
=
cns3xxx_sdhci_resources
,
};
void
__init
cns3xxx_sdhci_init
(
void
)
{
u32
__iomem
*
gpioa
=
__io
(
CNS3XXX_MISC_BASE_VIRT
+
0x0014
);
u32
gpioa_pins
=
__raw_readl
(
gpioa
);
/* MMC/SD pins share with GPIOA */
gpioa_pins
|=
0x1fff0004
;
__raw_writel
(
gpioa_pins
,
gpioa
);
cns3xxx_pwr_clk_en
(
CNS3XXX_PWR_CLK_EN
(
SDIO
));
cns3xxx_pwr_soft_rst
(
CNS3XXX_PWR_SOFTWARE_RST
(
SDIO
));
platform_device_register
(
&
cns3xxx_sdhci_pdev
);
}
arch/arm/mach-cns3xxx/devices.h
0 → 100644
View file @
cb86ae95
/*
* CNS3xxx common devices
*
* Copyright 2008 Cavium Networks
* Scott Shu
* Copyright 2010 MontaVista Software, LLC.
* Anton Vorontsov <avorontsov@mvista.com>
*
* This file 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.
*/
#ifndef __CNS3XXX_DEVICES_H_
#define __CNS3XXX_DEVICES_H_
void
__init
cns3xxx_ahci_init
(
void
);
void
__init
cns3xxx_sdhci_init
(
void
);
#endif
/* __CNS3XXX_DEVICES_H_ */
arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
View file @
cb86ae95
...
@@ -247,37 +247,36 @@
...
@@ -247,37 +247,36 @@
* Misc block
* Misc block
*/
*/
#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
#define MISC_MEM_MAP_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_MISC_BASE_VIRT + (offset))))
#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP(0x00)
#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP_VALUE(0x00)
#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP(0x04)
#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP_VALUE(0x04)
#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP(0x08)
#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP_VALUE(0x08)
#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP(0x0C)
#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP_VALUE(0x0C)
#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP(0x10)
#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP_VALUE(0x10)
#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP(0x14)
#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP_VALUE(0x14)
#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP(0x18)
#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP_VALUE(0x18)
#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP(0x1C)
#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP_VALUE(0x1C)
#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP(0x20)
#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP_VALUE(0x20)
#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x24)
#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x24)
#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x28)
#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x28)
#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x2C)
#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x2C)
#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x30)
#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x30)
#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP(0x34)
#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP_VALUE(0x34)
#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP(0x40)
#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP_VALUE(0x40)
#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP(0x44)
#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP_VALUE(0x44)
#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP(0x48)
#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP_VALUE(0x48)
#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP(0x4C)
#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP_VALUE(0x4C)
#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP(0x50)
#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP_VALUE(0x50)
#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP(0x54)
#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP_VALUE(0x54)
#define MISC_SATA_POWER_MODE MISC_MEM_MAP(0x310)
#define MISC_SATA_POWER_MODE MISC_MEM_MAP_VALUE(0x310)
#define MISC_USB_CFG_REG MISC_MEM_MAP(0x800)
#define MISC_USB_CFG_REG MISC_MEM_MAP_VALUE(0x800)
#define MISC_USB_STS_REG MISC_MEM_MAP(0x804)
#define MISC_USB_STS_REG MISC_MEM_MAP_VALUE(0x804)
#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP(0x808)
#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP_VALUE(0x808)
#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP(0x80c)
#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP_VALUE(0x80c)
#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP(0x810)
#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP_VALUE(0x810)
#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP(0x814)
#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP_VALUE(0x814)
#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004)
#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004)
#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100)
#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100)
...
@@ -300,21 +299,21 @@
...
@@ -300,21 +299,21 @@
/*
/*
* Power management and clock control
* Power management and clock control
*/
*/
#define PMU_
REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_PM_BASE_VIRT + (offset))
))
#define PMU_
MEM_MAP(offs) (void __iomem *)(CNS3XXX_PM_BASE_VIRT + (offs
))
#define PM_CLK_GATE_REG PMU_
REG_VALUE
(0x000)
#define PM_CLK_GATE_REG PMU_
MEM_MAP
(0x000)
#define PM_SOFT_RST_REG PMU_
REG_VALUE
(0x004)
#define PM_SOFT_RST_REG PMU_
MEM_MAP
(0x004)
#define PM_HS_CFG_REG PMU_
REG_VALUE
(0x008)
#define PM_HS_CFG_REG PMU_
MEM_MAP
(0x008)
#define PM_CACTIVE_STA_REG PMU_
REG_VALUE
(0x00C)
#define PM_CACTIVE_STA_REG PMU_
MEM_MAP
(0x00C)
#define PM_PWR_STA_REG PMU_
REG_VALUE
(0x010)
#define PM_PWR_STA_REG PMU_
MEM_MAP
(0x010)
#define PM_CLK_CTRL_REG PMU_
REG_VALUE
(0x014)
#define PM_CLK_CTRL_REG PMU_
MEM_MAP
(0x014)
#define PM_PLL_LCD_I2S_CTRL_REG PMU_
REG_VALUE
(0x018)
#define PM_PLL_LCD_I2S_CTRL_REG PMU_
MEM_MAP
(0x018)
#define PM_PLL_HM_PD_CTRL_REG PMU_
REG_VALUE
(0x01C)
#define PM_PLL_HM_PD_CTRL_REG PMU_
MEM_MAP
(0x01C)
#define PM_REGULAT_CTRL_REG PMU_
REG_VALUE
(0x020)
#define PM_REGULAT_CTRL_REG PMU_
MEM_MAP
(0x020)
#define PM_WDT_CTRL_REG PMU_
REG_VALUE
(0x024)
#define PM_WDT_CTRL_REG PMU_
MEM_MAP
(0x024)
#define PM_WU_CTRL0_REG PMU_
REG_VALUE
(0x028)
#define PM_WU_CTRL0_REG PMU_
MEM_MAP
(0x028)
#define PM_WU_CTRL1_REG PMU_
REG_VALUE
(0x02C)
#define PM_WU_CTRL1_REG PMU_
MEM_MAP
(0x02C)
#define PM_CSR_REG PMU_
REG_VALUE
(0x030)
#define PM_CSR_REG PMU_
MEM_MAP
(0x030)
/* PM_CLK_GATE_REG */
/* PM_CLK_GATE_REG */
#define PM_CLK_GATE_REG_OFFSET_SDIO (25)
#define PM_CLK_GATE_REG_OFFSET_SDIO (25)
...
...
arch/arm/mach-cns3xxx/pcie.c
0 → 100644
View file @
cb86ae95
/*
* PCI-E support for CNS3xxx
*
* Copyright 2008 Cavium Networks
* Richard Liu <richard.liu@caviumnetworks.com>
* Copyright 2010 MontaVista Software, LLC.
* Anton Vorontsov <avorontsov@mvista.com>
*
* This file 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/kernel.h>
#include <linux/bug.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/mach/map.h>
#include <mach/cns3xxx.h>
#include "core.h"
enum
cns3xxx_access_type
{
CNS3XXX_HOST_TYPE
=
0
,
CNS3XXX_CFG0_TYPE
,
CNS3XXX_CFG1_TYPE
,
CNS3XXX_NUM_ACCESS_TYPES
,
};
struct
cns3xxx_pcie
{
struct
map_desc
cfg_bases
[
CNS3XXX_NUM_ACCESS_TYPES
];
unsigned
int
irqs
[
2
];
struct
resource
res_io
;
struct
resource
res_mem
;
struct
hw_pci
hw_pci
;
bool
linked
;
};
static
struct
cns3xxx_pcie
cns3xxx_pcie
[];
/* forward decl. */
static
struct
cns3xxx_pcie
*
sysdata_to_cnspci
(
void
*
sysdata
)
{
struct
pci_sys_data
*
root
=
sysdata
;
return
&
cns3xxx_pcie
[
root
->
domain
];
}
static
struct
cns3xxx_pcie
*
pdev_to_cnspci
(
struct
pci_dev
*
dev
)
{
return
sysdata_to_cnspci
(
dev
->
sysdata
);
}
static
struct
cns3xxx_pcie
*
pbus_to_cnspci
(
struct
pci_bus
*
bus
)
{
return
sysdata_to_cnspci
(
bus
->
sysdata
);
}
static
void
__iomem
*
cns3xxx_pci_cfg_base
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
)
{
struct
cns3xxx_pcie
*
cnspci
=
pbus_to_cnspci
(
bus
);
int
busno
=
bus
->
number
;
int
slot
=
PCI_SLOT
(
devfn
);
int
offset
;
enum
cns3xxx_access_type
type
;
void
__iomem
*
base
;
/* If there is no link, just show the CNS PCI bridge. */
if
(
!
cnspci
->
linked
&&
(
busno
>
0
||
slot
>
0
))
return
NULL
;
/*
* The CNS PCI bridge doesn't fit into the PCI hierarchy, though
* we still want to access it. For this to work, we must place
* the first device on the same bus as the CNS PCI bridge.
*/
if
(
busno
==
0
)
{
if
(
slot
>
1
)
return
NULL
;
type
=
slot
;
}
else
{
type
=
CNS3XXX_CFG1_TYPE
;
}
base
=
(
void
__iomem
*
)
cnspci
->
cfg_bases
[
type
].
virtual
;
offset
=
((
busno
&
0xf
)
<<
20
)
|
(
devfn
<<
12
)
|
(
where
&
0xffc
);
return
base
+
offset
;
}
static
int
cns3xxx_pci_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
val
)
{
u32
v
;
void
__iomem
*
base
;
u32
mask
=
(
0x1ull
<<
(
size
*
8
))
-
1
;
int
shift
=
(
where
%
4
)
*
8
;
base
=
cns3xxx_pci_cfg_base
(
bus
,
devfn
,
where
);
if
(
!
base
)
{
*
val
=
0xffffffff
;
return
PCIBIOS_SUCCESSFUL
;
}
v
=
__raw_readl
(
base
);
if
(
bus
->
number
==
0
&&
devfn
==
0
&&
(
where
&
0xffc
)
==
PCI_CLASS_REVISION
)
{
/*
* RC's class is 0xb, but Linux PCI driver needs 0x604
* for a PCIe bridge. So we must fixup the class code
* to 0x604 here.
*/
v
&=
0xff
;
v
|=
0x604
<<
16
;
}
*
val
=
(
v
>>
shift
)
&
mask
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
cns3xxx_pci_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
val
)
{
u32
v
;
void
__iomem
*
base
;
u32
mask
=
(
0x1ull
<<
(
size
*
8
))
-
1
;
int
shift
=
(
where
%
4
)
*
8
;
base
=
cns3xxx_pci_cfg_base
(
bus
,
devfn
,
where
);
if
(
!
base
)
return
PCIBIOS_SUCCESSFUL
;
v
=
__raw_readl
(
base
);
v
&=
~
(
mask
<<
shift
);
v
|=
(
val
&
mask
)
<<
shift
;
__raw_writel
(
v
,
base
);
return
PCIBIOS_SUCCESSFUL
;
}
static
int
cns3xxx_pci_setup
(
int
nr
,
struct
pci_sys_data
*
sys
)
{
struct
cns3xxx_pcie
*
cnspci
=
sysdata_to_cnspci
(
sys
);
struct
resource
*
res_io
=
&
cnspci
->
res_io
;
struct
resource
*
res_mem
=
&
cnspci
->
res_mem
;
struct
resource
**
sysres
=
sys
->
resource
;
BUG_ON
(
request_resource
(
&
iomem_resource
,
res_io
)
||
request_resource
(
&
iomem_resource
,
res_mem
));
sysres
[
0
]
=
res_io
;
sysres
[
1
]
=
res_mem
;
return
1
;
}
static
struct
pci_ops
cns3xxx_pcie_ops
=
{
.
read
=
cns3xxx_pci_read_config
,
.
write
=
cns3xxx_pci_write_config
,
};
static
struct
pci_bus
*
cns3xxx_pci_scan_bus
(
int
nr
,
struct
pci_sys_data
*
sys
)
{
return
pci_scan_bus
(
sys
->
busnr
,
&
cns3xxx_pcie_ops
,
sys
);
}
static
int
cns3xxx_pcie_map_irq
(
struct
pci_dev
*
dev
,
u8
slot
,
u8
pin
)
{
struct
cns3xxx_pcie
*
cnspci
=
pdev_to_cnspci
(
dev
);
int
irq
=
cnspci
->
irqs
[
slot
];
pr_info
(
"PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d
\n
"
,
pci_domain_nr
(
dev
->
bus
),
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
PCI_FUNC
(
dev
->
devfn
),
slot
,
pin
,
irq
);
return
irq
;
}
static
struct
cns3xxx_pcie
cns3xxx_pcie
[]
=
{
[
0
]
=
{
.
cfg_bases
=
{
[
CNS3XXX_HOST_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE0_HOST_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE0_HOST_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
[
CNS3XXX_CFG0_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE0_CFG0_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE0_CFG0_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
[
CNS3XXX_CFG1_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE0_CFG1_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE0_CFG1_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
},
.
res_io
=
{
.
name
=
"PCIe0 I/O space"
,
.
start
=
CNS3XXX_PCIE0_IO_BASE
,
.
end
=
CNS3XXX_PCIE0_IO_BASE
+
SZ_16M
-
1
,
.
flags
=
IORESOURCE_IO
,
},
.
res_mem
=
{
.
name
=
"PCIe0 non-prefetchable"
,
.
start
=
CNS3XXX_PCIE0_MEM_BASE
,
.
end
=
CNS3XXX_PCIE0_MEM_BASE
+
SZ_16M
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
.
irqs
=
{
IRQ_CNS3XXX_PCIE0_RC
,
IRQ_CNS3XXX_PCIE0_DEVICE
,
},
.
hw_pci
=
{
.
domain
=
0
,
.
swizzle
=
pci_std_swizzle
,
.
nr_controllers
=
1
,
.
setup
=
cns3xxx_pci_setup
,
.
scan
=
cns3xxx_pci_scan_bus
,
.
map_irq
=
cns3xxx_pcie_map_irq
,
},
},
[
1
]
=
{
.
cfg_bases
=
{
[
CNS3XXX_HOST_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE1_HOST_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE1_HOST_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
[
CNS3XXX_CFG0_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE1_CFG0_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE1_CFG0_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
[
CNS3XXX_CFG1_TYPE
]
=
{
.
virtual
=
CNS3XXX_PCIE1_CFG1_BASE_VIRT
,
.
pfn
=
__phys_to_pfn
(
CNS3XXX_PCIE1_CFG1_BASE
),
.
length
=
SZ_16M
,
.
type
=
MT_DEVICE
,
},
},
.
res_io
=
{
.
name
=
"PCIe1 I/O space"
,
.
start
=
CNS3XXX_PCIE1_IO_BASE
,
.
end
=
CNS3XXX_PCIE1_IO_BASE
+
SZ_16M
-
1
,
.
flags
=
IORESOURCE_IO
,
},
.
res_mem
=
{
.
name
=
"PCIe1 non-prefetchable"
,
.
start
=
CNS3XXX_PCIE1_MEM_BASE
,
.
end
=
CNS3XXX_PCIE1_MEM_BASE
+
SZ_16M
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
.
irqs
=
{
IRQ_CNS3XXX_PCIE1_RC
,
IRQ_CNS3XXX_PCIE1_DEVICE
,
},
.
hw_pci
=
{
.
domain
=
1
,
.
swizzle
=
pci_std_swizzle
,
.
nr_controllers
=
1
,
.
setup
=
cns3xxx_pci_setup
,
.
scan
=
cns3xxx_pci_scan_bus
,
.
map_irq
=
cns3xxx_pcie_map_irq
,
},
},
};
static
void
__init
cns3xxx_pcie_check_link
(
struct
cns3xxx_pcie
*
cnspci
)
{
int
port
=
cnspci
->
hw_pci
.
domain
;
u32
reg
;
unsigned
long
time
;
reg
=
__raw_readl
(
MISC_PCIE_CTRL
(
port
));
/*
* Enable Application Request to 1, it will exit L1 automatically,
* but when chip back, it will use another clock, still can use 0x1.
*/
reg
|=
0x3
;
__raw_writel
(
reg
,
MISC_PCIE_CTRL
(
port
));
pr_info
(
"PCIe: Port[%d] Enable PCIe LTSSM
\n
"
,
port
);
pr_info
(
"PCIe: Port[%d] Check data link layer..."
,
port
);
time
=
jiffies
;
while
(
1
)
{
reg
=
__raw_readl
(
MISC_PCIE_PM_DEBUG
(
port
));
if
(
reg
&
0x1
)
{
pr_info
(
"Link up.
\n
"
);
cnspci
->
linked
=
1
;
break
;
}
else
if
(
time_after
(
jiffies
,
time
+
50
))
{
pr_info
(
"Device not found.
\n
"
);
break
;
}
}
}
static
void
__init
cns3xxx_pcie_hw_init
(
struct
cns3xxx_pcie
*
cnspci
)
{
int
port
=
cnspci
->
hw_pci
.
domain
;
struct
pci_sys_data
sd
=
{
.
domain
=
port
,
};
struct
pci_bus
bus
=
{
.
number
=
0
,
.
ops
=
&
cns3xxx_pcie_ops
,
.
sysdata
=
&
sd
,
};
u32
io_base
=
cnspci
->
res_io
.
start
>>
16
;
u32
mem_base
=
cnspci
->
res_mem
.
start
>>
16
;
u32
host_base
=
cnspci
->
cfg_bases
[
CNS3XXX_HOST_TYPE
].
pfn
;
u32
cfg0_base
=
cnspci
->
cfg_bases
[
CNS3XXX_CFG0_TYPE
].
pfn
;
u32
devfn
=
0
;
u8
tmp8
;
u16
pos
;
u16
dc
;
host_base
=
(
__pfn_to_phys
(
host_base
)
-
1
)
>>
16
;
cfg0_base
=
(
__pfn_to_phys
(
cfg0_base
)
-
1
)
>>
16
;
pci_bus_write_config_byte
(
&
bus
,
devfn
,
PCI_PRIMARY_BUS
,
0
);
pci_bus_write_config_byte
(
&
bus
,
devfn
,
PCI_SECONDARY_BUS
,
1
);
pci_bus_write_config_byte
(
&
bus
,
devfn
,
PCI_SUBORDINATE_BUS
,
1
);
pci_bus_read_config_byte
(
&
bus
,
devfn
,
PCI_PRIMARY_BUS
,
&
tmp8
);
pci_bus_read_config_byte
(
&
bus
,
devfn
,
PCI_SECONDARY_BUS
,
&
tmp8
);
pci_bus_read_config_byte
(
&
bus
,
devfn
,
PCI_SUBORDINATE_BUS
,
&
tmp8
);
pci_bus_write_config_word
(
&
bus
,
devfn
,
PCI_MEMORY_BASE
,
mem_base
);
pci_bus_write_config_word
(
&
bus
,
devfn
,
PCI_MEMORY_LIMIT
,
host_base
);
pci_bus_write_config_word
(
&
bus
,
devfn
,
PCI_IO_BASE_UPPER16
,
io_base
);
pci_bus_write_config_word
(
&
bus
,
devfn
,
PCI_IO_LIMIT_UPPER16
,
cfg0_base
);
if
(
!
cnspci
->
linked
)
return
;
/* Set Device Max_Read_Request_Size to 128 byte */
devfn
=
PCI_DEVFN
(
1
,
0
);
pos
=
pci_bus_find_capability
(
&
bus
,
devfn
,
PCI_CAP_ID_EXP
);
pci_bus_read_config_word
(
&
bus
,
devfn
,
pos
+
PCI_EXP_DEVCTL
,
&
dc
);
dc
&=
~
(
0x3
<<
12
);
/* Clear Device Control Register [14:12] */
pci_bus_write_config_word
(
&
bus
,
devfn
,
pos
+
PCI_EXP_DEVCTL
,
dc
);
pci_bus_read_config_word
(
&
bus
,
devfn
,
pos
+
PCI_EXP_DEVCTL
,
&
dc
);
if
(
!
(
dc
&
(
0x3
<<
12
)))
pr_info
(
"PCIe: Set Device Max_Read_Request_Size to 128 byte
\n
"
);
/* Disable PCIe0 Interrupt Mask INTA to INTD */
__raw_writel
(
~
0x3FFF
,
MISC_PCIE_INT_MASK
(
port
));
}
static
int
cns3xxx_pcie_abort_handler
(
unsigned
long
addr
,
unsigned
int
fsr
,
struct
pt_regs
*
regs
)
{
if
(
fsr
&
(
1
<<
10
))
regs
->
ARM_pc
+=
4
;
return
0
;
}
static
int
__init
cns3xxx_pcie_init
(
void
)
{
int
i
;
hook_fault_code
(
16
+
6
,
cns3xxx_pcie_abort_handler
,
SIGBUS
,
"imprecise external abort"
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cns3xxx_pcie
);
i
++
)
{
iotable_init
(
cns3xxx_pcie
[
i
].
cfg_bases
,
ARRAY_SIZE
(
cns3xxx_pcie
[
i
].
cfg_bases
));
cns3xxx_pwr_clk_en
(
0x1
<<
PM_CLK_GATE_REG_OFFSET_PCIE
(
i
));
cns3xxx_pwr_soft_rst
(
0x1
<<
PM_SOFT_RST_REG_OFFST_PCIE
(
i
));
cns3xxx_pcie_check_link
(
&
cns3xxx_pcie
[
i
]);
cns3xxx_pcie_hw_init
(
&
cns3xxx_pcie
[
i
]);
pci_common_init
(
&
cns3xxx_pcie
[
i
].
hw_pci
);
}
pci_assign_unassigned_resources
();
return
0
;
}
device_initcall
(
cns3xxx_pcie_init
);
arch/arm/mach-cns3xxx/pm.c
View file @
cb86ae95
...
@@ -6,18 +6,25 @@
...
@@ -6,18 +6,25 @@
* published by the Free Software Foundation.
* published by the Free Software Foundation.
*/
*/
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <mach/system.h>
#include <mach/system.h>
#include <mach/cns3xxx.h>
#include <mach/cns3xxx.h>
void
cns3xxx_pwr_clk_en
(
unsigned
int
block
)
void
cns3xxx_pwr_clk_en
(
unsigned
int
block
)
{
{
PM_CLK_GATE_REG
|=
(
block
&
PM_CLK_GATE_REG_MASK
);
u32
reg
=
__raw_readl
(
PM_CLK_GATE_REG
);
reg
|=
(
block
&
PM_CLK_GATE_REG_MASK
);
__raw_writel
(
reg
,
PM_CLK_GATE_REG
);
}
}
void
cns3xxx_pwr_power_up
(
unsigned
int
block
)
void
cns3xxx_pwr_power_up
(
unsigned
int
block
)
{
{
PM_PLL_HM_PD_CTRL_REG
&=
~
(
block
&
CNS3XXX_PWR_PLL_ALL
);
u32
reg
=
__raw_readl
(
PM_PLL_HM_PD_CTRL_REG
);
reg
&=
~
(
block
&
CNS3XXX_PWR_PLL_ALL
);
__raw_writel
(
reg
,
PM_PLL_HM_PD_CTRL_REG
);
/* Wait for 300us for the PLL output clock locked. */
/* Wait for 300us for the PLL output clock locked. */
udelay
(
300
);
udelay
(
300
);
...
@@ -25,22 +32,29 @@ void cns3xxx_pwr_power_up(unsigned int block)
...
@@ -25,22 +32,29 @@ void cns3xxx_pwr_power_up(unsigned int block)
void
cns3xxx_pwr_power_down
(
unsigned
int
block
)
void
cns3xxx_pwr_power_down
(
unsigned
int
block
)
{
{
u32
reg
=
__raw_readl
(
PM_PLL_HM_PD_CTRL_REG
);
/* write '1' to power down */
/* write '1' to power down */
PM_PLL_HM_PD_CTRL_REG
|=
(
block
&
CNS3XXX_PWR_PLL_ALL
);
reg
|=
(
block
&
CNS3XXX_PWR_PLL_ALL
);
__raw_writel
(
reg
,
PM_PLL_HM_PD_CTRL_REG
);
};
};
static
void
cns3xxx_pwr_soft_rst_force
(
unsigned
int
block
)
static
void
cns3xxx_pwr_soft_rst_force
(
unsigned
int
block
)
{
{
u32
reg
=
__raw_readl
(
PM_SOFT_RST_REG
);
/*
/*
* bit 0, 28, 29 => program low to reset,
* bit 0, 28, 29 => program low to reset,
* the other else program low and then high
* the other else program low and then high
*/
*/
if
(
block
&
0x30000001
)
{
if
(
block
&
0x30000001
)
{
PM_SOFT_RST_REG
&=
~
(
block
&
PM_SOFT_RST_REG_MASK
);
reg
&=
~
(
block
&
PM_SOFT_RST_REG_MASK
);
}
else
{
}
else
{
PM_SOFT_RST_REG
&=
~
(
block
&
PM_SOFT_RST_REG_MASK
);
reg
&=
~
(
block
&
PM_SOFT_RST_REG_MASK
);
PM_SOFT_RST_REG
|=
(
block
&
PM_SOFT_RST_REG_MASK
);
reg
|=
(
block
&
PM_SOFT_RST_REG_MASK
);
}
}
__raw_writel
(
reg
,
PM_SOFT_RST_REG
);
}
}
void
cns3xxx_pwr_soft_rst
(
unsigned
int
block
)
void
cns3xxx_pwr_soft_rst
(
unsigned
int
block
)
...
@@ -73,12 +87,13 @@ void arch_reset(char mode, const char *cmd)
...
@@ -73,12 +87,13 @@ void arch_reset(char mode, const char *cmd)
*/
*/
int
cns3xxx_cpu_clock
(
void
)
int
cns3xxx_cpu_clock
(
void
)
{
{
u32
reg
=
__raw_readl
(
PM_CLK_CTRL_REG
);
int
cpu
;
int
cpu
;
int
cpu_sel
;
int
cpu_sel
;
int
div_sel
;
int
div_sel
;
cpu_sel
=
(
PM_CLK_CTRL_REG
>>
PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL
)
&
0xf
;
cpu_sel
=
(
reg
>>
PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL
)
&
0xf
;
div_sel
=
(
PM_CLK_CTRL_REG
>>
PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV
)
&
0x3
;
div_sel
=
(
reg
>>
PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV
)
&
0x3
;
cpu
=
(
300
+
((
cpu_sel
/
3
)
*
100
)
+
((
cpu_sel
%
3
)
*
33
))
>>
div_sel
;
cpu
=
(
300
+
((
cpu_sel
/
3
)
*
100
)
+
((
cpu_sel
%
3
)
*
33
))
>>
div_sel
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment