mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 14:44:10 +08:00
Microblaze patches for 3.14-rc1
- Add CCF support - Fix BS=0 compilation - Wire up defconfig - Some minor cleanups and fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEABECAAYFAlLnf6AACgkQykllyylKDCEPhgCeNZmE2b1pEjeyZ7TGY2+uxi93 WrwAoIfey197x8D+S+bLgWYfaT++cGe+ =R9Zc -----END PGP SIGNATURE----- Merge tag 'microblaze-3.14-rc1' of git://git.monstr.eu/linux-2.6-microblaze Pull microblaze patches from Michal Simek: - add CCF support - fix BS=0 compilation - wire up defconfig - some minor cleanups and fixes * tag 'microblaze-3.14-rc1' of git://git.monstr.eu/linux-2.6-microblaze: microblaze: Add missing v8.50.a version microblaze: Fix missing bracket in printk microblaze: Fix compilation error for BS=0 microblaze: Disable stack protection from bootloader microblaze: Define read/write{b,w,l}_relaxed MMIO microblaze: timer: Do not initialized system timer twice microblaze: timer: Use generic sched_clock implementation microblaze: Add NOTES section to linker script microblaze: Add support for CCF microblaze: Simplify fcpu helper function microblaze/uapi: Use Kbuild logic to include <asm-generic/types.h> microblaze: Remove duplicate declarations of _stext[] and _etext[] microblaze: Remove _fdt_start casts microblaze: Wire up defconfig to mmu_defconfig
This commit is contained in:
commit
627f4b3ee3
@ -26,6 +26,8 @@ config MICROBLAZE
|
|||||||
select GENERIC_CPU_DEVICES
|
select GENERIC_CPU_DEVICES
|
||||||
select GENERIC_ATOMIC64
|
select GENERIC_ATOMIC64
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
|
select COMMON_CLK
|
||||||
|
select GENERIC_SCHED_CLOCK
|
||||||
select GENERIC_IDLE_POLL_SETUP
|
select GENERIC_IDLE_POLL_SETUP
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
select CLONE_BACKWARDS3
|
select CLONE_BACKWARDS3
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
KBUILD_DEFCONFIG := mmu_defconfig
|
||||||
|
|
||||||
ifeq ($(CONFIG_MMU),y)
|
ifeq ($(CONFIG_MMU),y)
|
||||||
UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
|
UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
|
||||||
else
|
else
|
||||||
|
@ -91,15 +91,18 @@ extern struct cpuinfo cpuinfo;
|
|||||||
|
|
||||||
/* fwd declarations of the various CPUinfo populators */
|
/* fwd declarations of the various CPUinfo populators */
|
||||||
void setup_cpuinfo(void);
|
void setup_cpuinfo(void);
|
||||||
|
void setup_cpuinfo_clk(void);
|
||||||
|
|
||||||
void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
|
void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu);
|
||||||
void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
|
void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
|
||||||
|
|
||||||
static inline unsigned int fcpu(struct device_node *cpu, char *n)
|
static inline unsigned int fcpu(struct device_node *cpu, char *n)
|
||||||
{
|
{
|
||||||
const __be32 *val;
|
u32 val = 0;
|
||||||
return (val = of_get_property(cpu, n, NULL)) ?
|
|
||||||
be32_to_cpup(val) : 0;
|
of_property_read_u32(cpu, n, &val);
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _ASM_MICROBLAZE_CPUINFO_H */
|
#endif /* _ASM_MICROBLAZE_CPUINFO_H */
|
||||||
|
@ -342,4 +342,12 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
|
|||||||
#define iowrite32_rep(p, src, count) \
|
#define iowrite32_rep(p, src, count) \
|
||||||
outsl((unsigned long) (p), (src), (count))
|
outsl((unsigned long) (p), (src), (count))
|
||||||
|
|
||||||
|
#define readb_relaxed readb
|
||||||
|
#define readw_relaxed readw
|
||||||
|
#define readl_relaxed readl
|
||||||
|
|
||||||
|
#define writeb_relaxed writeb
|
||||||
|
#define writew_relaxed writew
|
||||||
|
#define writel_relaxed writel
|
||||||
|
|
||||||
#endif /* _ASM_MICROBLAZE_IO_H */
|
#endif /* _ASM_MICROBLAZE_IO_H */
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
# ifndef __ASSEMBLY__
|
# ifndef __ASSEMBLY__
|
||||||
extern char _ssbss[], _esbss[];
|
extern char _ssbss[], _esbss[];
|
||||||
extern unsigned long __ivt_start[], __ivt_end[];
|
extern unsigned long __ivt_start[], __ivt_end[];
|
||||||
extern char _etext[], _stext[];
|
|
||||||
|
|
||||||
extern u32 _fdt_start[], _fdt_end[];
|
extern u32 _fdt_start[], _fdt_end[];
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
# UAPI Header export list
|
# UAPI Header export list
|
||||||
include include/uapi/asm-generic/Kbuild.asm
|
include include/uapi/asm-generic/Kbuild.asm
|
||||||
|
|
||||||
|
generic-y += types.h
|
||||||
|
|
||||||
header-y += auxvec.h
|
header-y += auxvec.h
|
||||||
header-y += bitsperlong.h
|
header-y += bitsperlong.h
|
||||||
header-y += byteorder.h
|
header-y += byteorder.h
|
||||||
@ -31,5 +33,4 @@ header-y += statfs.h
|
|||||||
header-y += swab.h
|
header-y += swab.h
|
||||||
header-y += termbits.h
|
header-y += termbits.h
|
||||||
header-y += termios.h
|
header-y += termios.h
|
||||||
header-y += types.h
|
|
||||||
header-y += unistd.h
|
header-y += unistd.h
|
||||||
|
@ -1 +0,0 @@
|
|||||||
#include <asm-generic/types.h>
|
|
@ -112,7 +112,4 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
|
|||||||
CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
|
CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
|
||||||
|
|
||||||
CI(fpga_family_code, TARGET_FAMILY);
|
CI(fpga_family_code, TARGET_FAMILY);
|
||||||
|
|
||||||
/* take timebase-frequency from DTS */
|
|
||||||
ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
|
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,6 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
|
|||||||
ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
|
ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
|
||||||
ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
|
ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
|
||||||
|
|
||||||
ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
|
|
||||||
|
|
||||||
ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
|
ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
|
||||||
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
|
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <asm/cpuinfo.h>
|
#include <asm/cpuinfo.h>
|
||||||
#include <asm/pvr.h>
|
#include <asm/pvr.h>
|
||||||
@ -39,6 +40,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
|
|||||||
{"8.30.a", 0x17},
|
{"8.30.a", 0x17},
|
||||||
{"8.40.a", 0x18},
|
{"8.40.a", 0x18},
|
||||||
{"8.40.b", 0x19},
|
{"8.40.b", 0x19},
|
||||||
|
{"8.50.a", 0x1a},
|
||||||
{"9.0", 0x1b},
|
{"9.0", 0x1b},
|
||||||
{"9.1", 0x1d},
|
{"9.1", 0x1d},
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
@ -68,11 +70,10 @@ const struct family_string_key family_string_lookup[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct cpuinfo cpuinfo;
|
struct cpuinfo cpuinfo;
|
||||||
|
static struct device_node *cpu;
|
||||||
|
|
||||||
void __init setup_cpuinfo(void)
|
void __init setup_cpuinfo(void)
|
||||||
{
|
{
|
||||||
struct device_node *cpu = NULL;
|
|
||||||
|
|
||||||
cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
|
cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
|
||||||
if (!cpu)
|
if (!cpu)
|
||||||
pr_err("You don't have cpu!!!\n");
|
pr_err("You don't have cpu!!!\n");
|
||||||
@ -102,3 +103,22 @@ void __init setup_cpuinfo(void)
|
|||||||
pr_warn("%s: Stream instructions enabled"
|
pr_warn("%s: Stream instructions enabled"
|
||||||
" - USERSPACE CAN LOCK THIS KERNEL!\n", __func__);
|
" - USERSPACE CAN LOCK THIS KERNEL!\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __init setup_cpuinfo_clk(void)
|
||||||
|
{
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
|
clk = of_clk_get(cpu, 0);
|
||||||
|
if (IS_ERR(clk)) {
|
||||||
|
pr_err("ERROR: CPU CCF input clock not found\n");
|
||||||
|
/* take timebase-frequency from DTS */
|
||||||
|
cpuinfo.cpu_clock_freq = fcpu(cpu, "timebase-frequency");
|
||||||
|
} else {
|
||||||
|
cpuinfo.cpu_clock_freq = clk_get_rate(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cpuinfo.cpu_clock_freq) {
|
||||||
|
pr_err("ERROR: CPU clock frequency not setup\n");
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -64,6 +64,10 @@ real_start:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mts rmsr, r0
|
mts rmsr, r0
|
||||||
|
/* Disable stack protection from bootloader */
|
||||||
|
mts rslr, r0
|
||||||
|
addi r8, r0, 0xFFFFFFF
|
||||||
|
mts rshr, r8
|
||||||
/*
|
/*
|
||||||
* According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
|
* According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
|
||||||
* if the msrclr instruction is not enabled. We use this to detect
|
* if the msrclr instruction is not enabled. We use this to detect
|
||||||
|
@ -147,15 +147,14 @@
|
|||||||
or r3, r0, NUM_TO_REG (regnum);
|
or r3, r0, NUM_TO_REG (regnum);
|
||||||
|
|
||||||
/* Shift right instruction depending on available configuration */
|
/* Shift right instruction depending on available configuration */
|
||||||
#if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
|
#if CONFIG_XILINX_MICROBLAZE0_USE_BARREL == 0
|
||||||
#define BSRLI(rD, rA, imm) \
|
|
||||||
bsrli rD, rA, imm
|
|
||||||
#else
|
|
||||||
#define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
|
|
||||||
/* Only the used shift constants defined here - add more if needed */
|
/* Only the used shift constants defined here - add more if needed */
|
||||||
#define BSRLI2(rD, rA) \
|
#define BSRLI2(rD, rA) \
|
||||||
srl rD, rA; /* << 1 */ \
|
srl rD, rA; /* << 1 */ \
|
||||||
srl rD, rD; /* << 2 */
|
srl rD, rD; /* << 2 */
|
||||||
|
#define BSRLI4(rD, rA) \
|
||||||
|
BSRLI2(rD, rA); \
|
||||||
|
BSRLI2(rD, rD)
|
||||||
#define BSRLI10(rD, rA) \
|
#define BSRLI10(rD, rA) \
|
||||||
srl rD, rA; /* << 1 */ \
|
srl rD, rA; /* << 1 */ \
|
||||||
srl rD, rD; /* << 2 */ \
|
srl rD, rD; /* << 2 */ \
|
||||||
@ -170,7 +169,33 @@
|
|||||||
#define BSRLI20(rD, rA) \
|
#define BSRLI20(rD, rA) \
|
||||||
BSRLI10(rD, rA); \
|
BSRLI10(rD, rA); \
|
||||||
BSRLI10(rD, rD)
|
BSRLI10(rD, rD)
|
||||||
|
|
||||||
|
.macro bsrli, rD, rA, IMM
|
||||||
|
.if (\IMM) == 2
|
||||||
|
BSRLI2(\rD, \rA)
|
||||||
|
.elseif (\IMM) == 10
|
||||||
|
BSRLI10(\rD, \rA)
|
||||||
|
.elseif (\IMM) == 12
|
||||||
|
BSRLI2(\rD, \rA)
|
||||||
|
BSRLI10(\rD, \rD)
|
||||||
|
.elseif (\IMM) == 14
|
||||||
|
BSRLI4(\rD, \rA)
|
||||||
|
BSRLI10(\rD, \rD)
|
||||||
|
.elseif (\IMM) == 20
|
||||||
|
BSRLI20(\rD, \rA)
|
||||||
|
.elseif (\IMM) == 24
|
||||||
|
BSRLI4(\rD, \rA)
|
||||||
|
BSRLI20(\rD, \rD)
|
||||||
|
.elseif (\IMM) == 28
|
||||||
|
BSRLI4(\rD, \rA)
|
||||||
|
BSRLI4(\rD, \rD)
|
||||||
|
BSRLI20(\rD, \rD)
|
||||||
|
.else
|
||||||
|
.error "BSRLI shift macros \IMM"
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_MMU */
|
#endif /* CONFIG_MMU */
|
||||||
|
|
||||||
.extern other_exception_handler /* Defined in exception.c */
|
.extern other_exception_handler /* Defined in exception.c */
|
||||||
@ -604,7 +629,7 @@ ex_handler_done:
|
|||||||
ex4:
|
ex4:
|
||||||
tophys(r4,r4)
|
tophys(r4,r4)
|
||||||
/* Create L1 (pgdir/pmd) address */
|
/* Create L1 (pgdir/pmd) address */
|
||||||
BSRLI(r5,r3, PGDIR_SHIFT - 2)
|
bsrli r5, r3, PGDIR_SHIFT - 2
|
||||||
andi r5, r5, PAGE_SIZE - 4
|
andi r5, r5, PAGE_SIZE - 4
|
||||||
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
||||||
or r4, r4, r5
|
or r4, r4, r5
|
||||||
@ -613,7 +638,7 @@ ex_handler_done:
|
|||||||
beqi r5, ex2 /* Bail if no table */
|
beqi r5, ex2 /* Bail if no table */
|
||||||
|
|
||||||
tophys(r5,r5)
|
tophys(r5,r5)
|
||||||
BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
|
bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
|
||||||
andi r6, r6, PAGE_SIZE - 4
|
andi r6, r6, PAGE_SIZE - 4
|
||||||
or r5, r5, r6
|
or r5, r5, r6
|
||||||
lwi r4, r5, 0 /* Get Linux PTE */
|
lwi r4, r5, 0 /* Get Linux PTE */
|
||||||
@ -705,7 +730,7 @@ ex_handler_done:
|
|||||||
ex6:
|
ex6:
|
||||||
tophys(r4,r4)
|
tophys(r4,r4)
|
||||||
/* Create L1 (pgdir/pmd) address */
|
/* Create L1 (pgdir/pmd) address */
|
||||||
BSRLI(r5,r3, PGDIR_SHIFT - 2)
|
bsrli r5, r3, PGDIR_SHIFT - 2
|
||||||
andi r5, r5, PAGE_SIZE - 4
|
andi r5, r5, PAGE_SIZE - 4
|
||||||
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
||||||
or r4, r4, r5
|
or r4, r4, r5
|
||||||
@ -714,7 +739,7 @@ ex_handler_done:
|
|||||||
beqi r5, ex7 /* Bail if no table */
|
beqi r5, ex7 /* Bail if no table */
|
||||||
|
|
||||||
tophys(r5,r5)
|
tophys(r5,r5)
|
||||||
BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
|
bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
|
||||||
andi r6, r6, PAGE_SIZE - 4
|
andi r6, r6, PAGE_SIZE - 4
|
||||||
or r5, r5, r6
|
or r5, r5, r6
|
||||||
lwi r4, r5, 0 /* Get Linux PTE */
|
lwi r4, r5, 0 /* Get Linux PTE */
|
||||||
@ -776,7 +801,7 @@ ex_handler_done:
|
|||||||
ex9:
|
ex9:
|
||||||
tophys(r4,r4)
|
tophys(r4,r4)
|
||||||
/* Create L1 (pgdir/pmd) address */
|
/* Create L1 (pgdir/pmd) address */
|
||||||
BSRLI(r5,r3, PGDIR_SHIFT - 2)
|
bsrli r5, r3, PGDIR_SHIFT - 2
|
||||||
andi r5, r5, PAGE_SIZE - 4
|
andi r5, r5, PAGE_SIZE - 4
|
||||||
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
|
||||||
or r4, r4, r5
|
or r4, r4, r5
|
||||||
@ -785,7 +810,7 @@ ex_handler_done:
|
|||||||
beqi r5, ex10 /* Bail if no table */
|
beqi r5, ex10 /* Bail if no table */
|
||||||
|
|
||||||
tophys(r5,r5)
|
tophys(r5,r5)
|
||||||
BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
|
bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
|
||||||
andi r6, r6, PAGE_SIZE - 4
|
andi r6, r6, PAGE_SIZE - 4
|
||||||
or r5, r5, r6
|
or r5, r5, r6
|
||||||
lwi r4, r5, 0 /* Get Linux PTE */
|
lwi r4, r5, 0 /* Get Linux PTE */
|
||||||
@ -922,7 +947,7 @@ ex_handler_done:
|
|||||||
.ent _unaligned_data_exception
|
.ent _unaligned_data_exception
|
||||||
_unaligned_data_exception:
|
_unaligned_data_exception:
|
||||||
andi r8, r3, 0x3E0; /* Mask and extract the register operand */
|
andi r8, r3, 0x3E0; /* Mask and extract the register operand */
|
||||||
BSRLI(r8,r8,2); /* r8 >> 2 = register operand * 8 */
|
bsrli r8, r8, 2; /* r8 >> 2 = register operand * 8 */
|
||||||
andi r6, r3, 0x400; /* Extract ESR[S] */
|
andi r6, r3, 0x400; /* Extract ESR[S] */
|
||||||
bneid r6, ex_sw_vm;
|
bneid r6, ex_sw_vm;
|
||||||
andi r6, r3, 0x800; /* Extract ESR[W] - delay slot */
|
andi r6, r3, 0x800; /* Extract ESR[W] - delay slot */
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
@ -136,7 +137,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
|
|||||||
lockdep_init();
|
lockdep_init();
|
||||||
|
|
||||||
/* initialize device tree for usage in early_printk */
|
/* initialize device tree for usage in early_printk */
|
||||||
early_init_devtree((void *)_fdt_start);
|
early_init_devtree(_fdt_start);
|
||||||
|
|
||||||
#ifdef CONFIG_EARLY_PRINTK
|
#ifdef CONFIG_EARLY_PRINTK
|
||||||
setup_early_printk(NULL);
|
setup_early_printk(NULL);
|
||||||
@ -152,8 +153,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
|
|||||||
if (fdt)
|
if (fdt)
|
||||||
pr_info("FDT at 0x%08x\n", fdt);
|
pr_info("FDT at 0x%08x\n", fdt);
|
||||||
else
|
else
|
||||||
pr_info("Compiled-in FDT at 0x%08x\n",
|
pr_info("Compiled-in FDT at %p\n", _fdt_start);
|
||||||
(unsigned int)_fdt_start);
|
|
||||||
|
|
||||||
#ifdef CONFIG_MTD_UCLINUX
|
#ifdef CONFIG_MTD_UCLINUX
|
||||||
pr_info("Found romfs @ 0x%08x (0x%08x)\n",
|
pr_info("Found romfs @ 0x%08x (0x%08x)\n",
|
||||||
@ -175,7 +175,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
|
|||||||
#else
|
#else
|
||||||
if (!msr) {
|
if (!msr) {
|
||||||
pr_info("!!!Your kernel not setup MSR instruction but ");
|
pr_info("!!!Your kernel not setup MSR instruction but ");
|
||||||
pr_cont"CPU have it %x\n", msr);
|
pr_cont("CPU have it %x\n", msr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -196,6 +196,8 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
|
|||||||
|
|
||||||
void __init time_init(void)
|
void __init time_init(void)
|
||||||
{
|
{
|
||||||
|
of_clk_init(NULL);
|
||||||
|
setup_cpuinfo_clk();
|
||||||
clocksource_of_init();
|
clocksource_of_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/sched_clock.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/clockchips.h>
|
#include <linux/clockchips.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <asm/cpuinfo.h>
|
#include <asm/cpuinfo.h>
|
||||||
#include <linux/cnt32_to_63.h>
|
|
||||||
|
|
||||||
static void __iomem *timer_baseaddr;
|
static void __iomem *timer_baseaddr;
|
||||||
|
|
||||||
@ -167,10 +167,15 @@ static __init void xilinx_clockevent_init(void)
|
|||||||
clockevents_register_device(&clockevent_xilinx_timer);
|
clockevents_register_device(&clockevent_xilinx_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 xilinx_clock_read(void)
|
||||||
|
{
|
||||||
|
return in_be32(timer_baseaddr + TCR1);
|
||||||
|
}
|
||||||
|
|
||||||
static cycle_t xilinx_read(struct clocksource *cs)
|
static cycle_t xilinx_read(struct clocksource *cs)
|
||||||
{
|
{
|
||||||
/* reading actual value of timer 1 */
|
/* reading actual value of timer 1 */
|
||||||
return (cycle_t) (in_be32(timer_baseaddr + TCR1));
|
return (cycle_t)xilinx_clock_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct timecounter xilinx_tc = {
|
static struct timecounter xilinx_tc = {
|
||||||
@ -222,17 +227,17 @@ static int __init xilinx_clocksource_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We have to protect accesses before timer initialization
|
|
||||||
* and return 0 for sched_clock function below.
|
|
||||||
*/
|
|
||||||
static int timer_initialized;
|
|
||||||
|
|
||||||
static void __init xilinx_timer_init(struct device_node *timer)
|
static void __init xilinx_timer_init(struct device_node *timer)
|
||||||
{
|
{
|
||||||
|
struct clk *clk;
|
||||||
|
static int initialized;
|
||||||
u32 irq;
|
u32 irq;
|
||||||
u32 timer_num = 1;
|
u32 timer_num = 1;
|
||||||
int ret;
|
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
timer_baseaddr = of_iomap(timer, 0);
|
timer_baseaddr = of_iomap(timer, 0);
|
||||||
if (!timer_baseaddr) {
|
if (!timer_baseaddr) {
|
||||||
@ -250,10 +255,20 @@ static void __init xilinx_timer_init(struct device_node *timer)
|
|||||||
|
|
||||||
pr_info("%s: irq=%d\n", timer->full_name, irq);
|
pr_info("%s: irq=%d\n", timer->full_name, irq);
|
||||||
|
|
||||||
/* If there is clock-frequency property than use it */
|
clk = of_clk_get(timer, 0);
|
||||||
ret = of_property_read_u32(timer, "clock-frequency", &timer_clock_freq);
|
if (IS_ERR(clk)) {
|
||||||
if (ret < 0)
|
pr_err("ERROR: timer CCF input clock not found\n");
|
||||||
|
/* If there is clock-frequency property than use it */
|
||||||
|
of_property_read_u32(timer, "clock-frequency",
|
||||||
|
&timer_clock_freq);
|
||||||
|
} else {
|
||||||
|
timer_clock_freq = clk_get_rate(clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!timer_clock_freq) {
|
||||||
|
pr_err("ERROR: Using CPU clock frequency\n");
|
||||||
timer_clock_freq = cpuinfo.cpu_clock_freq;
|
timer_clock_freq = cpuinfo.cpu_clock_freq;
|
||||||
|
}
|
||||||
|
|
||||||
freq_div_hz = timer_clock_freq / HZ;
|
freq_div_hz = timer_clock_freq / HZ;
|
||||||
|
|
||||||
@ -263,18 +278,8 @@ static void __init xilinx_timer_init(struct device_node *timer)
|
|||||||
#endif
|
#endif
|
||||||
xilinx_clocksource_init();
|
xilinx_clocksource_init();
|
||||||
xilinx_clockevent_init();
|
xilinx_clockevent_init();
|
||||||
timer_initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long long notrace sched_clock(void)
|
sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
|
||||||
{
|
|
||||||
if (timer_initialized) {
|
|
||||||
struct clocksource *cs = &clocksource_microblaze;
|
|
||||||
|
|
||||||
cycle_t cyc = cnt32_to_63(cs->read(NULL)) & LLONG_MAX;
|
|
||||||
return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
|
CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
|
||||||
|
@ -51,6 +51,7 @@ SECTIONS {
|
|||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
RODATA
|
RODATA
|
||||||
EXCEPTION_TABLE(16)
|
EXCEPTION_TABLE(16)
|
||||||
|
NOTES
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sdata2 section can go anywhere, but must be word aligned
|
* sdata2 section can go anywhere, but must be word aligned
|
||||||
|
Loading…
Reference in New Issue
Block a user