Pull MIPS updates from Ralf Baechle: "These are the highlists of the main MIPS pull request for 4.4: - Add latencytop support - Support appended DTBs - VDSO support and initially use it for gettimeofday. - Drop the .MIPS.abiflags and ELF NOTE sections from vmlinux - Support for the 5KE, an internal test core. - Switch all MIPS platfroms to libata drivers. - Improved support, cleanups for ralink and Lantiq platforms. - Support for the new xilfpga platform. - A number of DTB improvments for BMIPS. - Improved support for CM and CPS. - Minor JZ4740 and BCM47xx enhancements" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (120 commits) MIPS: idle: add case for CPU_5KE MIPS: Octeon: Support APPENDED_DTB MIPS: vmlinux: create a section for appended DTB MIPS: Clean up compat_siginfo_t MIPS: Fix PAGE_MASK definition MIPS: BMIPS: Enable GZIP ramdisk and timed printks MIPS: Add xilfpga defconfig MIPS: xilfpga: Add mipsfpga platform code MIPS: xilfpga: Add xilfpga device tree files. dt-bindings: MIPS: Document xilfpga bindings and boot style MIPS: Make MIPS_CMDLINE_DTB default MIPS: Make the kernel arguments from dtb available MIPS: Use USE_OF as the guard for appended dtb MIPS: BCM63XX: Use pr_* instead of printk MIPS: Loongson: Cleanup CONFIG_LOONGSON_SUSPEND. MIPS: lantiq: Disable xbar fpi burst mode MIPS: lantiq: Force the crossbar to big endian MIPS: lantiq: Initialize the USB core on boot MIPS: lantiq: Return correct value for fpi clock on ar9 MIPS: ralink: Add missing clock on rt305x ...
Unified · Split
| @@ -0,0 +1,83 @@ | ||
| 1 | +Imagination University Program MIPSfpga | |
| 2 | +======================================= | |
| 3 | + | |
| 4 | +Under the Imagination University Program, a microAptiv UP core has been | |
| 5 | +released for academic usage. | |
| 6 | + | |
| 7 | +As we are dealing with a MIPS core instantiated on an FPGA, specifications | |
| 8 | +are fluid and can be varied in RTL. | |
| 9 | + | |
| 10 | +This binding document is provided as baseline guidance for the example | |
| 11 | +project provided by IMG. | |
| 12 | + | |
| 13 | +The example project runs on the Nexys4DDR board by Digilent powered by | |
| 14 | +the ARTIX-7 FPGA by Xilinx. | |
| 15 | + | |
| 16 | +Relevant details about the example project and the Nexys4DDR board: | |
| 17 | + | |
| 18 | +- microAptiv UP core m14Kc | |
| 19 | +- 50MHz clock speed | |
| 20 | +- 128Mbyte DDR RAM at 0x0000_0000 | |
| 21 | +- 8Kbyte RAM at 0x1000_0000 | |
| 22 | +- axi_intc at 0x1020_0000 | |
| 23 | +- axi_uart16550 at 0x1040_0000 | |
| 24 | +- axi_gpio at 0x1060_0000 | |
| 25 | +- axi_i2c at 0x10A0_0000 | |
| 26 | +- custom_gpio at 0x10C0_0000 | |
| 27 | +- axi_ethernetlite at 0x10E0_0000 | |
| 28 | +- 8Kbyte BootRAM at 0x1FC0_0000 | |
| 29 | + | |
| 30 | +Required properties: | |
| 31 | +-------------------- | |
| 32 | + - compatible: Must include "digilent,nexys4ddr","img,xilfpga". | |
| 33 | + | |
| 34 | +CPU nodes: | |
| 35 | +---------- | |
| 36 | +A "cpus" node is required. Required properties: | |
| 37 | + - #address-cells: Must be 1. | |
| 38 | + - #size-cells: Must be 0. | |
| 39 | +A CPU sub-node is also required for at least CPU 0. Required properties: | |
| 40 | + - device_type: Must be "cpu". | |
| 41 | + - compatible: Must be "mips,m14Kc". | |
| 42 | + - reg: Must be <0>. | |
| 43 | + - clocks: phandle to ext clock for fixed-clock received by MIPS core. | |
| 44 | + | |
| 45 | +Example: | |
| 46 | + | |
| 47 | + compatible = "img,xilfpga","digilent,nexys4ddr"; | |
| 48 | + cpus { | |
| 49 | + #address-cells = <1>; | |
| 50 | + #size-cells = <0>; | |
| 51 | + | |
| 52 | + cpu0: cpu@0 { | |
| 53 | + device_type = "cpu"; | |
| 54 | + compatible = "mips,m14Kc"; | |
| 55 | + reg = <0>; | |
| 56 | + clocks = <&ext>; | |
| 57 | + }; | |
| 58 | + }; | |
| 59 | + | |
| 60 | + ext: ext { | |
| 61 | + compatible = "fixed-clock"; | |
| 62 | + #clock-cells = <0>; | |
| 63 | + clock-frequency = <50000000>; | |
| 64 | + }; | |
| 65 | + | |
| 66 | +Boot protocol: | |
| 67 | +-------------- | |
| 68 | + | |
| 69 | +The BootRAM is a writeable "RAM" in FPGA at 0x1FC0_0000. | |
| 70 | +This is for easy reprogrammibility via JTAG. | |
| 71 | + | |
| 72 | +The BootRAM initializes the cache and the axi_uart peripheral. | |
| 73 | + | |
| 74 | +DDR initialization is already handled by a HW IP block. | |
| 75 | + | |
| 76 | +When the example project bitstream is loaded, the cpu_reset button | |
| 77 | +needs to be pressed. | |
| 78 | + | |
| 79 | +The bootram initializes the cache and axi_uart. | |
| 80 | +Then outputs MIPSFPGA\n\r on the serial port on the Nexys4DDR board. | |
| 81 | + | |
| 82 | +At this point, the board is ready to load the Linux kernel | |
| 83 | +vmlinux file via JTAG. | |
| @@ -17,6 +17,7 @@ obj- := $(platform-) · 16 unmodified lines | ||
| 17 | 17 | obj-y += kernel/ |
| 18 | 18 | obj-y += mm/ |
| 19 | 19 | obj-y += net/ |
| 20 | +obj-y += vdso/ | |
| 20 | 21 | |
| 21 | 22 | ifdef CONFIG_KVM |
| 22 | 23 | obj-y += kvm/ |
| @@ -33,6 +33,7 @@ platforms += sibyte · 32 unmodified lines | ||
| 33 | 33 | platforms += sni |
| 34 | 34 | platforms += txx9 |
| 35 | 35 | platforms += vr41xx |
| 36 | +platforms += xilfpga | |
| 36 | 37 | |
| 37 | 38 | # include the platform specific files |
| 38 | 39 | include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms)) |
| @@ -5,6 +5,7 @@ config MIPS · 4 unmodified lines | ||
| 5 | 5 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 6 | 6 | select ARCH_MIGHT_HAVE_PC_SERIO |
| 7 | 7 | select ARCH_USE_CMPXCHG_LOCKREF if 64BIT |
| 8 | + select ARCH_USE_BUILTIN_BSWAP | |
| 8 | 9 | select HAVE_CONTEXT_TRACKING |
| 9 | 10 | select HAVE_GENERIC_DMA_COHERENT |
| 10 | 11 | select HAVE_IDE |
| @@ -60,6 +61,8 @@ config MIPS · 49 unmodified lines | ||
| 60 | 61 | select SYSCTL_EXCEPTION_TRACE |
| 61 | 62 | select HAVE_VIRT_CPU_ACCOUNTING_GEN |
| 62 | 63 | select HAVE_IRQ_TIME_ACCOUNTING |
| 64 | + select GENERIC_TIME_VSYSCALL | |
| 65 | + select ARCH_CLOCKSOURCE_DATA | |
| 63 | 66 | |
| 64 | 67 | menu "Machine selection" |
| 65 | 68 | |
| @@ -401,6 +404,28 @@ config MACH_PISTACHIO · 335 unmodified lines | ||
| 401 | 404 | help |
| 402 | 405 | This enables support for the IMG Pistachio SoC platform. |
| 403 | 406 | |
| 407 | +config MACH_XILFPGA | |
| 408 | + bool "MIPSfpga Xilinx based boards" | |
| 409 | + select ARCH_REQUIRE_GPIOLIB | |
| 410 | + select BOOT_ELF32 | |
| 411 | + select BOOT_RAW | |
| 412 | + select BUILTIN_DTB | |
| 413 | + select CEVT_R4K | |
| 414 | + select COMMON_CLK | |
| 415 | + select CSRC_R4K | |
| 416 | + select IRQ_MIPS_CPU | |
| 417 | + select LIBFDT | |
| 418 | + select MIPS_CPU_SCACHE | |
| 419 | + select SYS_HAS_EARLY_PRINTK | |
| 420 | + select SYS_HAS_CPU_MIPS32_R2 | |
| 421 | + select SYS_SUPPORTS_32BIT_KERNEL | |
| 422 | + select SYS_SUPPORTS_LITTLE_ENDIAN | |
| 423 | + select SYS_SUPPORTS_ZBOOT_UART16550 | |
| 424 | + select USE_OF | |
| 425 | + select USE_GENERIC_EARLY_PRINTK_8250 | |
| 426 | + help | |
| 427 | + This enables support for the IMG University Program MIPSfpga platform. | |
| 428 | + | |
| 404 | 429 | config MIPS_MALTA |
| 405 | 430 | bool "MIPS Malta board" |
| 406 | 431 | select ARCH_MAY_HAVE_PC_FDC |
| @@ -424,6 +449,7 @@ config MIPS_MALTA · 17 unmodified lines | ||
| 424 | 449 | select MIPS_L1_CACHE_SHIFT_6 |
| 425 | 450 | select PCI_GT64XXX_PCI0 |
| 426 | 451 | select MIPS_MSC |
| 452 | + select SMP_UP if SMP | |
| 427 | 453 | select SWAP_IO_SPACE |
| 428 | 454 | select SYS_HAS_CPU_MIPS32_R1 |
| 429 | 455 | select SYS_HAS_CPU_MIPS32_R2 |
| @@ -449,6 +475,8 @@ config MIPS_MALTA · 19 unmodified lines | ||
| 449 | 475 | select SYS_SUPPORTS_ZBOOT |
| 450 | 476 | select USE_OF |
| 451 | 477 | select ZONE_DMA32 if 64BIT |
| 478 | + select BUILTIN_DTB | |
| 479 | + select LIBFDT | |
| 452 | 480 | help |
| 453 | 481 | This enables support for the MIPS Technologies Malta evaluation |
| 454 | 482 | board. |
| @@ -964,6 +992,7 @@ source "arch/mips/loongson32/Kconfig" · 509 unmodified lines | ||
| 964 | 992 | source "arch/mips/loongson64/Kconfig" |
| 965 | 993 | source "arch/mips/netlogic/Kconfig" |
| 966 | 994 | source "arch/mips/paravirt/Kconfig" |
| 995 | +source "arch/mips/xilfpga/Kconfig" | |
| 967 | 996 | |
| 968 | 997 | endmenu |
| 969 | 998 | |
| @@ -1036,6 +1065,9 @@ config CSRC_R4K · 66 unmodified lines | ||
| 1036 | 1065 | config CSRC_SB1250 |
| 1037 | 1066 | bool |
| 1038 | 1067 | |
| 1068 | +config MIPS_CLOCK_VSYSCALL | |
| 1069 | + def_bool CSRC_R4K || CLKSRC_MIPS_GIC | |
| 1070 | + | |
| 1039 | 1071 | config GPIO_TXX9 |
| 1040 | 1072 | select ARCH_REQUIRE_GPIOLIB |
| 1041 | 1073 | bool |
| @@ -2529,6 +2561,9 @@ choice · 1487 unmodified lines | ||
| 2529 | 2561 | help |
| 2530 | 2562 | Allows the configuration of the timer frequency. |
| 2531 | 2563 | |
| 2564 | + config HZ_24 | |
| 2565 | + bool "24 HZ" if SYS_SUPPORTS_24HZ || SYS_SUPPORTS_ARBIT_HZ | |
| 2566 | + | |
| 2532 | 2567 | config HZ_48 |
| 2533 | 2568 | bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ |
| 2534 | 2569 | |
| @@ -2552,6 +2587,9 @@ choice · 17 unmodified lines | ||
| 2552 | 2587 | |
| 2553 | 2588 | endchoice |
| 2554 | 2589 | |
| 2590 | +config SYS_SUPPORTS_24HZ | |
| 2591 | + bool | |
| 2592 | + | |
| 2555 | 2593 | config SYS_SUPPORTS_48HZ |
| 2556 | 2594 | bool |
| 2557 | 2595 | |
| @@ -2575,13 +2613,18 @@ config SYS_SUPPORTS_1024HZ · 17 unmodified lines | ||
| 2575 | 2613 | |
| 2576 | 2614 | config SYS_SUPPORTS_ARBIT_HZ |
| 2577 | 2615 | bool |
| 2578 | − default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \ | |
| 2579 | − !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \ | |
| 2580 | − !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \ | |
| 2616 | + default y if !SYS_SUPPORTS_24HZ && \ | |
| 2617 | + !SYS_SUPPORTS_48HZ && \ | |
| 2618 | + !SYS_SUPPORTS_100HZ && \ | |
| 2619 | + !SYS_SUPPORTS_128HZ && \ | |
| 2620 | + !SYS_SUPPORTS_250HZ && \ | |
| 2621 | + !SYS_SUPPORTS_256HZ && \ | |
| 2622 | + !SYS_SUPPORTS_1000HZ && \ | |
| 2581 | 2623 | !SYS_SUPPORTS_1024HZ |
| 2582 | 2624 | |
| 2583 | 2625 | config HZ |
| 2584 | 2626 | int |
| 2627 | + default 24 if HZ_24 | |
| 2585 | 2628 | default 48 if HZ_48 |
| 2586 | 2629 | default 100 if HZ_100 |
| 2587 | 2630 | default 128 if HZ_128 |
| @@ -2685,7 +2728,7 @@ config BUILTIN_DTB · 97 unmodified lines | ||
| 2685 | 2728 | bool |
| 2686 | 2729 | |
| 2687 | 2730 | choice |
| 2688 | − prompt "Kernel appended dtb support" if OF | |
| 2731 | + prompt "Kernel appended dtb support" if USE_OF | |
| 2689 | 2732 | default MIPS_NO_APPENDED_DTB |
| 2690 | 2733 | |
| 2691 | 2734 | config MIPS_NO_APPENDED_DTB |
| @@ -2693,6 +2736,20 @@ choice · 1 unmodified line | ||
| 2693 | 2736 | help |
| 2694 | 2737 | Do not enable appended dtb support. |
| 2695 | 2738 | |
| 2739 | + config MIPS_ELF_APPENDED_DTB | |
| 2740 | + bool "vmlinux" | |
| 2741 | + help | |
| 2742 | + With this option, the boot code will look for a device tree binary | |
| 2743 | + DTB) included in the vmlinux ELF section .appended_dtb. By default | |
| 2744 | + it is empty and the DTB can be appended using binutils command | |
| 2745 | + objcopy: | |
| 2746 | + | |
| 2747 | + objcopy --update-section .appended_dtb=<filename>.dtb vmlinux | |
| 2748 | + | |
| 2749 | + This is meant as a backward compatiblity convenience for those | |
| 2750 | + systems with a bootloader that can't be upgraded to accommodate | |
| 2751 | + the documented boot protocol using a device tree. | |
| 2752 | + | |
| 2696 | 2753 | config MIPS_RAW_APPENDED_DTB |
| 2697 | 2754 | bool "vmlinux.bin" |
| 2698 | 2755 | help |
| @@ -2729,6 +2786,25 @@ choice · 30 unmodified lines | ||
| 2729 | 2786 | if you don't intend to always append a DTB. |
| 2730 | 2787 | endchoice |
| 2731 | 2788 | |
| 2789 | +choice | |
| 2790 | + prompt "Kernel command line type" if !CMDLINE_OVERRIDE | |
| 2791 | + default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \ | |
| 2792 | + !MIPS_MALTA && !MIPS_SEAD3 && \ | |
| 2793 | + !CAVIUM_OCTEON_SOC | |
| 2794 | + default MIPS_CMDLINE_FROM_BOOTLOADER | |
| 2795 | + | |
| 2796 | + config MIPS_CMDLINE_FROM_DTB | |
| 2797 | + depends on USE_OF | |
| 2798 | + bool "Dtb kernel arguments if available" | |
| 2799 | + | |
| 2800 | + config MIPS_CMDLINE_DTB_EXTEND | |
| 2801 | + depends on USE_OF | |
| 2802 | + bool "Extend dtb kernel arguments with bootloader arguments" | |
| 2803 | + | |
| 2804 | + config MIPS_CMDLINE_FROM_BOOTLOADER | |
| 2805 | + bool "Bootloader kernel arguments if available" | |
| 2806 | +endchoice | |
| 2807 | + | |
| 2732 | 2808 | endmenu |
| 2733 | 2809 | |
| 2734 | 2810 | config LOCKDEP_SUPPORT |
| @@ -2739,6 +2815,10 @@ config STACKTRACE_SUPPORT · 4 unmodified lines | ||
| 2739 | 2815 | bool |
| 2740 | 2816 | default y |
| 2741 | 2817 | |
| 2818 | +config HAVE_LATENCYTOP_SUPPORT | |
| 2819 | + bool | |
| 2820 | + default y | |
| 2821 | + | |
| 2742 | 2822 | config PGTABLE_LEVELS |
| 2743 | 2823 | int |
| 2744 | 2824 | default 3 if 64BIT && !PAGE_SIZE_64KB |
| @@ -113,4 +113,76 @@ config SPINLOCK_TEST · 112 unmodified lines | ||
| 113 | 113 | help |
| 114 | 114 | Add several files to the debugfs to test spinlock speed. |
| 115 | 115 | |
| 116 | +if CPU_MIPSR6 | |
| 117 | + | |
| 118 | +choice | |
| 119 | + prompt "Compact branch policy" | |
| 120 | + default MIPS_COMPACT_BRANCHES_OPTIMAL | |
| 121 | + | |
| 122 | +config MIPS_COMPACT_BRANCHES_NEVER | |
| 123 | + bool "Never (force delay slot branches)" | |
| 124 | + help | |
| 125 | + Pass the -mcompact-branches=never flag to the compiler in order to | |
| 126 | + force it to always emit branches with delay slots, and make no use | |
| 127 | + of the compact branch instructions introduced by MIPSr6. This is | |
| 128 | + useful if you suspect there may be an issue with compact branches in | |
| 129 | + either the compiler or the CPU. | |
| 130 | + | |
| 131 | +config MIPS_COMPACT_BRANCHES_OPTIMAL | |
| 132 | + bool "Optimal (use where beneficial)" | |
| 133 | + help | |
| 134 | + Pass the -mcompact-branches=optimal flag to the compiler in order for | |
| 135 | + it to make use of compact branch instructions where it deems them | |
| 136 | + beneficial, and use branches with delay slots elsewhere. This is the | |
| 137 | + default compiler behaviour, and should be used unless you have a | |
| 138 | + reason to choose otherwise. | |
| 139 | + | |
| 140 | +config MIPS_COMPACT_BRANCHES_ALWAYS | |
| 141 | + bool "Always (force compact branches)" | |
| 142 | + help | |
| 143 | + Pass the -mcompact-branches=always flag to the compiler in order to | |
| 144 | + force it to always emit compact branches, making no use of branch | |
| 145 | + instructions with delay slots. This can result in more compact code | |
| 146 | + which may be beneficial in some scenarios. | |
| 147 | + | |
| 148 | +endchoice | |
| 149 | + | |
| 150 | +endif # CPU_MIPSR6 | |
| 151 | + | |
| 152 | +config SCACHE_DEBUGFS | |
| 153 | + bool "L2 cache debugfs entries" | |
| 154 | + depends on DEBUG_FS | |
| 155 | + help | |
| 156 | + Enable this to allow parts of the L2 cache configuration, such as | |
| 157 | + whether or not prefetching is enabled, to be exposed to userland | |
| 158 | + via debugfs. | |
| 159 | + | |
| 160 | + If unsure, say N. | |
| 161 | + | |
| 162 | +menuconfig MIPS_CPS_NS16550 | |
| 163 | + bool "CPS SMP NS16550 UART output" | |
| 164 | + depends on MIPS_CPS | |
| 165 | + help | |
| 166 | + Output debug information via an ns16550 compatible UART if exceptions | |
| 167 | + occur early in the boot process of a secondary core. | |
| 168 | + | |
| 169 | +if MIPS_CPS_NS16550 | |
| 170 | + | |
| 171 | +config MIPS_CPS_NS16550_BASE | |
| 172 | + hex "UART Base Address" | |
| 173 | + default 0x1b0003f8 if MIPS_MALTA | |
| 174 | + help | |
| 175 | + The base address of the ns16550 compatible UART on which to output | |
| 176 | + debug information from the early stages of core startup. | |
| 177 | + | |
| 178 | +config MIPS_CPS_NS16550_SHIFT | |
| 179 | + int "UART Register Shift" | |
| 180 | + default 0 if MIPS_MALTA | |
| 181 | + help | |
| 182 | + The number of bits to shift ns16550 register indices by in order to | |
| 183 | + form their addresses. That is, log base 2 of the span between | |
| 184 | + adjacent ns16550 registers in the system. | |
| 185 | + | |
| 186 | +endif # MIPS_CPS_NS16550 | |
| 187 | + | |
| 116 | 188 | endmenu |
| @@ -204,6 +204,10 @@ toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$( · 203 unmodified lines | ||
| 204 | 204 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA |
| 205 | 205 | endif |
| 206 | 206 | |
| 207 | +cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_NEVER) += -mcompact-branches=never | |
| 208 | +cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_OPTIMAL) += -mcompact-branches=optimal | |
| 209 | +cflags-$(CONFIG_MIPS_COMPACT_BRANCHES_ALWAYS) += -mcompact-branches=always | |
| 210 | + | |
| 207 | 211 | # |
| 208 | 212 | # Firmware support |
| 209 | 213 | # |
| @@ -105,11 +105,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, · 104 unmodified lines | ||
| 105 | 105 | struct ssb_init_invariants *iv) |
| 106 | 106 | { |
| 107 | 107 | char buf[20]; |
| 108 | + int len, err; | |
| 108 | 109 | |
| 109 | 110 | /* Fill boardinfo structure */ |
| 110 | 111 | memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo)); |
| 111 | 112 | |
| 112 | − bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL); | |
| 113 | + len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf)); | |
| 114 | + if (len > 0) { | |
| 115 | + err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor); | |
| 116 | + if (err) | |
| 117 | + pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n", | |
| 118 | + buf); | |
| 119 | + } | |
| 120 | + if (!iv->boardinfo.vendor) | |
| 121 | + iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; | |
| 122 | + | |
| 123 | + len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)); | |
| 124 | + if (len > 0) { | |
| 125 | + err = kstrtou16(strim(buf), 0, &iv->boardinfo.type); | |
| 126 | + if (err) | |
| 127 | + pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n", | |
| 128 | + buf); | |
| 129 | + } | |
| 113 | 130 | |
| 114 | 131 | memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); |
| 115 | 132 | bcm47xx_fill_sprom(&iv->sprom, NULL, false); |
| @@ -60,9 +60,9 @@ static int get_nvram_var(const char *prefix, const char *postfix, · 59 unmodified lines | ||
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | #define NVRAM_READ_VAL(type) \ |
| 63 | −static void nvram_read_ ## type (const char *prefix, \ | |
| 64 | − const char *postfix, const char *name, \ | |
| 65 | − type *val, type allset, bool fallback) \ | |
| 63 | +static void nvram_read_ ## type(const char *prefix, \ | |
| 64 | + const char *postfix, const char *name, \ | |
| 65 | + type *val, type allset, bool fallback) \ | |
| 66 | 66 | { \ |
| 67 | 67 | char buf[100]; \ |
| 68 | 68 | int err; \ |
| @@ -422,7 +422,10 @@ static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, · 353 unmodified lines | ||
| 422 | 422 | int i; |
| 423 | 423 | |
| 424 | 424 | for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { |
| 425 | − struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; | |
| 425 | + struct ssb_sprom_core_pwr_info *pwr_info; | |
| 426 | + | |
| 427 | + pwr_info = &sprom->core_pwr_info[i]; | |
| 428 | + | |
| 426 | 429 | snprintf(postfix, sizeof(postfix), "%i", i); |
| 427 | 430 | nvram_read_u8(prefix, postfix, "maxp2ga", |
| 428 | 431 | &pwr_info->maxpwr_2g, 0, fallback); |
| @@ -470,7 +473,10 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, · 41 unmodified lines | ||
| 470 | 473 | int i; |
| 471 | 474 | |
| 472 | 475 | for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { |
| 473 | − struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; | |
| 476 | + struct ssb_sprom_core_pwr_info *pwr_info; | |
| 477 | + | |
| 478 | + pwr_info = &sprom->core_pwr_info[i]; | |
| 479 | + | |
| 474 | 480 | snprintf(postfix, sizeof(postfix), "%i", i); |
| 475 | 481 | nvram_read_u16(prefix, postfix, "pa2gw3a", |
| 476 | 482 | &pwr_info->pa_2g[3], 0, fallback); |
| @@ -535,10 +541,11 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, · 58 unmodified lines | ||
| 535 | 541 | nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback); |
| 536 | 542 | |
| 537 | 543 | /* The address prefix 00:90:4C is used by Broadcom in their initial |
| 538 | − configuration. When a mac address with the prefix 00:90:4C is used | |
| 539 | − all devices from the same series are sharing the same mac address. | |
| 540 | − To prevent mac address collisions we replace them with a mac address | |
| 541 | − based on the base address. */ | |
| 544 | + * configuration. When a mac address with the prefix 00:90:4C is used | |
| 545 | + * all devices from the same series are sharing the same mac address. | |
| 546 | + * To prevent mac address collisions we replace them with a mac address | |
| 547 | + * based on the base address. | |
| 548 | + */ | |
| 542 | 549 | if (!bcm47xx_is_valid_mac(sprom->il0mac)) { |
| 543 | 550 | u8 mac[6]; |
| 544 | 551 | |
| @@ -592,32 +599,23 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, · 47 unmodified lines | ||
| 592 | 599 | bcm47xx_sprom_fill_auto(sprom, prefix, fallback); |
| 593 | 600 | } |
| 594 | 601 | |
| 595 | −#ifdef CONFIG_BCM47XX_SSB | |
| 596 | −void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, | |
| 597 | − const char *prefix) | |
| 598 | −{ | |
| 599 | − nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, | |
| 600 | − true); | |
| 601 | − if (!boardinfo->vendor) | |
| 602 | − boardinfo->vendor = SSB_BOARDVENDOR_BCM; | |
| 603 | − | |
| 604 | − nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); | |
| 605 | −} | |
| 606 | −#endif | |
| 607 | − | |
| 608 | 602 | #if defined(CONFIG_BCM47XX_SSB) |
| 609 | 603 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) |
| 610 | 604 | { |
| 611 | 605 | char prefix[10]; |
| 612 | 606 | |
| 613 | − if (bus->bustype == SSB_BUSTYPE_PCI) { | |
| 607 | + switch (bus->bustype) { | |
| 608 | + case SSB_BUSTYPE_SSB: | |
| 609 | + bcm47xx_fill_sprom(out, NULL, false); | |
| 610 | + return 0; | |
| 611 | + case SSB_BUSTYPE_PCI: | |
| 614 | 612 | memset(out, 0, sizeof(struct ssb_sprom)); |
| 615 | 613 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", |
| 616 | 614 | bus->host_pci->bus->number + 1, |
| 617 | 615 | PCI_SLOT(bus->host_pci->devfn)); |
| 618 | 616 | bcm47xx_fill_sprom(out, prefix, false); |
| 619 | 617 | return 0; |
| 620 | − } else { | |
| 618 | + default: | |
| 621 | 619 | pr_warn("Unable to fill SPROM for given bustype.\n"); |
| 622 | 620 | return -EINVAL; |
| 623 | 621 | } |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 11 | + | |
| 10 | 12 | #include <linux/init.h> |
| 11 | 13 | #include <linux/kernel.h> |
| 12 | 14 | #include <linux/string.h> |
| @@ -31,7 +33,6 @@ · 18 unmodified lines | ||
| 31 | 33 | |
| 32 | 34 | #include <uapi/linux/bcm933xx_hcs.h> |
| 33 | 35 | |
| 34 | −#define PFX "board_bcm963xx: " | |
| 35 | 36 | |
| 36 | 37 | #define HCS_OFFSET_128K 0x20000 |
| 37 | 38 | |
| @@ -740,7 +741,7 @@ int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) · 702 unmodified lines | ||
| 740 | 741 | memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); |
| 741 | 742 | return 0; |
| 742 | 743 | } else { |
| 743 | − printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n"); | |
| 744 | + pr_err("unable to fill SPROM for given bustype\n"); | |
| 744 | 745 | return -EINVAL; |
| 745 | 746 | } |
| 746 | 747 | } |
| @@ -784,7 +785,7 @@ void __init board_prom_init(void) · 37 unmodified lines | ||
| 784 | 785 | cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]); |
| 785 | 786 | else |
| 786 | 787 | strcpy(cfe_version, "unknown"); |
| 787 | − printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); | |
| 788 | + pr_info("CFE version: %s\n", cfe_version); | |
| 788 | 789 | |
| 789 | 790 | bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); |
| 790 | 791 | |
| @@ -808,8 +809,7 @@ void __init board_prom_init(void) · 17 unmodified lines | ||
| 808 | 809 | char name[17]; |
| 809 | 810 | memcpy(name, board_name, 16); |
| 810 | 811 | name[16] = 0; |
| 811 | − printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", | |
| 812 | − name); | |
| 812 | + pr_err("unknown bcm963xx board: %s\n", name); | |
| 813 | 813 | return; |
| 814 | 814 | } |
| 815 | 815 | |
| @@ -854,7 +854,7 @@ void __init board_setup(void) · 38 unmodified lines | ||
| 854 | 854 | { |
| 855 | 855 | if (!board.name[0]) |
| 856 | 856 | panic("unable to detect bcm963xx board"); |
| 857 | − printk(KERN_INFO PFX "board name: %s\n", board.name); | |
| 857 | + pr_info("board name: %s\n", board.name); | |
| 858 | 858 | |
| 859 | 859 | /* make sure we're running on expected cpu */ |
| 860 | 860 | if (bcm63xx_get_cpu_id() != board.expected_cpu_id) |
| @@ -910,7 +910,7 @@ int __init board_register_devices(void) · 49 unmodified lines | ||
| 910 | 910 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
| 911 | 911 | if (ssb_arch_register_fallback_sprom( |
| 912 | 912 | &bcm63xx_get_fallback_sprom) < 0) |
| 913 | − pr_err(PFX "failed to register fallback SPROM\n"); | |
| 913 | + pr_err("failed to register fallback SPROM\n"); | |
| 914 | 914 | } |
| 915 | 915 | #endif |
| 916 | 916 | |
| @@ -376,10 +376,10 @@ void __init bcm63xx_cpu_init(void) · 375 unmodified lines | ||
| 376 | 376 | bcm63xx_cpu_freq = detect_cpu_clock(); |
| 377 | 377 | bcm63xx_memory_size = detect_memory_size(); |
| 378 | 378 | |
| 379 | − printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n", | |
| 380 | − bcm63xx_cpu_id, bcm63xx_cpu_rev); | |
| 381 | − printk(KERN_INFO "CPU frequency is %u MHz\n", | |
| 382 | − bcm63xx_cpu_freq / 1000000); | |
| 383 | − printk(KERN_INFO "%uMB of RAM installed\n", | |
| 384 | − bcm63xx_memory_size >> 20); | |
| 379 | + pr_info("Detected Broadcom 0x%04x CPU revision %02x\n", | |
| 380 | + bcm63xx_cpu_id, bcm63xx_cpu_rev); | |
| 381 | + pr_info("CPU frequency is %u MHz\n", | |
| 382 | + bcm63xx_cpu_freq / 1000000); | |
| 383 | + pr_info("%uMB of RAM installed\n", | |
| 384 | + bcm63xx_memory_size >> 20); | |
| 385 | 385 | } |
| @@ -139,6 +139,6 @@ int __init bcm63xx_pcmcia_register(void) · 138 unmodified lines | ||
| 139 | 139 | return platform_device_register(&bcm63xx_pcmcia_device); |
| 140 | 140 | |
| 141 | 141 | out_err: |
| 142 | − printk(KERN_ERR "unable to set pcmcia chip select\n"); | |
| 142 | + pr_err("unable to set pcmcia chip select\n"); | |
| 143 | 143 | return ret; |
| 144 | 144 | } |
| @@ -311,7 +311,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 310 unmodified lines | ||
| 311 | 311 | break; |
| 312 | 312 | |
| 313 | 313 | default: |
| 314 | − printk(KERN_ERR "bogus flow type combination given !\n"); | |
| 314 | + pr_err("bogus flow type combination given !\n"); | |
| 315 | 315 | return -EINVAL; |
| 316 | 316 | } |
| 317 | 317 | |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | void bcm63xx_machine_halt(void) |
| 26 | 26 | { |
| 27 | − printk(KERN_INFO "System halted\n"); | |
| 27 | + pr_info("System halted\n"); | |
| 28 | 28 | while (1) |
| 29 | 29 | ; |
| 30 | 30 | } |
| @@ -34,7 +34,7 @@ static void bcm6348_a1_reboot(void) · 3 unmodified lines | ||
| 34 | 34 | u32 reg; |
| 35 | 35 | |
| 36 | 36 | /* soft reset all blocks */ |
| 37 | − printk(KERN_INFO "soft-resetting all blocks ...\n"); | |
| 37 | + pr_info("soft-resetting all blocks ...\n"); | |
| 38 | 38 | reg = bcm_perf_readl(PERF_SOFTRESET_REG); |
| 39 | 39 | reg &= ~SOFTRESET_6348_ALL; |
| 40 | 40 | bcm_perf_writel(reg, PERF_SOFTRESET_REG); |
| @@ -46,7 +46,7 @@ static void bcm6348_a1_reboot(void) · 5 unmodified lines | ||
| 46 | 46 | mdelay(10); |
| 47 | 47 | |
| 48 | 48 | /* Jump to the power on address. */ |
| 49 | − printk(KERN_INFO "jumping to reset vector.\n"); | |
| 49 | + pr_info("jumping to reset vector.\n"); | |
| 50 | 50 | /* set high vectors (base at 0xbfc00000 */ |
| 51 | 51 | set_c0_status(ST0_BEV | ST0_ERL); |
| 52 | 52 | /* run uncached in kseg0 */ |
| @@ -110,7 +110,7 @@ void bcm63xx_machine_reboot(void) · 57 unmodified lines | ||
| 110 | 110 | if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1)) |
| 111 | 111 | bcm6348_a1_reboot(); |
| 112 | 112 | |
| 113 | − printk(KERN_INFO "triggering watchdog soft-reset...\n"); | |
| 113 | + pr_info("triggering watchdog soft-reset...\n"); | |
| 114 | 114 | if (BCMCPU_IS_6328()) { |
| 115 | 115 | bcm_wdt_writel(1, WDT_SOFTRESET_REG); |
| 116 | 116 | } else { |
| @@ -195,7 +195,7 @@ int bcm63xx_timer_init(void) · 194 unmodified lines | ||
| 195 | 195 | irq = bcm63xx_get_irq_number(IRQ_TIMER); |
| 196 | 196 | ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL); |
| 197 | 197 | if (ret) { |
| 198 | − printk(KERN_ERR "bcm63xx_timer: failed to register irq\n"); | |
| 198 | + pr_err("%s: failed to register irq\n", __func__); | |
| 199 | 199 | return ret; |
| 200 | 200 | } |
| 201 | 201 | |
| @@ -157,7 +157,6 @@ void __init plat_mem_setup(void) · 156 unmodified lines | ||
| 157 | 157 | panic("no dtb found"); |
| 158 | 158 | |
| 159 | 159 | __dt_setup_arch(dtb); |
| 160 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 161 | 160 | |
| 162 | 161 | for (q = bmips_quirk_list; q->quirk_fn; q++) { |
| 163 | 162 | if (of_flat_dt_is_compatible(of_get_flat_dt_root(), |
| @@ -6,6 +6,7 @@ dts-dirs += mti · 5 unmodified lines | ||
| 6 | 6 | dts-dirs += netlogic |
| 7 | 7 | dts-dirs += qca |
| 8 | 8 | dts-dirs += ralink |
| 9 | +dts-dirs += xilfpga | |
| 9 | 10 | |
| 10 | 11 | obj-y := $(addsuffix /, $(dts-dirs)) |
| 11 | 12 | |
| @@ -87,14 +87,32 @@ · 86 unmodified lines | ||
| 87 | 87 | compatible = "brcm,bcm7120-l2-intc"; |
| 88 | 88 | reg = <0x406780 0x8>; |
| 89 | 89 | |
| 90 | − brcm,int-map-mask = <0x44>; | |
| 90 | + brcm,int-map-mask = <0x44>, <0xf000000>; | |
| 91 | 91 | brcm,int-fwd-mask = <0x70000>; |
| 92 | 92 | |
| 93 | 93 | interrupt-controller; |
| 94 | 94 | #interrupt-cells = <1>; |
| 95 | 95 | |
| 96 | 96 | interrupt-parent = <&periph_intc>; |
| 97 | − interrupts = <59>; | |
| 97 | + interrupts = <59>, <57>; | |
| 98 | + interrupt-names = "upg_main", "upg_bsc"; | |
| 99 | + }; | |
| 100 | + | |
| 101 | + upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { | |
| 102 | + compatible = "brcm,bcm7120-l2-intc"; | |
| 103 | + reg = <0x408b80 0x8>; | |
| 104 | + | |
| 105 | + brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>; | |
| 106 | + brcm,int-fwd-mask = <0>; | |
| 107 | + brcm,irq-can-wake; | |
| 108 | + | |
| 109 | + interrupt-controller; | |
| 110 | + #interrupt-cells = <1>; | |
| 111 | + | |
| 112 | + interrupt-parent = <&periph_intc>; | |
| 113 | + interrupts = <60>, <58>, <62>; | |
| 114 | + interrupt-names = "upg_main_aon", "upg_bsc_aon", | |
| 115 | + "upg_spi"; | |
| 98 | 116 | }; |
| 99 | 117 | |
| 100 | 118 | sun_top_ctrl: syscon@404000 { |
| @@ -144,6 +162,56 @@ · 43 unmodified lines | ||
| 144 | 162 | status = "disabled"; |
| 145 | 163 | }; |
| 146 | 164 | |
| 165 | + bsca: i2c@406200 { | |
| 166 | + clock-frequency = <390000>; | |
| 167 | + compatible = "brcm,brcmstb-i2c"; | |
| 168 | + interrupt-parent = <&upg_irq0_intc>; | |
| 169 | + reg = <0x406200 0x58>; | |
| 170 | + interrupts = <24>; | |
| 171 | + interrupt-names = "upg_bsca"; | |
| 172 | + status = "disabled"; | |
| 173 | + }; | |
| 174 | + | |
| 175 | + bscb: i2c@406280 { | |
| 176 | + clock-frequency = <390000>; | |
| 177 | + compatible = "brcm,brcmstb-i2c"; | |
| 178 | + interrupt-parent = <&upg_irq0_intc>; | |
| 179 | + reg = <0x406280 0x58>; | |
| 180 | + interrupts = <25>; | |
| 181 | + interrupt-names = "upg_bscb"; | |
| 182 | + status = "disabled"; | |
| 183 | + }; | |
| 184 | + | |
| 185 | + bscc: i2c@406300 { | |
| 186 | + clock-frequency = <390000>; | |
| 187 | + compatible = "brcm,brcmstb-i2c"; | |
| 188 | + interrupt-parent = <&upg_irq0_intc>; | |
| 189 | + reg = <0x406300 0x58>; | |
| 190 | + interrupts = <26>; | |
| 191 | + interrupt-names = "upg_bscc"; | |
| 192 | + status = "disabled"; | |
| 193 | + }; | |
| 194 | + | |
| 195 | + bscd: i2c@406380 { | |
| 196 | + clock-frequency = <390000>; | |
| 197 | + compatible = "brcm,brcmstb-i2c"; | |
| 198 | + interrupt-parent = <&upg_irq0_intc>; | |
| 199 | + reg = <0x406380 0x58>; | |
| 200 | + interrupts = <27>; | |
| 201 | + interrupt-names = "upg_bscd"; | |
| 202 | + status = "disabled"; | |
| 203 | + }; | |
| 204 | + | |
| 205 | + bsce: i2c@408980 { | |
| 206 | + clock-frequency = <390000>; | |
| 207 | + compatible = "brcm,brcmstb-i2c"; | |
| 208 | + interrupt-parent = <&upg_aon_irq0_intc>; | |
| 209 | + reg = <0x408980 0x58>; | |
| 210 | + interrupts = <27>; | |
| 211 | + interrupt-names = "upg_bsce"; | |
| 212 | + status = "disabled"; | |
| 213 | + }; | |
| 214 | + | |
| 147 | 215 | enet0: ethernet@430000 { |
| 148 | 216 | phy-mode = "internal"; |
| 149 | 217 | phy-handle = <&phy1>; |
| @@ -246,5 +314,47 @@ · 96 unmodified lines | ||
| 246 | 314 | interrupts = <76>; |
| 247 | 315 | status = "disabled"; |
| 248 | 316 | }; |
| 317 | + | |
| 318 | + sata: sata@181000 { | |
| 319 | + compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; | |
| 320 | + reg-names = "ahci", "top-ctrl"; | |
| 321 | + reg = <0x181000 0xa9c>, <0x180020 0x1c>; | |
| 322 | + interrupt-parent = <&periph_intc>; | |
| 323 | + interrupts = <40>; | |
| 324 | + #address-cells = <1>; | |
| 325 | + #size-cells = <0>; | |
| 326 | + brcm,broken-ncq; | |
| 327 | + brcm,broken-phy; | |
| 328 | + status = "disabled"; | |
| 329 | + | |
| 330 | + sata0: sata-port@0 { | |
| 331 | + reg = <0>; | |
| 332 | + phys = <&sata_phy0>; | |
| 333 | + }; | |
| 334 | + | |
| 335 | + sata1: sata-port@1 { | |
| 336 | + reg = <1>; | |
| 337 | + phys = <&sata_phy1>; | |
| 338 | + }; | |
| 339 | + }; | |
| 340 | + | |
| 341 | + sata_phy: sata-phy@1800000 { | |
| 342 | + compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | |
| 343 | + reg = <0x180100 0x0eff>; | |
| 344 | + reg-names = "phy"; | |
| 345 | + #address-cells = <1>; | |
| 346 | + #size-cells = <0>; | |
| 347 | + status = "disabled"; | |
| 348 | + | |
| 349 | + sata_phy0: sata-phy@0 { | |
| 350 | + reg = <0>; | |
| 351 | + #phy-cells = <0>; | |
| 352 | + }; | |
| 353 | + | |
| 354 | + sata_phy1: sata-phy@1 { | |
| 355 | + reg = <1>; | |
| 356 | + #phy-cells = <0>; | |
| 357 | + }; | |
| 358 | + }; | |
| 249 | 359 | }; |
| 250 | 360 | }; |
| @@ -81,14 +81,32 @@ · 80 unmodified lines | ||
| 81 | 81 | compatible = "brcm,bcm7120-l2-intc"; |
| 82 | 82 | reg = <0x406600 0x8>; |
| 83 | 83 | |
| 84 | − brcm,int-map-mask = <0x44>; | |
| 84 | + brcm,int-map-mask = <0x44>, <0x7000000>; | |
| 85 | 85 | brcm,int-fwd-mask = <0x70000>; |
| 86 | 86 | |
| 87 | 87 | interrupt-controller; |
| 88 | 88 | #interrupt-cells = <1>; |
| 89 | 89 | |
| 90 | 90 | interrupt-parent = <&periph_intc>; |
| 91 | − interrupts = <56>; | |
| 91 | + interrupts = <56>, <54>; | |
| 92 | + interrupt-names = "upg_main", "upg_bsc"; | |
| 93 | + }; | |
| 94 | + | |
| 95 | + upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { | |
| 96 | + compatible = "brcm,bcm7120-l2-intc"; | |
| 97 | + reg = <0x408b80 0x8>; | |
| 98 | + | |
| 99 | + brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>; | |
| 100 | + brcm,int-fwd-mask = <0>; | |
| 101 | + brcm,irq-can-wake; | |
| 102 | + | |
| 103 | + interrupt-controller; | |
| 104 | + #interrupt-cells = <1>; | |
| 105 | + | |
| 106 | + interrupt-parent = <&periph_intc>; | |
| 107 | + interrupts = <57>, <55>, <59>; | |
| 108 | + interrupt-names = "upg_main_aon", "upg_bsc_aon", | |
| 109 | + "upg_spi"; | |
| 92 | 110 | }; |
| 93 | 111 | |
| 94 | 112 | sun_top_ctrl: syscon@404000 { |
| @@ -138,6 +156,46 @@ · 43 unmodified lines | ||
| 138 | 156 | status = "disabled"; |
| 139 | 157 | }; |
| 140 | 158 | |
| 159 | + bsca: i2c@406200 { | |
| 160 | + clock-frequency = <390000>; | |
| 161 | + compatible = "brcm,brcmstb-i2c"; | |
| 162 | + interrupt-parent = <&upg_irq0_intc>; | |
| 163 | + reg = <0x406200 0x58>; | |
| 164 | + interrupts = <24>; | |
| 165 | + interrupt-names = "upg_bsca"; | |
| 166 | + status = "disabled"; | |
| 167 | + }; | |
| 168 | + | |
| 169 | + bscb: i2c@406280 { | |
| 170 | + clock-frequency = <390000>; | |
| 171 | + compatible = "brcm,brcmstb-i2c"; | |
| 172 | + interrupt-parent = <&upg_irq0_intc>; | |
| 173 | + reg = <0x406280 0x58>; | |
| 174 | + interrupts = <25>; | |
| 175 | + interrupt-names = "upg_bscb"; | |
| 176 | + status = "disabled"; | |
| 177 | + }; | |
| 178 | + | |
| 179 | + bscc: i2c@406300 { | |
| 180 | + clock-frequency = <390000>; | |
| 181 | + compatible = "brcm,brcmstb-i2c"; | |
| 182 | + interrupt-parent = <&upg_irq0_intc>; | |
| 183 | + reg = <0x406300 0x58>; | |
| 184 | + interrupts = <26>; | |
| 185 | + interrupt-names = "upg_bscc"; | |
| 186 | + status = "disabled"; | |
| 187 | + }; | |
| 188 | + | |
| 189 | + bscd: i2c@408980 { | |
| 190 | + clock-frequency = <390000>; | |
| 191 | + compatible = "brcm,brcmstb-i2c"; | |
| 192 | + interrupt-parent = <&upg_aon_irq0_intc>; | |
| 193 | + reg = <0x408980 0x58>; | |
| 194 | + interrupts = <27>; | |
| 195 | + interrupt-names = "upg_bscd"; | |
| 196 | + status = "disabled"; | |
| 197 | + }; | |
| 198 | + | |
| 141 | 199 | enet0: ethernet@430000 { |
| 142 | 200 | phy-mode = "internal"; |
| 143 | 201 | phy-handle = <&phy1>; |
| @@ -81,14 +81,32 @@ · 80 unmodified lines | ||
| 81 | 81 | compatible = "brcm,bcm7120-l2-intc"; |
| 82 | 82 | reg = <0x406600 0x8>; |
| 83 | 83 | |
| 84 | − brcm,int-map-mask = <0x44>; | |
| 84 | + brcm,int-map-mask = <0x44>, <0x7000000>; | |
| 85 | 85 | brcm,int-fwd-mask = <0x70000>; |
| 86 | 86 | |
| 87 | 87 | interrupt-controller; |
| 88 | 88 | #interrupt-cells = <1>; |
| 89 | 89 | |
| 90 | 90 | interrupt-parent = <&periph_intc>; |
| 91 | − interrupts = <56>; | |
| 91 | + interrupts = <56>, <54>; | |
| 92 | + interrupt-names = "upg_main", "upg_bsc"; | |
| 93 | + }; | |
| 94 | + | |
| 95 | + upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { | |
| 96 | + compatible = "brcm,bcm7120-l2-intc"; | |
| 97 | + reg = <0x408b80 0x8>; | |
| 98 | + | |
| 99 | + brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>; | |
| 100 | + brcm,int-fwd-mask = <0>; | |
| 101 | + brcm,irq-can-wake; | |
| 102 | + | |
| 103 | + interrupt-controller; | |
| 104 | + #interrupt-cells = <1>; | |
| 105 | + | |
| 106 | + interrupt-parent = <&periph_intc>; | |
| 107 | + interrupts = <57>, <55>, <59>; | |
| 108 | + interrupt-names = "upg_main_aon", "upg_bsc_aon", | |
| 109 | + "upg_spi"; | |
| 92 | 110 | }; |
| 93 | 111 | |
| 94 | 112 | sun_top_ctrl: syscon@404000 { |
| @@ -138,6 +156,46 @@ · 43 unmodified lines | ||
| 138 | 156 | status = "disabled"; |
| 139 | 157 | }; |
| 140 | 158 | |
| 159 | + bsca: i2c@406200 { | |
| 160 | + clock-frequency = <390000>; | |
| 161 | + compatible = "brcm,brcmstb-i2c"; | |
| 162 | + interrupt-parent = <&upg_irq0_intc>; | |
| 163 | + reg = <0x406200 0x58>; | |
| 164 | + interrupts = <24>; | |
| 165 | + interrupt-names = "upg_bsca"; | |
| 166 | + status = "disabled"; | |
| 167 | + }; | |
| 168 | + | |
| 169 | + bscb: i2c@406280 { | |
| 170 | + clock-frequency = <390000>; | |
| 171 | + compatible = "brcm,brcmstb-i2c"; | |
| 172 | + interrupt-parent = <&upg_irq0_intc>; | |
| 173 | + reg = <0x406280 0x58>; | |
| 174 | + interrupts = <25>; | |
| 175 | + interrupt-names = "upg_bscb"; | |
| 176 | + status = "disabled"; | |
| 177 | + }; | |
| 178 | + | |
| 179 | + bscc: i2c@406300 { | |
| 180 | + clock-frequency = <390000>; | |
| 181 | + compatible = "brcm,brcmstb-i2c"; | |
| 182 | + interrupt-parent = <&upg_irq0_intc>; | |
| 183 | + reg = <0x406300 0x58>; | |
| 184 | + interrupts = <26>; | |
| 185 | + interrupt-names = "upg_bscc"; | |
| 186 | + status = "disabled"; | |
| 187 | + }; | |
| 188 | + | |
| 189 | + bscd: i2c@408980 { | |
| 190 | + clock-frequency = <390000>; | |
| 191 | + compatible = "brcm,brcmstb-i2c"; | |
| 192 | + interrupt-parent = <&upg_aon_irq0_intc>; | |
| 193 | + reg = <0x408980 0x58>; | |
| 194 | + interrupts = <27>; | |
| 195 | + interrupt-names = "upg_bscd"; | |
| 196 | + status = "disabled"; | |
| 197 | + }; | |
| 198 | + | |
| 141 | 199 | enet0: ethernet@430000 { |
| 142 | 200 | phy-mode = "internal"; |
| 143 | 201 | phy-handle = <&phy1>; |
| @@ -87,14 +87,32 @@ · 86 unmodified lines | ||
| 87 | 87 | compatible = "brcm,bcm7120-l2-intc"; |
| 88 | 88 | reg = <0x406600 0x8>; |
| 89 | 89 | |
| 90 | − brcm,int-map-mask = <0x44>; | |
| 90 | + brcm,int-map-mask = <0x44>, <0x7000000>; | |
| 91 | 91 | brcm,int-fwd-mask = <0x70000>; |
| 92 | 92 | |
| 93 | 93 | interrupt-controller; |
| 94 | 94 | #interrupt-cells = <1>; |
| 95 | 95 | |
| 96 | 96 | interrupt-parent = <&periph_intc>; |
| 97 | − interrupts = <56>; | |
| 97 | + interrupts = <56>, <54>; | |
| 98 | + interrupt-names = "upg_main", "upg_bsc"; | |
| 99 | + }; | |
| 100 | + | |
| 101 | + upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { | |
| 102 | + compatible = "brcm,bcm7120-l2-intc"; | |
| 103 | + reg = <0x408b80 0x8>; | |
| 104 | + | |
| 105 | + brcm,int-map-mask = <0x40>, <0x8000000>, <0x100000>; | |
| 106 | + brcm,int-fwd-mask = <0>; | |
| 107 | + brcm,irq-can-wake; | |
| 108 | + | |
| 109 | + interrupt-controller; | |
| 110 | + #interrupt-cells = <1>; | |
| 111 | + | |
| 112 | + interrupt-parent = <&periph_intc>; | |
| 113 | + interrupts = <57>, <55>, <59>; | |
| 114 | + interrupt-names = "upg_main_aon", "upg_bsc_aon", | |
| 115 | + "upg_spi"; | |
| 98 | 116 | }; |
| 99 | 117 | |
| 100 | 118 | sun_top_ctrl: syscon@404000 { |
| @@ -144,6 +162,36 @@ · 43 unmodified lines | ||
| 144 | 162 | status = "disabled"; |
| 145 | 163 | }; |
| 146 | 164 | |
| 165 | + bsca: i2c@406200 { | |
| 166 | + clock-frequency = <390000>; | |
| 167 | + compatible = "brcm,brcmstb-i2c"; | |
| 168 | + interrupt-parent = <&upg_irq0_intc>; | |
| 169 | + reg = <0x406200 0x58>; | |
| 170 | + interrupts = <24>; | |
| 171 | + interrupt-names = "upg_bsca"; | |
| 172 | + status = "disabled"; | |
| 173 | + }; | |
| 174 | + | |
| 175 | + bscb: i2c@406280 { | |
| 176 | + clock-frequency = <390000>; | |
| 177 | + compatible = "brcm,brcmstb-i2c"; | |
| 178 | + interrupt-parent = <&upg_irq0_intc>; | |
| 179 | + reg = <0x406280 0x58>; | |
| 180 | + interrupts = <25>; | |
| 181 | + interrupt-names = "upg_bscb"; | |
| 182 | + status = "disabled"; | |
| 183 | + }; | |
| 184 | + | |
| 185 | + bscd: i2c@408980 { | |
| 186 | + clock-frequency = <390000>; | |
| 187 | + compatible = "brcm,brcmstb-i2c"; | |
| 188 | + interrupt-parent = <&upg_aon_irq0_intc>; | |
| 189 | + reg = <0x408980 0x58>; | |
| 190 | + interrupts = <27>; | |
| 191 | + interrupt-names = "upg_bscd"; | |
| 192 | + status = "disabled"; | |
| 193 | + }; | |
| 194 | + | |
| 147 | 195 | enet0: ethernet@430000 { |
| 148 | 196 | phy-mode = "internal"; |
| 149 | 197 | phy-handle = <&phy1>; |
| @@ -189,5 +237,47 @@ · 39 unmodified lines | ||
| 189 | 237 | interrupts = <66>; |
| 190 | 238 | status = "disabled"; |
| 191 | 239 | }; |
| 240 | + | |
| 241 | + sata: sata@181000 { | |
| 242 | + compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; | |
| 243 | + reg-names = "ahci", "top-ctrl"; | |
| 244 | + reg = <0x181000 0xa9c>, <0x180020 0x1c>; | |
| 245 | + interrupt-parent = <&periph_intc>; | |
| 246 | + interrupts = <86>; | |
| 247 | + #address-cells = <1>; | |
| 248 | + #size-cells = <0>; | |
| 249 | + brcm,broken-ncq; | |
| 250 | + brcm,broken-phy; | |
| 251 | + status = "disabled"; | |
| 252 | + | |
| 253 | + sata0: sata-port@0 { | |
| 254 | + reg = <0>; | |
| 255 | + phys = <&sata_phy0>; | |
| 256 | + }; | |
| 257 | + | |
| 258 | + sata1: sata-port@1 { | |
| 259 | + reg = <1>; | |
| 260 | + phys = <&sata_phy1>; | |
| 261 | + }; | |
| 262 | + }; | |
| 263 | + | |
| 264 | + sata_phy: sata-phy@1800000 { | |
| 265 | + compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | |
| 266 | + reg = <0x180100 0x0eff>; | |
| 267 | + reg-names = "phy"; | |
| 268 | + #address-cells = <1>; | |
| 269 | + #size-cells = <0>; | |
| 270 | + status = "disabled"; | |
| 271 | + | |
| 272 | + sata_phy0: sata-phy@0 { | |
| 273 | + reg = <0>; | |
| 274 | + #phy-cells = <0>; | |
| 275 | + }; | |
| 276 | + | |
| 277 | + sata_phy1: sata-phy@1 { | |
| 278 | + reg = <1>; | |
| 279 | + #phy-cells = <0>; | |
| 280 | + }; | |
| 281 | + }; | |
| 192 | 282 | }; |
| 193 | 283 | }; |
| @@ -221,5 +221,47 @@ · 220 unmodified lines | ||
| 221 | 221 | interrupts = <73>; |
| 222 | 222 | status = "disabled"; |
| 223 | 223 | }; |
| 224 | + | |
| 225 | + sata: sata@181000 { | |
| 226 | + compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; | |
| 227 | + reg-names = "ahci", "top-ctrl"; | |
| 228 | + reg = <0x181000 0xa9c>, <0x180020 0x1c>; | |
| 229 | + interrupt-parent = <&periph_intc>; | |
| 230 | + interrupts = <40>; | |
| 231 | + #address-cells = <1>; | |
| 232 | + #size-cells = <0>; | |
| 233 | + brcm,broken-ncq; | |
| 234 | + brcm,broken-phy; | |
| 235 | + status = "disabled"; | |
| 236 | + | |
| 237 | + sata0: sata-port@0 { | |
| 238 | + reg = <0>; | |
| 239 | + phys = <&sata_phy0>; | |
| 240 | + }; | |
| 241 | + | |
| 242 | + sata1: sata-port@1 { | |
| 243 | + reg = <1>; | |
| 244 | + phys = <&sata_phy1>; | |
| 245 | + }; | |
| 246 | + }; | |
| 247 | + | |
| 248 | + sata_phy: sata-phy@1800000 { | |
| 249 | + compatible = "brcm,bcm7425-sata-phy", "brcm,phy-sata3"; | |
| 250 | + reg = <0x180100 0x0eff>; | |
| 251 | + reg-names = "phy"; | |
| 252 | + #address-cells = <1>; | |
| 253 | + #size-cells = <0>; | |
| 254 | + status = "disabled"; | |
| 255 | + | |
| 256 | + sata_phy0: sata-phy@0 { | |
| 257 | + reg = <0>; | |
| 258 | + #phy-cells = <0>; | |
| 259 | + }; | |
| 260 | + | |
| 261 | + sata_phy1: sata-phy@1 { | |
| 262 | + reg = <1>; | |
| 263 | + #phy-cells = <0>; | |
| 264 | + }; | |
| 265 | + }; | |
| 224 | 266 | }; |
| 225 | 267 | }; |
| @@ -29,6 +29,26 @@ · 28 unmodified lines | ||
| 29 | 29 | status = "okay"; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +&bsca { | |
| 33 | + status = "okay"; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +&bscb { | |
| 37 | + status = "okay"; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +&bscc { | |
| 41 | + status = "okay"; | |
| 42 | +}; | |
| 43 | + | |
| 44 | +&bscd { | |
| 45 | + status = "okay"; | |
| 46 | +}; | |
| 47 | + | |
| 48 | +&bsce { | |
| 49 | + status = "okay"; | |
| 50 | +}; | |
| 51 | + | |
| 32 | 52 | &enet0 { |
| 33 | 53 | status = "okay"; |
| 34 | 54 | }; |
| @@ -64,3 +84,11 @@ · 29 unmodified lines | ||
| 64 | 84 | &ohci3 { |
| 65 | 85 | status = "okay"; |
| 66 | 86 | }; |
| 87 | + | |
| 88 | +&sata { | |
| 89 | + status = "okay"; | |
| 90 | +}; | |
| 91 | + | |
| 92 | +&sata_phy { | |
| 93 | + status = "okay"; | |
| 94 | +}; | |
| @@ -29,6 +29,22 @@ · 28 unmodified lines | ||
| 29 | 29 | status = "okay"; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +&bsca { | |
| 33 | + status = "okay"; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +&bscb { | |
| 37 | + status = "okay"; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +&bscc { | |
| 41 | + status = "okay"; | |
| 42 | +}; | |
| 43 | + | |
| 44 | +&bscd { | |
| 45 | + status = "okay"; | |
| 46 | +}; | |
| 47 | + | |
| 32 | 48 | &enet0 { |
| 33 | 49 | status = "okay"; |
| 34 | 50 | }; |
| @@ -29,6 +29,22 @@ · 28 unmodified lines | ||
| 29 | 29 | status = "okay"; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +&bsca { | |
| 33 | + status = "okay"; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +&bscb { | |
| 37 | + status = "okay"; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +&bscc { | |
| 41 | + status = "okay"; | |
| 42 | +}; | |
| 43 | + | |
| 44 | +&bscd { | |
| 45 | + status = "okay"; | |
| 46 | +}; | |
| 47 | + | |
| 32 | 48 | &enet0 { |
| 33 | 49 | status = "okay"; |
| 34 | 50 | }; |
| @@ -29,6 +29,18 @@ · 28 unmodified lines | ||
| 29 | 29 | status = "okay"; |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +&bsca { | |
| 33 | + status = "okay"; | |
| 34 | +}; | |
| 35 | + | |
| 36 | +&bscb { | |
| 37 | + status = "okay"; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +&bscd { | |
| 41 | + status = "okay"; | |
| 42 | +}; | |
| 43 | + | |
| 32 | 44 | &enet0 { |
| 33 | 45 | status = "okay"; |
| 34 | 46 | }; |
| @@ -40,3 +52,11 @@ · 5 unmodified lines | ||
| 40 | 52 | &ohci0 { |
| 41 | 53 | status = "okay"; |
| 42 | 54 | }; |
| 55 | + | |
| 56 | +&sata { | |
| 57 | + status = "okay"; | |
| 58 | +}; | |
| 59 | + | |
| 60 | +&sata_phy { | |
| 61 | + status = "okay"; | |
| 62 | +}; | |
| @@ -1,5 +1,9 @@ | ||
| 1 | 1 | /dts-v1/; |
| 2 | 2 | |
| 3 | +/memreserve/ 0x00000000 0x00001000; /* YAMON exception vectors */ | |
| 4 | +/memreserve/ 0x00001000 0x000ef000; /* YAMON */ | |
| 5 | +/memreserve/ 0x000f0000 0x00010000; /* PIIX4 ISA memory */ | |
| 6 | + | |
| 3 | 7 | / { |
| 4 | 8 | #address-cells = <1>; |
| 5 | 9 | #size-cells = <1>; |
| @@ -0,0 +1,9 @@ | ||
| 1 | +dtb-$(CONFIG_XILFPGA_NEXYS4DDR) += nexys4ddr.dtb | |
| 2 | + | |
| 3 | +obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) | |
| 4 | + | |
| 5 | +# Force kbuild to make empty built-in.o if necessary | |
| 6 | +obj- += dummy.o | |
| 7 | + | |
| 8 | +always := $(dtb-y) | |
| 9 | +clean-files := *.dtb *.dtb.S | |
| @@ -0,0 +1,21 @@ | ||
| 1 | +/ { | |
| 2 | + #address-cells = <1>; | |
| 3 | + #size-cells = <1>; | |
| 4 | + compatible = "img,xilfpga"; | |
| 5 | + | |
| 6 | + cpus { | |
| 7 | + #address-cells = <1>; | |
| 8 | + #size-cells = <0>; | |
| 9 | + cpu@0 { | |
| 10 | + device_type = "cpu"; | |
| 11 | + compatible = "mips,m14Kc"; | |
| 12 | + clocks = <&ext>; | |
| 13 | + reg = <0>; | |
| 14 | + }; | |
| 15 | + }; | |
| 16 | + | |
| 17 | + ext: ext { | |
| 18 | + compatible = "fixed-clock"; | |
| 19 | + #clock-cells = <0>; | |
| 20 | + }; | |
| 21 | +}; | |
| @@ -0,0 +1,46 @@ | ||
| 1 | +/dts-v1/; | |
| 2 | + | |
| 3 | +#include "microAptiv.dtsi" | |
| 4 | + | |
| 5 | +/ { | |
| 6 | + compatible = "digilent,nexys4ddr"; | |
| 7 | + | |
| 8 | + memory { | |
| 9 | + device_type = "memory"; | |
| 10 | + reg = <0x0 0x08000000>; | |
| 11 | + }; | |
| 12 | + | |
| 13 | + cpuintc: interrupt-controller@0 { | |
| 14 | + #address-cells = <0>; | |
| 15 | + #interrupt-cells = <1>; | |
| 16 | + interrupt-controller; | |
| 17 | + compatible = "mti,cpu-interrupt-controller"; | |
| 18 | + }; | |
| 19 | + | |
| 20 | + axi_gpio: gpio@10600000 { | |
| 21 | + #gpio-cells = <1>; | |
| 22 | + compatible = "xlnx,xps-gpio-1.00.a"; | |
| 23 | + gpio-controller; | |
| 24 | + reg = <0x10600000 0x10000>; | |
| 25 | + xlnx,all-inputs = <0x0>; | |
| 26 | + xlnx,dout-default = <0x0>; | |
| 27 | + xlnx,gpio-width = <0x16>; | |
| 28 | + xlnx,interrupt-present = <0x0>; | |
| 29 | + xlnx,is-dual = <0x0>; | |
| 30 | + xlnx,tri-default = <0xffffffff>; | |
| 31 | + } ; | |
| 32 | + | |
| 33 | + axi_uart16550: serial@10400000 { | |
| 34 | + compatible = "ns16550a"; | |
| 35 | + reg = <0x10400000 0x10000>; | |
| 36 | + | |
| 37 | + reg-shift = <2>; | |
| 38 | + reg-offset = <0x1000>; | |
| 39 | + | |
| 40 | + clocks = <&ext>; | |
| 41 | + }; | |
| 42 | +}; | |
| 43 | + | |
| 44 | +&ext { | |
| 45 | + clock-frequency = <50000000>; | |
| 46 | +}; | |
| @@ -1081,6 +1081,7 @@ void __init prom_free_prom_memory(void) · 1080 unmodified lines | ||
| 1081 | 1081 | |
| 1082 | 1082 | int octeon_prune_device_tree(void); |
| 1083 | 1083 | |
| 1084 | +extern const char __appended_dtb; | |
| 1084 | 1085 | extern const char __dtb_octeon_3xxx_begin; |
| 1085 | 1086 | extern const char __dtb_octeon_68xx_begin; |
| 1086 | 1087 | void __init device_tree_init(void) |
| @@ -1088,11 +1089,19 @@ void __init device_tree_init(void) · 1 unmodified line | ||
| 1088 | 1089 | const void *fdt; |
| 1089 | 1090 | bool do_prune; |
| 1090 | 1091 | |
| 1092 | +#ifdef CONFIG_MIPS_ELF_APPENDED_DTB | |
| 1093 | + if (!fdt_check_header(&__appended_dtb)) { | |
| 1094 | + fdt = &__appended_dtb; | |
| 1095 | + do_prune = false; | |
| 1096 | + pr_info("Using appended Device Tree.\n"); | |
| 1097 | + } else | |
| 1098 | +#endif | |
| 1091 | 1099 | if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) { |
| 1092 | 1100 | fdt = phys_to_virt(octeon_bootinfo->fdt_addr); |
| 1093 | 1101 | if (fdt_check_header(fdt)) |
| 1094 | 1102 | panic("Corrupt Device Tree passed to kernel."); |
| 1095 | 1103 | do_prune = false; |
| 1104 | + pr_info("Using passed Device Tree.\n"); | |
| 1096 | 1105 | } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) { |
| 1097 | 1106 | fdt = &__dtb_octeon_68xx_begin; |
| 1098 | 1107 | do_prune = true; |
| @@ -1106,8 +1115,6 @@ void __init device_tree_init(void) · 7 unmodified lines | ||
| 1106 | 1115 | if (do_prune) { |
| 1107 | 1116 | octeon_prune_device_tree(); |
| 1108 | 1117 | pr_info("Using internal Device Tree.\n"); |
| 1109 | − } else { | |
| 1110 | − pr_info("Using passed Device Tree.\n"); | |
| 1111 | 1118 | } |
| 1112 | 1119 | unflatten_and_copy_device_tree(); |
| 1113 | 1120 | } |
| @@ -122,20 +122,20 @@ CONFIG_EEPROM_MAX6875=y · 121 unmodified lines | ||
| 122 | 122 | CONFIG_IDE=y |
| 123 | 123 | CONFIG_BLK_DEV_IDECD=y |
| 124 | 124 | CONFIG_BLK_DEV_IDETAPE=y |
| 125 | −CONFIG_IDE_GENERIC=y | |
| 126 | −CONFIG_BLK_DEV_GENERIC=y | |
| 127 | −CONFIG_BLK_DEV_CMD64X=y | |
| 128 | −CONFIG_BLK_DEV_IT8213=m | |
| 129 | 125 | CONFIG_BLK_DEV_TC86C001=m |
| 130 | 126 | CONFIG_BLK_DEV_SD=y |
| 131 | −CONFIG_CHR_DEV_ST=m | |
| 132 | −CONFIG_BLK_DEV_SR=m | |
| 127 | +CONFIG_CHR_DEV_ST=y | |
| 128 | +CONFIG_BLK_DEV_SR=y | |
| 133 | 129 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 134 | 130 | CONFIG_CHR_DEV_SG=m |
| 135 | 131 | CONFIG_CHR_DEV_SCH=m |
| 136 | 132 | CONFIG_ATA=y |
| 137 | 133 | CONFIG_SATA_SIL24=y |
| 134 | +CONFIG_PATA_CMD64X=y | |
| 135 | +CONFIG_PATA_IT8213=m | |
| 138 | 136 | CONFIG_PATA_SIL680=y |
| 137 | +CONFIG_ATA_GENERIC=y | |
| 138 | +CONFIG_PATA_LEGACY=y | |
| 139 | 139 | CONFIG_NETDEVICES=y |
| 140 | 140 | CONFIG_NET_ETHERNET=y |
| 141 | 141 | CONFIG_MII=y |
| @@ -8,7 +8,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y · 7 unmodified lines | ||
| 8 | 8 | # CONFIG_SWAP is not set |
| 9 | 9 | CONFIG_NO_HZ=y |
| 10 | 10 | CONFIG_BLK_DEV_INITRD=y |
| 11 | −# CONFIG_RD_GZIP is not set | |
| 11 | +CONFIG_RD_GZIP=y | |
| 12 | 12 | CONFIG_EXPERT=y |
| 13 | 13 | # CONFIG_VM_EVENT_COUNTERS is not set |
| 14 | 14 | # CONFIG_SLUB_DEBUG is not set |
| @@ -33,6 +33,7 @@ CONFIG_DEVTMPFS=y · 18 unmodified lines | ||
| 33 | 33 | CONFIG_DEVTMPFS_MOUNT=y |
| 34 | 34 | # CONFIG_STANDALONE is not set |
| 35 | 35 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
| 36 | +CONFIG_PRINTK_TIME=y | |
| 36 | 37 | CONFIG_BRCMSTB_GISB_ARB=y |
| 37 | 38 | CONFIG_MTD=y |
| 38 | 39 | CONFIG_MTD_CFI=y |
| @@ -9,7 +9,7 @@ CONFIG_MIPS_O32_FP64_SUPPORT=y · 8 unmodified lines | ||
| 9 | 9 | # CONFIG_SWAP is not set |
| 10 | 10 | CONFIG_NO_HZ=y |
| 11 | 11 | CONFIG_BLK_DEV_INITRD=y |
| 12 | −# CONFIG_RD_GZIP is not set | |
| 12 | +CONFIG_RD_GZIP=y | |
| 13 | 13 | CONFIG_EXPERT=y |
| 14 | 14 | # CONFIG_VM_EVENT_COUNTERS is not set |
| 15 | 15 | # CONFIG_SLUB_DEBUG is not set |
| @@ -34,6 +34,7 @@ CONFIG_DEVTMPFS=y · 18 unmodified lines | ||
| 34 | 34 | CONFIG_DEVTMPFS_MOUNT=y |
| 35 | 35 | # CONFIG_STANDALONE is not set |
| 36 | 36 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
| 37 | +CONFIG_PRINTK_TIME=y | |
| 37 | 38 | CONFIG_BRCMSTB_GISB_ARB=y |
| 38 | 39 | CONFIG_MTD=y |
| 39 | 40 | CONFIG_MTD_CFI=y |
| @@ -31,9 +31,9 @@ CONFIG_NETWORK_SECMARK=y · 30 unmodified lines | ||
| 31 | 31 | CONFIG_IP_SCTP=m |
| 32 | 32 | CONFIG_FW_LOADER=m |
| 33 | 33 | CONFIG_BLK_DEV_RAM=y |
| 34 | −# CONFIG_MISC_DEVICES is not set | |
| 35 | −CONFIG_IDE=y | |
| 36 | −CONFIG_IDE_GENERIC=y | |
| 34 | +CONFIG_BLK_DEV_SD=y | |
| 35 | +CONFIG_ATA=y | |
| 36 | +CONFIG_PATA_LEGACY=y | |
| 37 | 37 | CONFIG_NETDEVICES=y |
| 38 | 38 | CONFIG_PHYLIB=m |
| 39 | 39 | CONFIG_MARVELL_PHY=m |
| @@ -14,9 +14,9 @@ CONFIG_MODVERSIONS=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_MODULE_SRCVERSION_ALL=y |
| 15 | 15 | # CONFIG_BLK_DEV_BSG is not set |
| 16 | 16 | CONFIG_BLK_DEV_RAM=y |
| 17 | −# CONFIG_MISC_DEVICES is not set | |
| 18 | −CONFIG_IDE=y | |
| 19 | −CONFIG_IDE_GENERIC=y | |
| 17 | +CONFIG_BLK_DEV_SD=y | |
| 18 | +CONFIG_ATA=y | |
| 19 | +CONFIG_PATA_LEGACY=y | |
| 20 | 20 | # CONFIG_INPUT_MOUSEDEV is not set |
| 21 | 21 | # CONFIG_INPUT_KEYBOARD is not set |
| 22 | 22 | # CONFIG_INPUT_MOUSE is not set |
| @@ -34,7 +34,7 @@ CONFIG_MIPS32_N32=y · 33 unmodified lines | ||
| 34 | 34 | CONFIG_PM=y |
| 35 | 35 | # CONFIG_SUSPEND is not set |
| 36 | 36 | CONFIG_HIBERNATION=y |
| 37 | −CONFIG_PM_STD_PARTITION="/dev/hda3" | |
| 37 | +CONFIG_PM_STD_PARTITION="/dev/sda3" | |
| 38 | 38 | CONFIG_NET=y |
| 39 | 39 | CONFIG_PACKET=y |
| 40 | 40 | CONFIG_UNIX=y |
| @@ -114,20 +114,16 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m · 73 unmodified lines | ||
| 114 | 114 | CONFIG_BLK_DEV_RAM=m |
| 115 | 115 | CONFIG_CDROM_PKTCDVD=m |
| 116 | 116 | CONFIG_ATA_OVER_ETH=m |
| 117 | −# CONFIG_MISC_DEVICES is not set | |
| 118 | −CONFIG_IDE=y | |
| 119 | −CONFIG_BLK_DEV_IDECD=y | |
| 120 | −CONFIG_IDE_TASK_IOCTL=y | |
| 121 | −CONFIG_IDE_GENERIC=y | |
| 122 | −CONFIG_BLK_DEV_GENERIC=y | |
| 123 | −CONFIG_BLK_DEV_VIA82CXXX=y | |
| 124 | −CONFIG_SCSI=y | |
| 125 | 117 | CONFIG_BLK_DEV_SD=y |
| 126 | 118 | CONFIG_BLK_DEV_SR=y |
| 127 | 119 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 128 | 120 | CONFIG_CHR_DEV_SG=y |
| 129 | 121 | CONFIG_SCSI_CONSTANTS=y |
| 130 | 122 | # CONFIG_SCSI_LOWLEVEL is not set |
| 123 | +CONFIG_ATA=y | |
| 124 | +CONFIG_PATA_VIA=y | |
| 125 | +CONFIG_ATA_GENERIC=y | |
| 126 | +CONFIG_PATA_LEGACY=y | |
| 131 | 127 | CONFIG_NETDEVICES=y |
| 132 | 128 | CONFIG_MACVLAN=m |
| 133 | 129 | CONFIG_VETH=m |
| @@ -35,11 +35,11 @@ CONFIG_MTD_CHAR=y · 34 unmodified lines | ||
| 35 | 35 | CONFIG_MTD_BLOCK=y |
| 36 | 36 | CONFIG_MTD_CFI=y |
| 37 | 37 | CONFIG_MTD_CFI_AMDSTD=y |
| 38 | −# CONFIG_MISC_DEVICES is not set | |
| 39 | −CONFIG_IDE=y | |
| 40 | −CONFIG_IDE_GENERIC=y | |
| 41 | −CONFIG_BLK_DEV_GENERIC=y | |
| 42 | −CONFIG_BLK_DEV_CMD64X=y | |
| 38 | +CONFIG_BLK_DEV_SD=y | |
| 39 | +CONFIG_ATA=y | |
| 40 | +CONFIG_PATA_CMD64X=y | |
| 41 | +CONFIG_ATA_GENERIC=y | |
| 42 | +CONFIG_PATA_LEGACY=y | |
| 43 | 43 | CONFIG_NETDEVICES=y |
| 44 | 44 | CONFIG_NET_ETHERNET=y |
| 45 | 45 | CONFIG_NET_PCI=y |
| @@ -108,16 +108,11 @@ CONFIG_BLK_DEV_LOOP=y · 107 unmodified lines | ||
| 108 | 108 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 109 | 109 | CONFIG_BLK_DEV_RAM=y |
| 110 | 110 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
| 111 | −# CONFIG_MISC_DEVICES is not set | |
| 112 | −CONFIG_IDE=y | |
| 113 | −CONFIG_IDE_TASK_IOCTL=y | |
| 114 | −# CONFIG_IDEPCI_PCIBUS_ORDER is not set | |
| 115 | −CONFIG_BLK_DEV_AMD74XX=y | |
| 116 | −CONFIG_SCSI=m | |
| 117 | −CONFIG_BLK_DEV_SD=m | |
| 111 | +CONFIG_BLK_DEV_SD=y | |
| 118 | 112 | CONFIG_CHR_DEV_SG=m |
| 119 | −CONFIG_SCSI_MULTI_LUN=y | |
| 120 | 113 | # CONFIG_SCSI_LOWLEVEL is not set |
| 114 | +CONFIG_ATA=y | |
| 115 | +CONFIG_PATA_AMD=y | |
| 121 | 116 | CONFIG_MD=y |
| 122 | 117 | CONFIG_BLK_DEV_MD=m |
| 123 | 118 | CONFIG_MD_LINEAR=m |
| @@ -241,14 +241,11 @@ CONFIG_BLK_DEV_NBD=m · 240 unmodified lines | ||
| 241 | 241 | CONFIG_BLK_DEV_RAM=y |
| 242 | 242 | CONFIG_CDROM_PKTCDVD=m |
| 243 | 243 | CONFIG_ATA_OVER_ETH=m |
| 244 | −CONFIG_IDE=y | |
| 245 | −CONFIG_BLK_DEV_IDECD=y | |
| 246 | −CONFIG_IDE_GENERIC=y | |
| 247 | 244 | CONFIG_RAID_ATTRS=m |
| 248 | 245 | CONFIG_BLK_DEV_SD=y |
| 249 | 246 | CONFIG_CHR_DEV_ST=m |
| 250 | 247 | CONFIG_CHR_DEV_OSST=m |
| 251 | −CONFIG_BLK_DEV_SR=m | |
| 248 | +CONFIG_BLK_DEV_SR=y | |
| 252 | 249 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 253 | 250 | CONFIG_CHR_DEV_SG=m |
| 254 | 251 | CONFIG_SCSI_CONSTANTS=y |
| @@ -265,6 +262,7 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000 · 10 unmodified lines | ||
| 265 | 262 | # CONFIG_AIC7XXX_DEBUG_ENABLE is not set |
| 266 | 263 | CONFIG_ATA=y |
| 267 | 264 | CONFIG_ATA_PIIX=y |
| 265 | +CONFIG_PATA_LEGACY=y | |
| 268 | 266 | CONFIG_MD=y |
| 269 | 267 | CONFIG_BLK_DEV_MD=m |
| 270 | 268 | CONFIG_MD_LINEAR=m |
| @@ -248,17 +248,12 @@ CONFIG_CDROM_PKTCDVD=m · 247 unmodified lines | ||
| 248 | 248 | CONFIG_ATA_OVER_ETH=m |
| 249 | 249 | CONFIG_IDE=y |
| 250 | 250 | CONFIG_BLK_DEV_IDECD=y |
| 251 | −CONFIG_IDE_GENERIC=y | |
| 252 | −CONFIG_BLK_DEV_GENERIC=y | |
| 253 | −CONFIG_BLK_DEV_PIIX=y | |
| 254 | −CONFIG_BLK_DEV_IT8213=m | |
| 255 | 251 | CONFIG_BLK_DEV_TC86C001=m |
| 256 | 252 | CONFIG_RAID_ATTRS=m |
| 257 | −CONFIG_SCSI=m | |
| 258 | −CONFIG_BLK_DEV_SD=m | |
| 253 | +CONFIG_BLK_DEV_SD=y | |
| 259 | 254 | CONFIG_CHR_DEV_ST=m |
| 260 | 255 | CONFIG_CHR_DEV_OSST=m |
| 261 | −CONFIG_BLK_DEV_SR=m | |
| 256 | +CONFIG_BLK_DEV_SR=y | |
| 262 | 257 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 263 | 258 | CONFIG_CHR_DEV_SG=m |
| 264 | 259 | CONFIG_SCSI_MULTI_LUN=y |
| @@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m · 9 unmodified lines | ||
| 274 | 269 | CONFIG_SCSI_AIC7XXX=m |
| 275 | 270 | CONFIG_AIC7XXX_RESET_DELAY_MS=15000 |
| 276 | 271 | # CONFIG_AIC7XXX_DEBUG_ENABLE is not set |
| 272 | +CONFIG_ATA=y | |
| 273 | +CONFIG_ATA_PIIX=y | |
| 274 | +CONFIG_PATA_IT8213=m | |
| 275 | +CONFIG_PATA_OLDPIIX=y | |
| 276 | +CONFIG_PATA_MPIIX=y | |
| 277 | +CONFIG_ATA_GENERIC=y | |
| 278 | +CONFIG_PATA_LEGACY=y | |
| 277 | 279 | CONFIG_MD=y |
| 278 | 280 | CONFIG_BLK_DEV_MD=m |
| 279 | 281 | CONFIG_MD_LINEAR=m |
| @@ -248,17 +248,12 @@ CONFIG_ATA_OVER_ETH=m · 247 unmodified lines | ||
| 248 | 248 | CONFIG_VIRTIO_BLK=y |
| 249 | 249 | CONFIG_IDE=y |
| 250 | 250 | CONFIG_BLK_DEV_IDECD=y |
| 251 | −CONFIG_IDE_GENERIC=y | |
| 252 | −CONFIG_BLK_DEV_GENERIC=y | |
| 253 | −CONFIG_BLK_DEV_PIIX=y | |
| 254 | −CONFIG_BLK_DEV_IT8213=m | |
| 255 | 251 | CONFIG_BLK_DEV_TC86C001=m |
| 256 | 252 | CONFIG_RAID_ATTRS=m |
| 257 | −CONFIG_SCSI=m | |
| 258 | −CONFIG_BLK_DEV_SD=m | |
| 253 | +CONFIG_BLK_DEV_SD=y | |
| 259 | 254 | CONFIG_CHR_DEV_ST=m |
| 260 | 255 | CONFIG_CHR_DEV_OSST=m |
| 261 | −CONFIG_BLK_DEV_SR=m | |
| 256 | +CONFIG_BLK_DEV_SR=y | |
| 262 | 257 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 263 | 258 | CONFIG_CHR_DEV_SG=m |
| 264 | 259 | CONFIG_SCSI_MULTI_LUN=y |
| @@ -274,6 +269,13 @@ CONFIG_SCSI_AACRAID=m · 9 unmodified lines | ||
| 274 | 269 | CONFIG_SCSI_AIC7XXX=m |
| 275 | 270 | CONFIG_AIC7XXX_RESET_DELAY_MS=15000 |
| 276 | 271 | # CONFIG_AIC7XXX_DEBUG_ENABLE is not set |
| 272 | +CONFIG_ATA=y | |
| 273 | +CONFIG_ATA_PIIX=y | |
| 274 | +CONFIG_PATA_IT8213=m | |
| 275 | +CONFIG_PATA_OLDPIIX=y | |
| 276 | +CONFIG_PATA_MPIIX=y | |
| 277 | +CONFIG_ATA_GENERIC=y | |
| 278 | +CONFIG_PATA_LEGACY=y | |
| 277 | 279 | CONFIG_MD=y |
| 278 | 280 | CONFIG_BLK_DEV_MD=m |
| 279 | 281 | CONFIG_MD_LINEAR=m |
| @@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y · 79 unmodified lines | ||
| 80 | 80 | CONFIG_DEVTMPFS=y |
| 81 | 81 | CONFIG_BLK_DEV_LOOP=y |
| 82 | 82 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 83 | −CONFIG_IDE=y | |
| 84 | −# CONFIG_IDE_PROC_FS is not set | |
| 85 | −# CONFIG_IDEPCI_PCIBUS_ORDER is not set | |
| 86 | −CONFIG_BLK_DEV_GENERIC=y | |
| 87 | −CONFIG_BLK_DEV_PIIX=y | |
| 88 | −CONFIG_SCSI=y | |
| 89 | 83 | CONFIG_BLK_DEV_SD=y |
| 90 | 84 | CONFIG_CHR_DEV_SG=y |
| 91 | 85 | # CONFIG_SCSI_LOWLEVEL is not set |
| 86 | +CONFIG_ATA=y | |
| 87 | +CONFIG_ATA_PIIX=y | |
| 88 | +CONFIG_PATA_OLDPIIX=y | |
| 89 | +CONFIG_PATA_MPIIX=y | |
| 90 | +CONFIG_ATA_GENERIC=y | |
| 92 | 91 | CONFIG_NETDEVICES=y |
| 93 | 92 | # CONFIG_NET_VENDOR_3COM is not set |
| 94 | 93 | # CONFIG_NET_VENDOR_ADAPTEC is not set |
| @@ -81,15 +81,14 @@ CONFIG_NET_CLS_IND=y · 80 unmodified lines | ||
| 81 | 81 | CONFIG_DEVTMPFS=y |
| 82 | 82 | CONFIG_BLK_DEV_LOOP=y |
| 83 | 83 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 84 | −CONFIG_IDE=y | |
| 85 | −# CONFIG_IDE_PROC_FS is not set | |
| 86 | −# CONFIG_IDEPCI_PCIBUS_ORDER is not set | |
| 87 | −CONFIG_BLK_DEV_GENERIC=y | |
| 88 | −CONFIG_BLK_DEV_PIIX=y | |
| 89 | −CONFIG_SCSI=y | |
| 90 | 84 | CONFIG_BLK_DEV_SD=y |
| 91 | 85 | CONFIG_CHR_DEV_SG=y |
| 92 | 86 | # CONFIG_SCSI_LOWLEVEL is not set |
| 87 | +CONFIG_ATA=y | |
| 88 | +CONFIG_ATA_PIIX=y | |
| 89 | +CONFIG_PATA_OLDPIIX=y | |
| 90 | +CONFIG_PATA_MPIIX=y | |
| 91 | +CONFIG_ATA_GENERIC=y | |
| 93 | 92 | CONFIG_NETDEVICES=y |
| 94 | 93 | # CONFIG_NET_VENDOR_3COM is not set |
| 95 | 94 | # CONFIG_NET_VENDOR_ADAPTEC is not set |
| @@ -85,15 +85,14 @@ CONFIG_NET_CLS_IND=y · 84 unmodified lines | ||
| 85 | 85 | CONFIG_DEVTMPFS=y |
| 86 | 86 | CONFIG_BLK_DEV_LOOP=y |
| 87 | 87 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 88 | −CONFIG_IDE=y | |
| 89 | −# CONFIG_IDE_PROC_FS is not set | |
| 90 | −# CONFIG_IDEPCI_PCIBUS_ORDER is not set | |
| 91 | −CONFIG_BLK_DEV_GENERIC=y | |
| 92 | −CONFIG_BLK_DEV_PIIX=y | |
| 93 | −CONFIG_SCSI=y | |
| 94 | 88 | CONFIG_BLK_DEV_SD=y |
| 95 | 89 | CONFIG_CHR_DEV_SG=y |
| 96 | 90 | # CONFIG_SCSI_LOWLEVEL is not set |
| 91 | +CONFIG_ATA=y | |
| 92 | +CONFIG_ATA_PIIX=y | |
| 93 | +CONFIG_PATA_OLDPIIX=y | |
| 94 | +CONFIG_PATA_MPIIX=y | |
| 95 | +CONFIG_ATA_GENERIC=y | |
| 97 | 96 | CONFIG_NETDEVICES=y |
| 98 | 97 | # CONFIG_NET_VENDOR_3COM is not set |
| 99 | 98 | # CONFIG_NET_VENDOR_ADAPTEC is not set |
| @@ -80,15 +80,14 @@ CONFIG_NET_CLS_IND=y · 79 unmodified lines | ||
| 80 | 80 | CONFIG_DEVTMPFS=y |
| 81 | 81 | CONFIG_BLK_DEV_LOOP=y |
| 82 | 82 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 83 | −CONFIG_IDE=y | |
| 84 | −# CONFIG_IDE_PROC_FS is not set | |
| 85 | −# CONFIG_IDEPCI_PCIBUS_ORDER is not set | |
| 86 | −CONFIG_BLK_DEV_GENERIC=y | |
| 87 | −CONFIG_BLK_DEV_PIIX=y | |
| 88 | −CONFIG_SCSI=y | |
| 89 | 83 | CONFIG_BLK_DEV_SD=y |
| 90 | 84 | CONFIG_CHR_DEV_SG=y |
| 91 | 85 | # CONFIG_SCSI_LOWLEVEL is not set |
| 86 | +CONFIG_ATA=y | |
| 87 | +CONFIG_ATA_PIIX=y | |
| 88 | +CONFIG_PATA_OLDPIIX=y | |
| 89 | +CONFIG_PATA_MPIIX=y | |
| 90 | +CONFIG_ATA_GENERIC=y | |
| 92 | 91 | CONFIG_NETDEVICES=y |
| 93 | 92 | # CONFIG_NET_VENDOR_3COM is not set |
| 94 | 93 | # CONFIG_NET_VENDOR_ADAPTEC is not set |
| @@ -244,17 +244,12 @@ CONFIG_CDROM_PKTCDVD=m · 243 unmodified lines | ||
| 244 | 244 | CONFIG_ATA_OVER_ETH=m |
| 245 | 245 | CONFIG_IDE=y |
| 246 | 246 | CONFIG_BLK_DEV_IDECD=y |
| 247 | −CONFIG_IDE_GENERIC=y | |
| 248 | −CONFIG_BLK_DEV_GENERIC=y | |
| 249 | −CONFIG_BLK_DEV_PIIX=y | |
| 250 | −CONFIG_BLK_DEV_IT8213=m | |
| 251 | 247 | CONFIG_BLK_DEV_TC86C001=m |
| 252 | 248 | CONFIG_RAID_ATTRS=m |
| 253 | −CONFIG_SCSI=m | |
| 254 | −CONFIG_BLK_DEV_SD=m | |
| 249 | +CONFIG_BLK_DEV_SD=y | |
| 255 | 250 | CONFIG_CHR_DEV_ST=m |
| 256 | 251 | CONFIG_CHR_DEV_OSST=m |
| 257 | −CONFIG_BLK_DEV_SR=m | |
| 252 | +CONFIG_BLK_DEV_SR=y | |
| 258 | 253 | CONFIG_BLK_DEV_SR_VENDOR=y |
| 259 | 254 | CONFIG_CHR_DEV_SG=m |
| 260 | 255 | CONFIG_SCSI_CONSTANTS=y |
| @@ -269,6 +264,13 @@ CONFIG_SCSI_AACRAID=m · 8 unmodified lines | ||
| 269 | 264 | CONFIG_SCSI_AIC7XXX=m |
| 270 | 265 | CONFIG_AIC7XXX_RESET_DELAY_MS=15000 |
| 271 | 266 | # CONFIG_AIC7XXX_DEBUG_ENABLE is not set |
| 267 | +CONFIG_ATA=y | |
| 268 | +CONFIG_ATA_PIIX=y | |
| 269 | +CONFIG_PATA_IT8213=m | |
| 270 | +CONFIG_PATA_OLDPIIX=y | |
| 271 | +CONFIG_PATA_MPIIX=y | |
| 272 | +CONFIG_ATA_GENERIC=y | |
| 273 | +CONFIG_PATA_LEGACY=y | |
| 272 | 274 | CONFIG_MD=y |
| 273 | 275 | CONFIG_BLK_DEV_MD=m |
| 274 | 276 | CONFIG_MD_LINEAR=m |
| @@ -27,9 +27,9 @@ CONFIG_INET_XFRM_MODE_BEET=m · 26 unmodified lines | ||
| 27 | 27 | CONFIG_NETWORK_SECMARK=y |
| 28 | 28 | CONFIG_CONNECTOR=m |
| 29 | 29 | CONFIG_ATA_OVER_ETH=m |
| 30 | −# CONFIG_MISC_DEVICES is not set | |
| 31 | −CONFIG_IDE=y | |
| 32 | −CONFIG_IDE_GENERIC=y | |
| 30 | +CONFIG_BLK_DEV_SD=y | |
| 31 | +CONFIG_ATA=y | |
| 32 | +CONFIG_PATA_LEGACY=y | |
| 33 | 33 | CONFIG_NETDEVICES=y |
| 34 | 34 | # CONFIG_NETDEV_1000 is not set |
| 35 | 35 | # CONFIG_NETDEV_10000 is not set |
| @@ -0,0 +1,40 @@ | ||
| 1 | +CONFIG_MACH_XILFPGA=y | |
| 2 | +# CONFIG_COMPACTION is not set | |
| 3 | +# CONFIG_LOCALVERSION_AUTO is not set | |
| 4 | +CONFIG_EMBEDDED=y | |
| 5 | +# CONFIG_VM_EVENT_COUNTERS is not set | |
| 6 | +# CONFIG_COMPAT_BRK is not set | |
| 7 | +CONFIG_SLAB=y | |
| 8 | +# CONFIG_BLOCK is not set | |
| 9 | +# CONFIG_SUSPEND is not set | |
| 10 | +# CONFIG_UEVENT_HELPER is not set | |
| 11 | +CONFIG_DEVTMPFS=y | |
| 12 | +CONFIG_DEVTMPFS_MOUNT=y | |
| 13 | +# CONFIG_STANDALONE is not set | |
| 14 | +# CONFIG_PREVENT_FIRMWARE_BUILD is not set | |
| 15 | +# CONFIG_FW_LOADER is not set | |
| 16 | +# CONFIG_ALLOW_DEV_COREDUMP is not set | |
| 17 | +# CONFIG_INPUT_MOUSEDEV is not set | |
| 18 | +# CONFIG_INPUT_KEYBOARD is not set | |
| 19 | +# CONFIG_INPUT_MOUSE is not set | |
| 20 | +# CONFIG_SERIO is not set | |
| 21 | +CONFIG_VT_HW_CONSOLE_BINDING=y | |
| 22 | +# CONFIG_UNIX98_PTYS is not set | |
| 23 | +# CONFIG_LEGACY_PTYS is not set | |
| 24 | +CONFIG_SERIAL_8250=y | |
| 25 | +CONFIG_SERIAL_8250_CONSOLE=y | |
| 26 | +CONFIG_SERIAL_OF_PLATFORM=y | |
| 27 | +# CONFIG_HW_RANDOM is not set | |
| 28 | +CONFIG_GPIO_SYSFS=y | |
| 29 | +CONFIG_GPIO_XILINX=y | |
| 30 | +# CONFIG_HWMON is not set | |
| 31 | +# CONFIG_USB_SUPPORT is not set | |
| 32 | +# CONFIG_MIPS_PLATFORM_DEVICES is not set | |
| 33 | +# CONFIG_IOMMU_SUPPORT is not set | |
| 34 | +# CONFIG_PROC_PAGE_MONITOR is not set | |
| 35 | +# CONFIG_MISC_FILESYSTEMS is not set | |
| 36 | +CONFIG_PANIC_ON_OOPS=y | |
| 37 | +# CONFIG_SCHED_DEBUG is not set | |
| 38 | +# CONFIG_FTRACE is not set | |
| 39 | +CONFIG_CMDLINE_BOOL=y | |
| 40 | +CONFIG_CMDLINE="console=ttyS0,115200" | |
| @@ -11,19 +11,20 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include <asm/signal.h> |
| 13 | 13 | #include <asm/siginfo.h> |
| 14 | +#include <asm/vdso.h> | |
| 14 | 15 | |
| 15 | 16 | struct mips_abi { |
| 16 | 17 | int (* const setup_frame)(void *sig_return, struct ksignal *ksig, |
| 17 | 18 | struct pt_regs *regs, sigset_t *set); |
| 18 | − const unsigned long signal_return_offset; | |
| 19 | 19 | int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig, |
| 20 | 20 | struct pt_regs *regs, sigset_t *set); |
| 21 | − const unsigned long rt_signal_return_offset; | |
| 22 | 21 | const unsigned long restart; |
| 23 | 22 | |
| 24 | 23 | unsigned off_sc_fpregs; |
| 25 | 24 | unsigned off_sc_fpc_csr; |
| 26 | 25 | unsigned off_sc_used_math; |
| 26 | + | |
| 27 | + struct mips_vdso_image *vdso; | |
| 27 | 28 | }; |
| 28 | 29 | |
| 29 | 30 | #endif /* _ASM_ABI_H */ |
| @@ -507,7 +507,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) · 506 unmodified lines | ||
| 507 | 507 | * @u: ...unless v is equal to u. |
| 508 | 508 | * |
| 509 | 509 | * Atomically adds @a to @v, so long as it was not @u. |
| 510 | − * Returns the old value of @v. | |
| 510 | + * Returns true iff @v was not @u. | |
| 511 | 511 | */ |
| 512 | 512 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 513 | 513 | { |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifndef _ASM_BCACHE_H |
| 10 | 10 | #define _ASM_BCACHE_H |
| 11 | 11 | |
| 12 | +#include <linux/types.h> | |
| 12 | 13 | |
| 13 | 14 | /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent, |
| 14 | 15 | chipset implemented caches. On machines with other CPUs the CPU does the |
| @@ -18,6 +19,9 @@ struct bcache_ops { · 3 unmodified lines | ||
| 18 | 19 | void (*bc_disable)(void); |
| 19 | 20 | void (*bc_wback_inv)(unsigned long page, unsigned long size); |
| 20 | 21 | void (*bc_inv)(unsigned long page, unsigned long size); |
| 22 | + void (*bc_prefetch_enable)(void); | |
| 23 | + void (*bc_prefetch_disable)(void); | |
| 24 | + bool (*bc_prefetch_is_enabled)(void); | |
| 21 | 25 | }; |
| 22 | 26 | |
| 23 | 27 | extern void indy_sc_init(void); |
| @@ -46,6 +50,26 @@ static inline void bc_inv(unsigned long page, unsigned long size) · 22 unmodified lines | ||
| 46 | 50 | bcops->bc_inv(page, size); |
| 47 | 51 | } |
| 48 | 52 | |
| 53 | +static inline void bc_prefetch_enable(void) | |
| 54 | +{ | |
| 55 | + if (bcops->bc_prefetch_enable) | |
| 56 | + bcops->bc_prefetch_enable(); | |
| 57 | +} | |
| 58 | + | |
| 59 | +static inline void bc_prefetch_disable(void) | |
| 60 | +{ | |
| 61 | + if (bcops->bc_prefetch_disable) | |
| 62 | + bcops->bc_prefetch_disable(); | |
| 63 | +} | |
| 64 | + | |
| 65 | +static inline bool bc_prefetch_is_enabled(void) | |
| 66 | +{ | |
| 67 | + if (bcops->bc_prefetch_is_enabled) | |
| 68 | + return bcops->bc_prefetch_is_enabled(); | |
| 69 | + | |
| 70 | + return false; | |
| 71 | +} | |
| 72 | + | |
| 49 | 73 | #else /* !defined(CONFIG_BOARD_SCACHE) */ |
| 50 | 74 | |
| 51 | 75 | /* Not R4000 / R4400 / R4600 / R5000. */ |
| @@ -54,6 +78,9 @@ static inline void bc_inv(unsigned long page, unsigned long size) · 2 unmodified lines | ||
| 54 | 78 | #define bc_disable() do { } while (0) |
| 55 | 79 | #define bc_wback_inv(page, size) do { } while (0) |
| 56 | 80 | #define bc_inv(page, size) do { } while (0) |
| 81 | +#define bc_prefetch_enable() do { } while (0) | |
| 82 | +#define bc_prefetch_disable() do { } while (0) | |
| 83 | +#define bc_prefetch_is_enabled() 0 | |
| 57 | 84 | |
| 58 | 85 | #endif /* !defined(CONFIG_BOARD_SCACHE) */ |
| 59 | 86 | |
| @@ -84,6 +84,17 @@ void mips_cdmm_driver_unregister(struct mips_cdmm_driver *); · 83 unmodified lines | ||
| 84 | 84 | module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \ |
| 85 | 85 | mips_cdmm_driver_unregister) |
| 86 | 86 | |
| 87 | +/* | |
| 88 | + * builtin_mips_cdmm_driver() - Helper macro for drivers that don't do anything | |
| 89 | + * special in init and have no exit. This eliminates some boilerplate. Each | |
| 90 | + * driver may only use this macro once, and calling it replaces device_initcall | |
| 91 | + * (or in some cases, the legacy __initcall). This is meant to be a direct | |
| 92 | + * parallel of module_mips_cdmm_driver() above but without the __exit stuff that | |
| 93 | + * is not used for builtin cases. | |
| 94 | + */ | |
| 95 | +#define builtin_mips_cdmm_driver(__mips_cdmm_driver) \ | |
| 96 | + builtin_driver(__mips_cdmm_driver, mips_cdmm_driver_register) | |
| 97 | + | |
| 87 | 98 | /* drivers/tty/mips_ejtag_fdc.c */ |
| 88 | 99 | |
| 89 | 100 | #ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON |
| @@ -0,0 +1,29 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#ifndef __ASM_CLOCKSOURCE_H | |
| 12 | +#define __ASM_CLOCKSOURCE_H | |
| 13 | + | |
| 14 | +#include <linux/types.h> | |
| 15 | + | |
| 16 | +/* VDSO clocksources. */ | |
| 17 | +#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */ | |
| 18 | +#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */ | |
| 19 | +#define VDSO_CLOCK_GIC 2 /* Use the GIC. */ | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * struct arch_clocksource_data - Architecture-specific clocksource information. | |
| 23 | + * @vdso_clock_mode: Method the VDSO should use to access the clocksource. | |
| 24 | + */ | |
| 25 | +struct arch_clocksource_data { | |
| 26 | + u8 vdso_clock_mode; | |
| 27 | +}; | |
| 28 | + | |
| 29 | +#endif /* __ASM_CLOCKSOURCE_H */ | |
| @@ -130,6 +130,8 @@ typedef union compat_sigval { · 129 unmodified lines | ||
| 130 | 130 | compat_uptr_t sival_ptr; |
| 131 | 131 | } compat_sigval_t; |
| 132 | 132 | |
| 133 | +/* Can't use the generic version because si_code and si_errno are swapped */ | |
| 134 | + | |
| 133 | 135 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) |
| 134 | 136 | |
| 135 | 137 | typedef struct compat_siginfo { |
| @@ -138,57 +140,61 @@ typedef struct compat_siginfo { · 2 unmodified lines | ||
| 138 | 140 | int si_errno; |
| 139 | 141 | |
| 140 | 142 | union { |
| 141 | − int _pad[SI_PAD_SIZE32]; | |
| 143 | + int _pad[128 / sizeof(int) - 3]; | |
| 142 | 144 | |
| 143 | 145 | /* kill() */ |
| 144 | 146 | struct { |
| 145 | 147 | compat_pid_t _pid; /* sender's pid */ |
| 146 | − __compat_uid_t _uid; /* sender's uid */ | |
| 148 | + __compat_uid32_t _uid; /* sender's uid */ | |
| 147 | 149 | } _kill; |
| 148 | 150 | |
| 151 | + /* POSIX.1b timers */ | |
| 152 | + struct { | |
| 153 | + compat_timer_t _tid; /* timer id */ | |
| 154 | + int _overrun; /* overrun count */ | |
| 155 | + compat_sigval_t _sigval; /* same as below */ | |
| 156 | + } _timer; | |
| 157 | + | |
| 158 | + /* POSIX.1b signals */ | |
| 159 | + struct { | |
| 160 | + compat_pid_t _pid; /* sender's pid */ | |
| 161 | + __compat_uid32_t _uid; /* sender's uid */ | |
| 162 | + compat_sigval_t _sigval; | |
| 163 | + } _rt; | |
| 164 | + | |
| 149 | 165 | /* SIGCHLD */ |
| 150 | 166 | struct { |
| 151 | 167 | compat_pid_t _pid; /* which child */ |
| 152 | − __compat_uid_t _uid; /* sender's uid */ | |
| 168 | + __compat_uid32_t _uid; /* sender's uid */ | |
| 153 | 169 | int _status; /* exit code */ |
| 154 | 170 | compat_clock_t _utime; |
| 155 | 171 | compat_clock_t _stime; |
| 156 | 172 | } _sigchld; |
| 157 | 173 | |
| 158 | − /* IRIX SIGCHLD */ | |
| 159 | − struct { | |
| 160 | − compat_pid_t _pid; /* which child */ | |
| 161 | − compat_clock_t _utime; | |
| 162 | − int _status; /* exit code */ | |
| 163 | − compat_clock_t _stime; | |
| 164 | − } _irix_sigchld; | |
| 165 | − | |
| 166 | 174 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ |
| 167 | 175 | struct { |
| 168 | − s32 _addr; /* faulting insn/memory ref. */ | |
| 176 | + compat_uptr_t _addr; /* faulting insn/memory ref. */ | |
| 177 | +#ifdef __ARCH_SI_TRAPNO | |
| 178 | + int _trapno; /* TRAP # which caused the signal */ | |
| 179 | +#endif | |
| 180 | + short _addr_lsb; /* LSB of the reported address */ | |
| 181 | + struct { | |
| 182 | + compat_uptr_t _lower; | |
| 183 | + compat_uptr_t _upper; | |
| 184 | + } _addr_bnd; | |
| 169 | 185 | } _sigfault; |
| 170 | 186 | |
| 171 | − /* SIGPOLL, SIGXFSZ (To do ...) */ | |
| 187 | + /* SIGPOLL */ | |
| 172 | 188 | struct { |
| 173 | − int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | |
| 189 | + compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | |
| 174 | 190 | int _fd; |
| 175 | 191 | } _sigpoll; |
| 176 | 192 | |
| 177 | − /* POSIX.1b timers */ | |
| 178 | − struct { | |
| 179 | − timer_t _tid; /* timer id */ | |
| 180 | − int _overrun; /* overrun count */ | |
| 181 | − compat_sigval_t _sigval;/* same as below */ | |
| 182 | − int _sys_private; /* not to be passed to user */ | |
| 183 | − } _timer; | |
| 184 | − | |
| 185 | − /* POSIX.1b signals */ | |
| 186 | 193 | struct { |
| 187 | − compat_pid_t _pid; /* sender's pid */ | |
| 188 | − __compat_uid_t _uid; /* sender's uid */ | |
| 189 | − compat_sigval_t _sigval; | |
| 190 | − } _rt; | |
| 191 | − | |
| 194 | + compat_uptr_t _call_addr; /* calling insn */ | |
| 195 | + int _syscall; /* triggering system call number */ | |
| 196 | + compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */ | |
| 197 | + } _sigsys; | |
| 192 | 198 | } _sifields; |
| 193 | 199 | } compat_siginfo_t; |
| 194 | 200 | |
| @@ -131,11 +131,7 @@ · 130 unmodified lines | ||
| 131 | 131 | #endif |
| 132 | 132 | |
| 133 | 133 | #ifndef cpu_has_rixi |
| 134 | −# ifdef CONFIG_64BIT | |
| 135 | −# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) | |
| 136 | −# else /* CONFIG_32BIT */ | |
| 137 | −# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits) | |
| 138 | −# endif | |
| 134 | +#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) | |
| 139 | 135 | #endif |
| 140 | 136 | |
| 141 | 137 | #ifndef cpu_has_mmips |
| @@ -0,0 +1,22 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify it | |
| 5 | + * under the terms of the GNU General Public License as published by the | |
| 6 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 7 | + * option) any later version. | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#ifndef __MIPS_ASM_DEBUG_H__ | |
| 11 | +#define __MIPS_ASM_DEBUG_H__ | |
| 12 | + | |
| 13 | +#include <linux/dcache.h> | |
| 14 | + | |
| 15 | +/* | |
| 16 | + * mips_debugfs_dir corresponds to the "mips" directory at the top level | |
| 17 | + * of the DebugFS hierarchy. MIPS-specific DebugFS entires should be | |
| 18 | + * placed beneath this directory. | |
| 19 | + */ | |
| 20 | +extern struct dentry *mips_debugfs_dir; | |
| 21 | + | |
| 22 | +#endif /* __MIPS_ASM_DEBUG_H__ */ | |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #ifndef _ASM_ELF_H |
| 9 | 9 | #define _ASM_ELF_H |
| 10 | 10 | |
| 11 | +#include <linux/auxvec.h> | |
| 11 | 12 | #include <linux/fs.h> |
| 12 | 13 | #include <uapi/linux/elf.h> |
| 13 | 14 | |
| @@ -419,6 +420,12 @@ extern const char *__elf_platform; · 405 unmodified lines | ||
| 419 | 420 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
| 420 | 421 | #endif |
| 421 | 422 | |
| 423 | +#define ARCH_DLINFO \ | |
| 424 | +do { \ | |
| 425 | + NEW_AUX_ENT(AT_SYSINFO_EHDR, \ | |
| 426 | + (unsigned long)current->mm->context.vdso); \ | |
| 427 | +} while (0) | |
| 428 | + | |
| 422 | 429 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
| 423 | 430 | struct linux_binprm; |
| 424 | 431 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, |
| @@ -10,21 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <asm/bootinfo.h> /* For cleaner code... */ |
| 12 | 12 | |
| 13 | −enum fw_memtypes { | |
| 14 | − fw_dontuse, | |
| 15 | − fw_code, | |
| 16 | − fw_free, | |
| 17 | −}; | |
| 18 | − | |
| 19 | −typedef struct { | |
| 20 | − unsigned long base; /* Within KSEG0 */ | |
| 21 | − unsigned int size; /* bytes */ | |
| 22 | − enum fw_memtypes type; /* fw_memtypes */ | |
| 23 | −} fw_memblock_t; | |
| 24 | − | |
| 25 | −/* Maximum number of memory block descriptors. */ | |
| 26 | −#define FW_MAX_MEMBLOCKS 32 | |
| 27 | − | |
| 28 | 13 | extern int fw_argc; |
| 29 | 14 | extern int *_fw_argv; |
| 30 | 15 | extern int *_fw_envp; |
| @@ -38,7 +23,6 @@ extern int *_fw_envp; · 7 unmodified lines | ||
| 38 | 23 | |
| 39 | 24 | extern void fw_init_cmdline(void); |
| 40 | 25 | extern char *fw_getcmdline(void); |
| 41 | −extern fw_memblock_t *fw_getmdesc(int); | |
| 42 | 26 | extern void fw_meminit(void); |
| 43 | 27 | extern char *fw_getenv(char *name); |
| 44 | 28 | extern unsigned long fw_getenvl(char *name); |
| @@ -48,11 +48,6 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type; · 47 unmodified lines | ||
| 48 | 48 | void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, |
| 49 | 49 | bool fallback); |
| 50 | 50 | |
| 51 | −#ifdef CONFIG_BCM47XX_SSB | |
| 52 | −void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, | |
| 53 | − const char *prefix); | |
| 54 | −#endif | |
| 55 | − | |
| 56 | 51 | void bcm47xx_set_system_type(u16 chip_id); |
| 57 | 52 | |
| 58 | 53 | #endif /* __ASM_BCM47XX_H */ |
| @@ -35,6 +35,17 @@ · 34 unmodified lines | ||
| 35 | 35 | #define SOC_ID_VRX268_2 0x00C /* v1.2 */ |
| 36 | 36 | #define SOC_ID_GRX288_2 0x00D /* v1.2 */ |
| 37 | 37 | #define SOC_ID_GRX282_2 0x00E /* v1.2 */ |
| 38 | +#define SOC_ID_VRX220 0x000 | |
| 39 | + | |
| 40 | +#define SOC_ID_ARX362 0x004 | |
| 41 | +#define SOC_ID_ARX368 0x005 | |
| 42 | +#define SOC_ID_ARX382 0x007 | |
| 43 | +#define SOC_ID_ARX388 0x008 | |
| 44 | +#define SOC_ID_URX388 0x009 | |
| 45 | +#define SOC_ID_GRX383 0x010 | |
| 46 | +#define SOC_ID_GRX369 0x011 | |
| 47 | +#define SOC_ID_GRX387 0x00F | |
| 48 | +#define SOC_ID_GRX389 0x012 | |
| 38 | 49 | |
| 39 | 50 | /* SoC Types */ |
| 40 | 51 | #define SOC_TYPE_DANUBE 0x01 |
| @@ -43,6 +54,9 @@ · 2 unmodified lines | ||
| 43 | 54 | #define SOC_TYPE_VR9 0x04 /* v1.1 */ |
| 44 | 55 | #define SOC_TYPE_VR9_2 0x05 /* v1.2 */ |
| 45 | 56 | #define SOC_TYPE_AMAZON_SE 0x06 |
| 57 | +#define SOC_TYPE_AR10 0x07 | |
| 58 | +#define SOC_TYPE_GRX390 0x08 | |
| 59 | +#define SOC_TYPE_VRX220 0x09 | |
| 46 | 60 | |
| 47 | 61 | /* BOOT_SEL - find what boot media we have */ |
| 48 | 62 | #define BS_EXT_ROM 0x0 |
| @@ -0,0 +1,29 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Paul Burton <paul.burton@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#ifndef __MIPS_MALTA_DTSHIM_H__ | |
| 12 | +#define __MIPS_MALTA_DTSHIM_H__ | |
| 13 | + | |
| 14 | +#include <linux/init.h> | |
| 15 | + | |
| 16 | +#ifdef CONFIG_MIPS_MALTA | |
| 17 | + | |
| 18 | +extern void __init *malta_dt_shim(void *fdt); | |
| 19 | + | |
| 20 | +#else /* !CONFIG_MIPS_MALTA */ | |
| 21 | + | |
| 22 | +static inline void *malta_dt_shim(void *fdt) | |
| 23 | +{ | |
| 24 | + return fdt; | |
| 25 | +} | |
| 26 | + | |
| 27 | +#endif /* !CONFIG_MIPS_MALTA */ | |
| 28 | + | |
| 29 | +#endif /* __MIPS_MALTA_DTSHIM_H__ */ | |
| @@ -13,17 +13,11 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifndef _MT7620_REGS_H_ |
| 14 | 14 | #define _MT7620_REGS_H_ |
| 15 | 15 | |
| 16 | −enum mt762x_soc_type { | |
| 17 | − MT762X_SOC_UNKNOWN = 0, | |
| 18 | − MT762X_SOC_MT7620A, | |
| 19 | − MT762X_SOC_MT7620N, | |
| 20 | − MT762X_SOC_MT7628AN, | |
| 21 | −}; | |
| 22 | − | |
| 23 | 16 | #define MT7620_SYSC_BASE 0x10000000 |
| 24 | 17 | |
| 25 | 18 | #define SYSC_REG_CHIP_NAME0 0x00 |
| 26 | 19 | #define SYSC_REG_CHIP_NAME1 0x04 |
| 20 | +#define SYSC_REG_EFUSE_CFG 0x08 | |
| 27 | 21 | #define SYSC_REG_CHIP_REV 0x0c |
| 28 | 22 | #define SYSC_REG_SYSTEM_CONFIG0 0x10 |
| 29 | 23 | #define SYSC_REG_SYSTEM_CONFIG1 0x14 |
| @@ -13,6 +13,23 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifndef _RALINK_REGS_H_ |
| 14 | 14 | #define _RALINK_REGS_H_ |
| 15 | 15 | |
| 16 | +enum ralink_soc_type { | |
| 17 | + RALINK_UNKNOWN = 0, | |
| 18 | + RT2880_SOC, | |
| 19 | + RT3883_SOC, | |
| 20 | + RT305X_SOC_RT3050, | |
| 21 | + RT305X_SOC_RT3052, | |
| 22 | + RT305X_SOC_RT3350, | |
| 23 | + RT305X_SOC_RT3352, | |
| 24 | + RT305X_SOC_RT5350, | |
| 25 | + MT762X_SOC_MT7620A, | |
| 26 | + MT762X_SOC_MT7620N, | |
| 27 | + MT762X_SOC_MT7621AT, | |
| 28 | + MT762X_SOC_MT7628AN, | |
| 29 | + MT762X_SOC_MT7688, | |
| 30 | +}; | |
| 31 | +extern enum ralink_soc_type ralink_soc; | |
| 32 | + | |
| 16 | 33 | extern __iomem void *rt_sysc_membase; |
| 17 | 34 | extern __iomem void *rt_memc_membase; |
| 18 | 35 | |
| @@ -13,25 +13,16 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifndef _RT305X_REGS_H_ |
| 14 | 14 | #define _RT305X_REGS_H_ |
| 15 | 15 | |
| 16 | −enum rt305x_soc_type { | |
| 17 | − RT305X_SOC_UNKNOWN = 0, | |
| 18 | − RT305X_SOC_RT3050, | |
| 19 | − RT305X_SOC_RT3052, | |
| 20 | − RT305X_SOC_RT3350, | |
| 21 | − RT305X_SOC_RT3352, | |
| 22 | − RT305X_SOC_RT5350, | |
| 23 | −}; | |
| 24 | − | |
| 25 | −extern enum rt305x_soc_type rt305x_soc; | |
| 16 | +extern enum ralink_soc_type ralink_soc; | |
| 26 | 17 | |
| 27 | 18 | static inline int soc_is_rt3050(void) |
| 28 | 19 | { |
| 29 | − return rt305x_soc == RT305X_SOC_RT3050; | |
| 20 | + return ralink_soc == RT305X_SOC_RT3050; | |
| 30 | 21 | } |
| 31 | 22 | |
| 32 | 23 | static inline int soc_is_rt3052(void) |
| 33 | 24 | { |
| 34 | − return rt305x_soc == RT305X_SOC_RT3052; | |
| 25 | + return ralink_soc == RT305X_SOC_RT3052; | |
| 35 | 26 | } |
| 36 | 27 | |
| 37 | 28 | static inline int soc_is_rt305x(void) |
| @@ -41,17 +32,17 @@ static inline int soc_is_rt305x(void) · 3 unmodified lines | ||
| 41 | 32 | |
| 42 | 33 | static inline int soc_is_rt3350(void) |
| 43 | 34 | { |
| 44 | − return rt305x_soc == RT305X_SOC_RT3350; | |
| 35 | + return ralink_soc == RT305X_SOC_RT3350; | |
| 45 | 36 | } |
| 46 | 37 | |
| 47 | 38 | static inline int soc_is_rt3352(void) |
| 48 | 39 | { |
| 49 | − return rt305x_soc == RT305X_SOC_RT3352; | |
| 40 | + return ralink_soc == RT305X_SOC_RT3352; | |
| 50 | 41 | } |
| 51 | 42 | |
| 52 | 43 | static inline int soc_is_rt5350(void) |
| 53 | 44 | { |
| 54 | − return rt305x_soc == RT305X_SOC_RT5350; | |
| 45 | + return ralink_soc == RT305X_SOC_RT5350; | |
| 55 | 46 | } |
| 56 | 47 | |
| 57 | 48 | #define RT305X_SYSC_BASE 0x10000000 |
| @@ -0,0 +1,18 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#ifndef __MIPS_ASM_MACH_XILFPGA_IRQ_H__ | |
| 12 | +#define __MIPS_ASM_MACH_XILFPGA_IRQ_H__ | |
| 13 | + | |
| 14 | +#define NR_IRQS 32 | |
| 15 | + | |
| 16 | +#include_next <irq.h> | |
| 17 | + | |
| 18 | +#endif /* __MIPS_ASM_MACH_XILFPGA_IRQ_H__ */ | |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #ifndef __MIPS_ASM_MIPS_CM_H__ |
| 12 | 12 | #define __MIPS_ASM_MIPS_CM_H__ |
| 13 | 13 | |
| 14 | +#include <linux/bitops.h> | |
| 14 | 15 | #include <linux/errno.h> |
| 15 | 16 | #include <linux/io.h> |
| 16 | 17 | #include <linux/types.h> |
| @@ -36,12 +37,12 @@ extern phys_addr_t __mips_cm_phys_base(void); · 19 unmodified lines | ||
| 36 | 37 | /* |
| 37 | 38 | * mips_cm_is64 - determine CM register width |
| 38 | 39 | * |
| 39 | − * The CM register width is processor and CM specific. A 64-bit processor | |
| 40 | − * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit | |
| 41 | − * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs | |
| 42 | − * can be done either using regular 64-bit load/store instructions, or 32-bit | |
| 43 | − * load/store instruction on 32-bit register pairs. We opt for using 64-bit | |
| 44 | − * accesses on 64-bit CMs and kernels and 32-bit in any other case. | |
| 40 | + * The CM register width is determined by the version of the CM, with CM3 | |
| 41 | + * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs. | |
| 42 | + * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs, | |
| 43 | + * or vice-versa. This variable indicates the width of the memory accesses | |
| 44 | + * that the kernel will perform to GCRs, which may differ from the actual | |
| 45 | + * width of the GCRs. | |
| 45 | 46 | * |
| 46 | 47 | * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses. |
| 47 | 48 | */ |
| @@ -125,7 +126,17 @@ static inline u32 read32_gcr_##name(void) \ · 77 unmodified lines | ||
| 125 | 126 | \ |
| 126 | 127 | static inline u64 read64_gcr_##name(void) \ |
| 127 | 128 | { \ |
| 128 | − return __raw_readq(addr_gcr_##name()); \ | |
| 129 | + void __iomem *addr = addr_gcr_##name(); \ | |
| 130 | + u64 ret; \ | |
| 131 | + \ | |
| 132 | + if (mips_cm_is64) { \ | |
| 133 | + ret = __raw_readq(addr); \ | |
| 134 | + } else { \ | |
| 135 | + ret = __raw_readl(addr); \ | |
| 136 | + ret |= (u64)__raw_readl(addr + 0x4) << 32; \ | |
| 137 | + } \ | |
| 138 | + \ | |
| 139 | + return ret; \ | |
| 129 | 140 | } \ |
| 130 | 141 | \ |
| 131 | 142 | static inline unsigned long read_gcr_##name(void) \ |
| @@ -195,6 +206,8 @@ BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0) · 63 unmodified lines | ||
| 195 | 206 | BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0) |
| 196 | 207 | BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) |
| 197 | 208 | BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) |
| 209 | +BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) | |
| 210 | +BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) | |
| 198 | 211 | |
| 199 | 212 | /* Core Local & Core Other register accessor functions */ |
| 200 | 213 | BUILD_CM_Cx_RW(reset_release, 0x00) |
| @@ -245,11 +258,14 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 44 unmodified lines | ||
| 245 | 258 | ((minor) << CM_GCR_REV_MINOR_SHF)) |
| 246 | 259 | |
| 247 | 260 | #define CM_REV_CM2 CM_ENCODE_REV(6, 0) |
| 261 | +#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) | |
| 248 | 262 | #define CM_REV_CM3 CM_ENCODE_REV(8, 0) |
| 249 | 263 | |
| 250 | 264 | /* GCR_ERROR_CAUSE register fields */ |
| 251 | 265 | #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27 |
| 252 | 266 | #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27) |
| 267 | +#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58 | |
| 268 | +#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58) | |
| 253 | 269 | #define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0 |
| 254 | 270 | #define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0) |
| 255 | 271 | |
| @@ -321,6 +337,20 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 65 unmodified lines | ||
| 321 | 337 | #define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0 |
| 322 | 338 | #define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0) |
| 323 | 339 | |
| 340 | +/* GCR_L2_PFT_CONTROL register fields */ | |
| 341 | +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12 | |
| 342 | +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12) | |
| 343 | +#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8 | |
| 344 | +#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8) | |
| 345 | +#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0 | |
| 346 | +#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0) | |
| 347 | + | |
| 348 | +/* GCR_L2_PFT_CONTROL_B register fields */ | |
| 349 | +#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8 | |
| 350 | +#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8) | |
| 351 | +#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0 | |
| 352 | +#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0) | |
| 353 | + | |
| 324 | 354 | /* GCR_Cx_COHERENCE register fields */ |
| 325 | 355 | #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 |
| 326 | 356 | #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) |
| @@ -329,11 +359,15 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 2 unmodified lines | ||
| 329 | 359 | #define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 |
| 330 | 360 | #define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10) |
| 331 | 361 | #define CM_GCR_Cx_CONFIG_PVPE_SHF 0 |
| 332 | −#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x1ff) << 0) | |
| 362 | +#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0) | |
| 333 | 363 | |
| 334 | 364 | /* GCR_Cx_OTHER register fields */ |
| 335 | 365 | #define CM_GCR_Cx_OTHER_CORENUM_SHF 16 |
| 336 | 366 | #define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16) |
| 367 | +#define CM3_GCR_Cx_OTHER_CORE_SHF 8 | |
| 368 | +#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8) | |
| 369 | +#define CM3_GCR_Cx_OTHER_VP_SHF 0 | |
| 370 | +#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0) | |
| 337 | 371 | |
| 338 | 372 | /* GCR_Cx_RESET_BASE register fields */ |
| 339 | 373 | #define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12 |
| @@ -444,4 +478,32 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu) · 104 unmodified lines | ||
| 444 | 478 | return (core * mips_cm_max_vp_width()) + vp; |
| 445 | 479 | } |
| 446 | 480 | |
| 481 | +#ifdef CONFIG_MIPS_CM | |
| 482 | + | |
| 483 | +/** | |
| 484 | + * mips_cm_lock_other - lock access to another core | |
| 485 | + * @core: the other core to be accessed | |
| 486 | + * @vp: the VP within the other core to be accessed | |
| 487 | + * | |
| 488 | + * Call before operating upon a core via the 'other' register region in | |
| 489 | + * order to prevent the region being moved during access. Must be followed | |
| 490 | + * by a call to mips_cm_unlock_other. | |
| 491 | + */ | |
| 492 | +extern void mips_cm_lock_other(unsigned int core, unsigned int vp); | |
| 493 | + | |
| 494 | +/** | |
| 495 | + * mips_cm_unlock_other - unlock access to another core | |
| 496 | + * | |
| 497 | + * Call after operating upon another core via the 'other' register region. | |
| 498 | + * Must be called after mips_cm_lock_other. | |
| 499 | + */ | |
| 500 | +extern void mips_cm_unlock_other(void); | |
| 501 | + | |
| 502 | +#else /* !CONFIG_MIPS_CM */ | |
| 503 | + | |
| 504 | +static inline void mips_cm_lock_other(unsigned int core) { } | |
| 505 | +static inline void mips_cm_unlock_other(void) { } | |
| 506 | + | |
| 507 | +#endif /* !CONFIG_MIPS_CM */ | |
| 508 | + | |
| 447 | 509 | #endif /* __MIPS_ASM_MIPS_CM_H__ */ |
| @@ -149,7 +149,8 @@ BUILD_CPC_Cx_RW(other, 0x10) · 148 unmodified lines | ||
| 149 | 149 | * core: the other core to be accessed |
| 150 | 150 | * |
| 151 | 151 | * Call before operating upon a core via the 'other' register region in |
| 152 | − * order to prevent the region being moved during access. Must be followed | |
| 152 | + * order to prevent the region being moved during access. Must be called | |
| 153 | + * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed | |
| 153 | 154 | * by a call to mips_cpc_unlock_other. |
| 154 | 155 | */ |
| 155 | 156 | extern void mips_cpc_lock_other(unsigned int core); |
| @@ -50,7 +50,9 @@ · 49 unmodified lines | ||
| 50 | 50 | #define CP0_PAGEMASK $5 |
| 51 | 51 | #define CP0_WIRED $6 |
| 52 | 52 | #define CP0_INFO $7 |
| 53 | +#define CP0_HWRENA $7, 0 | |
| 53 | 54 | #define CP0_BADVADDR $8 |
| 55 | +#define CP0_BADINSTR $8, 1 | |
| 54 | 56 | #define CP0_COUNT $9 |
| 55 | 57 | #define CP0_ENTRYHI $10 |
| 56 | 58 | #define CP0_COMPARE $11 |
| @@ -58,7 +60,11 @@ · 1 unmodified line | ||
| 58 | 60 | #define CP0_CAUSE $13 |
| 59 | 61 | #define CP0_EPC $14 |
| 60 | 62 | #define CP0_PRID $15 |
| 63 | +#define CP0_EBASE $15, 1 | |
| 64 | +#define CP0_CMGCRBASE $15, 3 | |
| 61 | 65 | #define CP0_CONFIG $16 |
| 66 | +#define CP0_CONFIG3 $16, 3 | |
| 67 | +#define CP0_CONFIG5 $16, 5 | |
| 62 | 68 | #define CP0_LLADDR $17 |
| 63 | 69 | #define CP0_WATCHLO $18 |
| 64 | 70 | #define CP0_WATCHHI $19 |
| @@ -126,15 +132,9 @@ · 61 unmodified lines | ||
| 126 | 132 | #define R3K_ENTRYLO_N (_ULCAST_(1) << 11) |
| 127 | 133 | |
| 128 | 134 | /* MIPS32/64 EntryLo bit definitions */ |
| 129 | −#ifdef CONFIG_64BIT | |
| 130 | −/* as read by dmfc0 */ | |
| 131 | −#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62) | |
| 132 | −#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63) | |
| 133 | −#else | |
| 134 | −/* as read by mfc0 */ | |
| 135 | −#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30) | |
| 136 | −#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31) | |
| 137 | −#endif | |
| 135 | +#define MIPS_ENTRYLO_PFN_SHIFT 6 | |
| 136 | +#define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2)) | |
| 137 | +#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1)) | |
| 138 | 138 | |
| 139 | 139 | /* |
| 140 | 140 | * Values for PageMask register |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #define PAGE_SHIFT 16 |
| 34 | 34 | #endif |
| 35 | 35 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) |
| 36 | −#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) | |
| 36 | +#define PAGE_MASK (~(PAGE_SIZE - 1)) | |
| 37 | 37 | |
| 38 | 38 | /* |
| 39 | 39 | * This is used for calculating the real page sizes |
| @@ -36,12 +36,6 @@ extern unsigned int vced_count, vcei_count; · 35 unmodified lines | ||
| 36 | 36 | */ |
| 37 | 37 | #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 |
| 38 | 38 | |
| 39 | −/* | |
| 40 | − * A special page (the vdso) is mapped into all processes at the very | |
| 41 | − * top of the virtual memory space. | |
| 42 | − */ | |
| 43 | −#define SPECIAL_PAGES_SIZE PAGE_SIZE | |
| 44 | − | |
| 45 | 39 | #ifdef CONFIG_32BIT |
| 46 | 40 | #ifdef CONFIG_KVM_GUEST |
| 47 | 41 | /* User space process size is limited to 1GB in KVM Guest Mode */ |
| @@ -80,7 +74,7 @@ extern unsigned int vced_count, vcei_count; · 32 unmodified lines | ||
| 80 | 74 | |
| 81 | 75 | #endif |
| 82 | 76 | |
| 83 | −#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) | |
| 77 | +#define STACK_TOP (TASK_SIZE & PAGE_MASK) | |
| 84 | 78 | |
| 85 | 79 | /* |
| 86 | 80 | * This decides where the kernel will search for a free chunk of vm |
| @@ -1,29 +1,136 @@ | ||
| 1 | 1 | /* |
| 2 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | − * License. See the file "COPYING" in the main directory of this archive | |
| 4 | − * for more details. | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 5 | 4 | * |
| 6 | − * Copyright (C) 2009 Cavium Networks | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 7 | 9 | */ |
| 8 | 10 | |
| 9 | 11 | #ifndef __ASM_VDSO_H |
| 10 | 12 | #define __ASM_VDSO_H |
| 11 | 13 | |
| 12 | −#include <linux/types.h> | |
| 14 | +#include <linux/mm_types.h> | |
| 13 | 15 | |
| 16 | +#include <asm/barrier.h> | |
| 14 | 17 | |
| 15 | −#ifdef CONFIG_32BIT | |
| 16 | −struct mips_vdso { | |
| 17 | − u32 signal_trampoline[2]; | |
| 18 | − u32 rt_signal_trampoline[2]; | |
| 18 | +/** | |
| 19 | + * struct mips_vdso_image - Details of a VDSO image. | |
| 20 | + * @data: Pointer to VDSO image data (page-aligned). | |
| 21 | + * @size: Size of the VDSO image data (page-aligned). | |
| 22 | + * @off_sigreturn: Offset of the sigreturn() trampoline. | |
| 23 | + * @off_rt_sigreturn: Offset of the rt_sigreturn() trampoline. | |
| 24 | + * @mapping: Special mapping structure. | |
| 25 | + * | |
| 26 | + * This structure contains details of a VDSO image, including the image data | |
| 27 | + * and offsets of certain symbols required by the kernel. It is generated as | |
| 28 | + * part of the VDSO build process, aside from the mapping page array, which is | |
| 29 | + * populated at runtime. | |
| 30 | + */ | |
| 31 | +struct mips_vdso_image { | |
| 32 | + void *data; | |
| 33 | + unsigned long size; | |
| 34 | + | |
| 35 | + unsigned long off_sigreturn; | |
| 36 | + unsigned long off_rt_sigreturn; | |
| 37 | + | |
| 38 | + struct vm_special_mapping mapping; | |
| 19 | 39 | }; |
| 20 | −#else /* !CONFIG_32BIT */ | |
| 21 | −struct mips_vdso { | |
| 22 | − u32 o32_signal_trampoline[2]; | |
| 23 | − u32 o32_rt_signal_trampoline[2]; | |
| 24 | − u32 rt_signal_trampoline[2]; | |
| 25 | − u32 n32_rt_signal_trampoline[2]; | |
| 40 | + | |
| 41 | +/* | |
| 42 | + * The following structures are auto-generated as part of the build for each | |
| 43 | + * ABI by genvdso, see arch/mips/vdso/Makefile. | |
| 44 | + */ | |
| 45 | + | |
| 46 | +extern struct mips_vdso_image vdso_image; | |
| 47 | + | |
| 48 | +#ifdef CONFIG_MIPS32_O32 | |
| 49 | +extern struct mips_vdso_image vdso_image_o32; | |
| 50 | +#endif | |
| 51 | + | |
| 52 | +#ifdef CONFIG_MIPS32_N32 | |
| 53 | +extern struct mips_vdso_image vdso_image_n32; | |
| 54 | +#endif | |
| 55 | + | |
| 56 | +/** | |
| 57 | + * union mips_vdso_data - Data provided by the kernel for the VDSO. | |
| 58 | + * @xtime_sec: Current real time (seconds part). | |
| 59 | + * @xtime_nsec: Current real time (nanoseconds part, shifted). | |
| 60 | + * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part). | |
| 61 | + * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part). | |
| 62 | + * @seq_count: Counter to synchronise updates (odd = updating). | |
| 63 | + * @cs_shift: Clocksource shift value. | |
| 64 | + * @clock_mode: Clocksource to use for time functions. | |
| 65 | + * @cs_mult: Clocksource multiplier value. | |
| 66 | + * @cs_cycle_last: Clock cycle value at last update. | |
| 67 | + * @cs_mask: Clocksource mask value. | |
| 68 | + * @tz_minuteswest: Minutes west of Greenwich (from timezone). | |
| 69 | + * @tz_dsttime: Type of DST correction (from timezone). | |
| 70 | + * | |
| 71 | + * This structure contains data needed by functions within the VDSO. It is | |
| 72 | + * populated by the kernel and mapped read-only into user memory. The time | |
| 73 | + * fields are mirrors of internal data from the timekeeping infrastructure. | |
| 74 | + * | |
| 75 | + * Note: Care should be taken when modifying as the layout must remain the same | |
| 76 | + * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel). | |
| 77 | + */ | |
| 78 | +union mips_vdso_data { | |
| 79 | + struct { | |
| 80 | + u64 xtime_sec; | |
| 81 | + u64 xtime_nsec; | |
| 82 | + u32 wall_to_mono_sec; | |
| 83 | + u32 wall_to_mono_nsec; | |
| 84 | + u32 seq_count; | |
| 85 | + u32 cs_shift; | |
| 86 | + u8 clock_mode; | |
| 87 | + u32 cs_mult; | |
| 88 | + u64 cs_cycle_last; | |
| 89 | + u64 cs_mask; | |
| 90 | + s32 tz_minuteswest; | |
| 91 | + s32 tz_dsttime; | |
| 92 | + }; | |
| 93 | + | |
| 94 | + u8 page[PAGE_SIZE]; | |
| 26 | 95 | }; |
| 27 | −#endif /* CONFIG_32BIT */ | |
| 96 | + | |
| 97 | +static inline u32 vdso_data_read_begin(const union mips_vdso_data *data) | |
| 98 | +{ | |
| 99 | + u32 seq; | |
| 100 | + | |
| 101 | + while (true) { | |
| 102 | + seq = ACCESS_ONCE(data->seq_count); | |
| 103 | + if (likely(!(seq & 1))) { | |
| 104 | + /* Paired with smp_wmb() in vdso_data_write_*(). */ | |
| 105 | + smp_rmb(); | |
| 106 | + return seq; | |
| 107 | + } | |
| 108 | + | |
| 109 | + cpu_relax(); | |
| 110 | + } | |
| 111 | +} | |
| 112 | + | |
| 113 | +static inline bool vdso_data_read_retry(const union mips_vdso_data *data, | |
| 114 | + u32 start_seq) | |
| 115 | +{ | |
| 116 | + /* Paired with smp_wmb() in vdso_data_write_*(). */ | |
| 117 | + smp_rmb(); | |
| 118 | + return unlikely(data->seq_count != start_seq); | |
| 119 | +} | |
| 120 | + | |
| 121 | +static inline void vdso_data_write_begin(union mips_vdso_data *data) | |
| 122 | +{ | |
| 123 | + ++data->seq_count; | |
| 124 | + | |
| 125 | + /* Ensure sequence update is written before other data page values. */ | |
| 126 | + smp_wmb(); | |
| 127 | +} | |
| 128 | + | |
| 129 | +static inline void vdso_data_write_end(union mips_vdso_data *data) | |
| 130 | +{ | |
| 131 | + /* Ensure data values are written before updating sequence again. */ | |
| 132 | + smp_wmb(); | |
| 133 | + ++data->seq_count; | |
| 134 | +} | |
| 28 | 135 | |
| 29 | 136 | #endif /* __ASM_VDSO_H */ |
| @@ -1,9 +1,9 @@ | ||
| 1 | 1 | # UAPI Header export list |
| 2 | 2 | include include/uapi/asm-generic/Kbuild.asm |
| 3 | 3 | |
| 4 | −generic-y += auxvec.h | |
| 5 | 4 | generic-y += ipcbuf.h |
| 6 | 5 | |
| 6 | +header-y += auxvec.h | |
| 7 | 7 | header-y += bitfield.h |
| 8 | 8 | header-y += bitsperlong.h |
| 9 | 9 | header-y += break.h |
| @@ -0,0 +1,17 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#ifndef __ASM_AUXVEC_H | |
| 12 | +#define __ASM_AUXVEC_H | |
| 13 | + | |
| 14 | +/* Location of VDSO image. */ | |
| 15 | +#define AT_SYSINFO_EHDR 33 | |
| 16 | + | |
| 17 | +#endif /* __ASM_AUXVEC_H */ | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/power_supply.h> |
| 26 | 26 | #include <linux/power/jz4740-battery.h> |
| 27 | 27 | #include <linux/power/gpio-charger.h> |
| 28 | +#include <linux/pwm.h> | |
| 28 | 29 | |
| 29 | 30 | #include <asm/mach-jz4740/gpio.h> |
| 30 | 31 | #include <asm/mach-jz4740/jz4740_fb.h> |
| @@ -34,8 +35,6 @@ · 3 unmodified lines | ||
| 34 | 35 | #include <linux/regulator/fixed.h> |
| 35 | 36 | #include <linux/regulator/machine.h> |
| 36 | 37 | |
| 37 | −#include <linux/leds_pwm.h> | |
| 38 | − | |
| 39 | 38 | #include <asm/mach-jz4740/platform.h> |
| 40 | 39 | |
| 41 | 40 | #include "clock.h" |
| @@ -399,13 +398,15 @@ static struct platform_device avt2_usb_regulator_device = { · 357 unmodified lines | ||
| 399 | 398 | } |
| 400 | 399 | }; |
| 401 | 400 | |
| 401 | +static struct pwm_lookup qi_lb60_pwm_lookup[] = { | |
| 402 | + PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0, | |
| 403 | + PWM_POLARITY_NORMAL), | |
| 404 | +}; | |
| 405 | + | |
| 402 | 406 | /* beeper */ |
| 403 | 407 | static struct platform_device qi_lb60_pwm_beeper = { |
| 404 | 408 | .name = "pwm-beeper", |
| 405 | 409 | .id = -1, |
| 406 | − .dev = { | |
| 407 | − .platform_data = (void *)4, | |
| 408 | − }, | |
| 409 | 410 | }; |
| 410 | 411 | |
| 411 | 412 | /* charger */ |
| @@ -491,6 +492,8 @@ static int __init qi_lb60_init_platform_devices(void) · 79 unmodified lines | ||
| 491 | 492 | platform_device_register(&jz4740_usb_ohci_device); |
| 492 | 493 | } |
| 493 | 494 | |
| 495 | + pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup)); | |
| 496 | + | |
| 494 | 497 | return platform_add_devices(jz_platform_devices, |
| 495 | 498 | ARRAY_SIZE(jz_platform_devices)); |
| 496 | 499 | |
| @@ -51,6 +51,7 @@ obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o · 50 unmodified lines | ||
| 51 | 51 | obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o |
| 52 | 52 | obj-$(CONFIG_MIPS_CMP) += smp-cmp.o |
| 53 | 53 | obj-$(CONFIG_MIPS_CPS) += smp-cps.o cps-vec.o |
| 54 | +obj-$(CONFIG_MIPS_CPS_NS16550) += cps-vec-ns16550.o | |
| 54 | 55 | obj-$(CONFIG_MIPS_GIC_IPI) += smp-gic.o |
| 55 | 56 | obj-$(CONFIG_MIPS_SPRAM) += spram.o |
| 56 | 57 | |
| @@ -0,0 +1,202 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Paul Burton <paul.burton@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <asm/addrspace.h> | |
| 12 | +#include <asm/asm.h> | |
| 13 | +#include <asm/asm-offsets.h> | |
| 14 | +#include <asm/mipsregs.h> | |
| 15 | +#include <asm/regdef.h> | |
| 16 | +#include <linux/serial_reg.h> | |
| 17 | + | |
| 18 | +#define UART_TX_OFS (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT) | |
| 19 | +#define UART_LSR_OFS (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT) | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * _mips_cps_putc() - write a character to the UART | |
| 23 | + * @a0: ASCII character to write | |
| 24 | + * @t9: UART base address | |
| 25 | + */ | |
| 26 | +LEAF(_mips_cps_putc) | |
| 27 | +1: lw t0, UART_LSR_OFS(t9) | |
| 28 | + andi t0, t0, UART_LSR_TEMT | |
| 29 | + beqz t0, 1b | |
| 30 | + sb a0, UART_TX_OFS(t9) | |
| 31 | + jr ra | |
| 32 | + END(_mips_cps_putc) | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * _mips_cps_puts() - write a string to the UART | |
| 36 | + * @a0: pointer to NULL-terminated ASCII string | |
| 37 | + * @t9: UART base address | |
| 38 | + * | |
| 39 | + * Write a null-terminated ASCII string to the UART. | |
| 40 | + */ | |
| 41 | +NESTED(_mips_cps_puts, 0, ra) | |
| 42 | + move s7, ra | |
| 43 | + move s6, a0 | |
| 44 | + | |
| 45 | +1: lb a0, 0(s6) | |
| 46 | + beqz a0, 2f | |
| 47 | + jal _mips_cps_putc | |
| 48 | + PTR_ADDIU s6, s6, 1 | |
| 49 | + b 1b | |
| 50 | + | |
| 51 | +2: jr s7 | |
| 52 | + END(_mips_cps_puts) | |
| 53 | + | |
| 54 | +/** | |
| 55 | + * _mips_cps_putx4 - write a 4b hex value to the UART | |
| 56 | + * @a0: the 4b value to write to the UART | |
| 57 | + * @t9: UART base address | |
| 58 | + * | |
| 59 | + * Write a single hexadecimal character to the UART. | |
| 60 | + */ | |
| 61 | +NESTED(_mips_cps_putx4, 0, ra) | |
| 62 | + andi a0, a0, 0xf | |
| 63 | + li t0, '0' | |
| 64 | + blt a0, 10, 1f | |
| 65 | + li t0, 'a' | |
| 66 | + addiu a0, a0, -10 | |
| 67 | +1: addu a0, a0, t0 | |
| 68 | + b _mips_cps_putc | |
| 69 | + END(_mips_cps_putx4) | |
| 70 | + | |
| 71 | +/** | |
| 72 | + * _mips_cps_putx8 - write an 8b hex value to the UART | |
| 73 | + * @a0: the 8b value to write to the UART | |
| 74 | + * @t9: UART base address | |
| 75 | + * | |
| 76 | + * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART. | |
| 77 | + */ | |
| 78 | +NESTED(_mips_cps_putx8, 0, ra) | |
| 79 | + move s3, ra | |
| 80 | + move s2, a0 | |
| 81 | + srl a0, a0, 4 | |
| 82 | + jal _mips_cps_putx4 | |
| 83 | + move a0, s2 | |
| 84 | + move ra, s3 | |
| 85 | + b _mips_cps_putx4 | |
| 86 | + END(_mips_cps_putx8) | |
| 87 | + | |
| 88 | +/** | |
| 89 | + * _mips_cps_putx16 - write a 16b hex value to the UART | |
| 90 | + * @a0: the 16b value to write to the UART | |
| 91 | + * @t9: UART base address | |
| 92 | + * | |
| 93 | + * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART. | |
| 94 | + */ | |
| 95 | +NESTED(_mips_cps_putx16, 0, ra) | |
| 96 | + move s5, ra | |
| 97 | + move s4, a0 | |
| 98 | + srl a0, a0, 8 | |
| 99 | + jal _mips_cps_putx8 | |
| 100 | + move a0, s4 | |
| 101 | + move ra, s5 | |
| 102 | + b _mips_cps_putx8 | |
| 103 | + END(_mips_cps_putx16) | |
| 104 | + | |
| 105 | +/** | |
| 106 | + * _mips_cps_putx32 - write a 32b hex value to the UART | |
| 107 | + * @a0: the 32b value to write to the UART | |
| 108 | + * @t9: UART base address | |
| 109 | + * | |
| 110 | + * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART. | |
| 111 | + */ | |
| 112 | +NESTED(_mips_cps_putx32, 0, ra) | |
| 113 | + move s7, ra | |
| 114 | + move s6, a0 | |
| 115 | + srl a0, a0, 16 | |
| 116 | + jal _mips_cps_putx16 | |
| 117 | + move a0, s6 | |
| 118 | + move ra, s7 | |
| 119 | + b _mips_cps_putx16 | |
| 120 | + END(_mips_cps_putx32) | |
| 121 | + | |
| 122 | +#ifdef CONFIG_64BIT | |
| 123 | + | |
| 124 | +/** | |
| 125 | + * _mips_cps_putx64 - write a 64b hex value to the UART | |
| 126 | + * @a0: the 64b value to write to the UART | |
| 127 | + * @t9: UART base address | |
| 128 | + * | |
| 129 | + * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART. | |
| 130 | + */ | |
| 131 | +NESTED(_mips_cps_putx64, 0, ra) | |
| 132 | + move sp, ra | |
| 133 | + move s8, a0 | |
| 134 | + dsrl32 a0, a0, 0 | |
| 135 | + jal _mips_cps_putx32 | |
| 136 | + move a0, s8 | |
| 137 | + move ra, sp | |
| 138 | + b _mips_cps_putx32 | |
| 139 | + END(_mips_cps_putx64) | |
| 140 | + | |
| 141 | +#define _mips_cps_putxlong _mips_cps_putx64 | |
| 142 | + | |
| 143 | +#else /* !CONFIG_64BIT */ | |
| 144 | + | |
| 145 | +#define _mips_cps_putxlong _mips_cps_putx32 | |
| 146 | + | |
| 147 | +#endif /* !CONFIG_64BIT */ | |
| 148 | + | |
| 149 | +/** | |
| 150 | + * mips_cps_bev_dump() - dump relevant exception state to UART | |
| 151 | + * @a0: pointer to NULL-terminated ASCII string naming the exception | |
| 152 | + * | |
| 153 | + * Write information that may be useful in debugging an exception to the | |
| 154 | + * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception | |
| 155 | + * will only be run if something goes horribly wrong very early during | |
| 156 | + * the bringup of a core and it is very likely to be unsafe to perform | |
| 157 | + * memory accesses at that point (cache state indeterminate, EVA may not | |
| 158 | + * be configured, coherence may be disabled) let alone have a stack, | |
| 159 | + * this is all written in assembly using only registers & unmapped | |
| 160 | + * uncached access to the UART registers. | |
| 161 | + */ | |
| 162 | +LEAF(mips_cps_bev_dump) | |
| 163 | + move s0, ra | |
| 164 | + move s1, a0 | |
| 165 | + | |
| 166 | + li t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE) | |
| 167 | + | |
| 168 | + PTR_LA a0, str_newline | |
| 169 | + jal _mips_cps_puts | |
| 170 | + PTR_LA a0, str_bev | |
| 171 | + jal _mips_cps_puts | |
| 172 | + move a0, s1 | |
| 173 | + jal _mips_cps_puts | |
| 174 | + PTR_LA a0, str_newline | |
| 175 | + jal _mips_cps_puts | |
| 176 | + PTR_LA a0, str_newline | |
| 177 | + jal _mips_cps_puts | |
| 178 | + | |
| 179 | +#define DUMP_COP0_REG(reg, name, sz, _mfc0) \ | |
| 180 | + PTR_LA a0, 8f; \ | |
| 181 | + jal _mips_cps_puts; \ | |
| 182 | + _mfc0 a0, reg; \ | |
| 183 | + jal _mips_cps_putx##sz; \ | |
| 184 | + PTR_LA a0, str_newline; \ | |
| 185 | + jal _mips_cps_puts; \ | |
| 186 | + TEXT(name) | |
| 187 | + | |
| 188 | + DUMP_COP0_REG(CP0_CAUSE, "Cause: 0x", 32, mfc0) | |
| 189 | + DUMP_COP0_REG(CP0_STATUS, "Status: 0x", 32, mfc0) | |
| 190 | + DUMP_COP0_REG(CP0_EBASE, "EBase: 0x", long, MFC0) | |
| 191 | + DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0) | |
| 192 | + DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0) | |
| 193 | + | |
| 194 | + PTR_LA a0, str_newline | |
| 195 | + jal _mips_cps_puts | |
| 196 | + jr s0 | |
| 197 | + END(mips_cps_bev_dump) | |
| 198 | + | |
| 199 | +.pushsection .data | |
| 200 | +str_bev: .asciiz "BEV Exception: " | |
| 201 | +str_newline: .asciiz "\r\n" | |
| 202 | +.popsection | |
| @@ -25,14 +25,32 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | .set noreorder |
| 27 | 27 | |
| 28 | +#ifdef CONFIG_64BIT | |
| 29 | +# define STATUS_BITDEPS ST0_KX | |
| 30 | +#else | |
| 31 | +# define STATUS_BITDEPS 0 | |
| 32 | +#endif | |
| 33 | + | |
| 34 | +#ifdef CONFIG_MIPS_CPS_NS16550 | |
| 35 | + | |
| 36 | +#define DUMP_EXCEP(name) \ | |
| 37 | + PTR_LA a0, 8f; \ | |
| 38 | + jal mips_cps_bev_dump; \ | |
| 39 | + nop; \ | |
| 40 | + TEXT(name) | |
| 41 | + | |
| 42 | +#else /* !CONFIG_MIPS_CPS_NS16550 */ | |
| 43 | + | |
| 44 | +#define DUMP_EXCEP(name) | |
| 45 | + | |
| 46 | +#endif /* !CONFIG_MIPS_CPS_NS16550 */ | |
| 47 | + | |
| 28 | 48 | /* |
| 29 | 49 | * Set dest to non-zero if the core supports the MT ASE, else zero. If |
| 30 | 50 | * MT is not supported then branch to nomt. |
| 31 | 51 | */ |
| 32 | 52 | .macro has_mt dest, nomt |
| 33 | − mfc0 \dest, CP0_CONFIG | |
| 34 | − bgez \dest, \nomt | |
| 35 | − mfc0 \dest, CP0_CONFIG, 1 | |
| 53 | + mfc0 \dest, CP0_CONFIG, 1 | |
| 36 | 54 | bgez \dest, \nomt |
| 37 | 55 | mfc0 \dest, CP0_CONFIG, 2 |
| 38 | 56 | bgez \dest, \nomt |
| @@ -47,11 +65,9 @@ · 8 unmodified lines | ||
| 47 | 65 | |
| 48 | 66 | LEAF(mips_cps_core_entry) |
| 49 | 67 | /* |
| 50 | − * These first 12 bytes will be patched by cps_smp_setup to load the | |
| 51 | − * base address of the CM GCRs into register v1 and the CCA to use into | |
| 52 | − * register s0. | |
| 68 | + * These first 4 bytes will be patched by cps_smp_setup to load the | |
| 69 | + * CCA to use into register s0. | |
| 53 | 70 | */ |
| 54 | − .quad 0 | |
| 55 | 71 | .word 0 |
| 56 | 72 | |
| 57 | 73 | /* Check whether we're here due to an NMI */ |
| @@ -71,7 +87,7 @@ not_nmi: · 13 unmodified lines | ||
| 71 | 87 | mtc0 t0, CP0_CAUSE |
| 72 | 88 | |
| 73 | 89 | /* Setup Status */ |
| 74 | − li t0, ST0_CU1 | ST0_CU0 | |
| 90 | + li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS | |
| 75 | 91 | mtc0 t0, CP0_STATUS |
| 76 | 92 | |
| 77 | 93 | /* |
| @@ -151,6 +167,12 @@ dcache_done: · 73 unmodified lines | ||
| 151 | 167 | mtc0 t0, CP0_CONFIG |
| 152 | 168 | ehb |
| 153 | 169 | |
| 170 | + /* Calculate an uncached address for the CM GCRs */ | |
| 171 | + MFC0 v1, CP0_CMGCRBASE | |
| 172 | + PTR_SLL v1, v1, 4 | |
| 173 | + PTR_LI t0, UNCAC_BASE | |
| 174 | + PTR_ADDU v1, v1, t0 | |
| 175 | + | |
| 154 | 176 | /* Enter the coherent domain */ |
| 155 | 177 | li t0, 0xff |
| 156 | 178 | sw t0, GCR_CL_COHERENCE_OFS(v1) |
| @@ -188,36 +210,42 @@ dcache_done: · 31 unmodified lines | ||
| 188 | 210 | |
| 189 | 211 | .org 0x200 |
| 190 | 212 | LEAF(excep_tlbfill) |
| 213 | + DUMP_EXCEP("TLB Fill") | |
| 191 | 214 | b . |
| 192 | 215 | nop |
| 193 | 216 | END(excep_tlbfill) |
| 194 | 217 | |
| 195 | 218 | .org 0x280 |
| 196 | 219 | LEAF(excep_xtlbfill) |
| 220 | + DUMP_EXCEP("XTLB Fill") | |
| 197 | 221 | b . |
| 198 | 222 | nop |
| 199 | 223 | END(excep_xtlbfill) |
| 200 | 224 | |
| 201 | 225 | .org 0x300 |
| 202 | 226 | LEAF(excep_cache) |
| 227 | + DUMP_EXCEP("Cache") | |
| 203 | 228 | b . |
| 204 | 229 | nop |
| 205 | 230 | END(excep_cache) |
| 206 | 231 | |
| 207 | 232 | .org 0x380 |
| 208 | 233 | LEAF(excep_genex) |
| 234 | + DUMP_EXCEP("General") | |
| 209 | 235 | b . |
| 210 | 236 | nop |
| 211 | 237 | END(excep_genex) |
| 212 | 238 | |
| 213 | 239 | .org 0x400 |
| 214 | 240 | LEAF(excep_intex) |
| 241 | + DUMP_EXCEP("Interrupt") | |
| 215 | 242 | b . |
| 216 | 243 | nop |
| 217 | 244 | END(excep_intex) |
| 218 | 245 | |
| 219 | 246 | .org 0x480 |
| 220 | 247 | LEAF(excep_ejtag) |
| 248 | + DUMP_EXCEP("EJTAG") | |
| 221 | 249 | PTR_LA k0, ejtag_debug_handler |
| 222 | 250 | jr k0 |
| 223 | 251 | nop |
| @@ -536,8 +536,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) · 535 unmodified lines | ||
| 536 | 536 | c->options |= MIPS_CPU_SEGMENTS; |
| 537 | 537 | if (config3 & MIPS_CONF3_MSA) |
| 538 | 538 | c->ases |= MIPS_ASE_MSA; |
| 539 | − /* Only tested on 32-bit cores */ | |
| 540 | − if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) { | |
| 539 | + if (config3 & MIPS_CONF3_PW) { | |
| 541 | 540 | c->htw_seq = 0; |
| 542 | 541 | c->options |= MIPS_CPU_HTW; |
| 543 | 542 | } |
| @@ -28,6 +28,43 @@ static u64 notrace r4k_read_sched_clock(void) · 27 unmodified lines | ||
| 28 | 28 | return read_c0_count(); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | +static inline unsigned int rdhwr_count(void) | |
| 32 | +{ | |
| 33 | + unsigned int count; | |
| 34 | + | |
| 35 | + __asm__ __volatile__( | |
| 36 | + " .set push\n" | |
| 37 | + " .set mips32r2\n" | |
| 38 | + " rdhwr %0, $2\n" | |
| 39 | + " .set pop\n" | |
| 40 | + : "=r" (count)); | |
| 41 | + | |
| 42 | + return count; | |
| 43 | +} | |
| 44 | + | |
| 45 | +static bool rdhwr_count_usable(void) | |
| 46 | +{ | |
| 47 | + unsigned int prev, curr, i; | |
| 48 | + | |
| 49 | + /* | |
| 50 | + * Older QEMUs have a broken implementation of RDHWR for the CP0 count | |
| 51 | + * which always returns a constant value. Try to identify this and don't | |
| 52 | + * use it in the VDSO if it is broken. This workaround can be removed | |
| 53 | + * once the fix has been in QEMU stable for a reasonable amount of time. | |
| 54 | + */ | |
| 55 | + for (i = 0, prev = rdhwr_count(); i < 100; i++) { | |
| 56 | + curr = rdhwr_count(); | |
| 57 | + | |
| 58 | + if (curr != prev) | |
| 59 | + return true; | |
| 60 | + | |
| 61 | + prev = curr; | |
| 62 | + } | |
| 63 | + | |
| 64 | + pr_warn("Not using R4K clocksource in VDSO due to broken RDHWR\n"); | |
| 65 | + return false; | |
| 66 | +} | |
| 67 | + | |
| 31 | 68 | int __init init_r4k_clocksource(void) |
| 32 | 69 | { |
| 33 | 70 | if (!cpu_has_counter || !mips_hpt_frequency) |
| @@ -36,6 +73,13 @@ int __init init_r4k_clocksource(void) · 2 unmodified lines | ||
| 36 | 73 | /* Calculate a somewhat reasonable rating value */ |
| 37 | 74 | clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; |
| 38 | 75 | |
| 76 | + /* | |
| 77 | + * R2 onwards makes the count accessible to user mode so it can be used | |
| 78 | + * by the VDSO (HWREna is configured by configure_hwrena()). | |
| 79 | + */ | |
| 80 | + if (cpu_has_mips_r2_r6 && rdhwr_count_usable()) | |
| 81 | + clocksource_mips.archdata.vdso_clock_mode = VDSO_CLOCK_R4K; | |
| 82 | + | |
| 39 | 83 | clocksource_register_hz(&clocksource_mips, mips_hpt_frequency); |
| 40 | 84 | |
| 41 | 85 | sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency); |
| @@ -134,6 +134,16 @@ void __init check_wait(void) · 133 unmodified lines | ||
| 134 | 134 | return; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | + /* | |
| 138 | + * MIPSr6 specifies that masked interrupts should unblock an executing | |
| 139 | + * wait instruction, and thus that it is safe for us to use | |
| 140 | + * r4k_wait_irqoff. Yippee! | |
| 141 | + */ | |
| 142 | + if (cpu_has_mips_r6) { | |
| 143 | + cpu_wait = r4k_wait_irqoff; | |
| 144 | + return; | |
| 145 | + } | |
| 146 | + | |
| 137 | 147 | switch (current_cpu_type()) { |
| 138 | 148 | case CPU_R3081: |
| 139 | 149 | case CPU_R3081E: |
| @@ -155,12 +165,12 @@ void __init check_wait(void) · 15 unmodified lines | ||
| 155 | 165 | case CPU_4KEC: |
| 156 | 166 | case CPU_4KSC: |
| 157 | 167 | case CPU_5KC: |
| 168 | + case CPU_5KE: | |
| 158 | 169 | case CPU_25KF: |
| 159 | 170 | case CPU_PR4450: |
| 160 | 171 | case CPU_BMIPS3300: |
| 161 | 172 | case CPU_BMIPS4350: |
| 162 | 173 | case CPU_BMIPS4380: |
| 163 | − case CPU_BMIPS5000: | |
| 164 | 174 | case CPU_CAVIUM_OCTEON: |
| 165 | 175 | case CPU_CAVIUM_OCTEON_PLUS: |
| 166 | 176 | case CPU_CAVIUM_OCTEON2: |
| @@ -171,7 +181,9 @@ void __init check_wait(void) · 4 unmodified lines | ||
| 171 | 181 | case CPU_XLP: |
| 172 | 182 | cpu_wait = r4k_wait; |
| 173 | 183 | break; |
| 174 | − | |
| 184 | + case CPU_BMIPS5000: | |
| 185 | + cpu_wait = r4k_wait_irqoff; | |
| 186 | + break; | |
| 175 | 187 | case CPU_RM7000: |
| 176 | 188 | cpu_wait = rm7k_wait_irqoff; |
| 177 | 189 | break; |
| @@ -196,7 +208,6 @@ void __init check_wait(void) · 18 unmodified lines | ||
| 196 | 208 | case CPU_INTERAPTIV: |
| 197 | 209 | case CPU_M5150: |
| 198 | 210 | case CPU_QEMU_GENERIC: |
| 199 | − case CPU_I6400: | |
| 200 | 211 | cpu_wait = r4k_wait; |
| 201 | 212 | if (read_c0_config7() & MIPS_CONF7_WII) |
| 202 | 213 | cpu_wait = r4k_wait_irqoff; |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #include <linux/errno.h> |
| 12 | +#include <linux/percpu.h> | |
| 13 | +#include <linux/spinlock.h> | |
| 12 | 14 | |
| 13 | 15 | #include <asm/mips-cm.h> |
| 14 | 16 | #include <asm/mipsregs.h> |
| @@ -136,6 +138,9 @@ static char *cm3_causes[32] = { · 121 unmodified lines | ||
| 136 | 138 | "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" |
| 137 | 139 | }; |
| 138 | 140 | |
| 141 | +static DEFINE_PER_CPU_ALIGNED(spinlock_t, cm_core_lock); | |
| 142 | +static DEFINE_PER_CPU_ALIGNED(unsigned long, cm_core_lock_flags); | |
| 143 | + | |
| 139 | 144 | phys_addr_t __mips_cm_phys_base(void) |
| 140 | 145 | { |
| 141 | 146 | u32 config3 = read_c0_config3(); |
| @@ -200,6 +205,7 @@ int mips_cm_probe(void) · 58 unmodified lines | ||
| 200 | 205 | { |
| 201 | 206 | phys_addr_t addr; |
| 202 | 207 | u32 base_reg; |
| 208 | + unsigned cpu; | |
| 203 | 209 | |
| 204 | 210 | /* |
| 205 | 211 | * No need to probe again if we have already been |
| @@ -247,38 +253,70 @@ int mips_cm_probe(void) · 41 unmodified lines | ||
| 247 | 253 | /* determine register width for this CM */ |
| 248 | 254 | mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3); |
| 249 | 255 | |
| 256 | + for_each_possible_cpu(cpu) | |
| 257 | + spin_lock_init(&per_cpu(cm_core_lock, cpu)); | |
| 258 | + | |
| 250 | 259 | return 0; |
| 251 | 260 | } |
| 252 | 261 | |
| 253 | −void mips_cm_error_report(void) | |
| 262 | +void mips_cm_lock_other(unsigned int core, unsigned int vp) | |
| 254 | 263 | { |
| 255 | − unsigned long revision = mips_cm_revision(); | |
| 264 | + unsigned curr_core; | |
| 265 | + u32 val; | |
| 266 | + | |
| 267 | + preempt_disable(); | |
| 268 | + curr_core = current_cpu_data.core; | |
| 269 | + spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), | |
| 270 | + per_cpu(cm_core_lock_flags, curr_core)); | |
| 271 | + | |
| 272 | + if (mips_cm_revision() >= CM_REV_CM3) { | |
| 273 | + val = core << CM3_GCR_Cx_OTHER_CORE_SHF; | |
| 274 | + val |= vp << CM3_GCR_Cx_OTHER_VP_SHF; | |
| 275 | + } else { | |
| 276 | + BUG_ON(vp != 0); | |
| 277 | + val = core << CM_GCR_Cx_OTHER_CORENUM_SHF; | |
| 278 | + } | |
| 279 | + | |
| 280 | + write_gcr_cl_other(val); | |
| 281 | + | |
| 256 | 282 | /* |
| 257 | − * CM3 has a 64-bit Error cause register with 0:57 containing the error | |
| 258 | − * info and 63:58 the error type. For old CMs, everything is contained | |
| 259 | − * in a single 32-bit register (0:26 and 31:27 respectively). Even | |
| 260 | − * though the cm_error is u64, we will simply ignore the upper word | |
| 261 | − * for CM2. | |
| 283 | + * Ensure the core-other region reflects the appropriate core & | |
| 284 | + * VP before any accesses to it occur. | |
| 262 | 285 | */ |
| 263 | − u64 cm_error = read_gcr_error_cause(); | |
| 264 | − int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF + | |
| 265 | − ((revision >= CM_REV_CM3) ? 31 : 0); | |
| 266 | − unsigned long cm_addr = read_gcr_error_addr(); | |
| 267 | − unsigned long cm_other = read_gcr_error_mult(); | |
| 286 | + mb(); | |
| 287 | +} | |
| 288 | + | |
| 289 | +void mips_cm_unlock_other(void) | |
| 290 | +{ | |
| 291 | + unsigned curr_core = current_cpu_data.core; | |
| 292 | + | |
| 293 | + spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core), | |
| 294 | + per_cpu(cm_core_lock_flags, curr_core)); | |
| 295 | + preempt_enable(); | |
| 296 | +} | |
| 297 | + | |
| 298 | +void mips_cm_error_report(void) | |
| 299 | +{ | |
| 300 | + u64 cm_error, cm_addr, cm_other; | |
| 301 | + unsigned long revision; | |
| 268 | 302 | int ocause, cause; |
| 269 | 303 | char buf[256]; |
| 270 | 304 | |
| 271 | 305 | if (!mips_cm_present()) |
| 272 | 306 | return; |
| 273 | 307 | |
| 274 | − cause = cm_error >> cm_error_cause_sft; | |
| 308 | + revision = mips_cm_revision(); | |
| 275 | 309 | |
| 276 | − if (!cause) | |
| 277 | − /* All good */ | |
| 278 | − return; | |
| 279 | − | |
| 280 | − ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; | |
| 281 | 310 | if (revision < CM_REV_CM3) { /* CM2 */ |
| 311 | + cm_error = read_gcr_error_cause(); | |
| 312 | + cm_addr = read_gcr_error_addr(); | |
| 313 | + cm_other = read_gcr_error_mult(); | |
| 314 | + cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF; | |
| 315 | + ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; | |
| 316 | + | |
| 317 | + if (!cause) | |
| 318 | + return; | |
| 319 | + | |
| 282 | 320 | if (cause < 16) { |
| 283 | 321 | unsigned long cca_bits = (cm_error >> 15) & 7; |
| 284 | 322 | unsigned long tr_bits = (cm_error >> 12) & 7; |
| @@ -310,18 +348,30 @@ void mips_cm_error_report(void) · 25 unmodified lines | ||
| 310 | 348 | } |
| 311 | 349 | pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error, |
| 312 | 350 | cm2_causes[cause], buf); |
| 313 | − pr_err("CM_ADDR =%08lx\n", cm_addr); | |
| 314 | − pr_err("CM_OTHER=%08lx %s\n", cm_other, cm2_causes[ocause]); | |
| 351 | + pr_err("CM_ADDR =%08llx\n", cm_addr); | |
| 352 | + pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]); | |
| 315 | 353 | } else { /* CM3 */ |
| 316 | − /* Used by cause == {1,2,3} */ | |
| 317 | − unsigned long core_id_bits = (cm_error >> 22) & 0xf; | |
| 318 | − unsigned long vp_id_bits = (cm_error >> 18) & 0xf; | |
| 319 | − unsigned long cmd_bits = (cm_error >> 14) & 0xf; | |
| 320 | − unsigned long cmd_group_bits = (cm_error >> 11) & 0xf; | |
| 321 | − unsigned long cm3_cca_bits = (cm_error >> 8) & 7; | |
| 322 | − unsigned long mcp_bits = (cm_error >> 5) & 0xf; | |
| 323 | − unsigned long cm3_tr_bits = (cm_error >> 1) & 0xf; | |
| 324 | − unsigned long sched_bit = cm_error & 0x1; | |
| 354 | + ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; | |
| 355 | + ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; | |
| 356 | + | |
| 357 | + cm_error = read64_gcr_error_cause(); | |
| 358 | + cm_addr = read64_gcr_error_addr(); | |
| 359 | + cm_other = read64_gcr_error_mult(); | |
| 360 | + cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF; | |
| 361 | + ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; | |
| 362 | + | |
| 363 | + if (!cause) | |
| 364 | + return; | |
| 365 | + | |
| 366 | + /* Used by cause == {1,2,3} */ | |
| 367 | + core_id_bits = (cm_error >> 22) & 0xf; | |
| 368 | + vp_id_bits = (cm_error >> 18) & 0xf; | |
| 369 | + cmd_bits = (cm_error >> 14) & 0xf; | |
| 370 | + cmd_group_bits = (cm_error >> 11) & 0xf; | |
| 371 | + cm3_cca_bits = (cm_error >> 8) & 7; | |
| 372 | + mcp_bits = (cm_error >> 5) & 0xf; | |
| 373 | + cm3_tr_bits = (cm_error >> 1) & 0xf; | |
| 374 | + sched_bit = cm_error & 0x1; | |
| 325 | 375 | |
| 326 | 376 | if (cause == 1 || cause == 3) { /* Tag ECC */ |
| 327 | 377 | unsigned long tag_ecc = (cm_error >> 57) & 0x1; |
| @@ -363,12 +413,14 @@ void mips_cm_error_report(void) · 35 unmodified lines | ||
| 363 | 413 | cm3_cmd_group[cmd_group_bits], |
| 364 | 414 | cm3_cca_bits, 1 << mcp_bits, |
| 365 | 415 | cm3_tr[cm3_tr_bits], sched_bit); |
| 416 | + } else { | |
| 417 | + buf[0] = 0; | |
| 366 | 418 | } |
| 367 | 419 | |
| 368 | 420 | pr_err("CM_ERROR=%llx %s <%s>\n", cm_error, |
| 369 | 421 | cm3_causes[cause], buf); |
| 370 | − pr_err("CM_ADDR =%lx\n", cm_addr); | |
| 371 | − pr_err("CM_OTHER=%lx %s\n", cm_other, cm3_causes[ocause]); | |
| 422 | + pr_err("CM_ADDR =%llx\n", cm_addr); | |
| 423 | + pr_err("CM_OTHER=%llx %s\n", cm_other, cm3_causes[ocause]); | |
| 372 | 424 | } |
| 373 | 425 | |
| 374 | 426 | /* reprime cause register */ |
| @@ -76,6 +76,12 @@ void mips_cpc_lock_other(unsigned int core) · 75 unmodified lines | ||
| 76 | 76 | spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), |
| 77 | 77 | per_cpu(cpc_core_lock_flags, curr_core)); |
| 78 | 78 | write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF); |
| 79 | + | |
| 80 | + /* | |
| 81 | + * Ensure the core-other region reflects the appropriate core & | |
| 82 | + * VP before any accesses to it occur. | |
| 83 | + */ | |
| 84 | + mb(); | |
| 79 | 85 | } |
| 80 | 86 | |
| 81 | 87 | void mips_cpc_unlock_other(void) |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <asm/asm.h> |
| 23 | 23 | #include <asm/branch.h> |
| 24 | 24 | #include <asm/break.h> |
| 25 | +#include <asm/debug.h> | |
| 25 | 26 | #include <asm/fpu.h> |
| 26 | 27 | #include <asm/fpu_emulator.h> |
| 27 | 28 | #include <asm/inst.h> |
| @@ -2363,7 +2364,6 @@ static const struct file_operations mipsr2_clear_fops = { · 2335 unmodified lines | ||
| 2363 | 2364 | |
| 2364 | 2365 | static int __init mipsr2_init_debugfs(void) |
| 2365 | 2366 | { |
| 2366 | − extern struct dentry *mips_debugfs_dir; | |
| 2367 | 2367 | struct dentry *mipsr2_emul; |
| 2368 | 2368 | |
| 2369 | 2369 | if (!mips_debugfs_dir) |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/debugfs.h> |
| 11 | 11 | #include <linux/seq_file.h> |
| 12 | 12 | #include <asm/cpu.h> |
| 13 | +#include <asm/debug.h> | |
| 13 | 14 | #include <asm/mipsregs.h> |
| 14 | 15 | |
| 15 | 16 | static void build_segment_config(char *str, unsigned int cfg) |
| @@ -91,7 +92,6 @@ static const struct file_operations segments_fops = { · 75 unmodified lines | ||
| 91 | 92 | |
| 92 | 93 | static int __init segments_info(void) |
| 93 | 94 | { |
| 94 | − extern struct dentry *mips_debugfs_dir; | |
| 95 | 95 | struct dentry *segments; |
| 96 | 96 | |
| 97 | 97 | if (cpu_has_segments) { |
| @@ -33,11 +33,16 @@ · 32 unmodified lines | ||
| 33 | 33 | #include <asm/cache.h> |
| 34 | 34 | #include <asm/cdmm.h> |
| 35 | 35 | #include <asm/cpu.h> |
| 36 | +#include <asm/debug.h> | |
| 36 | 37 | #include <asm/sections.h> |
| 37 | 38 | #include <asm/setup.h> |
| 38 | 39 | #include <asm/smp-ops.h> |
| 39 | 40 | #include <asm/prom.h> |
| 40 | 41 | |
| 42 | +#ifdef CONFIG_MIPS_ELF_APPENDED_DTB | |
| 43 | +const char __section(.appended_dtb) __appended_dtb[0x100000]; | |
| 44 | +#endif /* CONFIG_MIPS_ELF_APPENDED_DTB */ | |
| 45 | + | |
| 41 | 46 | struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; |
| 42 | 47 | |
| 43 | 48 | EXPORT_SYMBOL(cpu_data); |
| @@ -616,6 +621,10 @@ static void __init request_crashkernel(struct resource *res) · 572 unmodified lines | ||
| 616 | 621 | } |
| 617 | 622 | #endif /* !defined(CONFIG_KEXEC) */ |
| 618 | 623 | |
| 624 | +#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) | |
| 625 | +#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) | |
| 626 | +#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND) | |
| 627 | + | |
| 619 | 628 | static void __init arch_mem_init(char **cmdline_p) |
| 620 | 629 | { |
| 621 | 630 | struct memblock_region *reg; |
| @@ -640,18 +649,24 @@ static void __init arch_mem_init(char **cmdline_p) · 18 unmodified lines | ||
| 640 | 649 | pr_info("Determined physical RAM map:\n"); |
| 641 | 650 | print_memory_map(); |
| 642 | 651 | |
| 643 | −#ifdef CONFIG_CMDLINE_BOOL | |
| 644 | −#ifdef CONFIG_CMDLINE_OVERRIDE | |
| 652 | +#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) | |
| 645 | 653 | strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); |
| 646 | 654 | #else |
| 655 | + if ((USE_PROM_CMDLINE && arcs_cmdline[0]) || | |
| 656 | + (USE_DTB_CMDLINE && !boot_command_line[0])) | |
| 657 | + strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | |
| 658 | + | |
| 659 | + if (EXTEND_WITH_PROM && arcs_cmdline[0]) { | |
| 660 | + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | |
| 661 | + strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | |
| 662 | + } | |
| 663 | + | |
| 664 | +#if defined(CONFIG_CMDLINE_BOOL) | |
| 647 | 665 | if (builtin_cmdline[0]) { |
| 648 | − strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); | |
| 649 | − strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 666 | + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); | |
| 667 | + strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); | |
| 650 | 668 | } |
| 651 | − strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | |
| 652 | 669 | #endif |
| 653 | −#else | |
| 654 | − strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE); | |
| 655 | 670 | #endif |
| 656 | 671 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
| 657 | 672 | |
| @@ -36,7 +36,6 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <asm/ucontext.h> |
| 37 | 37 | #include <asm/cpu-features.h> |
| 38 | 38 | #include <asm/war.h> |
| 39 | −#include <asm/vdso.h> | |
| 40 | 39 | #include <asm/dsp.h> |
| 41 | 40 | #include <asm/inst.h> |
| 42 | 41 | #include <asm/msa.h> |
| @@ -752,16 +751,15 @@ static int setup_rt_frame(void *sig_return, struct ksignal *ksig, · 709 unmodified lines | ||
| 752 | 751 | struct mips_abi mips_abi = { |
| 753 | 752 | #ifdef CONFIG_TRAD_SIGNALS |
| 754 | 753 | .setup_frame = setup_frame, |
| 755 | − .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline), | |
| 756 | 754 | #endif |
| 757 | 755 | .setup_rt_frame = setup_rt_frame, |
| 758 | − .rt_signal_return_offset = | |
| 759 | − offsetof(struct mips_vdso, rt_signal_trampoline), | |
| 760 | 756 | .restart = __NR_restart_syscall, |
| 761 | 757 | |
| 762 | 758 | .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs), |
| 763 | 759 | .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr), |
| 764 | 760 | .off_sc_used_math = offsetof(struct sigcontext, sc_used_math), |
| 761 | + | |
| 762 | + .vdso = &vdso_image, | |
| 765 | 763 | }; |
| 766 | 764 | |
| 767 | 765 | static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
| @@ -801,11 +799,11 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) · 33 unmodified lines | ||
| 801 | 799 | } |
| 802 | 800 | |
| 803 | 801 | if (sig_uses_siginfo(&ksig->ka)) |
| 804 | − ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, | |
| 802 | + ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn, | |
| 805 | 803 | ksig, regs, oldset); |
| 806 | 804 | else |
| 807 | − ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig, | |
| 808 | − regs, oldset); | |
| 805 | + ret = abi->setup_frame(vdso + abi->vdso->off_sigreturn, | |
| 806 | + ksig, regs, oldset); | |
| 809 | 807 | |
| 810 | 808 | signal_setup_done(ret, ksig, 0); |
| 811 | 809 | } |
| @@ -31,7 +31,6 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <asm/ucontext.h> |
| 32 | 32 | #include <asm/fpu.h> |
| 33 | 33 | #include <asm/war.h> |
| 34 | −#include <asm/vdso.h> | |
| 35 | 34 | #include <asm/dsp.h> |
| 36 | 35 | |
| 37 | 36 | #include "signal-common.h" |
| @@ -406,14 +405,12 @@ static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig, · 368 unmodified lines | ||
| 406 | 405 | */ |
| 407 | 406 | struct mips_abi mips_abi_32 = { |
| 408 | 407 | .setup_frame = setup_frame_32, |
| 409 | − .signal_return_offset = | |
| 410 | − offsetof(struct mips_vdso, o32_signal_trampoline), | |
| 411 | 408 | .setup_rt_frame = setup_rt_frame_32, |
| 412 | − .rt_signal_return_offset = | |
| 413 | − offsetof(struct mips_vdso, o32_rt_signal_trampoline), | |
| 414 | 409 | .restart = __NR_O32_restart_syscall, |
| 415 | 410 | |
| 416 | 411 | .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs), |
| 417 | 412 | .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr), |
| 418 | 413 | .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math), |
| 414 | + | |
| 415 | + .vdso = &vdso_image_o32, | |
| 419 | 416 | }; |
| @@ -38,7 +38,6 @@ · 37 unmodified lines | ||
| 38 | 38 | #include <asm/fpu.h> |
| 39 | 39 | #include <asm/cpu-features.h> |
| 40 | 40 | #include <asm/war.h> |
| 41 | −#include <asm/vdso.h> | |
| 42 | 41 | |
| 43 | 42 | #include "signal-common.h" |
| 44 | 43 | |
| @@ -151,11 +150,11 @@ static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig, · 106 unmodified lines | ||
| 151 | 150 | |
| 152 | 151 | struct mips_abi mips_abi_n32 = { |
| 153 | 152 | .setup_rt_frame = setup_rt_frame_n32, |
| 154 | − .rt_signal_return_offset = | |
| 155 | − offsetof(struct mips_vdso, n32_rt_signal_trampoline), | |
| 156 | 153 | .restart = __NR_N32_restart_syscall, |
| 157 | 154 | |
| 158 | 155 | .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs), |
| 159 | 156 | .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr), |
| 160 | 157 | .off_sc_used_math = offsetof(struct sigcontext, sc_used_math), |
| 158 | + | |
| 159 | + .vdso = &vdso_image_n32, | |
| 161 | 160 | }; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * option) any later version. |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | +#include <linux/delay.h> | |
| 11 | 12 | #include <linux/io.h> |
| 12 | 13 | #include <linux/irqchip/mips-gic.h> |
| 13 | 14 | #include <linux/sched.h> |
| @@ -37,8 +38,9 @@ static unsigned core_vpe_count(unsigned core) · 23 unmodified lines | ||
| 37 | 38 | if (!config_enabled(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) |
| 38 | 39 | return 1; |
| 39 | 40 | |
| 40 | − write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF); | |
| 41 | + mips_cm_lock_other(core, 0); | |
| 41 | 42 | cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; |
| 43 | + mips_cm_unlock_other(); | |
| 42 | 44 | return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; |
| 43 | 45 | } |
| 44 | 46 | |
| @@ -133,11 +135,9 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) · 88 unmodified lines | ||
| 133 | 135 | /* |
| 134 | 136 | * Patch the start of mips_cps_core_entry to provide: |
| 135 | 137 | * |
| 136 | − * v1 = CM base address | |
| 137 | 138 | * s0 = kseg0 CCA |
| 138 | 139 | */ |
| 139 | 140 | entry_code = (u32 *)&mips_cps_core_entry; |
| 140 | − UASM_i_LA(&entry_code, 3, (long)mips_cm_base); | |
| 141 | 141 | uasm_i_addiu(&entry_code, 16, 0, cca); |
| 142 | 142 | blast_dcache_range((unsigned long)&mips_cps_core_entry, |
| 143 | 143 | (unsigned long)entry_code); |
| @@ -190,10 +190,11 @@ err_out: · 46 unmodified lines | ||
| 190 | 190 | |
| 191 | 191 | static void boot_core(unsigned core) |
| 192 | 192 | { |
| 193 | − u32 access; | |
| 193 | + u32 access, stat, seq_state; | |
| 194 | + unsigned timeout; | |
| 194 | 195 | |
| 195 | 196 | /* Select the appropriate core */ |
| 196 | − write_gcr_cl_other(core << CM_GCR_Cx_OTHER_CORENUM_SHF); | |
| 197 | + mips_cm_lock_other(core, 0); | |
| 197 | 198 | |
| 198 | 199 | /* Set its reset vector */ |
| 199 | 200 | write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry)); |
| @@ -210,12 +211,36 @@ static void boot_core(unsigned core) · 10 unmodified lines | ||
| 210 | 211 | /* Reset the core */ |
| 211 | 212 | mips_cpc_lock_other(core); |
| 212 | 213 | write_cpc_co_cmd(CPC_Cx_CMD_RESET); |
| 214 | + | |
| 215 | + timeout = 100; | |
| 216 | + while (true) { | |
| 217 | + stat = read_cpc_co_stat_conf(); | |
| 218 | + seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK; | |
| 219 | + | |
| 220 | + /* U6 == coherent execution, ie. the core is up */ | |
| 221 | + if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6) | |
| 222 | + break; | |
| 223 | + | |
| 224 | + /* Delay a little while before we start warning */ | |
| 225 | + if (timeout) { | |
| 226 | + timeout--; | |
| 227 | + mdelay(10); | |
| 228 | + continue; | |
| 229 | + } | |
| 230 | + | |
| 231 | + pr_warn("Waiting for core %u to start... STAT_CONF=0x%x\n", | |
| 232 | + core, stat); | |
| 233 | + mdelay(1000); | |
| 234 | + } | |
| 235 | + | |
| 213 | 236 | mips_cpc_unlock_other(); |
| 214 | 237 | } else { |
| 215 | 238 | /* Take the core out of reset */ |
| 216 | 239 | write_gcr_co_reset_release(0); |
| 217 | 240 | } |
| 218 | 241 | |
| 242 | + mips_cm_unlock_other(); | |
| 243 | + | |
| 219 | 244 | /* The core is now powered up */ |
| 220 | 245 | bitmap_set(core_power, core, 1); |
| 221 | 246 | } |
| @@ -46,9 +46,11 @@ void gic_send_ipi_single(int cpu, unsigned int action) · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | if (mips_cpc_present() && (core != current_cpu_data.core)) { |
| 48 | 48 | while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { |
| 49 | + mips_cm_lock_other(core, 0); | |
| 49 | 50 | mips_cpc_lock_other(core); |
| 50 | 51 | write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); |
| 51 | 52 | mips_cpc_unlock_other(); |
| 53 | + mips_cm_unlock_other(); | |
| 52 | 54 | } |
| 53 | 55 | } |
| 54 | 56 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/debugfs.h> |
| 6 | 6 | #include <linux/export.h> |
| 7 | 7 | #include <linux/spinlock.h> |
| 8 | − | |
| 8 | +#include <asm/debug.h> | |
| 9 | 9 | |
| 10 | 10 | static int ss_get(void *data, u64 *val) |
| 11 | 11 | { |
| @@ -115,8 +115,6 @@ static int multi_get(void *data, u64 *val) · 103 unmodified lines | ||
| 115 | 115 | |
| 116 | 116 | DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n"); |
| 117 | 117 | |
| 118 | − | |
| 119 | −extern struct dentry *mips_debugfs_dir; | |
| 120 | 118 | static int __init spinlock_test(void) |
| 121 | 119 | { |
| 122 | 120 | struct dentry *d; |
| @@ -12,14 +12,15 @@ · 11 unmodified lines | ||
| 12 | 12 | * Save stack-backtrace addresses into a stack_trace buffer: |
| 13 | 13 | */ |
| 14 | 14 | static void save_raw_context_stack(struct stack_trace *trace, |
| 15 | − unsigned long reg29) | |
| 15 | + unsigned long reg29, int savesched) | |
| 16 | 16 | { |
| 17 | 17 | unsigned long *sp = (unsigned long *)reg29; |
| 18 | 18 | unsigned long addr; |
| 19 | 19 | |
| 20 | 20 | while (!kstack_end(sp)) { |
| 21 | 21 | addr = *sp++; |
| 22 | − if (__kernel_text_address(addr)) { | |
| 22 | + if (__kernel_text_address(addr) && | |
| 23 | + (savesched || !in_sched_functions(addr))) { | |
| 23 | 24 | if (trace->skip > 0) |
| 24 | 25 | trace->skip--; |
| 25 | 26 | else |
| @@ -31,7 +32,7 @@ static void save_raw_context_stack(struct stack_trace *trace, · 5 unmodified lines | ||
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | static void save_context_stack(struct stack_trace *trace, |
| 34 | − struct task_struct *tsk, struct pt_regs *regs) | |
| 35 | + struct task_struct *tsk, struct pt_regs *regs, int savesched) | |
| 35 | 36 | { |
| 36 | 37 | unsigned long sp = regs->regs[29]; |
| 37 | 38 | #ifdef CONFIG_KALLSYMS |
| @@ -43,20 +44,22 @@ static void save_context_stack(struct stack_trace *trace, · 5 unmodified lines | ||
| 43 | 44 | (unsigned long)task_stack_page(tsk); |
| 44 | 45 | if (stack_page && sp >= stack_page && |
| 45 | 46 | sp <= stack_page + THREAD_SIZE - 32) |
| 46 | − save_raw_context_stack(trace, sp); | |
| 47 | + save_raw_context_stack(trace, sp, savesched); | |
| 47 | 48 | return; |
| 48 | 49 | } |
| 49 | 50 | do { |
| 50 | − if (trace->skip > 0) | |
| 51 | − trace->skip--; | |
| 52 | − else | |
| 53 | − trace->entries[trace->nr_entries++] = pc; | |
| 54 | − if (trace->nr_entries >= trace->max_entries) | |
| 55 | − break; | |
| 51 | + if (savesched || !in_sched_functions(pc)) { | |
| 52 | + if (trace->skip > 0) | |
| 53 | + trace->skip--; | |
| 54 | + else | |
| 55 | + trace->entries[trace->nr_entries++] = pc; | |
| 56 | + if (trace->nr_entries >= trace->max_entries) | |
| 57 | + break; | |
| 58 | + } | |
| 56 | 59 | pc = unwind_stack(tsk, &sp, pc, &ra); |
| 57 | 60 | } while (pc); |
| 58 | 61 | #else |
| 59 | − save_raw_context_stack(trace, sp); | |
| 62 | + save_raw_context_stack(trace, sp, savesched); | |
| 60 | 63 | #endif |
| 61 | 64 | } |
| 62 | 65 | |
| @@ -82,6 +85,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) · 19 unmodified lines | ||
| 82 | 85 | regs->cp0_epc = tsk->thread.reg31; |
| 83 | 86 | } else |
| 84 | 87 | prepare_frametrace(regs); |
| 85 | − save_context_stack(trace, tsk, regs); | |
| 88 | + save_context_stack(trace, tsk, regs, tsk == current); | |
| 86 | 89 | } |
| 87 | 90 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/irq.h> |
| 38 | 38 | #include <linux/perf_event.h> |
| 39 | 39 | |
| 40 | +#include <asm/addrspace.h> | |
| 40 | 41 | #include <asm/bootinfo.h> |
| 41 | 42 | #include <asm/branch.h> |
| 42 | 43 | #include <asm/break.h> |
| @@ -1856,12 +1857,14 @@ void __noreturn nmi_exception_handler(struct pt_regs *regs) · 1813 unmodified lines | ||
| 1856 | 1857 | { |
| 1857 | 1858 | char str[100]; |
| 1858 | 1859 | |
| 1860 | + nmi_enter(); | |
| 1859 | 1861 | raw_notifier_call_chain(&nmi_chain, 0, regs); |
| 1860 | 1862 | bust_spinlocks(1); |
| 1861 | 1863 | snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n", |
| 1862 | 1864 | smp_processor_id(), regs->cp0_epc); |
| 1863 | 1865 | regs->cp0_epc = read_c0_errorepc(); |
| 1864 | 1866 | die(str, regs); |
| 1867 | + nmi_exit(); | |
| 1865 | 1868 | } |
| 1866 | 1869 | |
| 1867 | 1870 | #define VECTORSPACING 0x100 /* for EI/VI mode */ |
| @@ -2204,12 +2207,8 @@ void __init trap_init(void) · 336 unmodified lines | ||
| 2204 | 2207 | ebase = (unsigned long) |
| 2205 | 2208 | __alloc_bootmem(size, 1 << fls(size), 0); |
| 2206 | 2209 | } else { |
| 2207 | −#ifdef CONFIG_KVM_GUEST | |
| 2208 | −#define KVM_GUEST_KSEG0 0x40000000 | |
| 2209 | − ebase = KVM_GUEST_KSEG0; | |
| 2210 | −#else | |
| 2211 | − ebase = CKSEG0; | |
| 2212 | −#endif | |
| 2210 | + ebase = CAC_BASE; | |
| 2211 | + | |
| 2213 | 2212 | if (cpu_has_mips_r2_r6) |
| 2214 | 2213 | ebase += (read_c0_ebase() & 0x3ffff000); |
| 2215 | 2214 | } |
| @@ -85,6 +85,7 @@ · 84 unmodified lines | ||
| 85 | 85 | #include <asm/branch.h> |
| 86 | 86 | #include <asm/byteorder.h> |
| 87 | 87 | #include <asm/cop2.h> |
| 88 | +#include <asm/debug.h> | |
| 88 | 89 | #include <asm/fpu.h> |
| 89 | 90 | #include <asm/fpu_emulator.h> |
| 90 | 91 | #include <asm/inst.h> |
| @@ -2295,7 +2296,6 @@ sigbus: · 2204 unmodified lines | ||
| 2295 | 2296 | } |
| 2296 | 2297 | |
| 2297 | 2298 | #ifdef CONFIG_DEBUG_FS |
| 2298 | −extern struct dentry *mips_debugfs_dir; | |
| 2299 | 2299 | static int __init debugfs_unaligned(void) |
| 2300 | 2300 | { |
| 2301 | 2301 | struct dentry *d; |
| @@ -1,122 +1,175 @@ | ||
| 1 | 1 | /* |
| 2 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | − * License. See the file "COPYING" in the main directory of this archive | |
| 4 | − * for more details. | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 5 | 4 | * |
| 6 | − * Copyright (C) 2009, 2010 Cavium Networks, Inc. | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 7 | 9 | */ |
| 8 | 10 | |
| 9 | − | |
| 10 | −#include <linux/kernel.h> | |
| 11 | −#include <linux/err.h> | |
| 12 | −#include <linux/sched.h> | |
| 13 | −#include <linux/mm.h> | |
| 14 | −#include <linux/init.h> | |
| 15 | 11 | #include <linux/binfmts.h> |
| 16 | 12 | #include <linux/elf.h> |
| 17 | −#include <linux/vmalloc.h> | |
| 18 | −#include <linux/unistd.h> | |
| 19 | −#include <linux/random.h> | |
| 13 | +#include <linux/err.h> | |
| 14 | +#include <linux/init.h> | |
| 15 | +#include <linux/ioport.h> | |
| 16 | +#include <linux/irqchip/mips-gic.h> | |
| 17 | +#include <linux/mm.h> | |
| 18 | +#include <linux/sched.h> | |
| 19 | +#include <linux/slab.h> | |
| 20 | +#include <linux/timekeeper_internal.h> | |
| 20 | 21 | |
| 22 | +#include <asm/abi.h> | |
| 21 | 23 | #include <asm/vdso.h> |
| 22 | −#include <asm/uasm.h> | |
| 23 | −#include <asm/processor.h> | |
| 24 | + | |
| 25 | +/* Kernel-provided data used by the VDSO. */ | |
| 26 | +static union mips_vdso_data vdso_data __page_aligned_data; | |
| 24 | 27 | |
| 25 | 28 | /* |
| 26 | − * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | |
| 29 | + * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as | |
| 30 | + * what we map and where within the area they are mapped is determined at | |
| 31 | + * runtime. | |
| 27 | 32 | */ |
| 28 | −#define __NR_O32_sigreturn 4119 | |
| 29 | −#define __NR_O32_rt_sigreturn 4193 | |
| 30 | −#define __NR_N32_rt_sigreturn 6211 | |
| 33 | +static struct page *no_pages[] = { NULL }; | |
| 34 | +static struct vm_special_mapping vdso_vvar_mapping = { | |
| 35 | + .name = "[vvar]", | |
| 36 | + .pages = no_pages, | |
| 37 | +}; | |
| 31 | 38 | |
| 32 | −static struct page *vdso_page; | |
| 33 | − | |
| 34 | −static void __init install_trampoline(u32 *tramp, unsigned int sigreturn) | |
| 39 | +static void __init init_vdso_image(struct mips_vdso_image *image) | |
| 35 | 40 | { |
| 36 | − uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */ | |
| 37 | − uasm_i_syscall(&tramp, 0); | |
| 41 | + unsigned long num_pages, i; | |
| 42 | + | |
| 43 | + BUG_ON(!PAGE_ALIGNED(image->data)); | |
| 44 | + BUG_ON(!PAGE_ALIGNED(image->size)); | |
| 45 | + | |
| 46 | + num_pages = image->size / PAGE_SIZE; | |
| 47 | + | |
| 48 | + for (i = 0; i < num_pages; i++) { | |
| 49 | + image->mapping.pages[i] = | |
| 50 | + virt_to_page(image->data + (i * PAGE_SIZE)); | |
| 51 | + } | |
| 38 | 52 | } |
| 39 | 53 | |
| 40 | 54 | static int __init init_vdso(void) |
| 41 | 55 | { |
| 42 | − struct mips_vdso *vdso; | |
| 43 | − | |
| 44 | − vdso_page = alloc_page(GFP_KERNEL); | |
| 45 | − if (!vdso_page) | |
| 46 | − panic("Cannot allocate vdso"); | |
| 47 | − | |
| 48 | − vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL); | |
| 49 | − if (!vdso) | |
| 50 | − panic("Cannot map vdso"); | |
| 51 | − clear_page(vdso); | |
| 52 | − | |
| 53 | − install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn); | |
| 54 | −#ifdef CONFIG_32BIT | |
| 55 | − install_trampoline(vdso->signal_trampoline, __NR_sigreturn); | |
| 56 | −#else | |
| 57 | − install_trampoline(vdso->n32_rt_signal_trampoline, | |
| 58 | − __NR_N32_rt_sigreturn); | |
| 59 | − install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn); | |
| 60 | − install_trampoline(vdso->o32_rt_signal_trampoline, | |
| 61 | − __NR_O32_rt_sigreturn); | |
| 56 | + init_vdso_image(&vdso_image); | |
| 57 | + | |
| 58 | +#ifdef CONFIG_MIPS32_O32 | |
| 59 | + init_vdso_image(&vdso_image_o32); | |
| 62 | 60 | #endif |
| 63 | 61 | |
| 64 | − vunmap(vdso); | |
| 62 | +#ifdef CONFIG_MIPS32_N32 | |
| 63 | + init_vdso_image(&vdso_image_n32); | |
| 64 | +#endif | |
| 65 | 65 | |
| 66 | 66 | return 0; |
| 67 | 67 | } |
| 68 | 68 | subsys_initcall(init_vdso); |
| 69 | 69 | |
| 70 | −static unsigned long vdso_addr(unsigned long start) | |
| 70 | +void update_vsyscall(struct timekeeper *tk) | |
| 71 | 71 | { |
| 72 | − unsigned long offset = 0UL; | |
| 73 | − | |
| 74 | − if (current->flags & PF_RANDOMIZE) { | |
| 75 | − offset = get_random_int(); | |
| 76 | − offset <<= PAGE_SHIFT; | |
| 77 | − if (TASK_IS_32BIT_ADDR) | |
| 78 | − offset &= 0xfffffful; | |
| 79 | − else | |
| 80 | − offset &= 0xffffffful; | |
| 72 | + vdso_data_write_begin(&vdso_data); | |
| 73 | + | |
| 74 | + vdso_data.xtime_sec = tk->xtime_sec; | |
| 75 | + vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec; | |
| 76 | + vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec; | |
| 77 | + vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec; | |
| 78 | + vdso_data.cs_shift = tk->tkr_mono.shift; | |
| 79 | + | |
| 80 | + vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode; | |
| 81 | + if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { | |
| 82 | + vdso_data.cs_mult = tk->tkr_mono.mult; | |
| 83 | + vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last; | |
| 84 | + vdso_data.cs_mask = tk->tkr_mono.mask; | |
| 81 | 85 | } |
| 82 | 86 | |
| 83 | − return STACK_TOP + offset; | |
| 87 | + vdso_data_write_end(&vdso_data); | |
| 88 | +} | |
| 89 | + | |
| 90 | +void update_vsyscall_tz(void) | |
| 91 | +{ | |
| 92 | + if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { | |
| 93 | + vdso_data.tz_minuteswest = sys_tz.tz_minuteswest; | |
| 94 | + vdso_data.tz_dsttime = sys_tz.tz_dsttime; | |
| 95 | + } | |
| 84 | 96 | } |
| 85 | 97 | |
| 86 | 98 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) |
| 87 | 99 | { |
| 88 | − int ret; | |
| 89 | − unsigned long addr; | |
| 100 | + struct mips_vdso_image *image = current->thread.abi->vdso; | |
| 90 | 101 | struct mm_struct *mm = current->mm; |
| 102 | + unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr; | |
| 103 | + struct vm_area_struct *vma; | |
| 104 | + struct resource gic_res; | |
| 105 | + int ret; | |
| 91 | 106 | |
| 92 | 107 | down_write(&mm->mmap_sem); |
| 93 | 108 | |
| 94 | − addr = vdso_addr(mm->start_stack); | |
| 109 | + /* | |
| 110 | + * Determine total area size. This includes the VDSO data itself, the | |
| 111 | + * data page, and the GIC user page if present. Always create a mapping | |
| 112 | + * for the GIC user area if the GIC is present regardless of whether it | |
| 113 | + * is the current clocksource, in case it comes into use later on. We | |
| 114 | + * only map a page even though the total area is 64K, as we only need | |
| 115 | + * the counter registers at the start. | |
| 116 | + */ | |
| 117 | + gic_size = gic_present ? PAGE_SIZE : 0; | |
| 118 | + vvar_size = gic_size + PAGE_SIZE; | |
| 119 | + size = vvar_size + image->size; | |
| 120 | + | |
| 121 | + base = get_unmapped_area(NULL, 0, size, 0, 0); | |
| 122 | + if (IS_ERR_VALUE(base)) { | |
| 123 | + ret = base; | |
| 124 | + goto out; | |
| 125 | + } | |
| 126 | + | |
| 127 | + data_addr = base + gic_size; | |
| 128 | + vdso_addr = data_addr + PAGE_SIZE; | |
| 95 | 129 | |
| 96 | − addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0); | |
| 97 | − if (IS_ERR_VALUE(addr)) { | |
| 98 | − ret = addr; | |
| 99 | − goto up_fail; | |
| 130 | + vma = _install_special_mapping(mm, base, vvar_size, | |
| 131 | + VM_READ | VM_MAYREAD, | |
| 132 | + &vdso_vvar_mapping); | |
| 133 | + if (IS_ERR(vma)) { | |
| 134 | + ret = PTR_ERR(vma); | |
| 135 | + goto out; | |
| 100 | 136 | } |
| 101 | 137 | |
| 102 | − ret = install_special_mapping(mm, addr, PAGE_SIZE, | |
| 103 | − VM_READ|VM_EXEC| | |
| 104 | − VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, | |
| 105 | − &vdso_page); | |
| 138 | + /* Map GIC user page. */ | |
| 139 | + if (gic_size) { | |
| 140 | + ret = gic_get_usm_range(&gic_res); | |
| 141 | + if (ret) | |
| 142 | + goto out; | |
| 143 | + | |
| 144 | + ret = io_remap_pfn_range(vma, base, | |
| 145 | + gic_res.start >> PAGE_SHIFT, | |
| 146 | + gic_size, | |
| 147 | + pgprot_noncached(PAGE_READONLY)); | |
| 148 | + if (ret) | |
| 149 | + goto out; | |
| 150 | + } | |
| 106 | 151 | |
| 152 | + /* Map data page. */ | |
| 153 | + ret = remap_pfn_range(vma, data_addr, | |
| 154 | + virt_to_phys(&vdso_data) >> PAGE_SHIFT, | |
| 155 | + PAGE_SIZE, PAGE_READONLY); | |
| 107 | 156 | if (ret) |
| 108 | − goto up_fail; | |
| 157 | + goto out; | |
| 158 | + | |
| 159 | + /* Map VDSO image. */ | |
| 160 | + vma = _install_special_mapping(mm, vdso_addr, image->size, | |
| 161 | + VM_READ | VM_EXEC | | |
| 162 | + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC, | |
| 163 | + &image->mapping); | |
| 164 | + if (IS_ERR(vma)) { | |
| 165 | + ret = PTR_ERR(vma); | |
| 166 | + goto out; | |
| 167 | + } | |
| 109 | 168 | |
| 110 | − mm->context.vdso = (void *)addr; | |
| 169 | + mm->context.vdso = (void *)vdso_addr; | |
| 170 | + ret = 0; | |
| 111 | 171 | |
| 112 | −up_fail: | |
| 172 | +out: | |
| 113 | 173 | up_write(&mm->mmap_sem); |
| 114 | 174 | return ret; |
| 115 | 175 | } |
| 116 | − | |
| 117 | −const char *arch_vma_name(struct vm_area_struct *vma) | |
| 118 | −{ | |
| 119 | − if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) | |
| 120 | − return "[vdso]"; | |
| 121 | − return NULL; | |
| 122 | −} | |
| @@ -17,7 +17,9 @@ OUTPUT_ARCH(mips) · 16 unmodified lines | ||
| 17 | 17 | ENTRY(kernel_entry) |
| 18 | 18 | PHDRS { |
| 19 | 19 | text PT_LOAD FLAGS(7); /* RWX */ |
| 20 | +#ifndef CONFIG_CAVIUM_OCTEON_SOC | |
| 20 | 21 | note PT_NOTE FLAGS(4); /* R__ */ |
| 22 | +#endif /* CAVIUM_OCTEON_SOC */ | |
| 21 | 23 | } |
| 22 | 24 | |
| 23 | 25 | #ifdef CONFIG_32BIT |
| @@ -71,7 +73,12 @@ SECTIONS · 47 unmodified lines | ||
| 71 | 73 | __stop___dbe_table = .; |
| 72 | 74 | } |
| 73 | 75 | |
| 74 | − NOTES :text :note | |
| 76 | +#ifdef CONFIG_CAVIUM_OCTEON_SOC | |
| 77 | +#define NOTES_HEADER | |
| 78 | +#else /* CONFIG_CAVIUM_OCTEON_SOC */ | |
| 79 | +#define NOTES_HEADER :note | |
| 80 | +#endif /* CONFIG_CAVIUM_OCTEON_SOC */ | |
| 81 | + NOTES :text NOTES_HEADER | |
| 75 | 82 | .dummy : { *(.dummy) } :text |
| 76 | 83 | |
| 77 | 84 | _sdata = .; /* Start of data section */ |
| @@ -132,6 +139,11 @@ SECTIONS · 54 unmodified lines | ||
| 132 | 139 | __appended_dtb = .; |
| 133 | 140 | /* leave space for appended DTB */ |
| 134 | 141 | . += 0x100000; |
| 142 | +#elif defined(CONFIG_MIPS_ELF_APPENDED_DTB) | |
| 143 | + .appended_dtb : AT(ADDR(.appended_dtb) - LOAD_OFFSET) { | |
| 144 | + *(.appended_dtb) | |
| 145 | + KEEP(*(.appended_dtb)) | |
| 146 | + } | |
| 135 | 147 | #endif |
| 136 | 148 | /* |
| 137 | 149 | * Align to 64K in attempt to eliminate holes before the |
| @@ -181,6 +193,7 @@ SECTIONS · 43 unmodified lines | ||
| 181 | 193 | DISCARDS |
| 182 | 194 | /DISCARD/ : { |
| 183 | 195 | /* ABI crap starts here */ |
| 196 | + *(.MIPS.abiflags) | |
| 184 | 197 | *(.MIPS.options) |
| 185 | 198 | *(.options) |
| 186 | 199 | *(.pdr) |
| @@ -36,14 +36,6 @@ · 35 unmodified lines | ||
| 36 | 36 | #define PT_HOST_USERLOCAL PT_EPC |
| 37 | 37 | |
| 38 | 38 | #define CP0_DDATA_LO $28,3 |
| 39 | −#define CP0_CONFIG3 $16,3 | |
| 40 | −#define CP0_CONFIG5 $16,5 | |
| 41 | −#define CP0_EBASE $15,1 | |
| 42 | − | |
| 43 | −#define CP0_INTCTL $12,1 | |
| 44 | −#define CP0_SRSCTL $12,2 | |
| 45 | −#define CP0_SRSMAP $12,3 | |
| 46 | −#define CP0_HWRENA $7,0 | |
| 47 | 39 | |
| 48 | 40 | /* Resume Flags */ |
| 49 | 41 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
| @@ -99,6 +99,23 @@ int clk_set_rate(struct clk *clk, unsigned long rate) · 98 unmodified lines | ||
| 99 | 99 | } |
| 100 | 100 | EXPORT_SYMBOL(clk_set_rate); |
| 101 | 101 | |
| 102 | +long clk_round_rate(struct clk *clk, unsigned long rate) | |
| 103 | +{ | |
| 104 | + if (unlikely(!clk_good(clk))) | |
| 105 | + return 0; | |
| 106 | + if (clk->rates && *clk->rates) { | |
| 107 | + unsigned long *r = clk->rates; | |
| 108 | + | |
| 109 | + while (*r && (*r != rate)) | |
| 110 | + r++; | |
| 111 | + if (!*r) { | |
| 112 | + return clk->rate; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + return rate; | |
| 116 | +} | |
| 117 | +EXPORT_SYMBOL(clk_round_rate); | |
| 118 | + | |
| 102 | 119 | int clk_enable(struct clk *clk) |
| 103 | 120 | { |
| 104 | 121 | if (unlikely(!clk_good(clk))) |
| @@ -31,13 +31,18 @@ · 30 unmodified lines | ||
| 31 | 31 | #define CLOCK_240M 240000000 |
| 32 | 32 | #define CLOCK_250M 250000000 |
| 33 | 33 | #define CLOCK_266M 266666666 |
| 34 | +#define CLOCK_288M 288888888 | |
| 34 | 35 | #define CLOCK_300M 300000000 |
| 35 | 36 | #define CLOCK_333M 333333333 |
| 37 | +#define CLOCK_360M 360000000 | |
| 36 | 38 | #define CLOCK_393M 393215332 |
| 37 | 39 | #define CLOCK_400M 400000000 |
| 40 | +#define CLOCK_432M 432000000 | |
| 38 | 41 | #define CLOCK_450M 450000000 |
| 39 | 42 | #define CLOCK_500M 500000000 |
| 40 | 43 | #define CLOCK_600M 600000000 |
| 44 | +#define CLOCK_666M 666666666 | |
| 45 | +#define CLOCK_720M 720000000 | |
| 41 | 46 | |
| 42 | 47 | /* clock out speeds */ |
| 43 | 48 | #define CLOCK_32_768K 32768 |
| @@ -80,4 +85,12 @@ extern unsigned long ltq_vr9_cpu_hz(void); · 36 unmodified lines | ||
| 80 | 85 | extern unsigned long ltq_vr9_fpi_hz(void); |
| 81 | 86 | extern unsigned long ltq_vr9_pp32_hz(void); |
| 82 | 87 | |
| 88 | +extern unsigned long ltq_ar10_cpu_hz(void); | |
| 89 | +extern unsigned long ltq_ar10_fpi_hz(void); | |
| 90 | +extern unsigned long ltq_ar10_pp32_hz(void); | |
| 91 | + | |
| 92 | +extern unsigned long ltq_grx390_cpu_hz(void); | |
| 93 | +extern unsigned long ltq_grx390_fpi_hz(void); | |
| 94 | +extern unsigned long ltq_grx390_pp32_hz(void); | |
| 95 | + | |
| 83 | 96 | #endif |
| @@ -369,8 +369,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) · 368 unmodified lines | ||
| 369 | 369 | if (of_address_to_resource(node, i, &res)) |
| 370 | 370 | panic("Failed to get icu memory range"); |
| 371 | 371 | |
| 372 | − if (request_mem_region(res.start, resource_size(&res), | |
| 373 | − res.name) < 0) | |
| 372 | + if (!request_mem_region(res.start, resource_size(&res), | |
| 373 | + res.name)) | |
| 374 | 374 | pr_err("Failed to request icu memory"); |
| 375 | 375 | |
| 376 | 376 | ltq_icu_membase[i] = ioremap_nocache(res.start, |
| @@ -449,8 +449,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) · 72 unmodified lines | ||
| 449 | 449 | if (ret != exin_avail) |
| 450 | 450 | panic("failed to load external irq resources"); |
| 451 | 451 | |
| 452 | − if (request_mem_region(res.start, resource_size(&res), | |
| 453 | − res.name) < 0) | |
| 452 | + if (!request_mem_region(res.start, resource_size(&res), | |
| 453 | + res.name)) | |
| 454 | 454 | pr_err("Failed to request eiu memory"); |
| 455 | 455 | |
| 456 | 456 | ltq_eiu_membase = ioremap_nocache(res.start, |
| @@ -77,8 +77,6 @@ void __init plat_mem_setup(void) · 76 unmodified lines | ||
| 77 | 77 | * parsed resulting in our memory appearing |
| 78 | 78 | */ |
| 79 | 79 | __dt_setup_arch(__dtb_start); |
| 80 | − | |
| 81 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 82 | 80 | } |
| 83 | 81 | |
| 84 | 82 | void __init device_tree_init(void) |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * by the Free Software Foundation. |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> |
| 7 | + * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | |
| 7 | 8 | */ |
| 8 | 9 | |
| 9 | 10 | #include <linux/io.h> |
| @@ -25,9 +26,9 @@ static unsigned int ram_clocks[] = { · 15 unmodified lines | ||
| 25 | 26 | /* legacy xway clock */ |
| 26 | 27 | #define CGU_SYS 0x10 |
| 27 | 28 | |
| 28 | −/* vr9 clock */ | |
| 29 | −#define CGU_SYS_VR9 0x0c | |
| 30 | −#define CGU_IF_CLK_VR9 0x24 | |
| 29 | +/* vr9, ar10/grx390 clock */ | |
| 30 | +#define CGU_SYS_XRX 0x0c | |
| 31 | +#define CGU_IF_CLK_AR10 0x24 | |
| 31 | 32 | |
| 32 | 33 | unsigned long ltq_danube_fpi_hz(void) |
| 33 | 34 | { |
| @@ -87,8 +88,9 @@ unsigned long ltq_ar9_fpi_hz(void) · 53 unmodified lines | ||
| 87 | 88 | unsigned long sys = ltq_ar9_sys_hz(); |
| 88 | 89 | |
| 89 | 90 | if (ltq_cgu_r32(CGU_SYS) & BIT(0)) |
| 90 | − return sys; | |
| 91 | − return sys >> 1; | |
| 91 | + return sys / 3; | |
| 92 | + else | |
| 93 | + return sys / 2; | |
| 92 | 94 | } |
| 93 | 95 | |
| 94 | 96 | unsigned long ltq_ar9_cpu_hz(void) |
| @@ -104,7 +106,7 @@ unsigned long ltq_vr9_cpu_hz(void) · 9 unmodified lines | ||
| 104 | 106 | unsigned int cpu_sel; |
| 105 | 107 | unsigned long clk; |
| 106 | 108 | |
| 107 | − cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf; | |
| 109 | + cpu_sel = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0xf; | |
| 108 | 110 | |
| 109 | 111 | switch (cpu_sel) { |
| 110 | 112 | case 0: |
| @@ -145,7 +147,7 @@ unsigned long ltq_vr9_fpi_hz(void) · 34 unmodified lines | ||
| 145 | 147 | unsigned long clk; |
| 146 | 148 | |
| 147 | 149 | cpu_clk = ltq_vr9_cpu_hz(); |
| 148 | − ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3; | |
| 150 | + ocp_sel = ltq_cgu_r32(CGU_SYS_XRX) & 0x3; | |
| 149 | 151 | |
| 150 | 152 | switch (ocp_sel) { |
| 151 | 153 | case 0: |
| @@ -174,15 +176,18 @@ unsigned long ltq_vr9_fpi_hz(void) · 22 unmodified lines | ||
| 174 | 176 | |
| 175 | 177 | unsigned long ltq_vr9_pp32_hz(void) |
| 176 | 178 | { |
| 177 | − unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3; | |
| 179 | + unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | |
| 178 | 180 | unsigned long clk; |
| 179 | 181 | |
| 180 | 182 | switch (clksys) { |
| 183 | + case 0: | |
| 184 | + clk = CLOCK_500M; | |
| 185 | + break; | |
| 181 | 186 | case 1: |
| 182 | − clk = CLOCK_450M; | |
| 187 | + clk = CLOCK_432M; | |
| 183 | 188 | break; |
| 184 | 189 | case 2: |
| 185 | − clk = CLOCK_300M; | |
| 190 | + clk = CLOCK_288M; | |
| 186 | 191 | break; |
| 187 | 192 | default: |
| 188 | 193 | clk = CLOCK_500M; |
| @@ -191,3 +196,158 @@ unsigned long ltq_vr9_pp32_hz(void) · 2 unmodified lines | ||
| 191 | 196 | |
| 192 | 197 | return clk; |
| 193 | 198 | } |
| 199 | + | |
| 200 | +unsigned long ltq_ar10_cpu_hz(void) | |
| 201 | +{ | |
| 202 | + unsigned int clksys; | |
| 203 | + int cpu_fs = (ltq_cgu_r32(CGU_SYS_XRX) >> 8) & 0x1; | |
| 204 | + int freq_div = (ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7; | |
| 205 | + | |
| 206 | + switch (cpu_fs) { | |
| 207 | + case 0: | |
| 208 | + clksys = CLOCK_500M; | |
| 209 | + break; | |
| 210 | + case 1: | |
| 211 | + clksys = CLOCK_600M; | |
| 212 | + break; | |
| 213 | + default: | |
| 214 | + clksys = CLOCK_500M; | |
| 215 | + break; | |
| 216 | + } | |
| 217 | + | |
| 218 | + switch (freq_div) { | |
| 219 | + case 0: | |
| 220 | + return clksys; | |
| 221 | + case 1: | |
| 222 | + return clksys >> 1; | |
| 223 | + case 2: | |
| 224 | + return clksys >> 2; | |
| 225 | + default: | |
| 226 | + return clksys; | |
| 227 | + } | |
| 228 | +} | |
| 229 | + | |
| 230 | +unsigned long ltq_ar10_fpi_hz(void) | |
| 231 | +{ | |
| 232 | + int freq_fpi = (ltq_cgu_r32(CGU_IF_CLK_AR10) >> 25) & 0xf; | |
| 233 | + | |
| 234 | + switch (freq_fpi) { | |
| 235 | + case 1: | |
| 236 | + return CLOCK_300M; | |
| 237 | + case 5: | |
| 238 | + return CLOCK_250M; | |
| 239 | + case 2: | |
| 240 | + return CLOCK_150M; | |
| 241 | + case 6: | |
| 242 | + return CLOCK_125M; | |
| 243 | + | |
| 244 | + default: | |
| 245 | + return CLOCK_125M; | |
| 246 | + } | |
| 247 | +} | |
| 248 | + | |
| 249 | +unsigned long ltq_ar10_pp32_hz(void) | |
| 250 | +{ | |
| 251 | + unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | |
| 252 | + unsigned long clk; | |
| 253 | + | |
| 254 | + switch (clksys) { | |
| 255 | + case 1: | |
| 256 | + clk = CLOCK_250M; | |
| 257 | + break; | |
| 258 | + case 4: | |
| 259 | + clk = CLOCK_400M; | |
| 260 | + break; | |
| 261 | + default: | |
| 262 | + clk = CLOCK_250M; | |
| 263 | + break; | |
| 264 | + } | |
| 265 | + | |
| 266 | + return clk; | |
| 267 | +} | |
| 268 | + | |
| 269 | +unsigned long ltq_grx390_cpu_hz(void) | |
| 270 | +{ | |
| 271 | + unsigned int clksys; | |
| 272 | + int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); | |
| 273 | + int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX) >> 4) & 0x7); | |
| 274 | + | |
| 275 | + switch (cpu_fs) { | |
| 276 | + case 0: | |
| 277 | + clksys = CLOCK_600M; | |
| 278 | + break; | |
| 279 | + case 1: | |
| 280 | + clksys = CLOCK_666M; | |
| 281 | + break; | |
| 282 | + case 2: | |
| 283 | + clksys = CLOCK_720M; | |
| 284 | + break; | |
| 285 | + default: | |
| 286 | + clksys = CLOCK_600M; | |
| 287 | + break; | |
| 288 | + } | |
| 289 | + | |
| 290 | + switch (freq_div) { | |
| 291 | + case 0: | |
| 292 | + return clksys; | |
| 293 | + case 1: | |
| 294 | + return clksys >> 1; | |
| 295 | + case 2: | |
| 296 | + return clksys >> 2; | |
| 297 | + default: | |
| 298 | + return clksys; | |
| 299 | + } | |
| 300 | +} | |
| 301 | + | |
| 302 | +unsigned long ltq_grx390_fpi_hz(void) | |
| 303 | +{ | |
| 304 | + /* fpi clock is derived from ddr_clk */ | |
| 305 | + unsigned int clksys; | |
| 306 | + int cpu_fs = ((ltq_cgu_r32(CGU_SYS_XRX) >> 9) & 0x3); | |
| 307 | + int freq_div = ((ltq_cgu_r32(CGU_SYS_XRX)) & 0x7); | |
| 308 | + switch (cpu_fs) { | |
| 309 | + case 0: | |
| 310 | + clksys = CLOCK_600M; | |
| 311 | + break; | |
| 312 | + case 1: | |
| 313 | + clksys = CLOCK_666M; | |
| 314 | + break; | |
| 315 | + case 2: | |
| 316 | + clksys = CLOCK_720M; | |
| 317 | + break; | |
| 318 | + default: | |
| 319 | + clksys = CLOCK_600M; | |
| 320 | + break; | |
| 321 | + } | |
| 322 | + | |
| 323 | + switch (freq_div) { | |
| 324 | + case 1: | |
| 325 | + return clksys >> 1; | |
| 326 | + case 2: | |
| 327 | + return clksys >> 2; | |
| 328 | + default: | |
| 329 | + return clksys >> 1; | |
| 330 | + } | |
| 331 | +} | |
| 332 | + | |
| 333 | +unsigned long ltq_grx390_pp32_hz(void) | |
| 334 | +{ | |
| 335 | + unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 0x7; | |
| 336 | + unsigned long clk; | |
| 337 | + | |
| 338 | + switch (clksys) { | |
| 339 | + case 1: | |
| 340 | + clk = CLOCK_250M; | |
| 341 | + break; | |
| 342 | + case 2: | |
| 343 | + clk = CLOCK_432M; | |
| 344 | + break; | |
| 345 | + case 4: | |
| 346 | + clk = CLOCK_400M; | |
| 347 | + break; | |
| 348 | + default: | |
| 349 | + clk = CLOCK_250M; | |
| 350 | + break; | |
| 351 | + } | |
| 352 | + return clk; | |
| 353 | +} | |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * by the Free Software Foundation. |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> |
| 7 | + * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | |
| 7 | 8 | */ |
| 8 | 9 | |
| 9 | 10 | #include <linux/export.h> |
| @@ -19,8 +20,11 @@ · 9 unmodified lines | ||
| 19 | 20 | #define SOC_TWINPASS "Twinpass" |
| 20 | 21 | #define SOC_AMAZON_SE "Amazon_SE" |
| 21 | 22 | #define SOC_AR9 "AR9" |
| 22 | −#define SOC_GR9 "GR9" | |
| 23 | −#define SOC_VR9 "VR9" | |
| 23 | +#define SOC_GR9 "GRX200" | |
| 24 | +#define SOC_VR9 "xRX200" | |
| 25 | +#define SOC_VRX220 "xRX220" | |
| 26 | +#define SOC_AR10 "xRX300" | |
| 27 | +#define SOC_GRX390 "xRX330" | |
| 24 | 28 | |
| 25 | 29 | #define COMP_DANUBE "lantiq,danube" |
| 26 | 30 | #define COMP_TWINPASS "lantiq,twinpass" |
| @@ -28,6 +32,8 @@ · 1 unmodified line | ||
| 28 | 32 | #define COMP_AR9 "lantiq,ar9" |
| 29 | 33 | #define COMP_GR9 "lantiq,gr9" |
| 30 | 34 | #define COMP_VR9 "lantiq,vr9" |
| 35 | +#define COMP_AR10 "lantiq,ar10" | |
| 36 | +#define COMP_GRX390 "lantiq,grx390" | |
| 31 | 37 | |
| 32 | 38 | #define PART_SHIFT 12 |
| 33 | 39 | #define PART_MASK 0x0FFFFFFF |
| @@ -101,6 +107,12 @@ void __init ltq_soc_detect(struct ltq_soc_info *i) · 67 unmodified lines | ||
| 101 | 107 | i->compatible = COMP_VR9; |
| 102 | 108 | break; |
| 103 | 109 | |
| 110 | + case SOC_ID_VRX220: | |
| 111 | + i->name = SOC_VRX220; | |
| 112 | + i->type = SOC_TYPE_VRX220; | |
| 113 | + i->compatible = COMP_VR9; | |
| 114 | + break; | |
| 115 | + | |
| 104 | 116 | case SOC_ID_GRX282_2: |
| 105 | 117 | case SOC_ID_GRX288_2: |
| 106 | 118 | i->name = SOC_GR9; |
| @@ -108,6 +120,25 @@ void __init ltq_soc_detect(struct ltq_soc_info *i) · 1 unmodified line | ||
| 108 | 120 | i->compatible = COMP_GR9; |
| 109 | 121 | break; |
| 110 | 122 | |
| 123 | + case SOC_ID_ARX362: | |
| 124 | + case SOC_ID_ARX368: | |
| 125 | + case SOC_ID_ARX382: | |
| 126 | + case SOC_ID_ARX388: | |
| 127 | + case SOC_ID_URX388: | |
| 128 | + i->name = SOC_AR10; | |
| 129 | + i->type = SOC_TYPE_AR10; | |
| 130 | + i->compatible = COMP_AR10; | |
| 131 | + break; | |
| 132 | + | |
| 133 | + case SOC_ID_GRX383: | |
| 134 | + case SOC_ID_GRX369: | |
| 135 | + case SOC_ID_GRX387: | |
| 136 | + case SOC_ID_GRX389: | |
| 137 | + i->name = SOC_GRX390; | |
| 138 | + i->type = SOC_TYPE_GRX390; | |
| 139 | + i->compatible = COMP_GRX390; | |
| 140 | + break; | |
| 141 | + | |
| 111 | 142 | default: |
| 112 | 143 | unreachable(); |
| 113 | 144 | break; |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * by the Free Software Foundation. |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> |
| 7 | + * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | |
| 7 | 8 | */ |
| 8 | 9 | |
| 9 | 10 | #include <linux/init.h> |
| @@ -22,9 +23,6 @@ · 12 unmodified lines | ||
| 22 | 23 | |
| 23 | 24 | #include "../prom.h" |
| 24 | 25 | |
| 25 | −#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) | |
| 26 | −#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) | |
| 27 | − | |
| 28 | 26 | /* reset request register */ |
| 29 | 27 | #define RCU_RST_REQ 0x0010 |
| 30 | 28 | /* reset status register */ |
| @@ -32,11 +30,33 @@ · 1 unmodified line | ||
| 32 | 30 | /* vr9 gphy registers */ |
| 33 | 31 | #define RCU_GFS_ADD0_XRX200 0x0020 |
| 34 | 32 | #define RCU_GFS_ADD1_XRX200 0x0068 |
| 33 | +/* xRX300 gphy registers */ | |
| 34 | +#define RCU_GFS_ADD0_XRX300 0x0020 | |
| 35 | +#define RCU_GFS_ADD1_XRX300 0x0058 | |
| 36 | +#define RCU_GFS_ADD2_XRX300 0x00AC | |
| 37 | +/* xRX330 gphy registers */ | |
| 38 | +#define RCU_GFS_ADD0_XRX330 0x0020 | |
| 39 | +#define RCU_GFS_ADD1_XRX330 0x0058 | |
| 40 | +#define RCU_GFS_ADD2_XRX330 0x00AC | |
| 41 | +#define RCU_GFS_ADD3_XRX330 0x0264 | |
| 42 | + | |
| 43 | +/* xbar BE flag */ | |
| 44 | +#define RCU_AHB_ENDIAN 0x004C | |
| 45 | +#define RCU_VR9_BE_AHB1S 0x00000008 | |
| 35 | 46 | |
| 36 | 47 | /* reboot bit */ |
| 37 | 48 | #define RCU_RD_GPHY0_XRX200 BIT(31) |
| 38 | 49 | #define RCU_RD_SRST BIT(30) |
| 39 | 50 | #define RCU_RD_GPHY1_XRX200 BIT(29) |
| 51 | +/* xRX300 bits */ | |
| 52 | +#define RCU_RD_GPHY0_XRX300 BIT(31) | |
| 53 | +#define RCU_RD_GPHY1_XRX300 BIT(29) | |
| 54 | +#define RCU_RD_GPHY2_XRX300 BIT(28) | |
| 55 | +/* xRX330 bits */ | |
| 56 | +#define RCU_RD_GPHY0_XRX330 BIT(31) | |
| 57 | +#define RCU_RD_GPHY1_XRX330 BIT(29) | |
| 58 | +#define RCU_RD_GPHY2_XRX330 BIT(28) | |
| 59 | +#define RCU_RD_GPHY3_XRX330 BIT(10) | |
| 40 | 60 | |
| 41 | 61 | /* reset cause */ |
| 42 | 62 | #define RCU_STAT_SHIFT 26 |
| @@ -44,9 +64,60 @@ · 1 unmodified line | ||
| 44 | 64 | #define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) |
| 45 | 65 | #define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) |
| 46 | 66 | |
| 67 | +/* dwc2 USB configuration registers */ | |
| 68 | +#define RCU_USB1CFG 0x0018 | |
| 69 | +#define RCU_USB2CFG 0x0034 | |
| 70 | + | |
| 71 | +/* USB DMA endianness bits */ | |
| 72 | +#define RCU_USBCFG_HDSEL_BIT BIT(11) | |
| 73 | +#define RCU_USBCFG_HOST_END_BIT BIT(10) | |
| 74 | +#define RCU_USBCFG_SLV_END_BIT BIT(9) | |
| 75 | + | |
| 76 | +/* USB reset bits */ | |
| 77 | +#define RCU_USBRESET 0x0010 | |
| 78 | + | |
| 79 | +#define USBRESET_BIT BIT(4) | |
| 80 | + | |
| 81 | +#define RCU_USBRESET2 0x0048 | |
| 82 | + | |
| 83 | +#define USB1RESET_BIT BIT(4) | |
| 84 | +#define USB2RESET_BIT BIT(5) | |
| 85 | + | |
| 86 | +#define RCU_CFG1A 0x0038 | |
| 87 | +#define RCU_CFG1B 0x003C | |
| 88 | + | |
| 89 | +/* USB PMU devices */ | |
| 90 | +#define PMU_AHBM BIT(15) | |
| 91 | +#define PMU_USB0 BIT(6) | |
| 92 | +#define PMU_USB1 BIT(27) | |
| 93 | + | |
| 94 | +/* USB PHY PMU devices */ | |
| 95 | +#define PMU_USB0_P BIT(0) | |
| 96 | +#define PMU_USB1_P BIT(26) | |
| 97 | + | |
| 47 | 98 | /* remapped base addr of the reset control unit */ |
| 48 | 99 | static void __iomem *ltq_rcu_membase; |
| 49 | 100 | static struct device_node *ltq_rcu_np; |
| 101 | +static DEFINE_SPINLOCK(ltq_rcu_lock); | |
| 102 | + | |
| 103 | +static void ltq_rcu_w32(uint32_t val, uint32_t reg_off) | |
| 104 | +{ | |
| 105 | + ltq_w32(val, ltq_rcu_membase + reg_off); | |
| 106 | +} | |
| 107 | + | |
| 108 | +static uint32_t ltq_rcu_r32(uint32_t reg_off) | |
| 109 | +{ | |
| 110 | + return ltq_r32(ltq_rcu_membase + reg_off); | |
| 111 | +} | |
| 112 | + | |
| 113 | +static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off) | |
| 114 | +{ | |
| 115 | + unsigned long flags; | |
| 116 | + | |
| 117 | + spin_lock_irqsave(<q_rcu_lock, flags); | |
| 118 | + ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off); | |
| 119 | + spin_unlock_irqrestore(<q_rcu_lock, flags); | |
| 120 | +} | |
| 50 | 121 | |
| 51 | 122 | /* This function is used by the watchdog driver */ |
| 52 | 123 | int ltq_reset_cause(void) |
| @@ -67,15 +138,40 @@ unsigned char ltq_boot_select(void) · 14 unmodified lines | ||
| 67 | 138 | return RCU_BOOT_SEL(val); |
| 68 | 139 | } |
| 69 | 140 | |
| 70 | −/* reset / boot a gphy */ | |
| 71 | −static struct ltq_xrx200_gphy_reset { | |
| 141 | +struct ltq_gphy_reset { | |
| 72 | 142 | u32 rd; |
| 73 | 143 | u32 addr; |
| 74 | −} xrx200_gphy[] = { | |
| 144 | +}; | |
| 145 | + | |
| 146 | +/* reset / boot a gphy */ | |
| 147 | +static struct ltq_gphy_reset xrx200_gphy[] = { | |
| 75 | 148 | {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200}, |
| 76 | 149 | {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200}, |
| 77 | 150 | }; |
| 78 | 151 | |
| 152 | +/* reset / boot a gphy */ | |
| 153 | +static struct ltq_gphy_reset xrx300_gphy[] = { | |
| 154 | + {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300}, | |
| 155 | + {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300}, | |
| 156 | + {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300}, | |
| 157 | +}; | |
| 158 | + | |
| 159 | +/* reset / boot a gphy */ | |
| 160 | +static struct ltq_gphy_reset xrx330_gphy[] = { | |
| 161 | + {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330}, | |
| 162 | + {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330}, | |
| 163 | + {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330}, | |
| 164 | + {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330}, | |
| 165 | +}; | |
| 166 | + | |
| 167 | +static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs, | |
| 168 | + dma_addr_t dev_addr) | |
| 169 | +{ | |
| 170 | + ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ); | |
| 171 | + ltq_rcu_w32(dev_addr, phy_regs->addr); | |
| 172 | + ltq_rcu_w32_mask(phy_regs->rd, 0, RCU_RST_REQ); | |
| 173 | +} | |
| 174 | + | |
| 79 | 175 | /* reset and boot a gphy. these phys only exist on xrx200 SoC */ |
| 80 | 176 | int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) |
| 81 | 177 | { |
| @@ -86,23 +182,34 @@ int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) · 4 unmodified lines | ||
| 86 | 182 | return -EINVAL; |
| 87 | 183 | } |
| 88 | 184 | |
| 89 | − clk = clk_get_sys("1f203000.rcu", "gphy"); | |
| 90 | − if (IS_ERR(clk)) | |
| 91 | − return PTR_ERR(clk); | |
| 92 | − | |
| 93 | − clk_enable(clk); | |
| 94 | − | |
| 95 | − if (id > 1) { | |
| 96 | − dev_err(dev, "%u is an invalid gphy id\n", id); | |
| 97 | − return -EINVAL; | |
| 185 | + if (of_machine_is_compatible("lantiq,vr9")) { | |
| 186 | + clk = clk_get_sys("1f203000.rcu", "gphy"); | |
| 187 | + if (IS_ERR(clk)) | |
| 188 | + return PTR_ERR(clk); | |
| 189 | + clk_enable(clk); | |
| 98 | 190 | } |
| 191 | + | |
| 99 | 192 | dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); |
| 100 | 193 | |
| 101 | − ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd, | |
| 102 | − RCU_RST_REQ); | |
| 103 | − ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); | |
| 104 | − ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd, | |
| 105 | − RCU_RST_REQ); | |
| 194 | + if (of_machine_is_compatible("lantiq,vr9")) { | |
| 195 | + if (id >= ARRAY_SIZE(xrx200_gphy)) { | |
| 196 | + dev_err(dev, "%u is an invalid gphy id\n", id); | |
| 197 | + return -EINVAL; | |
| 198 | + } | |
| 199 | + xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr); | |
| 200 | + } else if (of_machine_is_compatible("lantiq,ar10")) { | |
| 201 | + if (id >= ARRAY_SIZE(xrx300_gphy)) { | |
| 202 | + dev_err(dev, "%u is an invalid gphy id\n", id); | |
| 203 | + return -EINVAL; | |
| 204 | + } | |
| 205 | + xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr); | |
| 206 | + } else if (of_machine_is_compatible("lantiq,grx390")) { | |
| 207 | + if (id >= ARRAY_SIZE(xrx330_gphy)) { | |
| 208 | + dev_err(dev, "%u is an invalid gphy id\n", id); | |
| 209 | + return -EINVAL; | |
| 210 | + } | |
| 211 | + xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr); | |
| 212 | + } | |
| 106 | 213 | return 0; |
| 107 | 214 | } |
| 108 | 215 | |
| @@ -200,6 +307,45 @@ static void ltq_machine_power_off(void) · 91 unmodified lines | ||
| 200 | 307 | unreachable(); |
| 201 | 308 | } |
| 202 | 309 | |
| 310 | +static void ltq_usb_init(void) | |
| 311 | +{ | |
| 312 | + /* Power for USB cores 1 & 2 */ | |
| 313 | + ltq_pmu_enable(PMU_AHBM); | |
| 314 | + ltq_pmu_enable(PMU_USB0); | |
| 315 | + ltq_pmu_enable(PMU_USB1); | |
| 316 | + | |
| 317 | + ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A); | |
| 318 | + ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B); | |
| 319 | + | |
| 320 | + /* Enable USB PHY power for cores 1 & 2 */ | |
| 321 | + ltq_pmu_enable(PMU_USB0_P); | |
| 322 | + ltq_pmu_enable(PMU_USB1_P); | |
| 323 | + | |
| 324 | + /* Configure cores to host mode */ | |
| 325 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT, | |
| 326 | + RCU_USB1CFG); | |
| 327 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT, | |
| 328 | + RCU_USB2CFG); | |
| 329 | + | |
| 330 | + /* Select DMA endianness (Host-endian: big-endian) */ | |
| 331 | + ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT) | |
| 332 | + | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG); | |
| 333 | + ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT) | |
| 334 | + | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG); | |
| 335 | + | |
| 336 | + /* Hard reset USB state machines */ | |
| 337 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET); | |
| 338 | + udelay(50 * 1000); | |
| 339 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET); | |
| 340 | + | |
| 341 | + /* Soft reset USB state machines */ | |
| 342 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) | |
| 343 | + | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2); | |
| 344 | + udelay(50 * 1000); | |
| 345 | + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) | |
| 346 | + & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2); | |
| 347 | +} | |
| 348 | + | |
| 203 | 349 | static int __init mips_reboot_setup(void) |
| 204 | 350 | { |
| 205 | 351 | struct resource res; |
| @@ -216,13 +362,21 @@ static int __init mips_reboot_setup(void) · 10 unmodified lines | ||
| 216 | 362 | if (of_address_to_resource(ltq_rcu_np, 0, &res)) |
| 217 | 363 | panic("Failed to get rcu memory range"); |
| 218 | 364 | |
| 219 | − if (request_mem_region(res.start, resource_size(&res), res.name) < 0) | |
| 365 | + if (!request_mem_region(res.start, resource_size(&res), res.name)) | |
| 220 | 366 | pr_err("Failed to request rcu memory"); |
| 221 | 367 | |
| 222 | 368 | ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res)); |
| 223 | 369 | if (!ltq_rcu_membase) |
| 224 | 370 | panic("Failed to remap core memory"); |
| 225 | 371 | |
| 372 | + if (of_machine_is_compatible("lantiq,ar9") || | |
| 373 | + of_machine_is_compatible("lantiq,vr9")) | |
| 374 | + ltq_usb_init(); | |
| 375 | + | |
| 376 | + if (of_machine_is_compatible("lantiq,vr9")) | |
| 377 | + ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S, | |
| 378 | + RCU_AHB_ENDIAN); | |
| 379 | + | |
| 226 | 380 | _machine_restart = ltq_machine_restart; |
| 227 | 381 | _machine_halt = ltq_machine_halt; |
| 228 | 382 | pm_power_off = ltq_machine_power_off; |
| @@ -4,11 +4,13 @@ · 3 unmodified lines | ||
| 4 | 4 | * by the Free Software Foundation. |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org> |
| 7 | + * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG | |
| 7 | 8 | */ |
| 8 | 9 | |
| 9 | 10 | #include <linux/ioport.h> |
| 10 | 11 | #include <linux/export.h> |
| 11 | 12 | #include <linux/clkdev.h> |
| 13 | +#include <linux/spinlock.h> | |
| 12 | 14 | #include <linux/of.h> |
| 13 | 15 | #include <linux/of_platform.h> |
| 14 | 16 | #include <linux/of_address.h> |
| @@ -18,16 +20,18 @@ · 3 unmodified lines | ||
| 18 | 20 | #include "../clk.h" |
| 19 | 21 | #include "../prom.h" |
| 20 | 22 | |
| 21 | −/* clock control register */ | |
| 23 | +/* clock control register for legacy */ | |
| 22 | 24 | #define CGU_IFCCR 0x0018 |
| 23 | 25 | #define CGU_IFCCR_VR9 0x0024 |
| 24 | −/* system clock register */ | |
| 26 | +/* system clock register for legacy */ | |
| 25 | 27 | #define CGU_SYS 0x0010 |
| 26 | 28 | /* pci control register */ |
| 27 | 29 | #define CGU_PCICR 0x0034 |
| 28 | 30 | #define CGU_PCICR_VR9 0x0038 |
| 29 | 31 | /* ephy configuration register */ |
| 30 | 32 | #define CGU_EPHY 0x10 |
| 33 | + | |
| 34 | +/* Legacy PMU register for ar9, ase, danube */ | |
| 31 | 35 | /* power control register */ |
| 32 | 36 | #define PMU_PWDCR 0x1C |
| 33 | 37 | /* power status register */ |
| @@ -41,13 +45,56 @@ · 7 unmodified lines | ||
| 41 | 45 | /* power status register */ |
| 42 | 46 | #define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR)) |
| 43 | 47 | |
| 48 | + | |
| 49 | +/* PMU register for ar10 and grx390 */ | |
| 50 | + | |
| 51 | +/* First register set */ | |
| 52 | +#define PMU_CLK_SR 0x20 /* status */ | |
| 53 | +#define PMU_CLK_CR_A 0x24 /* Enable */ | |
| 54 | +#define PMU_CLK_CR_B 0x28 /* Disable */ | |
| 55 | +/* Second register set */ | |
| 56 | +#define PMU_CLK_SR1 0x30 /* status */ | |
| 57 | +#define PMU_CLK_CR1_A 0x34 /* Enable */ | |
| 58 | +#define PMU_CLK_CR1_B 0x38 /* Disable */ | |
| 59 | +/* Third register set */ | |
| 60 | +#define PMU_ANA_SR 0x40 /* status */ | |
| 61 | +#define PMU_ANA_CR_A 0x44 /* Enable */ | |
| 62 | +#define PMU_ANA_CR_B 0x48 /* Disable */ | |
| 63 | + | |
| 64 | +/* Status */ | |
| 65 | +static u32 pmu_clk_sr[] = { | |
| 66 | + PMU_CLK_SR, | |
| 67 | + PMU_CLK_SR1, | |
| 68 | + PMU_ANA_SR, | |
| 69 | +}; | |
| 70 | + | |
| 71 | +/* Enable */ | |
| 72 | +static u32 pmu_clk_cr_a[] = { | |
| 73 | + PMU_CLK_CR_A, | |
| 74 | + PMU_CLK_CR1_A, | |
| 75 | + PMU_ANA_CR_A, | |
| 76 | +}; | |
| 77 | + | |
| 78 | +/* Disable */ | |
| 79 | +static u32 pmu_clk_cr_b[] = { | |
| 80 | + PMU_CLK_CR_B, | |
| 81 | + PMU_CLK_CR1_B, | |
| 82 | + PMU_ANA_CR_B, | |
| 83 | +}; | |
| 84 | + | |
| 85 | +#define PWDCR_EN_XRX(x) (pmu_clk_cr_a[(x)]) | |
| 86 | +#define PWDCR_DIS_XRX(x) (pmu_clk_cr_b[(x)]) | |
| 87 | +#define PWDSR_XRX(x) (pmu_clk_sr[(x)]) | |
| 88 | + | |
| 44 | 89 | /* clock gates that we can en/disable */ |
| 45 | 90 | #define PMU_USB0_P BIT(0) |
| 91 | +#define PMU_ASE_SDIO BIT(2) /* ASE special */ | |
| 46 | 92 | #define PMU_PCI BIT(4) |
| 47 | 93 | #define PMU_DMA BIT(5) |
| 48 | 94 | #define PMU_USB0 BIT(6) |
| 49 | 95 | #define PMU_ASC0 BIT(7) |
| 50 | 96 | #define PMU_EPHY BIT(7) /* ase */ |
| 97 | +#define PMU_USIF BIT(7) /* from vr9 until grx390 */ | |
| 51 | 98 | #define PMU_SPI BIT(8) |
| 52 | 99 | #define PMU_DFE BIT(9) |
| 53 | 100 | #define PMU_EBU BIT(10) |
| @@ -56,12 +103,15 @@ · 2 unmodified lines | ||
| 56 | 103 | #define PMU_AHBS BIT(13) /* vr9 */ |
| 57 | 104 | #define PMU_FPI BIT(14) |
| 58 | 105 | #define PMU_AHBM BIT(15) |
| 106 | +#define PMU_SDIO BIT(16) /* danube, ar9, vr9 */ | |
| 59 | 107 | #define PMU_ASC1 BIT(17) |
| 60 | 108 | #define PMU_PPE_QSB BIT(18) |
| 61 | 109 | #define PMU_PPE_SLL01 BIT(19) |
| 110 | +#define PMU_DEU BIT(20) | |
| 62 | 111 | #define PMU_PPE_TC BIT(21) |
| 63 | 112 | #define PMU_PPE_EMA BIT(22) |
| 64 | 113 | #define PMU_PPE_DPLUM BIT(23) |
| 114 | +#define PMU_PPE_DP BIT(23) | |
| 65 | 115 | #define PMU_PPE_DPLUS BIT(24) |
| 66 | 116 | #define PMU_USB1_P BIT(26) |
| 67 | 117 | #define PMU_USB1 BIT(27) |
| @@ -70,30 +120,59 @@ · 2 unmodified lines | ||
| 70 | 120 | #define PMU_GPHY BIT(30) |
| 71 | 121 | #define PMU_PCIE_CLK BIT(31) |
| 72 | 122 | |
| 73 | −#define PMU1_PCIE_PHY BIT(0) | |
| 123 | +#define PMU1_PCIE_PHY BIT(0) /* vr9-specific,moved in ar10/grx390 */ | |
| 74 | 124 | #define PMU1_PCIE_CTL BIT(1) |
| 75 | 125 | #define PMU1_PCIE_PDI BIT(4) |
| 76 | 126 | #define PMU1_PCIE_MSI BIT(5) |
| 127 | +#define PMU1_CKE BIT(6) | |
| 128 | +#define PMU1_PCIE1_CTL BIT(17) | |
| 129 | +#define PMU1_PCIE1_PDI BIT(20) | |
| 130 | +#define PMU1_PCIE1_MSI BIT(21) | |
| 131 | +#define PMU1_PCIE2_CTL BIT(25) | |
| 132 | +#define PMU1_PCIE2_PDI BIT(26) | |
| 133 | +#define PMU1_PCIE2_MSI BIT(27) | |
| 134 | + | |
| 135 | +#define PMU_ANALOG_USB0_P BIT(0) | |
| 136 | +#define PMU_ANALOG_USB1_P BIT(1) | |
| 137 | +#define PMU_ANALOG_PCIE0_P BIT(8) | |
| 138 | +#define PMU_ANALOG_PCIE1_P BIT(9) | |
| 139 | +#define PMU_ANALOG_PCIE2_P BIT(10) | |
| 140 | +#define PMU_ANALOG_DSL_AFE BIT(16) | |
| 141 | +#define PMU_ANALOG_DCDC_2V5 BIT(17) | |
| 142 | +#define PMU_ANALOG_DCDC_1VX BIT(18) | |
| 143 | +#define PMU_ANALOG_DCDC_1V0 BIT(19) | |
| 77 | 144 | |
| 78 | 145 | #define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) |
| 79 | 146 | #define pmu_r32(x) ltq_r32(pmu_membase + (x)) |
| 80 | 147 | |
| 148 | +#define XBAR_ALWAYS_LAST 0x430 | |
| 149 | +#define XBAR_FPI_BURST_EN BIT(1) | |
| 150 | +#define XBAR_AHB_BURST_EN BIT(2) | |
| 151 | + | |
| 152 | +#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y)) | |
| 153 | +#define xbar_r32(x) ltq_r32(ltq_xbar_membase + (x)) | |
| 154 | + | |
| 81 | 155 | static void __iomem *pmu_membase; |
| 156 | +static void __iomem *ltq_xbar_membase; | |
| 82 | 157 | void __iomem *ltq_cgu_membase; |
| 83 | 158 | void __iomem *ltq_ebu_membase; |
| 84 | 159 | |
| 85 | 160 | static u32 ifccr = CGU_IFCCR; |
| 86 | 161 | static u32 pcicr = CGU_PCICR; |
| 87 | 162 | |
| 163 | +static DEFINE_SPINLOCK(g_pmu_lock); | |
| 164 | + | |
| 88 | 165 | /* legacy function kept alive to ease clkdev transition */ |
| 89 | 166 | void ltq_pmu_enable(unsigned int module) |
| 90 | 167 | { |
| 91 | − int err = 1000000; | |
| 168 | + int retry = 1000000; | |
| 92 | 169 | |
| 170 | + spin_lock(&g_pmu_lock); | |
| 93 | 171 | pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR); |
| 94 | − do {} while (--err && (pmu_r32(PMU_PWDSR) & module)); | |
| 172 | + do {} while (--retry && (pmu_r32(PMU_PWDSR) & module)); | |
| 173 | + spin_unlock(&g_pmu_lock); | |
| 95 | 174 | |
| 96 | − if (!err) | |
| 175 | + if (!retry) | |
| 97 | 176 | panic("activating PMU module failed!"); |
| 98 | 177 | } |
| 99 | 178 | EXPORT_SYMBOL(ltq_pmu_enable); |
| @@ -101,7 +180,15 @@ EXPORT_SYMBOL(ltq_pmu_enable); · 1 unmodified line | ||
| 101 | 180 | /* legacy function kept alive to ease clkdev transition */ |
| 102 | 181 | void ltq_pmu_disable(unsigned int module) |
| 103 | 182 | { |
| 183 | + int retry = 1000000; | |
| 184 | + | |
| 185 | + spin_lock(&g_pmu_lock); | |
| 104 | 186 | pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR); |
| 187 | + do {} while (--retry && (!(pmu_r32(PMU_PWDSR) & module))); | |
| 188 | + spin_unlock(&g_pmu_lock); | |
| 189 | + | |
| 190 | + if (!retry) | |
| 191 | + pr_warn("deactivating PMU module failed!"); | |
| 105 | 192 | } |
| 106 | 193 | EXPORT_SYMBOL(ltq_pmu_disable); |
| 107 | 194 | |
| @@ -123,9 +210,20 @@ static int pmu_enable(struct clk *clk) · 15 unmodified lines | ||
| 123 | 210 | { |
| 124 | 211 | int retry = 1000000; |
| 125 | 212 | |
| 126 | − pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits, | |
| 127 | − PWDCR(clk->module)); | |
| 128 | − do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits)); | |
| 213 | + if (of_machine_is_compatible("lantiq,ar10") | |
| 214 | + || of_machine_is_compatible("lantiq,grx390")) { | |
| 215 | + pmu_w32(clk->bits, PWDCR_EN_XRX(clk->module)); | |
| 216 | + do {} while (--retry && | |
| 217 | + (!(pmu_r32(PWDSR_XRX(clk->module)) & clk->bits))); | |
| 218 | + | |
| 219 | + } else { | |
| 220 | + spin_lock(&g_pmu_lock); | |
| 221 | + pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits, | |
| 222 | + PWDCR(clk->module)); | |
| 223 | + do {} while (--retry && | |
| 224 | + (pmu_r32(PWDSR(clk->module)) & clk->bits)); | |
| 225 | + spin_unlock(&g_pmu_lock); | |
| 226 | + } | |
| 129 | 227 | |
| 130 | 228 | if (!retry) |
| 131 | 229 | panic("activating PMU module failed!"); |
| @@ -136,8 +234,24 @@ static int pmu_enable(struct clk *clk) · 4 unmodified lines | ||
| 136 | 234 | /* disable a clock gate */ |
| 137 | 235 | static void pmu_disable(struct clk *clk) |
| 138 | 236 | { |
| 139 | − pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits, | |
| 140 | − PWDCR(clk->module)); | |
| 237 | + int retry = 1000000; | |
| 238 | + | |
| 239 | + if (of_machine_is_compatible("lantiq,ar10") | |
| 240 | + || of_machine_is_compatible("lantiq,grx390")) { | |
| 241 | + pmu_w32(clk->bits, PWDCR_DIS_XRX(clk->module)); | |
| 242 | + do {} while (--retry && | |
| 243 | + (pmu_r32(PWDSR_XRX(clk->module)) & clk->bits)); | |
| 244 | + } else { | |
| 245 | + spin_lock(&g_pmu_lock); | |
| 246 | + pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits, | |
| 247 | + PWDCR(clk->module)); | |
| 248 | + do {} while (--retry && | |
| 249 | + (!(pmu_r32(PWDSR(clk->module)) & clk->bits))); | |
| 250 | + spin_unlock(&g_pmu_lock); | |
| 251 | + } | |
| 252 | + | |
| 253 | + if (!retry) | |
| 254 | + pr_warn("deactivating PMU module failed!"); | |
| 141 | 255 | } |
| 142 | 256 | |
| 143 | 257 | /* the pci enable helper */ |
| @@ -179,6 +293,16 @@ static void pci_ext_disable(struct clk *clk) · 35 unmodified lines | ||
| 179 | 293 | ltq_cgu_w32((1 << 31) | (1 << 30), pcicr); |
| 180 | 294 | } |
| 181 | 295 | |
| 296 | +static void xbar_fpi_burst_disable(void) | |
| 297 | +{ | |
| 298 | + u32 reg; | |
| 299 | + | |
| 300 | + /* bit 1 as 1 --burst; bit 1 as 0 -- single */ | |
| 301 | + reg = xbar_r32(XBAR_ALWAYS_LAST); | |
| 302 | + reg &= ~XBAR_FPI_BURST_EN; | |
| 303 | + xbar_w32(reg, XBAR_ALWAYS_LAST); | |
| 304 | +} | |
| 305 | + | |
| 182 | 306 | /* enable a clockout source */ |
| 183 | 307 | static int clkout_enable(struct clk *clk) |
| 184 | 308 | { |
| @@ -202,8 +326,8 @@ static int clkout_enable(struct clk *clk) · 17 unmodified lines | ||
| 202 | 326 | } |
| 203 | 327 | |
| 204 | 328 | /* manage the clock gates via PMU */ |
| 205 | −static void clkdev_add_pmu(const char *dev, const char *con, | |
| 206 | − unsigned int module, unsigned int bits) | |
| 329 | +static void clkdev_add_pmu(const char *dev, const char *con, bool deactivate, | |
| 330 | + unsigned int module, unsigned int bits) | |
| 207 | 331 | { |
| 208 | 332 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); |
| 209 | 333 | |
| @@ -214,6 +338,13 @@ static void clkdev_add_pmu(const char *dev, const char *con, · 4 unmodified lines | ||
| 214 | 338 | clk->disable = pmu_disable; |
| 215 | 339 | clk->module = module; |
| 216 | 340 | clk->bits = bits; |
| 341 | + if (deactivate) { | |
| 342 | + /* | |
| 343 | + * Disable it during the initialization. Module should enable | |
| 344 | + * when used | |
| 345 | + */ | |
| 346 | + pmu_disable(clk); | |
| 347 | + } | |
| 217 | 348 | clkdev_add(&clk->cl); |
| 218 | 349 | } |
| 219 | 350 | |
| @@ -312,12 +443,12 @@ void __init ltq_soc_init(void) · 92 unmodified lines | ||
| 312 | 443 | of_address_to_resource(np_ebu, 0, &res_ebu)) |
| 313 | 444 | panic("Failed to get core resources"); |
| 314 | 445 | |
| 315 | − if ((request_mem_region(res_pmu.start, resource_size(&res_pmu), | |
| 316 | − res_pmu.name) < 0) || | |
| 317 | − (request_mem_region(res_cgu.start, resource_size(&res_cgu), | |
| 318 | − res_cgu.name) < 0) || | |
| 319 | − (request_mem_region(res_ebu.start, resource_size(&res_ebu), | |
| 320 | − res_ebu.name) < 0)) | |
| 446 | + if (!request_mem_region(res_pmu.start, resource_size(&res_pmu), | |
| 447 | + res_pmu.name) || | |
| 448 | + !request_mem_region(res_cgu.start, resource_size(&res_cgu), | |
| 449 | + res_cgu.name) || | |
| 450 | + !request_mem_region(res_ebu.start, resource_size(&res_ebu), | |
| 451 | + res_ebu.name)) | |
| 321 | 452 | pr_err("Failed to request core resources"); |
| 322 | 453 | |
| 323 | 454 | pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu)); |
| @@ -328,17 +459,37 @@ void __init ltq_soc_init(void) · 4 unmodified lines | ||
| 328 | 459 | if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) |
| 329 | 460 | panic("Failed to remap core resources"); |
| 330 | 461 | |
| 462 | + if (of_machine_is_compatible("lantiq,vr9")) { | |
| 463 | + struct resource res_xbar; | |
| 464 | + struct device_node *np_xbar = | |
| 465 | + of_find_compatible_node(NULL, NULL, | |
| 466 | + "lantiq,xbar-xway"); | |
| 467 | + | |
| 468 | + if (!np_xbar) | |
| 469 | + panic("Failed to load xbar nodes from devicetree"); | |
| 470 | + if (of_address_to_resource(np_pmu, 0, &res_xbar)) | |
| 471 | + panic("Failed to get xbar resources"); | |
| 472 | + if (request_mem_region(res_xbar.start, resource_size(&res_xbar), | |
| 473 | + res_xbar.name) < 0) | |
| 474 | + panic("Failed to get xbar resources"); | |
| 475 | + | |
| 476 | + ltq_xbar_membase = ioremap_nocache(res_xbar.start, | |
| 477 | + resource_size(&res_xbar)); | |
| 478 | + if (!ltq_xbar_membase) | |
| 479 | + panic("Failed to remap xbar resources"); | |
| 480 | + } | |
| 481 | + | |
| 331 | 482 | /* make sure to unprotect the memory region where flash is located */ |
| 332 | 483 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); |
| 333 | 484 | |
| 334 | 485 | /* add our generic xway clocks */ |
| 335 | − clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI); | |
| 336 | − clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0); | |
| 337 | − clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT); | |
| 338 | − clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP); | |
| 339 | − clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA); | |
| 340 | − clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI); | |
| 341 | − clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU); | |
| 486 | + clkdev_add_pmu("10000000.fpi", NULL, 0, 0, PMU_FPI); | |
| 487 | + clkdev_add_pmu("1e100400.serial", NULL, 0, 0, PMU_ASC0); | |
| 488 | + clkdev_add_pmu("1e100a00.gptu", NULL, 1, 0, PMU_GPT); | |
| 489 | + clkdev_add_pmu("1e100bb0.stp", NULL, 1, 0, PMU_STP); | |
| 490 | + clkdev_add_pmu("1e104100.dma", NULL, 1, 0, PMU_DMA); | |
| 491 | + clkdev_add_pmu("1e100800.spi", NULL, 1, 0, PMU_SPI); | |
| 492 | + clkdev_add_pmu("1e105300.ebu", NULL, 0, 0, PMU_EBU); | |
| 342 | 493 | clkdev_add_clkout(); |
| 343 | 494 | |
| 344 | 495 | /* add the soc dependent clocks */ |
| @@ -346,14 +497,30 @@ void __init ltq_soc_init(void) · 1 unmodified line | ||
| 346 | 497 | ifccr = CGU_IFCCR_VR9; |
| 347 | 498 | pcicr = CGU_PCICR_VR9; |
| 348 | 499 | } else { |
| 349 | − clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE); | |
| 500 | + clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE); | |
| 350 | 501 | } |
| 351 | 502 | |
| 352 | 503 | if (!of_machine_is_compatible("lantiq,ase")) { |
| 353 | − clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1); | |
| 504 | + clkdev_add_pmu("1e100c00.serial", NULL, 0, 0, PMU_ASC1); | |
| 354 | 505 | clkdev_add_pci(); |
| 355 | 506 | } |
| 356 | 507 | |
| 508 | + if (of_machine_is_compatible("lantiq,grx390") || | |
| 509 | + of_machine_is_compatible("lantiq,ar10")) { | |
| 510 | + clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P); | |
| 511 | + clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P); | |
| 512 | + /* rc 0 */ | |
| 513 | + clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); | |
| 514 | + clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); | |
| 515 | + clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); | |
| 516 | + clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); | |
| 517 | + /* rc 1 */ | |
| 518 | + clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P); | |
| 519 | + clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI); | |
| 520 | + clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI); | |
| 521 | + clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL); | |
| 522 | + } | |
| 523 | + | |
| 357 | 524 | if (of_machine_is_compatible("lantiq,ase")) { |
| 358 | 525 | if (ltq_cgu_r32(CGU_SYS) & (1 << 5)) |
| 359 | 526 | clkdev_add_static(CLOCK_266M, CLOCK_133M, |
| @@ -361,28 +528,84 @@ void __init ltq_soc_init(void) · 1 unmodified line | ||
| 361 | 528 | else |
| 362 | 529 | clkdev_add_static(CLOCK_133M, CLOCK_133M, |
| 363 | 530 | CLOCK_133M, CLOCK_133M); |
| 364 | − clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY), | |
| 365 | − clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY); | |
| 531 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); | |
| 532 | + clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); | |
| 533 | + clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE); | |
| 534 | + clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY); | |
| 535 | + clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY); | |
| 536 | + clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO); | |
| 537 | + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | |
| 538 | + } else if (of_machine_is_compatible("lantiq,grx390")) { | |
| 539 | + clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(), | |
| 540 | + ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz()); | |
| 541 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); | |
| 542 | + clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); | |
| 543 | + /* rc 2 */ | |
| 544 | + clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); | |
| 545 | + clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); | |
| 546 | + clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); | |
| 547 | + clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL); | |
| 548 | + clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP); | |
| 549 | + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); | |
| 550 | + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | |
| 551 | + } else if (of_machine_is_compatible("lantiq,ar10")) { | |
| 552 | + clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(), | |
| 553 | + ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz()); | |
| 554 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); | |
| 555 | + clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); | |
| 556 | + clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | | |
| 557 | + PMU_PPE_DP | PMU_PPE_TC); | |
| 558 | + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); | |
| 559 | + clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); | |
| 560 | + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | |
| 561 | + clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); | |
| 562 | + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | |
| 366 | 563 | } else if (of_machine_is_compatible("lantiq,vr9")) { |
| 367 | 564 | clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), |
| 368 | 565 | ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz()); |
| 369 | − clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY); | |
| 370 | − clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK); | |
| 371 | − clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI); | |
| 372 | − clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); | |
| 373 | − clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); | |
| 374 | − clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); | |
| 375 | − clkdev_add_pmu("1e108000.eth", NULL, 0, | |
| 566 | + clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); | |
| 567 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM); | |
| 568 | + clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); | |
| 569 | + clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM); | |
| 570 | + clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); | |
| 571 | + clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); | |
| 572 | + clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); | |
| 573 | + clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); | |
| 574 | + clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); | |
| 575 | + clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS); | |
| 576 | + | |
| 577 | + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); | |
| 578 | + clkdev_add_pmu("1e108000.eth", NULL, 1, 0, | |
| 376 | 579 | PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | |
| 377 | 580 | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | |
| 378 | 581 | PMU_PPE_QSB | PMU_PPE_TOP); |
| 379 | − clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY); | |
| 582 | + clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); | |
| 583 | + clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | |
| 584 | + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | |
| 585 | + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | |
| 380 | 586 | } else if (of_machine_is_compatible("lantiq,ar9")) { |
| 381 | 587 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), |
| 382 | 588 | ltq_ar9_fpi_hz(), CLOCK_250M); |
| 383 | − clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH); | |
| 589 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); | |
| 590 | + clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); | |
| 591 | + clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); | |
| 592 | + clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); | |
| 593 | + clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); | |
| 594 | + clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | |
| 595 | + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | |
| 596 | + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | |
| 597 | + clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0); | |
| 384 | 598 | } else { |
| 385 | 599 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), |
| 386 | 600 | ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); |
| 601 | + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); | |
| 602 | + clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); | |
| 603 | + clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | |
| 604 | + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | |
| 605 | + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | |
| 606 | + clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0); | |
| 387 | 607 | } |
| 608 | + | |
| 609 | + if (of_machine_is_compatible("lantiq,vr9")) | |
| 610 | + xbar_fpi_burst_disable(); | |
| 388 | 611 | } |
| @@ -15,4 +15,4 @@ obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o · 14 unmodified lines | ||
| 15 | 15 | obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o |
| 16 | 16 | |
| 17 | 17 | # libgcc-style stuff needed in the kernel |
| 18 | −obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o | |
| 18 | +obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o ucmpdi2.o | |
| @@ -0,0 +1,15 @@ | ||
| 1 | +#include <linux/module.h> | |
| 2 | + | |
| 3 | +unsigned long long __bswapdi2(unsigned long long u) | |
| 4 | +{ | |
| 5 | + return (((u) & 0xff00000000000000ull) >> 56) | | |
| 6 | + (((u) & 0x00ff000000000000ull) >> 40) | | |
| 7 | + (((u) & 0x0000ff0000000000ull) >> 24) | | |
| 8 | + (((u) & 0x000000ff00000000ull) >> 8) | | |
| 9 | + (((u) & 0x00000000ff000000ull) << 8) | | |
| 10 | + (((u) & 0x0000000000ff0000ull) << 24) | | |
| 11 | + (((u) & 0x000000000000ff00ull) << 40) | | |
| 12 | + (((u) & 0x00000000000000ffull) << 56); | |
| 13 | +} | |
| 14 | + | |
| 15 | +EXPORT_SYMBOL(__bswapdi2); | |
| @@ -0,0 +1,11 @@ | ||
| 1 | +#include <linux/module.h> | |
| 2 | + | |
| 3 | +unsigned int __bswapsi2(unsigned int u) | |
| 4 | +{ | |
| 5 | + return (((u) & 0xff000000) >> 24) | | |
| 6 | + (((u) & 0x00ff0000) >> 8) | | |
| 7 | + (((u) & 0x0000ff00) << 8) | | |
| 8 | + (((u) & 0x000000ff) << 24); | |
| 9 | +} | |
| 10 | + | |
| 11 | +EXPORT_SYMBOL(__bswapsi2); | |
| @@ -120,11 +120,6 @@ config RS780_HPET · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | If unsure, say Yes. |
| 122 | 122 | |
| 123 | −config LOONGSON_SUSPEND | |
| 124 | − bool | |
| 125 | − default y | |
| 126 | − depends on CPU_SUPPORTS_CPUFREQ && SUSPEND | |
| 127 | − | |
| 128 | 123 | config LOONGSON_UART_BASE |
| 129 | 124 | bool |
| 130 | 125 | default y |
| @@ -23,7 +23,7 @@ obj-$(CONFIG_CS5536) += cs5536/ · 22 unmodified lines | ||
| 23 | 23 | # Suspend Support |
| 24 | 24 | # |
| 25 | 25 | |
| 26 | −obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o | |
| 26 | +obj-$(CONFIG_SUSPEND) += pm.o | |
| 27 | 27 | |
| 28 | 28 | # |
| 29 | 29 | # Big Memory (SWIOTLB) Support |
| @@ -8,4 +8,4 @@ obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o · 7 unmodified lines | ||
| 8 | 8 | # Suspend Support |
| 9 | 9 | # |
| 10 | 10 | |
| 11 | −obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o | |
| 11 | +obj-$(CONFIG_SUSPEND) += pm.o | |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <linux/init.h> |
| 5 | 5 | #include <linux/percpu.h> |
| 6 | 6 | #include <linux/types.h> |
| 7 | +#include <asm/debug.h> | |
| 7 | 8 | #include <asm/fpu_emulator.h> |
| 8 | 9 | #include <asm/local.h> |
| 9 | 10 | |
| @@ -27,7 +28,6 @@ static int fpuemu_stat_get(void *data, u64 *val) · 17 unmodified lines | ||
| 27 | 28 | } |
| 28 | 29 | DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); |
| 29 | 30 | |
| 30 | −extern struct dentry *mips_debugfs_dir; | |
| 31 | 31 | static int __init debugfs_fpuemu(void) |
| 32 | 32 | { |
| 33 | 33 | struct dentry *d, *dir; |
| @@ -28,3 +28,4 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o · 27 unmodified lines | ||
| 28 | 28 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o |
| 29 | 29 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o |
| 30 | 30 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o |
| 31 | +obj-$(CONFIG_SCACHE_DEBUGFS) += sc-debugfs.o | |
| @@ -0,0 +1,81 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Paul Burton <paul.burton@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <asm/bcache.h> | |
| 12 | +#include <asm/debug.h> | |
| 13 | +#include <asm/uaccess.h> | |
| 14 | +#include <linux/debugfs.h> | |
| 15 | +#include <linux/init.h> | |
| 16 | + | |
| 17 | +static ssize_t sc_prefetch_read(struct file *file, char __user *user_buf, | |
| 18 | + size_t count, loff_t *ppos) | |
| 19 | +{ | |
| 20 | + bool enabled = bc_prefetch_is_enabled(); | |
| 21 | + char buf[3]; | |
| 22 | + | |
| 23 | + buf[0] = enabled ? 'Y' : 'N'; | |
| 24 | + buf[1] = '\n'; | |
| 25 | + buf[2] = 0; | |
| 26 | + | |
| 27 | + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); | |
| 28 | +} | |
| 29 | + | |
| 30 | +static ssize_t sc_prefetch_write(struct file *file, | |
| 31 | + const char __user *user_buf, | |
| 32 | + size_t count, loff_t *ppos) | |
| 33 | +{ | |
| 34 | + char buf[32]; | |
| 35 | + ssize_t buf_size; | |
| 36 | + bool enabled; | |
| 37 | + int err; | |
| 38 | + | |
| 39 | + buf_size = min(count, sizeof(buf) - 1); | |
| 40 | + if (copy_from_user(buf, user_buf, buf_size)) | |
| 41 | + return -EFAULT; | |
| 42 | + | |
| 43 | + buf[buf_size] = '\0'; | |
| 44 | + err = strtobool(buf, &enabled); | |
| 45 | + if (err) | |
| 46 | + return err; | |
| 47 | + | |
| 48 | + if (enabled) | |
| 49 | + bc_prefetch_enable(); | |
| 50 | + else | |
| 51 | + bc_prefetch_disable(); | |
| 52 | + | |
| 53 | + return count; | |
| 54 | +} | |
| 55 | + | |
| 56 | +static const struct file_operations sc_prefetch_fops = { | |
| 57 | + .open = simple_open, | |
| 58 | + .llseek = default_llseek, | |
| 59 | + .read = sc_prefetch_read, | |
| 60 | + .write = sc_prefetch_write, | |
| 61 | +}; | |
| 62 | + | |
| 63 | +static int __init sc_debugfs_init(void) | |
| 64 | +{ | |
| 65 | + struct dentry *dir, *file; | |
| 66 | + | |
| 67 | + if (!mips_debugfs_dir) | |
| 68 | + return -ENODEV; | |
| 69 | + | |
| 70 | + dir = debugfs_create_dir("l2cache", mips_debugfs_dir); | |
| 71 | + if (IS_ERR(dir)) | |
| 72 | + return PTR_ERR(dir); | |
| 73 | + | |
| 74 | + file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir, | |
| 75 | + NULL, &sc_prefetch_fops); | |
| 76 | + if (IS_ERR(file)) | |
| 77 | + return PTR_ERR(file); | |
| 78 | + | |
| 79 | + return 0; | |
| 80 | +} | |
| 81 | +late_initcall(sc_debugfs_init); | |
| @@ -51,11 +51,69 @@ static void mips_sc_disable(void) · 50 unmodified lines | ||
| 51 | 51 | /* L2 cache is permanently enabled */ |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | +static void mips_sc_prefetch_enable(void) | |
| 55 | +{ | |
| 56 | + unsigned long pftctl; | |
| 57 | + | |
| 58 | + if (mips_cm_revision() < CM_REV_CM2_5) | |
| 59 | + return; | |
| 60 | + | |
| 61 | + /* | |
| 62 | + * If there is one or more L2 prefetch unit present then enable | |
| 63 | + * prefetching for both code & data, for all ports. | |
| 64 | + */ | |
| 65 | + pftctl = read_gcr_l2_pft_control(); | |
| 66 | + if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) { | |
| 67 | + pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; | |
| 68 | + pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; | |
| 69 | + pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; | |
| 70 | + write_gcr_l2_pft_control(pftctl); | |
| 71 | + | |
| 72 | + pftctl = read_gcr_l2_pft_control_b(); | |
| 73 | + pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; | |
| 74 | + pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; | |
| 75 | + write_gcr_l2_pft_control_b(pftctl); | |
| 76 | + } | |
| 77 | +} | |
| 78 | + | |
| 79 | +static void mips_sc_prefetch_disable(void) | |
| 80 | +{ | |
| 81 | + unsigned long pftctl; | |
| 82 | + | |
| 83 | + if (mips_cm_revision() < CM_REV_CM2_5) | |
| 84 | + return; | |
| 85 | + | |
| 86 | + pftctl = read_gcr_l2_pft_control(); | |
| 87 | + pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; | |
| 88 | + write_gcr_l2_pft_control(pftctl); | |
| 89 | + | |
| 90 | + pftctl = read_gcr_l2_pft_control_b(); | |
| 91 | + pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; | |
| 92 | + pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; | |
| 93 | + write_gcr_l2_pft_control_b(pftctl); | |
| 94 | +} | |
| 95 | + | |
| 96 | +static bool mips_sc_prefetch_is_enabled(void) | |
| 97 | +{ | |
| 98 | + unsigned long pftctl; | |
| 99 | + | |
| 100 | + if (mips_cm_revision() < CM_REV_CM2_5) | |
| 101 | + return false; | |
| 102 | + | |
| 103 | + pftctl = read_gcr_l2_pft_control(); | |
| 104 | + if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK)) | |
| 105 | + return false; | |
| 106 | + return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK); | |
| 107 | +} | |
| 108 | + | |
| 54 | 109 | static struct bcache_ops mips_sc_ops = { |
| 55 | 110 | .bc_enable = mips_sc_enable, |
| 56 | 111 | .bc_disable = mips_sc_disable, |
| 57 | 112 | .bc_wback_inv = mips_sc_wback_inv, |
| 58 | − .bc_inv = mips_sc_inv | |
| 113 | + .bc_inv = mips_sc_inv, | |
| 114 | + .bc_prefetch_enable = mips_sc_prefetch_enable, | |
| 115 | + .bc_prefetch_disable = mips_sc_prefetch_disable, | |
| 116 | + .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled, | |
| 59 | 117 | }; |
| 60 | 118 | |
| 61 | 119 | /* |
| @@ -162,13 +220,13 @@ static inline int __init mips_sc_probe(void) · 100 unmodified lines | ||
| 162 | 220 | return 0; |
| 163 | 221 | |
| 164 | 222 | tmp = (config2 >> 8) & 0x0f; |
| 165 | − if (0 <= tmp && tmp <= 7) | |
| 223 | + if (tmp <= 7) | |
| 166 | 224 | c->scache.sets = 64 << tmp; |
| 167 | 225 | else |
| 168 | 226 | return 0; |
| 169 | 227 | |
| 170 | 228 | tmp = (config2 >> 0) & 0x0f; |
| 171 | − if (0 <= tmp && tmp <= 7) | |
| 229 | + if (tmp <= 7) | |
| 172 | 230 | c->scache.ways = tmp + 1; |
| 173 | 231 | else |
| 174 | 232 | return 0; |
| @@ -186,6 +244,7 @@ int mips_sc_init(void) · 11 unmodified lines | ||
| 186 | 244 | int found = mips_sc_probe(); |
| 187 | 245 | if (found) { |
| 188 | 246 | mips_sc_enable(); |
| 247 | + mips_sc_prefetch_enable(); | |
| 189 | 248 | bcops = &mips_sc_ops; |
| 190 | 249 | } |
| 191 | 250 | return found; |
| @@ -311,6 +311,7 @@ static struct uasm_label labels[128]; · 310 unmodified lines | ||
| 311 | 311 | static struct uasm_reloc relocs[128]; |
| 312 | 312 | |
| 313 | 313 | static int check_for_high_segbits; |
| 314 | +static bool fill_includes_sw_bits; | |
| 314 | 315 | |
| 315 | 316 | static unsigned int kscratch_used_mask; |
| 316 | 317 | |
| @@ -630,8 +631,14 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l, · 313 unmodified lines | ||
| 630 | 631 | static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, |
| 631 | 632 | unsigned int reg) |
| 632 | 633 | { |
| 633 | − if (cpu_has_rixi) { | |
| 634 | − UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); | |
| 634 | + if (cpu_has_rixi && _PAGE_NO_EXEC) { | |
| 635 | + if (fill_includes_sw_bits) { | |
| 636 | + UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); | |
| 637 | + } else { | |
| 638 | + UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC)); | |
| 639 | + UASM_i_ROTR(p, reg, reg, | |
| 640 | + ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC)); | |
| 641 | + } | |
| 635 | 642 | } else { |
| 636 | 643 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 637 | 644 | uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
| @@ -1005,21 +1012,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) · 367 unmodified lines | ||
| 1005 | 1012 | * 64bit address support (36bit on a 32bit CPU) in a 32bit |
| 1006 | 1013 | * Kernel is a special case. Only a few CPUs use it. |
| 1007 | 1014 | */ |
| 1008 | −#ifdef CONFIG_PHYS_ADDR_T_64BIT | |
| 1009 | − if (cpu_has_64bits) { | |
| 1010 | − uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ | |
| 1011 | − uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ | |
| 1012 | − if (cpu_has_rixi) { | |
| 1013 | − UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); | |
| 1014 | − UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | |
| 1015 | − UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); | |
| 1016 | − } else { | |
| 1017 | − uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */ | |
| 1018 | − UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | |
| 1019 | − uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */ | |
| 1020 | − } | |
| 1021 | − UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */ | |
| 1022 | − } else { | |
| 1015 | + if (config_enabled(CONFIG_PHYS_ADDR_T_64BIT) && !cpu_has_64bits) { | |
| 1023 | 1016 | int pte_off_even = sizeof(pte_t) / 2; |
| 1024 | 1017 | int pte_off_odd = pte_off_even + sizeof(pte_t); |
| 1025 | 1018 | #ifdef CONFIG_XPA |
| @@ -1043,31 +1036,23 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) · 17 unmodified lines | ||
| 1043 | 1036 | uasm_i_mthc0(p, tmp, C0_ENTRYLO0); |
| 1044 | 1037 | uasm_i_mthc0(p, ptep, C0_ENTRYLO1); |
| 1045 | 1038 | #endif |
| 1039 | + return; | |
| 1046 | 1040 | } |
| 1047 | −#else | |
| 1041 | + | |
| 1048 | 1042 | UASM_i_LW(p, tmp, 0, ptep); /* get even pte */ |
| 1049 | 1043 | UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ |
| 1050 | 1044 | if (r45k_bvahwbug()) |
| 1051 | 1045 | build_tlb_probe_entry(p); |
| 1052 | − if (cpu_has_rixi) { | |
| 1053 | − UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); | |
| 1054 | − if (r4k_250MHZhwbug()) | |
| 1055 | − UASM_i_MTC0(p, 0, C0_ENTRYLO0); | |
| 1056 | − UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | |
| 1057 | − UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); | |
| 1058 | − } else { | |
| 1059 | − UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */ | |
| 1060 | − if (r4k_250MHZhwbug()) | |
| 1061 | − UASM_i_MTC0(p, 0, C0_ENTRYLO0); | |
| 1062 | − UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | |
| 1063 | − UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */ | |
| 1064 | − if (r45k_bvahwbug()) | |
| 1065 | − uasm_i_mfc0(p, tmp, C0_INDEX); | |
| 1066 | − } | |
| 1046 | + build_convert_pte_to_entrylo(p, tmp); | |
| 1047 | + if (r4k_250MHZhwbug()) | |
| 1048 | + UASM_i_MTC0(p, 0, C0_ENTRYLO0); | |
| 1049 | + UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | |
| 1050 | + build_convert_pte_to_entrylo(p, ptep); | |
| 1051 | + if (r45k_bvahwbug()) | |
| 1052 | + uasm_i_mfc0(p, tmp, C0_INDEX); | |
| 1067 | 1053 | if (r4k_250MHZhwbug()) |
| 1068 | 1054 | UASM_i_MTC0(p, 0, C0_ENTRYLO1); |
| 1069 | 1055 | UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */ |
| 1070 | −#endif | |
| 1071 | 1056 | } |
| 1072 | 1057 | |
| 1073 | 1058 | struct mips_huge_tlb_info { |
| @@ -2299,6 +2284,10 @@ static void config_htw_params(void) · 1225 unmodified lines | ||
| 2299 | 2284 | /* re-initialize the PTI field including the even/odd bit */ |
| 2300 | 2285 | pwfield &= ~MIPS_PWFIELD_PTI_MASK; |
| 2301 | 2286 | pwfield |= PAGE_SHIFT << MIPS_PWFIELD_PTI_SHIFT; |
| 2287 | + if (CONFIG_PGTABLE_LEVELS >= 3) { | |
| 2288 | + pwfield &= ~MIPS_PWFIELD_MDI_MASK; | |
| 2289 | + pwfield |= PMD_SHIFT << MIPS_PWFIELD_MDI_SHIFT; | |
| 2290 | + } | |
| 2302 | 2291 | /* Set the PTEI right shift */ |
| 2303 | 2292 | ptei = _PAGE_GLOBAL_SHIFT << MIPS_PWFIELD_PTEI_SHIFT; |
| 2304 | 2293 | pwfield |= ptei; |
| @@ -2320,9 +2309,11 @@ static void config_htw_params(void) · 15 unmodified lines | ||
| 2320 | 2309 | |
| 2321 | 2310 | pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT; |
| 2322 | 2311 | pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT; |
| 2312 | + if (CONFIG_PGTABLE_LEVELS >= 3) | |
| 2313 | + pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT; | |
| 2323 | 2314 | |
| 2324 | 2315 | /* If XPA has been enabled, PTEs are 64-bit in size. */ |
| 2325 | − if (read_c0_pagegrain() & PG_ELPA) | |
| 2316 | + if (config_enabled(CONFIG_64BITS) || (read_c0_pagegrain() & PG_ELPA)) | |
| 2326 | 2317 | pwsize |= 1; |
| 2327 | 2318 | |
| 2328 | 2319 | write_c0_pwsize(pwsize); |
| @@ -2360,6 +2351,41 @@ static void config_xpa_params(void) · 31 unmodified lines | ||
| 2360 | 2351 | #endif |
| 2361 | 2352 | } |
| 2362 | 2353 | |
| 2354 | +static void check_pabits(void) | |
| 2355 | +{ | |
| 2356 | + unsigned long entry; | |
| 2357 | + unsigned pabits, fillbits; | |
| 2358 | + | |
| 2359 | + if (!cpu_has_rixi || !_PAGE_NO_EXEC) { | |
| 2360 | + /* | |
| 2361 | + * We'll only be making use of the fact that we can rotate bits | |
| 2362 | + * into the fill if the CPU supports RIXI, so don't bother | |
| 2363 | + * probing this for CPUs which don't. | |
| 2364 | + */ | |
| 2365 | + return; | |
| 2366 | + } | |
| 2367 | + | |
| 2368 | + write_c0_entrylo0(~0ul); | |
| 2369 | + back_to_back_c0_hazard(); | |
| 2370 | + entry = read_c0_entrylo0(); | |
| 2371 | + | |
| 2372 | + /* clear all non-PFN bits */ | |
| 2373 | + entry &= ~((1 << MIPS_ENTRYLO_PFN_SHIFT) - 1); | |
| 2374 | + entry &= ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI); | |
| 2375 | + | |
| 2376 | + /* find a lower bound on PABITS, and upper bound on fill bits */ | |
| 2377 | + pabits = fls_long(entry) + 6; | |
| 2378 | + fillbits = max_t(int, (int)BITS_PER_LONG - pabits, 0); | |
| 2379 | + | |
| 2380 | + /* minus the RI & XI bits */ | |
| 2381 | + fillbits -= min_t(unsigned, fillbits, 2); | |
| 2382 | + | |
| 2383 | + if (fillbits >= ilog2(_PAGE_NO_EXEC)) | |
| 2384 | + fill_includes_sw_bits = true; | |
| 2385 | + | |
| 2386 | + pr_debug("Entry* registers contain %u fill bits\n", fillbits); | |
| 2387 | +} | |
| 2388 | + | |
| 2363 | 2389 | void build_tlb_refill_handler(void) |
| 2364 | 2390 | { |
| 2365 | 2391 | /* |
| @@ -2370,6 +2396,7 @@ void build_tlb_refill_handler(void) · 4 unmodified lines | ||
| 2370 | 2396 | static int run_once = 0; |
| 2371 | 2397 | |
| 2372 | 2398 | output_pgtable_bits_defines(); |
| 2399 | + check_pabits(); | |
| 2373 | 2400 | |
| 2374 | 2401 | #ifdef CONFIG_64BIT |
| 2375 | 2402 | check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3); |
| @@ -5,9 +5,18 @@ · 4 unmodified lines | ||
| 5 | 5 | # Copyright (C) 2008 Wind River Systems, Inc. |
| 6 | 6 | # written by Ralf Baechle <ralf@linux-mips.org> |
| 7 | 7 | # |
| 8 | −obj-y := malta-display.o malta-dt.o malta-init.o \ | |
| 9 | − malta-int.o malta-memory.o malta-platform.o \ | |
| 10 | − malta-reset.o malta-setup.o malta-time.o | |
| 8 | +obj-y += malta-display.o | |
| 9 | +obj-y += malta-dt.o | |
| 10 | +obj-y += malta-dtshim.o | |
| 11 | +obj-y += malta-init.o | |
| 12 | +obj-y += malta-int.o | |
| 13 | +obj-y += malta-memory.o | |
| 14 | +obj-y += malta-platform.o | |
| 15 | +obj-y += malta-reset.o | |
| 16 | +obj-y += malta-setup.o | |
| 17 | +obj-y += malta-time.o | |
| 11 | 18 | |
| 12 | 19 | obj-$(CONFIG_MIPS_CMP) += malta-amon.o |
| 13 | 20 | obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o |
| 21 | + | |
| 22 | +CFLAGS_malta-dtshim.o = -I$(src)/../../../scripts/dtc/libfdt | |
| @@ -0,0 +1,162 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Paul Burton <paul.burton@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <linux/bug.h> | |
| 12 | +#include <linux/kernel.h> | |
| 13 | +#include <linux/libfdt.h> | |
| 14 | +#include <linux/of_fdt.h> | |
| 15 | +#include <linux/sizes.h> | |
| 16 | +#include <asm/bootinfo.h> | |
| 17 | +#include <asm/fw/fw.h> | |
| 18 | +#include <asm/page.h> | |
| 19 | + | |
| 20 | +static unsigned char fdt_buf[16 << 10] __initdata; | |
| 21 | + | |
| 22 | +/* determined physical memory size, not overridden by command line args */ | |
| 23 | +extern unsigned long physical_memsize; | |
| 24 | + | |
| 25 | +#define MAX_MEM_ARRAY_ENTRIES 1 | |
| 26 | + | |
| 27 | +static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) | |
| 28 | +{ | |
| 29 | + unsigned long size_preio; | |
| 30 | + unsigned entries; | |
| 31 | + | |
| 32 | + entries = 1; | |
| 33 | + mem_array[0] = cpu_to_be32(PHYS_OFFSET); | |
| 34 | + if (config_enabled(CONFIG_EVA)) { | |
| 35 | + /* | |
| 36 | + * The current Malta EVA configuration is "special" in that it | |
| 37 | + * always makes use of addresses in the upper half of the 32 bit | |
| 38 | + * physical address map, which gives it a contiguous region of | |
| 39 | + * DDR but limits it to 2GB. | |
| 40 | + */ | |
| 41 | + mem_array[1] = cpu_to_be32(size); | |
| 42 | + } else { | |
| 43 | + size_preio = min_t(unsigned long, size, SZ_256M); | |
| 44 | + mem_array[1] = cpu_to_be32(size_preio); | |
| 45 | + } | |
| 46 | + | |
| 47 | + BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES); | |
| 48 | + return entries; | |
| 49 | +} | |
| 50 | + | |
| 51 | +static void __init append_memory(void *fdt, int root_off) | |
| 52 | +{ | |
| 53 | + __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; | |
| 54 | + unsigned long memsize; | |
| 55 | + unsigned mem_entries; | |
| 56 | + int i, err, mem_off; | |
| 57 | + char *var, param_name[10], *var_names[] = { | |
| 58 | + "ememsize", "memsize", | |
| 59 | + }; | |
| 60 | + | |
| 61 | + /* if a memory node already exists, leave it alone */ | |
| 62 | + mem_off = fdt_path_offset(fdt, "/memory"); | |
| 63 | + if (mem_off >= 0) | |
| 64 | + return; | |
| 65 | + | |
| 66 | + /* find memory size from the bootloader environment */ | |
| 67 | + for (i = 0; i < ARRAY_SIZE(var_names); i++) { | |
| 68 | + var = fw_getenv(var_names[i]); | |
| 69 | + if (!var) | |
| 70 | + continue; | |
| 71 | + | |
| 72 | + err = kstrtoul(var, 0, &physical_memsize); | |
| 73 | + if (!err) | |
| 74 | + break; | |
| 75 | + | |
| 76 | + pr_warn("Failed to read the '%s' env variable '%s'\n", | |
| 77 | + var_names[i], var); | |
| 78 | + } | |
| 79 | + | |
| 80 | + if (!physical_memsize) { | |
| 81 | + pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); | |
| 82 | + physical_memsize = 32 << 20; | |
| 83 | + } | |
| 84 | + | |
| 85 | + if (config_enabled(CONFIG_CPU_BIG_ENDIAN)) { | |
| 86 | + /* | |
| 87 | + * SOC-it swaps, or perhaps doesn't swap, when DMA'ing | |
| 88 | + * the last word of physical memory. | |
| 89 | + */ | |
| 90 | + physical_memsize -= PAGE_SIZE; | |
| 91 | + } | |
| 92 | + | |
| 93 | + /* default to using all available RAM */ | |
| 94 | + memsize = physical_memsize; | |
| 95 | + | |
| 96 | + /* allow the user to override the usable memory */ | |
| 97 | + for (i = 0; i < ARRAY_SIZE(var_names); i++) { | |
| 98 | + snprintf(param_name, sizeof(param_name), "%s=", var_names[i]); | |
| 99 | + var = strstr(arcs_cmdline, param_name); | |
| 100 | + if (!var) | |
| 101 | + continue; | |
| 102 | + | |
| 103 | + memsize = memparse(var + strlen(param_name), NULL); | |
| 104 | + } | |
| 105 | + | |
| 106 | + /* if the user says there's more RAM than we thought, believe them */ | |
| 107 | + physical_memsize = max_t(unsigned long, physical_memsize, memsize); | |
| 108 | + | |
| 109 | + /* append memory to the DT */ | |
| 110 | + mem_off = fdt_add_subnode(fdt, root_off, "memory"); | |
| 111 | + if (mem_off < 0) | |
| 112 | + panic("Unable to add memory node to DT: %d", mem_off); | |
| 113 | + | |
| 114 | + err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); | |
| 115 | + if (err) | |
| 116 | + panic("Unable to set memory node device_type: %d", err); | |
| 117 | + | |
| 118 | + mem_entries = gen_fdt_mem_array(mem_array, physical_memsize); | |
| 119 | + err = fdt_setprop(fdt, mem_off, "reg", mem_array, | |
| 120 | + mem_entries * 2 * sizeof(mem_array[0])); | |
| 121 | + if (err) | |
| 122 | + panic("Unable to set memory regs property: %d", err); | |
| 123 | + | |
| 124 | + mem_entries = gen_fdt_mem_array(mem_array, memsize); | |
| 125 | + err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array, | |
| 126 | + mem_entries * 2 * sizeof(mem_array[0])); | |
| 127 | + if (err) | |
| 128 | + panic("Unable to set linux,usable-memory property: %d", err); | |
| 129 | +} | |
| 130 | + | |
| 131 | +void __init *malta_dt_shim(void *fdt) | |
| 132 | +{ | |
| 133 | + int root_off, len, err; | |
| 134 | + const char *compat; | |
| 135 | + | |
| 136 | + if (fdt_check_header(fdt)) | |
| 137 | + panic("Corrupt DT"); | |
| 138 | + | |
| 139 | + err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); | |
| 140 | + if (err) | |
| 141 | + panic("Unable to open FDT: %d", err); | |
| 142 | + | |
| 143 | + root_off = fdt_path_offset(fdt_buf, "/"); | |
| 144 | + if (root_off < 0) | |
| 145 | + panic("No / node in DT"); | |
| 146 | + | |
| 147 | + compat = fdt_getprop(fdt_buf, root_off, "compatible", &len); | |
| 148 | + if (!compat) | |
| 149 | + panic("No root compatible property in DT: %d", len); | |
| 150 | + | |
| 151 | + /* if this isn't Malta, leave the DT alone */ | |
| 152 | + if (strncmp(compat, "mti,malta", len)) | |
| 153 | + return fdt; | |
| 154 | + | |
| 155 | + append_memory(fdt_buf, root_off); | |
| 156 | + | |
| 157 | + err = fdt_pack(fdt_buf); | |
| 158 | + if (err) | |
| 159 | + panic("Unable to pack FDT: %d\n", err); | |
| 160 | + | |
| 161 | + return fdt_buf; | |
| 162 | +} | |
| @@ -302,6 +302,7 @@ mips_pci_controller: · 301 unmodified lines | ||
| 302 | 302 | return; |
| 303 | 303 | if (!register_vsmp_smp_ops()) |
| 304 | 304 | return; |
| 305 | + register_up_smp_ops(); | |
| 305 | 306 | } |
| 306 | 307 | |
| 307 | 308 | void platform_early_l2_init(void) |
| @@ -21,147 +21,20 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <asm/sections.h> |
| 22 | 22 | #include <asm/fw/fw.h> |
| 23 | 23 | |
| 24 | −static fw_memblock_t mdesc[FW_MAX_MEMBLOCKS]; | |
| 25 | − | |
| 26 | 24 | /* determined physical memory size, not overridden by command line args */ |
| 27 | 25 | unsigned long physical_memsize = 0L; |
| 28 | 26 | |
| 29 | −fw_memblock_t * __init fw_getmdesc(int eva) | |
| 30 | −{ | |
| 31 | − char *memsize_str, *ememsize_str = NULL, *ptr; | |
| 32 | − unsigned long memsize = 0, ememsize = 0; | |
| 33 | − static char cmdline[COMMAND_LINE_SIZE] __initdata; | |
| 34 | − int tmp; | |
| 35 | − | |
| 36 | − /* otherwise look in the environment */ | |
| 37 | − | |
| 38 | − memsize_str = fw_getenv("memsize"); | |
| 39 | − if (memsize_str) { | |
| 40 | − tmp = kstrtoul(memsize_str, 0, &memsize); | |
| 41 | − if (tmp) | |
| 42 | − pr_warn("Failed to read the 'memsize' env variable.\n"); | |
| 43 | − } | |
| 44 | − if (eva) { | |
| 45 | − /* Look for ememsize for EVA */ | |
| 46 | − ememsize_str = fw_getenv("ememsize"); | |
| 47 | − if (ememsize_str) { | |
| 48 | − tmp = kstrtoul(ememsize_str, 0, &ememsize); | |
| 49 | − if (tmp) | |
| 50 | − pr_warn("Failed to read the 'ememsize' env variable.\n"); | |
| 51 | − } | |
| 52 | − } | |
| 53 | − if (!memsize && !ememsize) { | |
| 54 | − pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); | |
| 55 | − physical_memsize = 0x02000000; | |
| 56 | − } else { | |
| 57 | − if (memsize > (256 << 20)) { /* memsize should be capped to 256M */ | |
| 58 | − pr_warn("Unsupported memsize value (0x%lx) detected! " | |
| 59 | − "Using 0x10000000 (256M) instead\n", | |
| 60 | − memsize); | |
| 61 | − memsize = 256 << 20; | |
| 62 | − } | |
| 63 | − /* If ememsize is set, then set physical_memsize to that */ | |
| 64 | − physical_memsize = ememsize ? : memsize; | |
| 65 | − } | |
| 66 | − | |
| 67 | −#ifdef CONFIG_CPU_BIG_ENDIAN | |
| 68 | − /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last | |
| 69 | − word of physical memory */ | |
| 70 | − physical_memsize -= PAGE_SIZE; | |
| 71 | −#endif | |
| 72 | − | |
| 73 | − /* Check the command line for a memsize directive that overrides | |
| 74 | − the physical/default amount */ | |
| 75 | − strcpy(cmdline, arcs_cmdline); | |
| 76 | − ptr = strstr(cmdline, "memsize="); | |
| 77 | − if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
| 78 | − ptr = strstr(ptr, " memsize="); | |
| 79 | − /* And now look for ememsize */ | |
| 80 | − if (eva) { | |
| 81 | − ptr = strstr(cmdline, "ememsize="); | |
| 82 | − if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) | |
| 83 | − ptr = strstr(ptr, " ememsize="); | |
| 84 | − } | |
| 85 | − | |
| 86 | − if (ptr) | |
| 87 | − memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr); | |
| 88 | − else | |
| 89 | − memsize = physical_memsize; | |
| 90 | − | |
| 91 | − /* Last 64K for HIGHMEM arithmetics */ | |
| 92 | − if (memsize > 0x7fff0000) | |
| 93 | − memsize = 0x7fff0000; | |
| 94 | − | |
| 95 | − memset(mdesc, 0, sizeof(mdesc)); | |
| 96 | − | |
| 97 | − mdesc[0].type = fw_dontuse; | |
| 98 | − mdesc[0].base = PHYS_OFFSET; | |
| 99 | − mdesc[0].size = 0x00001000; | |
| 100 | − | |
| 101 | − mdesc[1].type = fw_code; | |
| 102 | − mdesc[1].base = mdesc[0].base + 0x00001000UL; | |
| 103 | − mdesc[1].size = 0x000ef000; | |
| 104 | − | |
| 105 | − /* | |
| 106 | − * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | |
| 107 | − * south bridge and PCI access always forwarded to the ISA Bus and | |
| 108 | − * BIOSCS# is always generated. | |
| 109 | − * This mean that this area can't be used as DMA memory for PCI | |
| 110 | − * devices. | |
| 111 | − */ | |
| 112 | − mdesc[2].type = fw_dontuse; | |
| 113 | − mdesc[2].base = mdesc[0].base + 0x000f0000UL; | |
| 114 | − mdesc[2].size = 0x00010000; | |
| 115 | − | |
| 116 | − mdesc[3].type = fw_dontuse; | |
| 117 | − mdesc[3].base = mdesc[0].base + 0x00100000UL; | |
| 118 | − mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - | |
| 119 | − 0x00100000UL; | |
| 120 | − | |
| 121 | − mdesc[4].type = fw_free; | |
| 122 | − mdesc[4].base = mdesc[0].base + CPHYSADDR(PFN_ALIGN(&_end)); | |
| 123 | − mdesc[4].size = memsize - CPHYSADDR(mdesc[4].base); | |
| 124 | − | |
| 125 | − return &mdesc[0]; | |
| 126 | −} | |
| 127 | − | |
| 128 | 27 | static void free_init_pages_eva_malta(void *begin, void *end) |
| 129 | 28 | { |
| 130 | 29 | free_init_pages("unused kernel", __pa_symbol((unsigned long *)begin), |
| 131 | 30 | __pa_symbol((unsigned long *)end)); |
| 132 | 31 | } |
| 133 | 32 | |
| 134 | −static int __init fw_memtype_classify(unsigned int type) | |
| 135 | −{ | |
| 136 | − switch (type) { | |
| 137 | − case fw_free: | |
| 138 | − return BOOT_MEM_RAM; | |
| 139 | − case fw_code: | |
| 140 | − return BOOT_MEM_ROM_DATA; | |
| 141 | − default: | |
| 142 | − return BOOT_MEM_RESERVED; | |
| 143 | − } | |
| 144 | −} | |
| 145 | − | |
| 146 | 33 | void __init fw_meminit(void) |
| 147 | 34 | { |
| 148 | − fw_memblock_t *p; | |
| 149 | − | |
| 150 | − p = fw_getmdesc(config_enabled(CONFIG_EVA)); | |
| 151 | − free_init_pages_eva = (config_enabled(CONFIG_EVA) ? | |
| 152 | − free_init_pages_eva_malta : NULL); | |
| 35 | + bool eva = config_enabled(CONFIG_EVA); | |
| 153 | 36 | |
| 154 | − while (p->size) { | |
| 155 | − long type; | |
| 156 | − unsigned long base, size; | |
| 157 | − | |
| 158 | − type = fw_memtype_classify(p->type); | |
| 159 | − base = p->base; | |
| 160 | − size = p->size; | |
| 161 | − | |
| 162 | − add_memory_region(base, size, type); | |
| 163 | − p++; | |
| 164 | − } | |
| 37 | + free_init_pages_eva = eva ? free_init_pages_eva_malta : NULL; | |
| 165 | 38 | } |
| 166 | 39 | |
| 167 | 40 | void __init prom_free_prom_memory(void) |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/time.h> |
| 28 | 28 | |
| 29 | 29 | #include <asm/fw/fw.h> |
| 30 | +#include <asm/mach-malta/malta-dtshim.h> | |
| 30 | 31 | #include <asm/mips-cm.h> |
| 31 | 32 | #include <asm/mips-boards/generic.h> |
| 32 | 33 | #include <asm/mips-boards/malta.h> |
| @@ -250,8 +251,10 @@ static void __init bonito_quirks_setup(void) · 217 unmodified lines | ||
| 250 | 251 | void __init plat_mem_setup(void) |
| 251 | 252 | { |
| 252 | 253 | unsigned int i; |
| 254 | + void *fdt = __dtb_start; | |
| 253 | 255 | |
| 254 | − __dt_setup_arch(__dtb_start); | |
| 256 | + fdt = malta_dt_shim(fdt); | |
| 257 | + __dt_setup_arch(fdt); | |
| 255 | 258 | |
| 256 | 259 | if (config_enabled(CONFIG_EVA)) |
| 257 | 260 | /* EVA has already been configured in mach-malta/kernel-init.h */ |
| @@ -87,7 +87,6 @@ void __init *xlp_dt_init(void *fdtp) · 86 unmodified lines | ||
| 87 | 87 | void __init xlp_early_init_devtree(void) |
| 88 | 88 | { |
| 89 | 89 | __dt_setup_arch(xlp_fdt_blob); |
| 90 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 91 | 90 | } |
| 92 | 91 | |
| 93 | 92 | void __init device_tree_init(void) |
| @@ -432,8 +432,7 @@ static int rt3883_pci_probe(struct platform_device *pdev) · 431 unmodified lines | ||
| 432 | 432 | |
| 433 | 433 | /* find the interrupt controller child node */ |
| 434 | 434 | for_each_child_of_node(np, child) { |
| 435 | − if (of_get_property(child, "interrupt-controller", NULL) && | |
| 436 | − of_node_get(child)) { | |
| 435 | + if (of_get_property(child, "interrupt-controller", NULL)) { | |
| 437 | 436 | rpc->intc_of_node = child; |
| 438 | 437 | break; |
| 439 | 438 | } |
| @@ -449,8 +448,7 @@ static int rt3883_pci_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 449 | 448 | /* find the PCI host bridge child node */ |
| 450 | 449 | for_each_child_of_node(np, child) { |
| 451 | 450 | if (child->type && |
| 452 | − of_node_cmp(child->type, "pci") == 0 && | |
| 453 | − of_node_get(child)) { | |
| 451 | + of_node_cmp(child->type, "pci") == 0) { | |
| 454 | 452 | rpc->pci_controller.of_node = child; |
| 455 | 453 | break; |
| 456 | 454 | } |
| @@ -58,7 +58,6 @@ void __init plat_mem_setup(void) · 57 unmodified lines | ||
| 58 | 58 | panic("Device-tree not present"); |
| 59 | 59 | |
| 60 | 60 | __dt_setup_arch((void *)fw_arg1); |
| 61 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 62 | 61 | |
| 63 | 62 | plat_setup_iocoherency(); |
| 64 | 63 | } |
| @@ -48,7 +48,7 @@ static int systick_next_event(unsigned long delta, · 47 unmodified lines | ||
| 48 | 48 | sdev = container_of(evt, struct systick_device, dev); |
| 49 | 49 | count = ioread32(sdev->membase + SYSTICK_COUNT); |
| 50 | 50 | count = (count + delta) % SYSTICK_FREQ; |
| 51 | − iowrite32(count + delta, sdev->membase + SYSTICK_COMPARE); | |
| 51 | + iowrite32(count, sdev->membase + SYSTICK_COMPARE); | |
| 52 | 52 | |
| 53 | 53 | return 0; |
| 54 | 54 | } |
| @@ -25,11 +25,13 @@ · 24 unmodified lines | ||
| 25 | 25 | #define MT7628_CHIP_NAME1 0x20203832 |
| 26 | 26 | |
| 27 | 27 | #define UART_REG_TX 0x04 |
| 28 | +#define UART_REG_LCR 0x0c | |
| 28 | 29 | #define UART_REG_LSR 0x14 |
| 29 | 30 | #define UART_REG_LSR_RT2880 0x1c |
| 30 | 31 | |
| 31 | 32 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); |
| 32 | 33 | static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE); |
| 34 | +static int init_complete; | |
| 33 | 35 | |
| 34 | 36 | static inline void uart_w32(u32 val, unsigned reg) |
| 35 | 37 | { |
| @@ -47,8 +49,32 @@ static inline int soc_is_mt7628(void) · 11 unmodified lines | ||
| 47 | 49 | (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1); |
| 48 | 50 | } |
| 49 | 51 | |
| 52 | +static void find_uart_base(void) | |
| 53 | +{ | |
| 54 | + int i; | |
| 55 | + | |
| 56 | + if (!soc_is_mt7628()) | |
| 57 | + return; | |
| 58 | + | |
| 59 | + for (i = 0; i < 3; i++) { | |
| 60 | + u32 reg = uart_r32(UART_REG_LCR + (0x100 * i)); | |
| 61 | + | |
| 62 | + if (!reg) | |
| 63 | + continue; | |
| 64 | + | |
| 65 | + uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE + | |
| 66 | + (0x100 * i)); | |
| 67 | + break; | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 50 | 71 | void prom_putchar(unsigned char ch) |
| 51 | 72 | { |
| 73 | + if (!init_complete) { | |
| 74 | + find_uart_base(); | |
| 75 | + init_complete = 1; | |
| 76 | + } | |
| 77 | + | |
| 52 | 78 | if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) { |
| 53 | 79 | uart_w32(ch, UART_TX); |
| 54 | 80 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) |
| @@ -37,8 +37,17 @@ · 36 unmodified lines | ||
| 37 | 37 | #define PMU1_CFG 0x8C |
| 38 | 38 | #define DIG_SW_SEL BIT(25) |
| 39 | 39 | |
| 40 | −/* is this a MT7620 or a MT7628 */ | |
| 41 | −enum mt762x_soc_type mt762x_soc; | |
| 40 | +/* clock scaling */ | |
| 41 | +#define CLKCFG_FDIV_MASK 0x1f00 | |
| 42 | +#define CLKCFG_FDIV_USB_VAL 0x0300 | |
| 43 | +#define CLKCFG_FFRAC_MASK 0x001f | |
| 44 | +#define CLKCFG_FFRAC_USB_VAL 0x0003 | |
| 45 | + | |
| 46 | +/* EFUSE bits */ | |
| 47 | +#define EFUSE_MT7688 0x100000 | |
| 48 | + | |
| 49 | +/* DRAM type bit */ | |
| 50 | +#define DRAM_TYPE_MT7628_MASK 0x1 | |
| 42 | 51 | |
| 43 | 52 | /* does the board have sdram or ddram */ |
| 44 | 53 | static int dram_type; |
| @@ -227,6 +236,12 @@ static struct rt2880_pmx_group mt7628an_pinmux_data[] = { · 182 unmodified lines | ||
| 227 | 236 | { 0 } |
| 228 | 237 | }; |
| 229 | 238 | |
| 239 | +static inline int is_mt76x8(void) | |
| 240 | +{ | |
| 241 | + return ralink_soc == MT762X_SOC_MT7628AN || | |
| 242 | + ralink_soc == MT762X_SOC_MT7688; | |
| 243 | +} | |
| 244 | + | |
| 230 | 245 | static __init u32 |
| 231 | 246 | mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div) |
| 232 | 247 | { |
| @@ -381,7 +396,7 @@ void __init ralink_clk_init(void) · 148 unmodified lines | ||
| 381 | 396 | #define RINT(x) ((x) / 1000000) |
| 382 | 397 | #define RFRAC(x) (((x) / 1000) % 1000) |
| 383 | 398 | |
| 384 | − if (mt762x_soc == MT762X_SOC_MT7628AN) { | |
| 399 | + if (is_mt76x8()) { | |
| 385 | 400 | if (xtal_rate == MHZ(40)) |
| 386 | 401 | cpu_rate = MHZ(580); |
| 387 | 402 | else |
| @@ -423,6 +438,20 @@ void __init ralink_clk_init(void) · 35 unmodified lines | ||
| 423 | 438 | ralink_clk_add("10000b00.spi", sys_rate); |
| 424 | 439 | ralink_clk_add("10000c00.uartlite", periph_rate); |
| 425 | 440 | ralink_clk_add("10180000.wmac", xtal_rate); |
| 441 | + | |
| 442 | + if (IS_ENABLED(CONFIG_USB) && is_mt76x8()) { | |
| 443 | + /* | |
| 444 | + * When the CPU goes into sleep mode, the BUS clock will be | |
| 445 | + * too low for USB to function properly. Adjust the busses | |
| 446 | + * fractional divider to fix this | |
| 447 | + */ | |
| 448 | + u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG); | |
| 449 | + | |
| 450 | + val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK); | |
| 451 | + val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL; | |
| 452 | + | |
| 453 | + rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG); | |
| 454 | + } | |
| 426 | 455 | } |
| 427 | 456 | |
| 428 | 457 | void __init ralink_of_remap(void) |
| @@ -499,20 +528,24 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 70 unmodified lines | ||
| 499 | 528 | |
| 500 | 529 | if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) { |
| 501 | 530 | if (bga) { |
| 502 | − mt762x_soc = MT762X_SOC_MT7620A; | |
| 531 | + ralink_soc = MT762X_SOC_MT7620A; | |
| 503 | 532 | name = "MT7620A"; |
| 504 | 533 | soc_info->compatible = "ralink,mt7620a-soc"; |
| 505 | 534 | } else { |
| 506 | − mt762x_soc = MT762X_SOC_MT7620N; | |
| 535 | + ralink_soc = MT762X_SOC_MT7620N; | |
| 507 | 536 | name = "MT7620N"; |
| 508 | 537 | soc_info->compatible = "ralink,mt7620n-soc"; |
| 509 | −#ifdef CONFIG_PCI | |
| 510 | − panic("mt7620n is only supported for non pci kernels"); | |
| 511 | −#endif | |
| 512 | 538 | } |
| 513 | 539 | } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) { |
| 514 | − mt762x_soc = MT762X_SOC_MT7628AN; | |
| 515 | − name = "MT7628AN"; | |
| 540 | + u32 efuse = __raw_readl(sysc + SYSC_REG_EFUSE_CFG); | |
| 541 | + | |
| 542 | + if (efuse & EFUSE_MT7688) { | |
| 543 | + ralink_soc = MT762X_SOC_MT7688; | |
| 544 | + name = "MT7688"; | |
| 545 | + } else { | |
| 546 | + ralink_soc = MT762X_SOC_MT7628AN; | |
| 547 | + name = "MT7628AN"; | |
| 548 | + } | |
| 516 | 549 | soc_info->compatible = "ralink,mt7628an-soc"; |
| 517 | 550 | } else { |
| 518 | 551 | panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); |
| @@ -525,10 +558,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 6 unmodified lines | ||
| 525 | 558 | (rev & CHIP_REV_ECO_MASK)); |
| 526 | 559 | |
| 527 | 560 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); |
| 528 | − dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; | |
| 561 | + if (is_mt76x8()) | |
| 562 | + dram_type = cfg0 & DRAM_TYPE_MT7628_MASK; | |
| 563 | + else | |
| 564 | + dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & | |
| 565 | + SYSCFG0_DRAM_TYPE_MASK; | |
| 529 | 566 | |
| 530 | 567 | soc_info->mem_base = MT7620_DRAM_BASE; |
| 531 | − if (mt762x_soc == MT762X_SOC_MT7628AN) | |
| 568 | + if (is_mt76x8()) | |
| 532 | 569 | mt7628_dram_init(soc_info); |
| 533 | 570 | else |
| 534 | 571 | mt7620_dram_init(soc_info); |
| @@ -541,7 +578,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 6 unmodified lines | ||
| 541 | 578 | pr_info("Digital PMU set to %s control\n", |
| 542 | 579 | (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); |
| 543 | 580 | |
| 544 | − if (mt762x_soc == MT762X_SOC_MT7628AN) | |
| 581 | + if (is_mt76x8()) | |
| 545 | 582 | rt2880_pinmux_data = mt7628an_pinmux_data; |
| 546 | 583 | else |
| 547 | 584 | rt2880_pinmux_data = mt7620a_pinmux_data; |
| @@ -74,8 +74,6 @@ void __init plat_mem_setup(void) · 73 unmodified lines | ||
| 74 | 74 | */ |
| 75 | 75 | __dt_setup_arch(__dtb_start); |
| 76 | 76 | |
| 77 | − strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 78 | − | |
| 79 | 77 | of_scan_flat_dt(early_init_dt_find_memory, NULL); |
| 80 | 78 | if (memory_dtb) |
| 81 | 79 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); |
| @@ -15,11 +15,16 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/bootinfo.h> |
| 16 | 16 | #include <asm/addrspace.h> |
| 17 | 17 | |
| 18 | +#include <asm/mach-ralink/ralink_regs.h> | |
| 19 | + | |
| 18 | 20 | #include "common.h" |
| 19 | 21 | |
| 20 | 22 | struct ralink_soc_info soc_info; |
| 21 | 23 | struct rt2880_pmx_group *rt2880_pinmux_data = NULL; |
| 22 | 24 | |
| 25 | +enum ralink_soc_type ralink_soc; | |
| 26 | +EXPORT_SYMBOL_GPL(ralink_soc); | |
| 27 | + | |
| 23 | 28 | const char *get_system_type(void) |
| 24 | 29 | { |
| 25 | 30 | return soc_info.sys_type; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/pm.h> |
| 12 | 12 | #include <linux/io.h> |
| 13 | 13 | #include <linux/of.h> |
| 14 | +#include <linux/delay.h> | |
| 14 | 15 | #include <linux/reset-controller.h> |
| 15 | 16 | |
| 16 | 17 | #include <asm/reboot.h> |
| @@ -18,8 +19,10 @@ · 1 unmodified line | ||
| 18 | 19 | #include <asm/mach-ralink/ralink_regs.h> |
| 19 | 20 | |
| 20 | 21 | /* Reset Control */ |
| 21 | −#define SYSC_REG_RESET_CTRL 0x034 | |
| 22 | −#define RSTCTL_RESET_SYSTEM BIT(0) | |
| 22 | +#define SYSC_REG_RESET_CTRL 0x034 | |
| 23 | + | |
| 24 | +#define RSTCTL_RESET_PCI BIT(26) | |
| 25 | +#define RSTCTL_RESET_SYSTEM BIT(0) | |
| 23 | 26 | |
| 24 | 27 | static int ralink_assert_device(struct reset_controller_dev *rcdev, |
| 25 | 28 | unsigned long id) |
| @@ -83,6 +86,11 @@ void ralink_rst_init(void) · 57 unmodified lines | ||
| 83 | 86 | |
| 84 | 87 | static void ralink_restart(char *command) |
| 85 | 88 | { |
| 89 | + if (IS_ENABLED(CONFIG_PCI)) { | |
| 90 | + rt_sysc_m32(0, RSTCTL_RESET_PCI, SYSC_REG_RESET_CTRL); | |
| 91 | + mdelay(50); | |
| 92 | + } | |
| 93 | + | |
| 86 | 94 | local_irq_disable(); |
| 87 | 95 | rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL); |
| 88 | 96 | unreachable(); |
| @@ -98,7 +106,6 @@ static int __init mips_reboot_setup(void) · 9 unmodified lines | ||
| 98 | 106 | { |
| 99 | 107 | _machine_restart = ralink_restart; |
| 100 | 108 | _machine_halt = ralink_halt; |
| 101 | − pm_power_off = ralink_halt; | |
| 102 | 109 | |
| 103 | 110 | return 0; |
| 104 | 111 | } |
| @@ -119,4 +119,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 118 unmodified lines | ||
| 119 | 119 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; |
| 120 | 120 | |
| 121 | 121 | rt2880_pinmux_data = rt2880_pinmux_data_act; |
| 122 | + ralink_soc == RT2880_SOC; | |
| 122 | 123 | } |
| @@ -21,8 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | #include "common.h" |
| 23 | 23 | |
| 24 | −enum rt305x_soc_type rt305x_soc; | |
| 25 | − | |
| 26 | 24 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
| 27 | 25 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
| 28 | 26 | static struct rt2880_pmx_func uartf_func[] = { |
| @@ -201,6 +199,7 @@ void __init ralink_clk_init(void) · 172 unmodified lines | ||
| 201 | 199 | } |
| 202 | 200 | |
| 203 | 201 | ralink_clk_add("cpu", cpu_rate); |
| 202 | + ralink_clk_add("sys", sys_rate); | |
| 204 | 203 | ralink_clk_add("10000b00.spi", sys_rate); |
| 205 | 204 | ralink_clk_add("10000100.timer", wdt_rate); |
| 206 | 205 | ralink_clk_add("10000120.watchdog", wdt_rate); |
| @@ -235,24 +234,24 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 28 unmodified lines | ||
| 235 | 234 | |
| 236 | 235 | icache_sets = (read_c0_config1() >> 22) & 7; |
| 237 | 236 | if (icache_sets == 1) { |
| 238 | − rt305x_soc = RT305X_SOC_RT3050; | |
| 237 | + ralink_soc = RT305X_SOC_RT3050; | |
| 239 | 238 | name = "RT3050"; |
| 240 | 239 | soc_info->compatible = "ralink,rt3050-soc"; |
| 241 | 240 | } else { |
| 242 | − rt305x_soc = RT305X_SOC_RT3052; | |
| 241 | + ralink_soc = RT305X_SOC_RT3052; | |
| 243 | 242 | name = "RT3052"; |
| 244 | 243 | soc_info->compatible = "ralink,rt3052-soc"; |
| 245 | 244 | } |
| 246 | 245 | } else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) { |
| 247 | − rt305x_soc = RT305X_SOC_RT3350; | |
| 246 | + ralink_soc = RT305X_SOC_RT3350; | |
| 248 | 247 | name = "RT3350"; |
| 249 | 248 | soc_info->compatible = "ralink,rt3350-soc"; |
| 250 | 249 | } else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) { |
| 251 | − rt305x_soc = RT305X_SOC_RT3352; | |
| 250 | + ralink_soc = RT305X_SOC_RT3352; | |
| 252 | 251 | name = "RT3352"; |
| 253 | 252 | soc_info->compatible = "ralink,rt3352-soc"; |
| 254 | 253 | } else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) { |
| 255 | − rt305x_soc = RT305X_SOC_RT5350; | |
| 254 | + ralink_soc = RT305X_SOC_RT5350; | |
| 256 | 255 | name = "RT5350"; |
| 257 | 256 | soc_info->compatible = "ralink,rt5350-soc"; |
| 258 | 257 | } else { |
| @@ -153,4 +153,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) · 152 unmodified lines | ||
| 153 | 153 | soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; |
| 154 | 154 | |
| 155 | 155 | rt2880_pinmux_data = rt3883_pinmux_data; |
| 156 | + | |
| 157 | + ralink_soc == RT3883_SOC; | |
| 156 | 158 | } |
| @@ -0,0 +1,4 @@ | ||
| 1 | +*.so* | |
| 2 | +vdso-*image.c | |
| 3 | +genvdso | |
| 4 | +vdso*.lds | |
| @@ -0,0 +1,160 @@ | ||
| 1 | +# Objects to go into the VDSO. | |
| 2 | +obj-vdso-y := elf.o gettimeofday.o sigreturn.o | |
| 3 | + | |
| 4 | +# Common compiler flags between ABIs. | |
| 5 | +ccflags-vdso := \ | |
| 6 | + $(filter -I%,$(KBUILD_CFLAGS)) \ | |
| 7 | + $(filter -E%,$(KBUILD_CFLAGS)) \ | |
| 8 | + $(filter -march=%,$(KBUILD_CFLAGS)) | |
| 9 | +cflags-vdso := $(ccflags-vdso) \ | |
| 10 | + $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ | |
| 11 | + -O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \ | |
| 12 | + $(call cc-option, -fno-stack-protector) | |
| 13 | +aflags-vdso := $(ccflags-vdso) \ | |
| 14 | + $(filter -I%,$(KBUILD_CFLAGS)) \ | |
| 15 | + $(filter -E%,$(KBUILD_CFLAGS)) \ | |
| 16 | + -D__ASSEMBLY__ -Wa,-gdwarf-2 | |
| 17 | + | |
| 18 | +# | |
| 19 | +# For the pre-R6 code in arch/mips/vdso/vdso.h for locating | |
| 20 | +# the base address of VDSO, the linker will emit a R_MIPS_PC32 | |
| 21 | +# relocation in binutils > 2.25 but it will fail with older versions | |
| 22 | +# because that relocation is not supported for that symbol. As a result | |
| 23 | +# of which we are forced to disable the VDSO symbols when building | |
| 24 | +# with < 2.25 binutils on pre-R6 kernels. For more references on why we | |
| 25 | +# can't use other methods to get the base address of VDSO please refer to | |
| 26 | +# the comments on that file. | |
| 27 | +# | |
| 28 | +ifndef CONFIG_CPU_MIPSR6 | |
| 29 | + ifeq ($(call ld-ifversion, -gt, 22400000, y),) | |
| 30 | + $(warning MIPS VDSO requires binutils > 2.24) | |
| 31 | + obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y)) | |
| 32 | + ccflags-vdso += -DDISABLE_MIPS_VDSO | |
| 33 | + endif | |
| 34 | +endif | |
| 35 | + | |
| 36 | +# VDSO linker flags. | |
| 37 | +VDSO_LDFLAGS := \ | |
| 38 | + -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \ | |
| 39 | + -nostdlib -shared \ | |
| 40 | + $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \ | |
| 41 | + $(call cc-ldoption, -Wl$(comma)--build-id) | |
| 42 | + | |
| 43 | +GCOV_PROFILE := n | |
| 44 | + | |
| 45 | +# | |
| 46 | +# Shared build commands. | |
| 47 | +# | |
| 48 | + | |
| 49 | +quiet_cmd_vdsold = VDSO $@ | |
| 50 | + cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ | |
| 51 | + -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ | |
| 52 | + | |
| 53 | +hostprogs-y := genvdso | |
| 54 | + | |
| 55 | +quiet_cmd_genvdso = GENVDSO $@ | |
| 56 | +define cmd_genvdso | |
| 57 | + cp $< $(<:%.dbg=%) && \ | |
| 58 | + $(OBJCOPY) -S $< $(<:%.dbg=%) && \ | |
| 59 | + $(obj)/genvdso $< $(<:%.dbg=%) $@ $(VDSO_NAME) | |
| 60 | +endef | |
| 61 | + | |
| 62 | +# | |
| 63 | +# Build native VDSO. | |
| 64 | +# | |
| 65 | + | |
| 66 | +native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS)) | |
| 67 | + | |
| 68 | +targets += $(obj-vdso-y) | |
| 69 | +targets += vdso.lds vdso.so.dbg vdso.so vdso-image.c | |
| 70 | + | |
| 71 | +obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) | |
| 72 | + | |
| 73 | +$(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi) | |
| 74 | +$(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) | |
| 75 | + | |
| 76 | +$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) | |
| 77 | + | |
| 78 | +$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE | |
| 79 | + $(call if_changed,vdsold) | |
| 80 | + | |
| 81 | +$(obj)/vdso-image.c: $(obj)/vdso.so.dbg $(obj)/genvdso FORCE | |
| 82 | + $(call if_changed,genvdso) | |
| 83 | + | |
| 84 | +obj-y += vdso-image.o | |
| 85 | + | |
| 86 | +# | |
| 87 | +# Build O32 VDSO. | |
| 88 | +# | |
| 89 | + | |
| 90 | +# Define these outside the ifdef to ensure they are picked up by clean. | |
| 91 | +targets += $(obj-vdso-y:%.o=%-o32.o) | |
| 92 | +targets += vdso-o32.lds vdso-o32.so.dbg vdso-o32.so vdso-o32-image.c | |
| 93 | + | |
| 94 | +ifdef CONFIG_MIPS32_O32 | |
| 95 | + | |
| 96 | +obj-vdso-o32 := $(obj-vdso-y:%.o=$(obj)/%-o32.o) | |
| 97 | + | |
| 98 | +$(obj-vdso-o32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=32 | |
| 99 | +$(obj-vdso-o32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=32 | |
| 100 | + | |
| 101 | +$(obj)/%-o32.o: $(src)/%.S FORCE | |
| 102 | + $(call if_changed_dep,as_o_S) | |
| 103 | + | |
| 104 | +$(obj)/%-o32.o: $(src)/%.c FORCE | |
| 105 | + $(call cmd,force_checksrc) | |
| 106 | + $(call if_changed_rule,cc_o_c) | |
| 107 | + | |
| 108 | +$(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := -mabi=32 | |
| 109 | +$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE | |
| 110 | + $(call if_changed_dep,cpp_lds_S) | |
| 111 | + | |
| 112 | +$(obj)/vdso-o32.so.dbg: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE | |
| 113 | + $(call if_changed,vdsold) | |
| 114 | + | |
| 115 | +$(obj)/vdso-o32-image.c: VDSO_NAME := o32 | |
| 116 | +$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg $(obj)/genvdso FORCE | |
| 117 | + $(call if_changed,genvdso) | |
| 118 | + | |
| 119 | +obj-y += vdso-o32-image.o | |
| 120 | + | |
| 121 | +endif | |
| 122 | + | |
| 123 | +# | |
| 124 | +# Build N32 VDSO. | |
| 125 | +# | |
| 126 | + | |
| 127 | +targets += $(obj-vdso-y:%.o=%-n32.o) | |
| 128 | +targets += vdso-n32.lds vdso-n32.so.dbg vdso-n32.so vdso-n32-image.c | |
| 129 | + | |
| 130 | +ifdef CONFIG_MIPS32_N32 | |
| 131 | + | |
| 132 | +obj-vdso-n32 := $(obj-vdso-y:%.o=$(obj)/%-n32.o) | |
| 133 | + | |
| 134 | +$(obj-vdso-n32): KBUILD_CFLAGS := $(cflags-vdso) -mabi=n32 | |
| 135 | +$(obj-vdso-n32): KBUILD_AFLAGS := $(aflags-vdso) -mabi=n32 | |
| 136 | + | |
| 137 | +$(obj)/%-n32.o: $(src)/%.S FORCE | |
| 138 | + $(call if_changed_dep,as_o_S) | |
| 139 | + | |
| 140 | +$(obj)/%-n32.o: $(src)/%.c FORCE | |
| 141 | + $(call cmd,force_checksrc) | |
| 142 | + $(call if_changed_rule,cc_o_c) | |
| 143 | + | |
| 144 | +$(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := -mabi=n32 | |
| 145 | +$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE | |
| 146 | + $(call if_changed_dep,cpp_lds_S) | |
| 147 | + | |
| 148 | +$(obj)/vdso-n32.so.dbg: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE | |
| 149 | + $(call if_changed,vdsold) | |
| 150 | + | |
| 151 | +$(obj)/vdso-n32-image.c: VDSO_NAME := n32 | |
| 152 | +$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg $(obj)/genvdso FORCE | |
| 153 | + $(call if_changed,genvdso) | |
| 154 | + | |
| 155 | +obj-y += vdso-n32-image.o | |
| 156 | + | |
| 157 | +endif | |
| 158 | + | |
| 159 | +# FIXME: Need install rule for debug. | |
| 160 | +# Needs to deal with dependency for generation of dbg by cmd_genvdso... | |
| @@ -0,0 +1,68 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include "vdso.h" | |
| 12 | + | |
| 13 | +#include <linux/elfnote.h> | |
| 14 | +#include <linux/version.h> | |
| 15 | + | |
| 16 | +ELFNOTE_START(Linux, 0, "a") | |
| 17 | + .long LINUX_VERSION_CODE | |
| 18 | +ELFNOTE_END | |
| 19 | + | |
| 20 | +/* | |
| 21 | + * The .MIPS.abiflags section must be defined with the FP ABI flags set | |
| 22 | + * to 'any' to be able to link with both old and new libraries. | |
| 23 | + * Newer toolchains are capable of automatically generating this, but we want | |
| 24 | + * to work with older toolchains as well. Therefore, we define the contents of | |
| 25 | + * this section here (under different names), and then genvdso will patch | |
| 26 | + * it to have the correct name and type. | |
| 27 | + * | |
| 28 | + * We base the .MIPS.abiflags section on preprocessor definitions rather than | |
| 29 | + * CONFIG_* because we need to match the particular ABI we are building the | |
| 30 | + * VDSO for. | |
| 31 | + * | |
| 32 | + * See https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking | |
| 33 | + * for the .MIPS.abiflags section description. | |
| 34 | + */ | |
| 35 | + | |
| 36 | + .section .mips_abiflags, "a" | |
| 37 | + .align 3 | |
| 38 | +__mips_abiflags: | |
| 39 | + .hword 0 /* version */ | |
| 40 | + .byte __mips /* isa_level */ | |
| 41 | + | |
| 42 | + /* isa_rev */ | |
| 43 | +#ifdef __mips_isa_rev | |
| 44 | + .byte __mips_isa_rev | |
| 45 | +#else | |
| 46 | + .byte 0 | |
| 47 | +#endif | |
| 48 | + | |
| 49 | + /* gpr_size */ | |
| 50 | +#ifdef __mips64 | |
| 51 | + .byte 2 /* AFL_REG_64 */ | |
| 52 | +#else | |
| 53 | + .byte 1 /* AFL_REG_32 */ | |
| 54 | +#endif | |
| 55 | + | |
| 56 | + /* cpr1_size */ | |
| 57 | +#if (defined(__mips_isa_rev) && __mips_isa_rev >= 6) || defined(__mips64) | |
| 58 | + .byte 2 /* AFL_REG_64 */ | |
| 59 | +#else | |
| 60 | + .byte 1 /* AFL_REG_32 */ | |
| 61 | +#endif | |
| 62 | + | |
| 63 | + .byte 0 /* cpr2_size (AFL_REG_NONE) */ | |
| 64 | + .byte 0 /* fp_abi (Val_GNU_MIPS_ABI_FP_ANY) */ | |
| 65 | + .word 0 /* isa_ext */ | |
| 66 | + .word 0 /* ases */ | |
| 67 | + .word 0 /* flags1 */ | |
| 68 | + .word 0 /* flags2 */ | |
| @@ -0,0 +1,293 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +/* | |
| 12 | + * This tool is used to generate the real VDSO images from the raw image. It | |
| 13 | + * first patches up the MIPS ABI flags and GNU attributes sections defined in | |
| 14 | + * elf.S to have the correct name and type. It then generates a C source file | |
| 15 | + * to be compiled into the kernel containing the VDSO image data and a | |
| 16 | + * mips_vdso_image struct for it, including symbol offsets extracted from the | |
| 17 | + * image. | |
| 18 | + * | |
| 19 | + * We need to be passed both a stripped and unstripped VDSO image. The stripped | |
| 20 | + * image is compiled into the kernel, but we must also patch up the unstripped | |
| 21 | + * image's ABI flags sections so that it can be installed and used for | |
| 22 | + * debugging. | |
| 23 | + */ | |
| 24 | + | |
| 25 | +#include <sys/mman.h> | |
| 26 | +#include <sys/stat.h> | |
| 27 | +#include <sys/types.h> | |
| 28 | + | |
| 29 | +#include <byteswap.h> | |
| 30 | +#include <elf.h> | |
| 31 | +#include <errno.h> | |
| 32 | +#include <fcntl.h> | |
| 33 | +#include <inttypes.h> | |
| 34 | +#include <stdarg.h> | |
| 35 | +#include <stdbool.h> | |
| 36 | +#include <stdio.h> | |
| 37 | +#include <stdlib.h> | |
| 38 | +#include <string.h> | |
| 39 | +#include <unistd.h> | |
| 40 | + | |
| 41 | +/* Define these in case the system elf.h is not new enough to have them. */ | |
| 42 | +#ifndef SHT_GNU_ATTRIBUTES | |
| 43 | +# define SHT_GNU_ATTRIBUTES 0x6ffffff5 | |
| 44 | +#endif | |
| 45 | +#ifndef SHT_MIPS_ABIFLAGS | |
| 46 | +# define SHT_MIPS_ABIFLAGS 0x7000002a | |
| 47 | +#endif | |
| 48 | + | |
| 49 | +enum { | |
| 50 | + ABI_O32 = (1 << 0), | |
| 51 | + ABI_N32 = (1 << 1), | |
| 52 | + ABI_N64 = (1 << 2), | |
| 53 | + | |
| 54 | + ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64, | |
| 55 | +}; | |
| 56 | + | |
| 57 | +/* Symbols the kernel requires offsets for. */ | |
| 58 | +static struct { | |
| 59 | + const char *name; | |
| 60 | + const char *offset_name; | |
| 61 | + unsigned int abis; | |
| 62 | +} vdso_symbols[] = { | |
| 63 | + { "__vdso_sigreturn", "off_sigreturn", ABI_O32 }, | |
| 64 | + { "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL }, | |
| 65 | + {} | |
| 66 | +}; | |
| 67 | + | |
| 68 | +static const char *program_name; | |
| 69 | +static const char *vdso_name; | |
| 70 | +static unsigned char elf_class; | |
| 71 | +static unsigned int elf_abi; | |
| 72 | +static bool need_swap; | |
| 73 | +static FILE *out_file; | |
| 74 | + | |
| 75 | +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
| 76 | +# define HOST_ORDER ELFDATA2LSB | |
| 77 | +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
| 78 | +# define HOST_ORDER ELFDATA2MSB | |
| 79 | +#endif | |
| 80 | + | |
| 81 | +#define BUILD_SWAP(bits) \ | |
| 82 | + static uint##bits##_t swap_uint##bits(uint##bits##_t val) \ | |
| 83 | + { \ | |
| 84 | + return need_swap ? bswap_##bits(val) : val; \ | |
| 85 | + } | |
| 86 | + | |
| 87 | +BUILD_SWAP(16) | |
| 88 | +BUILD_SWAP(32) | |
| 89 | +BUILD_SWAP(64) | |
| 90 | + | |
| 91 | +#define __FUNC(name, bits) name##bits | |
| 92 | +#define _FUNC(name, bits) __FUNC(name, bits) | |
| 93 | +#define FUNC(name) _FUNC(name, ELF_BITS) | |
| 94 | + | |
| 95 | +#define __ELF(x, bits) Elf##bits##_##x | |
| 96 | +#define _ELF(x, bits) __ELF(x, bits) | |
| 97 | +#define ELF(x) _ELF(x, ELF_BITS) | |
| 98 | + | |
| 99 | +/* | |
| 100 | + * Include genvdso.h twice with ELF_BITS defined differently to get functions | |
| 101 | + * for both ELF32 and ELF64. | |
| 102 | + */ | |
| 103 | + | |
| 104 | +#define ELF_BITS 64 | |
| 105 | +#include "genvdso.h" | |
| 106 | +#undef ELF_BITS | |
| 107 | + | |
| 108 | +#define ELF_BITS 32 | |
| 109 | +#include "genvdso.h" | |
| 110 | +#undef ELF_BITS | |
| 111 | + | |
| 112 | +static void *map_vdso(const char *path, size_t *_size) | |
| 113 | +{ | |
| 114 | + int fd; | |
| 115 | + struct stat stat; | |
| 116 | + void *addr; | |
| 117 | + const Elf32_Ehdr *ehdr; | |
| 118 | + | |
| 119 | + fd = open(path, O_RDWR); | |
| 120 | + if (fd < 0) { | |
| 121 | + fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name, | |
| 122 | + path, strerror(errno)); | |
| 123 | + return NULL; | |
| 124 | + } | |
| 125 | + | |
| 126 | + if (fstat(fd, &stat) != 0) { | |
| 127 | + fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name, | |
| 128 | + path, strerror(errno)); | |
| 129 | + return NULL; | |
| 130 | + } | |
| 131 | + | |
| 132 | + addr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, | |
| 133 | + 0); | |
| 134 | + if (addr == MAP_FAILED) { | |
| 135 | + fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name, | |
| 136 | + path, strerror(errno)); | |
| 137 | + return NULL; | |
| 138 | + } | |
| 139 | + | |
| 140 | + /* ELF32/64 header formats are the same for the bits we're checking. */ | |
| 141 | + ehdr = addr; | |
| 142 | + | |
| 143 | + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { | |
| 144 | + fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name, | |
| 145 | + path); | |
| 146 | + return NULL; | |
| 147 | + } | |
| 148 | + | |
| 149 | + elf_class = ehdr->e_ident[EI_CLASS]; | |
| 150 | + switch (elf_class) { | |
| 151 | + case ELFCLASS32: | |
| 152 | + case ELFCLASS64: | |
| 153 | + break; | |
| 154 | + default: | |
| 155 | + fprintf(stderr, "%s: '%s' has invalid ELF class\n", | |
| 156 | + program_name, path); | |
| 157 | + return NULL; | |
| 158 | + } | |
| 159 | + | |
| 160 | + switch (ehdr->e_ident[EI_DATA]) { | |
| 161 | + case ELFDATA2LSB: | |
| 162 | + case ELFDATA2MSB: | |
| 163 | + need_swap = ehdr->e_ident[EI_DATA] != HOST_ORDER; | |
| 164 | + break; | |
| 165 | + default: | |
| 166 | + fprintf(stderr, "%s: '%s' has invalid ELF data order\n", | |
| 167 | + program_name, path); | |
| 168 | + return NULL; | |
| 169 | + } | |
| 170 | + | |
| 171 | + if (swap_uint16(ehdr->e_machine) != EM_MIPS) { | |
| 172 | + fprintf(stderr, | |
| 173 | + "%s: '%s' has invalid ELF machine (expected EM_MIPS)\n", | |
| 174 | + program_name, path); | |
| 175 | + return NULL; | |
| 176 | + } else if (swap_uint16(ehdr->e_type) != ET_DYN) { | |
| 177 | + fprintf(stderr, | |
| 178 | + "%s: '%s' has invalid ELF type (expected ET_DYN)\n", | |
| 179 | + program_name, path); | |
| 180 | + return NULL; | |
| 181 | + } | |
| 182 | + | |
| 183 | + *_size = stat.st_size; | |
| 184 | + return addr; | |
| 185 | +} | |
| 186 | + | |
| 187 | +static bool patch_vdso(const char *path, void *vdso) | |
| 188 | +{ | |
| 189 | + if (elf_class == ELFCLASS64) | |
| 190 | + return patch_vdso64(path, vdso); | |
| 191 | + else | |
| 192 | + return patch_vdso32(path, vdso); | |
| 193 | +} | |
| 194 | + | |
| 195 | +static bool get_symbols(const char *path, void *vdso) | |
| 196 | +{ | |
| 197 | + if (elf_class == ELFCLASS64) | |
| 198 | + return get_symbols64(path, vdso); | |
| 199 | + else | |
| 200 | + return get_symbols32(path, vdso); | |
| 201 | +} | |
| 202 | + | |
| 203 | +int main(int argc, char **argv) | |
| 204 | +{ | |
| 205 | + const char *dbg_vdso_path, *vdso_path, *out_path; | |
| 206 | + void *dbg_vdso, *vdso; | |
| 207 | + size_t dbg_vdso_size, vdso_size, i; | |
| 208 | + | |
| 209 | + program_name = argv[0]; | |
| 210 | + | |
| 211 | + if (argc < 4 || argc > 5) { | |
| 212 | + fprintf(stderr, | |
| 213 | + "Usage: %s <debug VDSO> <stripped VDSO> <output file> [<name>]\n", | |
| 214 | + program_name); | |
| 215 | + return EXIT_FAILURE; | |
| 216 | + } | |
| 217 | + | |
| 218 | + dbg_vdso_path = argv[1]; | |
| 219 | + vdso_path = argv[2]; | |
| 220 | + out_path = argv[3]; | |
| 221 | + vdso_name = (argc > 4) ? argv[4] : ""; | |
| 222 | + | |
| 223 | + dbg_vdso = map_vdso(dbg_vdso_path, &dbg_vdso_size); | |
| 224 | + if (!dbg_vdso) | |
| 225 | + return EXIT_FAILURE; | |
| 226 | + | |
| 227 | + vdso = map_vdso(vdso_path, &vdso_size); | |
| 228 | + if (!vdso) | |
| 229 | + return EXIT_FAILURE; | |
| 230 | + | |
| 231 | + /* Patch both the VDSOs' ABI flags sections. */ | |
| 232 | + if (!patch_vdso(dbg_vdso_path, dbg_vdso)) | |
| 233 | + return EXIT_FAILURE; | |
| 234 | + if (!patch_vdso(vdso_path, vdso)) | |
| 235 | + return EXIT_FAILURE; | |
| 236 | + | |
| 237 | + if (msync(dbg_vdso, dbg_vdso_size, MS_SYNC) != 0) { | |
| 238 | + fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name, | |
| 239 | + dbg_vdso_path, strerror(errno)); | |
| 240 | + return EXIT_FAILURE; | |
| 241 | + } else if (msync(vdso, vdso_size, MS_SYNC) != 0) { | |
| 242 | + fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name, | |
| 243 | + vdso_path, strerror(errno)); | |
| 244 | + return EXIT_FAILURE; | |
| 245 | + } | |
| 246 | + | |
| 247 | + out_file = fopen(out_path, "w"); | |
| 248 | + if (!out_file) { | |
| 249 | + fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name, | |
| 250 | + out_path, strerror(errno)); | |
| 251 | + return EXIT_FAILURE; | |
| 252 | + } | |
| 253 | + | |
| 254 | + fprintf(out_file, "/* Automatically generated - do not edit */\n"); | |
| 255 | + fprintf(out_file, "#include <linux/linkage.h>\n"); | |
| 256 | + fprintf(out_file, "#include <linux/mm.h>\n"); | |
| 257 | + fprintf(out_file, "#include <asm/vdso.h>\n"); | |
| 258 | + | |
| 259 | + /* Write out the stripped VDSO data. */ | |
| 260 | + fprintf(out_file, | |
| 261 | + "static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t", | |
| 262 | + vdso_size); | |
| 263 | + for (i = 0; i < vdso_size; i++) { | |
| 264 | + if (!(i % 10)) | |
| 265 | + fprintf(out_file, "\n\t"); | |
| 266 | + fprintf(out_file, "0x%02x, ", ((unsigned char *)vdso)[i]); | |
| 267 | + } | |
| 268 | + fprintf(out_file, "\n};\n"); | |
| 269 | + | |
| 270 | + /* Preallocate a page array. */ | |
| 271 | + fprintf(out_file, | |
| 272 | + "static struct page *vdso_pages[PAGE_ALIGN(%zu) / PAGE_SIZE];\n", | |
| 273 | + vdso_size); | |
| 274 | + | |
| 275 | + fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n", | |
| 276 | + (vdso_name[0]) ? "_" : "", vdso_name); | |
| 277 | + fprintf(out_file, "\t.data = vdso_data,\n"); | |
| 278 | + fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size); | |
| 279 | + fprintf(out_file, "\t.mapping = {\n"); | |
| 280 | + fprintf(out_file, "\t\t.name = \"[vdso]\",\n"); | |
| 281 | + fprintf(out_file, "\t\t.pages = vdso_pages,\n"); | |
| 282 | + fprintf(out_file, "\t},\n"); | |
| 283 | + | |
| 284 | + /* Calculate and write symbol offsets to <output file> */ | |
| 285 | + if (!get_symbols(dbg_vdso_path, dbg_vdso)) { | |
| 286 | + unlink(out_path); | |
| 287 | + return EXIT_FAILURE; | |
| 288 | + } | |
| 289 | + | |
| 290 | + fprintf(out_file, "};\n"); | |
| 291 | + | |
| 292 | + return EXIT_SUCCESS; | |
| 293 | +} | |
| @@ -0,0 +1,187 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +static inline bool FUNC(patch_vdso)(const char *path, void *vdso) | |
| 12 | +{ | |
| 13 | + const ELF(Ehdr) *ehdr = vdso; | |
| 14 | + void *shdrs; | |
| 15 | + ELF(Shdr) *shdr; | |
| 16 | + char *shstrtab, *name; | |
| 17 | + uint16_t sh_count, sh_entsize, i; | |
| 18 | + unsigned int local_gotno, symtabno, gotsym; | |
| 19 | + ELF(Dyn) *dyn = NULL; | |
| 20 | + | |
| 21 | + shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff); | |
| 22 | + sh_count = swap_uint16(ehdr->e_shnum); | |
| 23 | + sh_entsize = swap_uint16(ehdr->e_shentsize); | |
| 24 | + | |
| 25 | + shdr = shdrs + (sh_entsize * swap_uint16(ehdr->e_shstrndx)); | |
| 26 | + shstrtab = vdso + FUNC(swap_uint)(shdr->sh_offset); | |
| 27 | + | |
| 28 | + for (i = 0; i < sh_count; i++) { | |
| 29 | + shdr = shdrs + (i * sh_entsize); | |
| 30 | + name = shstrtab + swap_uint32(shdr->sh_name); | |
| 31 | + | |
| 32 | + /* | |
| 33 | + * Ensure there are no relocation sections - ld.so does not | |
| 34 | + * relocate the VDSO so if there are relocations things will | |
| 35 | + * break. | |
| 36 | + */ | |
| 37 | + switch (swap_uint32(shdr->sh_type)) { | |
| 38 | + case SHT_REL: | |
| 39 | + case SHT_RELA: | |
| 40 | + fprintf(stderr, | |
| 41 | + "%s: '%s' contains relocation sections\n", | |
| 42 | + program_name, path); | |
| 43 | + return false; | |
| 44 | + case SHT_DYNAMIC: | |
| 45 | + dyn = vdso + FUNC(swap_uint)(shdr->sh_offset); | |
| 46 | + break; | |
| 47 | + } | |
| 48 | + | |
| 49 | + /* Check for existing sections. */ | |
| 50 | + if (strcmp(name, ".MIPS.abiflags") == 0) { | |
| 51 | + fprintf(stderr, | |
| 52 | + "%s: '%s' already contains a '.MIPS.abiflags' section\n", | |
| 53 | + program_name, path); | |
| 54 | + return false; | |
| 55 | + } | |
| 56 | + | |
| 57 | + if (strcmp(name, ".mips_abiflags") == 0) { | |
| 58 | + strcpy(name, ".MIPS.abiflags"); | |
| 59 | + shdr->sh_type = swap_uint32(SHT_MIPS_ABIFLAGS); | |
| 60 | + shdr->sh_entsize = shdr->sh_size; | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + /* | |
| 65 | + * Ensure the GOT has no entries other than the standard 2, for the same | |
| 66 | + * reason we check that there's no relocation sections above. | |
| 67 | + * The standard two entries are: | |
| 68 | + * - Lazy resolver | |
| 69 | + * - Module pointer | |
| 70 | + */ | |
| 71 | + if (dyn) { | |
| 72 | + local_gotno = symtabno = gotsym = 0; | |
| 73 | + | |
| 74 | + while (FUNC(swap_uint)(dyn->d_tag) != DT_NULL) { | |
| 75 | + switch (FUNC(swap_uint)(dyn->d_tag)) { | |
| 76 | + /* | |
| 77 | + * This member holds the number of local GOT entries. | |
| 78 | + */ | |
| 79 | + case DT_MIPS_LOCAL_GOTNO: | |
| 80 | + local_gotno = FUNC(swap_uint)(dyn->d_un.d_val); | |
| 81 | + break; | |
| 82 | + /* | |
| 83 | + * This member holds the number of entries in the | |
| 84 | + * .dynsym section. | |
| 85 | + */ | |
| 86 | + case DT_MIPS_SYMTABNO: | |
| 87 | + symtabno = FUNC(swap_uint)(dyn->d_un.d_val); | |
| 88 | + break; | |
| 89 | + /* | |
| 90 | + * This member holds the index of the first dynamic | |
| 91 | + * symbol table entry that corresponds to an entry in | |
| 92 | + * the GOT. | |
| 93 | + */ | |
| 94 | + case DT_MIPS_GOTSYM: | |
| 95 | + gotsym = FUNC(swap_uint)(dyn->d_un.d_val); | |
| 96 | + break; | |
| 97 | + } | |
| 98 | + | |
| 99 | + dyn++; | |
| 100 | + } | |
| 101 | + | |
| 102 | + if (local_gotno > 2 || symtabno - gotsym) { | |
| 103 | + fprintf(stderr, | |
| 104 | + "%s: '%s' contains unexpected GOT entries\n", | |
| 105 | + program_name, path); | |
| 106 | + return false; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + | |
| 110 | + return true; | |
| 111 | +} | |
| 112 | + | |
| 113 | +static inline bool FUNC(get_symbols)(const char *path, void *vdso) | |
| 114 | +{ | |
| 115 | + const ELF(Ehdr) *ehdr = vdso; | |
| 116 | + void *shdrs, *symtab; | |
| 117 | + ELF(Shdr) *shdr; | |
| 118 | + const ELF(Sym) *sym; | |
| 119 | + char *strtab, *name; | |
| 120 | + uint16_t sh_count, sh_entsize, st_count, st_entsize, i, j; | |
| 121 | + uint64_t offset; | |
| 122 | + uint32_t flags; | |
| 123 | + | |
| 124 | + shdrs = vdso + FUNC(swap_uint)(ehdr->e_shoff); | |
| 125 | + sh_count = swap_uint16(ehdr->e_shnum); | |
| 126 | + sh_entsize = swap_uint16(ehdr->e_shentsize); | |
| 127 | + | |
| 128 | + for (i = 0; i < sh_count; i++) { | |
| 129 | + shdr = shdrs + (i * sh_entsize); | |
| 130 | + | |
| 131 | + if (swap_uint32(shdr->sh_type) == SHT_SYMTAB) | |
| 132 | + break; | |
| 133 | + } | |
| 134 | + | |
| 135 | + if (i == sh_count) { | |
| 136 | + fprintf(stderr, "%s: '%s' has no symbol table\n", program_name, | |
| 137 | + path); | |
| 138 | + return false; | |
| 139 | + } | |
| 140 | + | |
| 141 | + /* Get flags */ | |
| 142 | + flags = swap_uint32(ehdr->e_flags); | |
| 143 | + if (elf_class == ELFCLASS64) | |
| 144 | + elf_abi = ABI_N64; | |
| 145 | + else if (flags & EF_MIPS_ABI2) | |
| 146 | + elf_abi = ABI_N32; | |
| 147 | + else | |
| 148 | + elf_abi = ABI_O32; | |
| 149 | + | |
| 150 | + /* Get symbol table. */ | |
| 151 | + symtab = vdso + FUNC(swap_uint)(shdr->sh_offset); | |
| 152 | + st_entsize = FUNC(swap_uint)(shdr->sh_entsize); | |
| 153 | + st_count = FUNC(swap_uint)(shdr->sh_size) / st_entsize; | |
| 154 | + | |
| 155 | + /* Get string table. */ | |
| 156 | + shdr = shdrs + (swap_uint32(shdr->sh_link) * sh_entsize); | |
| 157 | + strtab = vdso + FUNC(swap_uint)(shdr->sh_offset); | |
| 158 | + | |
| 159 | + /* Write offsets for symbols needed by the kernel. */ | |
| 160 | + for (i = 0; vdso_symbols[i].name; i++) { | |
| 161 | + if (!(vdso_symbols[i].abis & elf_abi)) | |
| 162 | + continue; | |
| 163 | + | |
| 164 | + for (j = 0; j < st_count; j++) { | |
| 165 | + sym = symtab + (j * st_entsize); | |
| 166 | + name = strtab + swap_uint32(sym->st_name); | |
| 167 | + | |
| 168 | + if (!strcmp(name, vdso_symbols[i].name)) { | |
| 169 | + offset = FUNC(swap_uint)(sym->st_value); | |
| 170 | + | |
| 171 | + fprintf(out_file, | |
| 172 | + "\t.%s = 0x%" PRIx64 ",\n", | |
| 173 | + vdso_symbols[i].offset_name, offset); | |
| 174 | + break; | |
| 175 | + } | |
| 176 | + } | |
| 177 | + | |
| 178 | + if (j == st_count) { | |
| 179 | + fprintf(stderr, | |
| 180 | + "%s: '%s' is missing required symbol '%s'\n", | |
| 181 | + program_name, path, vdso_symbols[i].name); | |
| 182 | + return false; | |
| 183 | + } | |
| 184 | + } | |
| 185 | + | |
| 186 | + return true; | |
| 187 | +} | |
| @@ -0,0 +1,232 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include "vdso.h" | |
| 12 | + | |
| 13 | +#include <linux/compiler.h> | |
| 14 | +#include <linux/irqchip/mips-gic.h> | |
| 15 | +#include <linux/time.h> | |
| 16 | + | |
| 17 | +#include <asm/clocksource.h> | |
| 18 | +#include <asm/io.h> | |
| 19 | +#include <asm/mips-cm.h> | |
| 20 | +#include <asm/unistd.h> | |
| 21 | +#include <asm/vdso.h> | |
| 22 | + | |
| 23 | +static __always_inline int do_realtime_coarse(struct timespec *ts, | |
| 24 | + const union mips_vdso_data *data) | |
| 25 | +{ | |
| 26 | + u32 start_seq; | |
| 27 | + | |
| 28 | + do { | |
| 29 | + start_seq = vdso_data_read_begin(data); | |
| 30 | + | |
| 31 | + ts->tv_sec = data->xtime_sec; | |
| 32 | + ts->tv_nsec = data->xtime_nsec >> data->cs_shift; | |
| 33 | + } while (vdso_data_read_retry(data, start_seq)); | |
| 34 | + | |
| 35 | + return 0; | |
| 36 | +} | |
| 37 | + | |
| 38 | +static __always_inline int do_monotonic_coarse(struct timespec *ts, | |
| 39 | + const union mips_vdso_data *data) | |
| 40 | +{ | |
| 41 | + u32 start_seq; | |
| 42 | + u32 to_mono_sec; | |
| 43 | + u32 to_mono_nsec; | |
| 44 | + | |
| 45 | + do { | |
| 46 | + start_seq = vdso_data_read_begin(data); | |
| 47 | + | |
| 48 | + ts->tv_sec = data->xtime_sec; | |
| 49 | + ts->tv_nsec = data->xtime_nsec >> data->cs_shift; | |
| 50 | + | |
| 51 | + to_mono_sec = data->wall_to_mono_sec; | |
| 52 | + to_mono_nsec = data->wall_to_mono_nsec; | |
| 53 | + } while (vdso_data_read_retry(data, start_seq)); | |
| 54 | + | |
| 55 | + ts->tv_sec += to_mono_sec; | |
| 56 | + timespec_add_ns(ts, to_mono_nsec); | |
| 57 | + | |
| 58 | + return 0; | |
| 59 | +} | |
| 60 | + | |
| 61 | +#ifdef CONFIG_CSRC_R4K | |
| 62 | + | |
| 63 | +static __always_inline u64 read_r4k_count(void) | |
| 64 | +{ | |
| 65 | + unsigned int count; | |
| 66 | + | |
| 67 | + __asm__ __volatile__( | |
| 68 | + " .set push\n" | |
| 69 | + " .set mips32r2\n" | |
| 70 | + " rdhwr %0, $2\n" | |
| 71 | + " .set pop\n" | |
| 72 | + : "=r" (count)); | |
| 73 | + | |
| 74 | + return count; | |
| 75 | +} | |
| 76 | + | |
| 77 | +#endif | |
| 78 | + | |
| 79 | +#ifdef CONFIG_CLKSRC_MIPS_GIC | |
| 80 | + | |
| 81 | +static __always_inline u64 read_gic_count(const union mips_vdso_data *data) | |
| 82 | +{ | |
| 83 | + void __iomem *gic = get_gic(data); | |
| 84 | + u32 hi, hi2, lo; | |
| 85 | + | |
| 86 | + do { | |
| 87 | + hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); | |
| 88 | + lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS); | |
| 89 | + hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); | |
| 90 | + } while (hi2 != hi); | |
| 91 | + | |
| 92 | + return (((u64)hi) << 32) + lo; | |
| 93 | +} | |
| 94 | + | |
| 95 | +#endif | |
| 96 | + | |
| 97 | +static __always_inline u64 get_ns(const union mips_vdso_data *data) | |
| 98 | +{ | |
| 99 | + u64 cycle_now, delta, nsec; | |
| 100 | + | |
| 101 | + switch (data->clock_mode) { | |
| 102 | +#ifdef CONFIG_CSRC_R4K | |
| 103 | + case VDSO_CLOCK_R4K: | |
| 104 | + cycle_now = read_r4k_count(); | |
| 105 | + break; | |
| 106 | +#endif | |
| 107 | +#ifdef CONFIG_CLKSRC_MIPS_GIC | |
| 108 | + case VDSO_CLOCK_GIC: | |
| 109 | + cycle_now = read_gic_count(data); | |
| 110 | + break; | |
| 111 | +#endif | |
| 112 | + default: | |
| 113 | + return 0; | |
| 114 | + } | |
| 115 | + | |
| 116 | + delta = (cycle_now - data->cs_cycle_last) & data->cs_mask; | |
| 117 | + | |
| 118 | + nsec = (delta * data->cs_mult) + data->xtime_nsec; | |
| 119 | + nsec >>= data->cs_shift; | |
| 120 | + | |
| 121 | + return nsec; | |
| 122 | +} | |
| 123 | + | |
| 124 | +static __always_inline int do_realtime(struct timespec *ts, | |
| 125 | + const union mips_vdso_data *data) | |
| 126 | +{ | |
| 127 | + u32 start_seq; | |
| 128 | + u64 ns; | |
| 129 | + | |
| 130 | + do { | |
| 131 | + start_seq = vdso_data_read_begin(data); | |
| 132 | + | |
| 133 | + if (data->clock_mode == VDSO_CLOCK_NONE) | |
| 134 | + return -ENOSYS; | |
| 135 | + | |
| 136 | + ts->tv_sec = data->xtime_sec; | |
| 137 | + ns = get_ns(data); | |
| 138 | + } while (vdso_data_read_retry(data, start_seq)); | |
| 139 | + | |
| 140 | + ts->tv_nsec = 0; | |
| 141 | + timespec_add_ns(ts, ns); | |
| 142 | + | |
| 143 | + return 0; | |
| 144 | +} | |
| 145 | + | |
| 146 | +static __always_inline int do_monotonic(struct timespec *ts, | |
| 147 | + const union mips_vdso_data *data) | |
| 148 | +{ | |
| 149 | + u32 start_seq; | |
| 150 | + u64 ns; | |
| 151 | + u32 to_mono_sec; | |
| 152 | + u32 to_mono_nsec; | |
| 153 | + | |
| 154 | + do { | |
| 155 | + start_seq = vdso_data_read_begin(data); | |
| 156 | + | |
| 157 | + if (data->clock_mode == VDSO_CLOCK_NONE) | |
| 158 | + return -ENOSYS; | |
| 159 | + | |
| 160 | + ts->tv_sec = data->xtime_sec; | |
| 161 | + ns = get_ns(data); | |
| 162 | + | |
| 163 | + to_mono_sec = data->wall_to_mono_sec; | |
| 164 | + to_mono_nsec = data->wall_to_mono_nsec; | |
| 165 | + } while (vdso_data_read_retry(data, start_seq)); | |
| 166 | + | |
| 167 | + ts->tv_sec += to_mono_sec; | |
| 168 | + ts->tv_nsec = 0; | |
| 169 | + timespec_add_ns(ts, ns + to_mono_nsec); | |
| 170 | + | |
| 171 | + return 0; | |
| 172 | +} | |
| 173 | + | |
| 174 | +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL | |
| 175 | + | |
| 176 | +/* | |
| 177 | + * This is behind the ifdef so that we don't provide the symbol when there's no | |
| 178 | + * possibility of there being a usable clocksource, because there's nothing we | |
| 179 | + * can do without it. When libc fails the symbol lookup it should fall back on | |
| 180 | + * the standard syscall path. | |
| 181 | + */ | |
| 182 | +int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) | |
| 183 | +{ | |
| 184 | + const union mips_vdso_data *data = get_vdso_data(); | |
| 185 | + struct timespec ts; | |
| 186 | + int ret; | |
| 187 | + | |
| 188 | + ret = do_realtime(&ts, data); | |
| 189 | + if (ret) | |
| 190 | + return ret; | |
| 191 | + | |
| 192 | + if (tv) { | |
| 193 | + tv->tv_sec = ts.tv_sec; | |
| 194 | + tv->tv_usec = ts.tv_nsec / 1000; | |
| 195 | + } | |
| 196 | + | |
| 197 | + if (tz) { | |
| 198 | + tz->tz_minuteswest = data->tz_minuteswest; | |
| 199 | + tz->tz_dsttime = data->tz_dsttime; | |
| 200 | + } | |
| 201 | + | |
| 202 | + return 0; | |
| 203 | +} | |
| 204 | + | |
| 205 | +#endif /* CONFIG_CLKSRC_MIPS_GIC */ | |
| 206 | + | |
| 207 | +int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts) | |
| 208 | +{ | |
| 209 | + const union mips_vdso_data *data = get_vdso_data(); | |
| 210 | + int ret; | |
| 211 | + | |
| 212 | + switch (clkid) { | |
| 213 | + case CLOCK_REALTIME_COARSE: | |
| 214 | + ret = do_realtime_coarse(ts, data); | |
| 215 | + break; | |
| 216 | + case CLOCK_MONOTONIC_COARSE: | |
| 217 | + ret = do_monotonic_coarse(ts, data); | |
| 218 | + break; | |
| 219 | + case CLOCK_REALTIME: | |
| 220 | + ret = do_realtime(ts, data); | |
| 221 | + break; | |
| 222 | + case CLOCK_MONOTONIC: | |
| 223 | + ret = do_monotonic(ts, data); | |
| 224 | + break; | |
| 225 | + default: | |
| 226 | + ret = -ENOSYS; | |
| 227 | + break; | |
| 228 | + } | |
| 229 | + | |
| 230 | + /* If we return -ENOSYS libc should fall back to a syscall. */ | |
| 231 | + return ret; | |
| 232 | +} | |
| @@ -0,0 +1,49 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include "vdso.h" | |
| 12 | + | |
| 13 | +#include <uapi/asm/unistd.h> | |
| 14 | + | |
| 15 | +#include <asm/regdef.h> | |
| 16 | +#include <asm/asm.h> | |
| 17 | + | |
| 18 | + .section .text | |
| 19 | + .cfi_sections .debug_frame | |
| 20 | + | |
| 21 | +LEAF(__vdso_rt_sigreturn) | |
| 22 | + .cfi_startproc | |
| 23 | + .frame sp, 0, ra | |
| 24 | + .mask 0x00000000, 0 | |
| 25 | + .fmask 0x00000000, 0 | |
| 26 | + .cfi_signal_frame | |
| 27 | + | |
| 28 | + li v0, __NR_rt_sigreturn | |
| 29 | + syscall | |
| 30 | + | |
| 31 | + .cfi_endproc | |
| 32 | + END(__vdso_rt_sigreturn) | |
| 33 | + | |
| 34 | +#if _MIPS_SIM == _MIPS_SIM_ABI32 | |
| 35 | + | |
| 36 | +LEAF(__vdso_sigreturn) | |
| 37 | + .cfi_startproc | |
| 38 | + .frame sp, 0, ra | |
| 39 | + .mask 0x00000000, 0 | |
| 40 | + .fmask 0x00000000, 0 | |
| 41 | + .cfi_signal_frame | |
| 42 | + | |
| 43 | + li v0, __NR_sigreturn | |
| 44 | + syscall | |
| 45 | + | |
| 46 | + .cfi_endproc | |
| 47 | + END(__vdso_sigreturn) | |
| 48 | + | |
| 49 | +#endif | |
| @@ -0,0 +1,89 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <asm/sgidefs.h> | |
| 12 | + | |
| 13 | +#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT) | |
| 14 | + | |
| 15 | +/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */ | |
| 16 | +#undef CONFIG_64BIT | |
| 17 | +#define CONFIG_32BIT 1 | |
| 18 | +#ifndef __ASSEMBLY__ | |
| 19 | +#include <asm-generic/atomic64.h> | |
| 20 | +#endif | |
| 21 | +#endif | |
| 22 | + | |
| 23 | +#ifndef __ASSEMBLY__ | |
| 24 | + | |
| 25 | +#include <asm/asm.h> | |
| 26 | +#include <asm/page.h> | |
| 27 | +#include <asm/vdso.h> | |
| 28 | + | |
| 29 | +static inline unsigned long get_vdso_base(void) | |
| 30 | +{ | |
| 31 | + unsigned long addr; | |
| 32 | + | |
| 33 | + /* | |
| 34 | + * We can't use cpu_has_mips_r6 since it needs the cpu_data[] | |
| 35 | + * kernel symbol. | |
| 36 | + */ | |
| 37 | +#ifdef CONFIG_CPU_MIPSR6 | |
| 38 | + /* | |
| 39 | + * lapc <symbol> is an alias to addiupc reg, <symbol> - . | |
| 40 | + * | |
| 41 | + * We can't use addiupc because there is no label-label | |
| 42 | + * support for the addiupc reloc | |
| 43 | + */ | |
| 44 | + __asm__("lapc %0, _start \n" | |
| 45 | + : "=r" (addr) : :); | |
| 46 | +#else | |
| 47 | + /* | |
| 48 | + * Get the base load address of the VDSO. We have to avoid generating | |
| 49 | + * relocations and references to the GOT because ld.so does not peform | |
| 50 | + * relocations on the VDSO. We use the current offset from the VDSO base | |
| 51 | + * and perform a PC-relative branch which gives the absolute address in | |
| 52 | + * ra, and take the difference. The assembler chokes on | |
| 53 | + * "li %0, _start - .", so embed the offset as a word and branch over | |
| 54 | + * it. | |
| 55 | + * | |
| 56 | + */ | |
| 57 | + | |
| 58 | + __asm__( | |
| 59 | + " .set push \n" | |
| 60 | + " .set noreorder \n" | |
| 61 | + " bal 1f \n" | |
| 62 | + " nop \n" | |
| 63 | + " .word _start - . \n" | |
| 64 | + "1: lw %0, 0($31) \n" | |
| 65 | + " " STR(PTR_ADDU) " %0, $31, %0 \n" | |
| 66 | + " .set pop \n" | |
| 67 | + : "=r" (addr) | |
| 68 | + : | |
| 69 | + : "$31"); | |
| 70 | +#endif /* CONFIG_CPU_MIPSR6 */ | |
| 71 | + | |
| 72 | + return addr; | |
| 73 | +} | |
| 74 | + | |
| 75 | +static inline const union mips_vdso_data *get_vdso_data(void) | |
| 76 | +{ | |
| 77 | + return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE); | |
| 78 | +} | |
| 79 | + | |
| 80 | +#ifdef CONFIG_CLKSRC_MIPS_GIC | |
| 81 | + | |
| 82 | +static inline void __iomem *get_gic(const union mips_vdso_data *data) | |
| 83 | +{ | |
| 84 | + return (void __iomem *)data - PAGE_SIZE; | |
| 85 | +} | |
| 86 | + | |
| 87 | +#endif /* CONFIG_CLKSRC_MIPS_GIC */ | |
| 88 | + | |
| 89 | +#endif /* __ASSEMBLY__ */ | |
| @@ -0,0 +1,105 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Imagination Technologies | |
| 3 | + * Author: Alex Smith <alex.smith@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <asm/sgidefs.h> | |
| 12 | + | |
| 13 | +#if _MIPS_SIM == _MIPS_SIM_ABI64 | |
| 14 | +OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips") | |
| 15 | +#elif _MIPS_SIM == _MIPS_SIM_NABI32 | |
| 16 | +OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", "elf32-ntradlittlemips") | |
| 17 | +#else | |
| 18 | +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips") | |
| 19 | +#endif | |
| 20 | + | |
| 21 | +OUTPUT_ARCH(mips) | |
| 22 | + | |
| 23 | +SECTIONS | |
| 24 | +{ | |
| 25 | + PROVIDE(_start = .); | |
| 26 | + . = SIZEOF_HEADERS; | |
| 27 | + | |
| 28 | + /* | |
| 29 | + * In order to retain compatibility with older toolchains we provide the | |
| 30 | + * ABI flags section ourself. Newer assemblers will automatically | |
| 31 | + * generate .MIPS.abiflags sections so we discard such input sections, | |
| 32 | + * and then manually define our own section here. genvdso will patch | |
| 33 | + * this section to have the correct name/type. | |
| 34 | + */ | |
| 35 | + .mips_abiflags : { *(.mips_abiflags) } :text :abiflags | |
| 36 | + | |
| 37 | + .reginfo : { *(.reginfo) } :text :reginfo | |
| 38 | + | |
| 39 | + .hash : { *(.hash) } :text | |
| 40 | + .gnu.hash : { *(.gnu.hash) } | |
| 41 | + .dynsym : { *(.dynsym) } | |
| 42 | + .dynstr : { *(.dynstr) } | |
| 43 | + .gnu.version : { *(.gnu.version) } | |
| 44 | + .gnu.version_d : { *(.gnu.version_d) } | |
| 45 | + .gnu.version_r : { *(.gnu.version_r) } | |
| 46 | + | |
| 47 | + .note : { *(.note.*) } :text :note | |
| 48 | + | |
| 49 | + .text : { *(.text*) } :text | |
| 50 | + PROVIDE (__etext = .); | |
| 51 | + PROVIDE (_etext = .); | |
| 52 | + PROVIDE (etext = .); | |
| 53 | + | |
| 54 | + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr | |
| 55 | + .eh_frame : { KEEP (*(.eh_frame)) } :text | |
| 56 | + | |
| 57 | + .dynamic : { *(.dynamic) } :text :dynamic | |
| 58 | + | |
| 59 | + .rodata : { *(.rodata*) } :text | |
| 60 | + | |
| 61 | + _end = .; | |
| 62 | + PROVIDE(end = .); | |
| 63 | + | |
| 64 | + /DISCARD/ : { | |
| 65 | + *(.MIPS.abiflags) | |
| 66 | + *(.gnu.attributes) | |
| 67 | + *(.note.GNU-stack) | |
| 68 | + *(.data .data.* .gnu.linkonce.d.* .sdata*) | |
| 69 | + *(.bss .sbss .dynbss .dynsbss) | |
| 70 | + } | |
| 71 | +} | |
| 72 | + | |
| 73 | +PHDRS | |
| 74 | +{ | |
| 75 | + /* | |
| 76 | + * Provide a PT_MIPS_ABIFLAGS header to assign the ABI flags section | |
| 77 | + * to. We can specify the header type directly here so no modification | |
| 78 | + * is needed later on. | |
| 79 | + */ | |
| 80 | + abiflags 0x70000003; | |
| 81 | + | |
| 82 | + /* | |
| 83 | + * The ABI flags header must exist directly after the PT_INTERP header, | |
| 84 | + * so we must explicitly place the PT_MIPS_REGINFO header after it to | |
| 85 | + * stop the linker putting one in at the start. | |
| 86 | + */ | |
| 87 | + reginfo 0x70000000; | |
| 88 | + | |
| 89 | + text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ | |
| 90 | + dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | |
| 91 | + note PT_NOTE FLAGS(4); /* PF_R */ | |
| 92 | + eh_frame_hdr PT_GNU_EH_FRAME; | |
| 93 | +} | |
| 94 | + | |
| 95 | +VERSION | |
| 96 | +{ | |
| 97 | + LINUX_2.6 { | |
| 98 | +#ifndef DISABLE_MIPS_VDSO | |
| 99 | + global: | |
| 100 | + __vdso_clock_gettime; | |
| 101 | + __vdso_gettimeofday; | |
| 102 | +#endif | |
| 103 | + local: *; | |
| 104 | + }; | |
| 105 | +} | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +choice | |
| 2 | + prompt "Machine type" | |
| 3 | + depends on MACH_XILFPGA | |
| 4 | + default XILFPGA_NEXYS4DDR | |
| 5 | + | |
| 6 | +config XILFPGA_NEXYS4DDR | |
| 7 | + bool "Nexys4DDR by Digilent" | |
| 8 | + | |
| 9 | +endchoice | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +# | |
| 2 | +# Makefile for the Xilfpga | |
| 3 | +# | |
| 4 | + | |
| 5 | +obj-y += init.o | |
| 6 | +obj-y += intc.o | |
| 7 | +obj-y += time.o | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +platform-$(CONFIG_MACH_XILFPGA) += xilfpga/ | |
| 2 | +cflags-$(CONFIG_MACH_XILFPGA) += -I$(srctree)/arch/mips/include/asm/mach-xilfpga | |
| 3 | +load-$(CONFIG_MACH_XILFPGA) += 0xffffffff80100000 | |
| @@ -0,0 +1,57 @@ | ||
| 1 | +/* | |
| 2 | + * Xilfpga platform setup | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Imagination Technologies | |
| 5 | + * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify it | |
| 8 | + * under the terms and conditions of the GNU General Public License, | |
| 9 | + * version 2, as published by the Free Software Foundation. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <linux/of_fdt.h> | |
| 13 | +#include <linux/of_platform.h> | |
| 14 | + | |
| 15 | +#include <asm/prom.h> | |
| 16 | + | |
| 17 | +#define XILFPGA_UART_BASE 0xb0401000 | |
| 18 | + | |
| 19 | +const char *get_system_type(void) | |
| 20 | +{ | |
| 21 | + return "MIPSfpga"; | |
| 22 | +} | |
| 23 | + | |
| 24 | +void __init plat_mem_setup(void) | |
| 25 | +{ | |
| 26 | + __dt_setup_arch(__dtb_start); | |
| 27 | + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | |
| 28 | +} | |
| 29 | + | |
| 30 | +void __init prom_init(void) | |
| 31 | +{ | |
| 32 | + setup_8250_early_printk_port(XILFPGA_UART_BASE, 2, 50000); | |
| 33 | +} | |
| 34 | + | |
| 35 | +void __init prom_free_prom_memory(void) | |
| 36 | +{ | |
| 37 | +} | |
| 38 | + | |
| 39 | +void __init device_tree_init(void) | |
| 40 | +{ | |
| 41 | + if (!initial_boot_params) | |
| 42 | + return; | |
| 43 | + | |
| 44 | + unflatten_and_copy_device_tree(); | |
| 45 | +} | |
| 46 | + | |
| 47 | +static int __init plat_of_setup(void) | |
| 48 | +{ | |
| 49 | + if (!of_have_populated_dt()) | |
| 50 | + panic("Device tree not present"); | |
| 51 | + | |
| 52 | + if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL)) | |
| 53 | + panic("Failed to populate DT"); | |
| 54 | + | |
| 55 | + return 0; | |
| 56 | +} | |
| 57 | +arch_initcall(plat_of_setup); | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +/* | |
| 2 | + * Xilfpga interrupt controller setup | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Imagination Technologies | |
| 5 | + * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify it | |
| 8 | + * under the terms and conditions of the GNU General Public License, | |
| 9 | + * version 2, as published by the Free Software Foundation. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <linux/of.h> | |
| 13 | +#include <linux/of_irq.h> | |
| 14 | + | |
| 15 | +#include <asm/irq_cpu.h> | |
| 16 | + | |
| 17 | +static struct of_device_id of_irq_ids[] __initdata = { | |
| 18 | + { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, | |
| 19 | + {}, | |
| 20 | +}; | |
| 21 | + | |
| 22 | +void __init arch_init_irq(void) | |
| 23 | +{ | |
| 24 | + of_irq_init(of_irq_ids); | |
| 25 | +} | |
| @@ -0,0 +1,41 @@ | ||
| 1 | +/* | |
| 2 | + * Xilfpga clocksource/timer setup | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Imagination Technologies | |
| 5 | + * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify it | |
| 8 | + * under the terms and conditions of the GNU General Public License, | |
| 9 | + * version 2, as published by the Free Software Foundation. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <linux/clk.h> | |
| 13 | +#include <linux/clk-provider.h> | |
| 14 | +#include <linux/clocksource.h> | |
| 15 | +#include <linux/of.h> | |
| 16 | + | |
| 17 | +#include <asm/time.h> | |
| 18 | + | |
| 19 | +void __init plat_time_init(void) | |
| 20 | +{ | |
| 21 | + struct device_node *np; | |
| 22 | + struct clk *clk; | |
| 23 | + | |
| 24 | + of_clk_init(NULL); | |
| 25 | + clocksource_probe(); | |
| 26 | + | |
| 27 | + np = of_get_cpu_node(0, NULL); | |
| 28 | + if (!np) { | |
| 29 | + pr_err("Failed to get CPU node\n"); | |
| 30 | + return; | |
| 31 | + } | |
| 32 | + | |
| 33 | + clk = of_clk_get(np, 0); | |
| 34 | + if (IS_ERR(clk)) { | |
| 35 | + pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); | |
| 36 | + return; | |
| 37 | + } | |
| 38 | + | |
| 39 | + mips_hpt_frequency = clk_get_rate(clk) / 2; | |
| 40 | + clk_put(clk); | |
| 41 | +} | |
| @@ -140,9 +140,10 @@ static cycle_t gic_hpt_read(struct clocksource *cs) · 139 unmodified lines | ||
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | static struct clocksource gic_clocksource = { |
| 143 | − .name = "GIC", | |
| 144 | − .read = gic_hpt_read, | |
| 145 | − .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
| 143 | + .name = "GIC", | |
| 144 | + .read = gic_hpt_read, | |
| 145 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
| 146 | + .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC }, | |
| 146 | 147 | }; |
| 147 | 148 | |
| 148 | 149 | static void __init __gic_clocksource_init(void) |
| @@ -29,6 +29,7 @@ struct gic_pcpu_mask { · 28 unmodified lines | ||
| 29 | 29 | DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | +static unsigned long __gic_base_addr; | |
| 32 | 33 | static void __iomem *gic_base; |
| 33 | 34 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
| 34 | 35 | static DEFINE_SPINLOCK(gic_lock); |
| @@ -301,6 +302,17 @@ int gic_get_c0_fdc_int(void) · 266 unmodified lines | ||
| 301 | 302 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC)); |
| 302 | 303 | } |
| 303 | 304 | |
| 305 | +int gic_get_usm_range(struct resource *gic_usm_res) | |
| 306 | +{ | |
| 307 | + if (!gic_present) | |
| 308 | + return -1; | |
| 309 | + | |
| 310 | + gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS; | |
| 311 | + gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1); | |
| 312 | + | |
| 313 | + return 0; | |
| 314 | +} | |
| 315 | + | |
| 304 | 316 | static void gic_handle_shared_int(bool chained) |
| 305 | 317 | { |
| 306 | 318 | unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4; |
| @@ -798,6 +810,8 @@ static void __init __gic_init(unsigned long gic_base_addr, · 491 unmodified lines | ||
| 798 | 810 | { |
| 799 | 811 | unsigned int gicconfig; |
| 800 | 812 | |
| 813 | + __gic_base_addr = gic_base_addr; | |
| 814 | + | |
| 801 | 815 | gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size); |
| 802 | 816 | |
| 803 | 817 | gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #define __LINUX_IRQCHIP_MIPS_GIC_H |
| 10 | 10 | |
| 11 | 11 | #include <linux/clocksource.h> |
| 12 | +#include <linux/ioport.h> | |
| 12 | 13 | |
| 13 | 14 | #define GIC_MAX_INTRS 256 |
| 14 | 15 | |
| @@ -245,6 +246,8 @@ · 230 unmodified lines | ||
| 245 | 246 | #define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) |
| 246 | 247 | #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) |
| 247 | 248 | |
| 249 | +#ifdef CONFIG_MIPS_GIC | |
| 250 | + | |
| 248 | 251 | extern unsigned int gic_present; |
| 249 | 252 | |
| 250 | 253 | extern void gic_init(unsigned long gic_base_addr, |
| @@ -264,4 +267,18 @@ extern unsigned int plat_ipi_resched_int_xlate(unsigned int); · 13 unmodified lines | ||
| 264 | 267 | extern int gic_get_c0_compare_int(void); |
| 265 | 268 | extern int gic_get_c0_perfcount_int(void); |
| 266 | 269 | extern int gic_get_c0_fdc_int(void); |
| 270 | +extern int gic_get_usm_range(struct resource *gic_usm_res); | |
| 271 | + | |
| 272 | +#else /* CONFIG_MIPS_GIC */ | |
| 273 | + | |
| 274 | +#define gic_present 0 | |
| 275 | + | |
| 276 | +static inline int gic_get_usm_range(struct resource *gic_usm_res) | |
| 277 | +{ | |
| 278 | + /* Shouldn't be called. */ | |
| 279 | + return -1; | |
| 280 | +} | |
| 281 | + | |
| 282 | +#endif /* CONFIG_MIPS_GIC */ | |
| 283 | + | |
| 267 | 284 | #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ |