-
-
Save cjdelisle/1bf34f4b16a476ce28dd5513e8a91dc1 to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/.get_maintainer.ignore b/.get_maintainer.ignore | |
deleted file mode 100644 | |
index cca6d870f7a5..000000000000 | |
--- a/.get_maintainer.ignore | |
+++ /dev/null | |
@@ -1 +0,0 @@ | |
-Christoph Hellwig <hch@lst.de> | |
diff --git a/.gitattributes b/.gitattributes | |
deleted file mode 100644 | |
index 89c411b5ce6b..000000000000 | |
--- a/.gitattributes | |
+++ /dev/null | |
@@ -1,2 +0,0 @@ | |
-*.c diff=cpp | |
-*.h diff=cpp | |
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt | |
index 0120c7f1109c..a46929bc1ec8 100644 | |
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt | |
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt | |
@@ -7,10 +7,19 @@ This file documents differences between the core properties in mmc.txt | |
and the properties used by the msdc driver. | |
Required properties: | |
-- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc" | |
+- compatible: value should be either of the following. | |
+ "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135 | |
+ "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173 | |
+ "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701 | |
+ "mediatek,mt7622-mmc": for MT7622 SoC | |
+ "mediatek,mt7623-mmc", "mediatek,mt2701-mmc": for MT7623 SoC | |
+ | |
+- reg: physical base address of the controller and length | |
- interrupts: Should contain MSDC interrupt number | |
-- clocks: MSDC source clock, HCLK | |
-- clock-names: "source", "hclk" | |
+- clocks: Should contain phandle for the clock feeding the MMC controller | |
+- clock-names: Should contain the following: | |
+ "source" - source clock (required) | |
+ "hclk" - HCLK which used for host (required) | |
- pinctrl-names: should be "default", "state_uhs" | |
- pinctrl-0: should contain default/high speed pin ctrl | |
- pinctrl-1: should contain uhs mode pin ctrl | |
@@ -21,6 +30,19 @@ Optional properties: | |
- assigned-clocks: PLL of the source clock | |
- assigned-clock-parents: parent of source clock, used for HS400 mode to get 400Mhz source clock | |
- hs400-ds-delay: HS400 DS delay setting | |
+- mediatek,hs200-cmd-int-delay: HS200 command internal delay setting. | |
+ This field has total 32 stages. | |
+ The value is an integer from 0 to 31. | |
+- mediatek,hs400-cmd-int-delay: HS400 command internal delay setting | |
+ This field has total 32 stages. | |
+ The value is an integer from 0 to 31. | |
+- mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection | |
+ If present,HS400 command responses are sampled on rising edges. | |
+ If not present,HS400 command responses are sampled on falling edges. | |
+- mediatek,latch-ck: Some SoCs do not support enhance_rx, need set correct latch-ck to avoid data crc | |
+ error caused by stop clock(fifo full) | |
+ Valid range = [0:0x7]. if not present, default value is 0. | |
+ applied to compatible "mediatek,mt2701-mmc". | |
Examples: | |
mmc0: mmc@11230000 { | |
@@ -38,4 +60,7 @@ mmc0: mmc@11230000 { | |
assigned-clocks = <&topckgen CLK_TOP_MSDC50_0_SEL>; | |
assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>; | |
hs400-ds-delay = <0x14015>; | |
+ mediatek,hs200-cmd-int-delay = <26>; | |
+ mediatek,hs400-cmd-int-delay = <14>; | |
+ mediatek,hs400-cmd-resp-sel-rising; | |
}; | |
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt | |
new file mode 100644 | |
index 000000000000..3a6ce55dd310 | |
--- /dev/null | |
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt | |
@@ -0,0 +1,284 @@ | |
+MediaTek Gen2 PCIe controller | |
+ | |
+Required properties: | |
+- compatible: Should contain one of the following strings: | |
+ "mediatek,mt2701-pcie" | |
+ "mediatek,mt2712-pcie" | |
+ "mediatek,mt7622-pcie" | |
+ "mediatek,mt7623-pcie" | |
+- device_type: Must be "pci" | |
+- reg: Base addresses and lengths of the PCIe subsys and root ports. | |
+- reg-names: Names of the above areas to use during resource lookup. | |
+- #address-cells: Address representation for root ports (must be 3) | |
+- #size-cells: Size representation for root ports (must be 2) | |
+- clocks: Must contain an entry for each entry in clock-names. | |
+ See ../clocks/clock-bindings.txt for details. | |
+- clock-names: | |
+ Mandatory entries: | |
+ - sys_ckN :transaction layer and data link layer clock | |
+ Required entries for MT2701/MT7623: | |
+ - free_ck :for reference clock of PCIe subsys | |
+ Required entries for MT2712/MT7622: | |
+ - ahb_ckN :AHB slave interface operating clock for CSR access and RC | |
+ initiated MMIO access | |
+ Required entries for MT7622: | |
+ - axi_ckN :application layer MMIO channel operating clock | |
+ - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when | |
+ pcie_mac_ck/pcie_pipe_ck is turned off | |
+ - obff_ckN :OBFF functional block operating clock | |
+ - pipe_ckN :LTSSM and PHY/MAC layer operating clock | |
+ where N starting from 0 to one less than the number of root ports. | |
+- phys: List of PHY specifiers (used by generic PHY framework). | |
+- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | |
+ number of PHYs as specified in *phys* property. | |
+- power-domains: A phandle and power domain specifier pair to the power domain | |
+ which is responsible for collapsing and restoring power to the peripheral. | |
+- bus-range: Range of bus numbers associated with this controller. | |
+- ranges: Ranges for the PCI memory and I/O regions. | |
+ | |
+Required properties for MT7623/MT2701: | |
+- #interrupt-cells: Size representation for interrupts (must be 1) | |
+- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | |
+ Please refer to the standard PCI bus binding document for a more detailed | |
+ explanation. | |
+- resets: Must contain an entry for each entry in reset-names. | |
+ See ../reset/reset.txt for details. | |
+- reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the | |
+ number of root ports. | |
+ | |
+Required properties for MT2712/MT7622: | |
+-interrupts: A list of interrupt outputs of the controller, must have one | |
+ entry for each PCIe port | |
+ | |
+In addition, the device tree node must have sub-nodes describing each | |
+PCIe port interface, having the following mandatory properties: | |
+ | |
+Required properties: | |
+- device_type: Must be "pci" | |
+- reg: Only the first four bytes are used to refer to the correct bus number | |
+ and device number. | |
+- #address-cells: Must be 3 | |
+- #size-cells: Must be 2 | |
+- #interrupt-cells: Must be 1 | |
+- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | |
+ Please refer to the standard PCI bus binding document for a more detailed | |
+ explanation. | |
+- ranges: Sub-ranges distributed from the PCIe controller node. An empty | |
+ property is sufficient. | |
+- num-lanes: Number of lanes to use for this port. | |
+ | |
+Examples for MT7623: | |
+ | |
+ hifsys: syscon@1a000000 { | |
+ compatible = "mediatek,mt7623-hifsys", | |
+ "mediatek,mt2701-hifsys", | |
+ "syscon"; | |
+ reg = <0 0x1a000000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ #reset-cells = <1>; | |
+ }; | |
+ | |
+ pcie: pcie-controller@1a140000 { | |
+ compatible = "mediatek,mt7623-pcie"; | |
+ device_type = "pci"; | |
+ reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ | |
+ <0 0x1a142000 0 0x1000>, /* Port0 registers */ | |
+ <0 0x1a143000 0 0x1000>, /* Port1 registers */ | |
+ <0 0x1a144000 0 0x1000>; /* Port2 registers */ | |
+ reg-names = "subsys", "port0", "port1", "port2"; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ interrupt-map-mask = <0xf800 0 0 0>; | |
+ interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, | |
+ <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, | |
+ <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>, | |
+ <&hifsys CLK_HIFSYS_PCIE0>, | |
+ <&hifsys CLK_HIFSYS_PCIE1>, | |
+ <&hifsys CLK_HIFSYS_PCIE2>; | |
+ clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; | |
+ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, | |
+ <&hifsys MT2701_HIFSYS_PCIE1_RST>, | |
+ <&hifsys MT2701_HIFSYS_PCIE2_RST>; | |
+ reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; | |
+ phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, | |
+ <&pcie2_phy PHY_TYPE_PCIE>; | |
+ phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; | |
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | |
+ bus-range = <0x00 0xff>; | |
+ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ | |
+ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ | |
+ | |
+ pcie@0,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0000 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ interrupt-map-mask = <0 0 0 0>; | |
+ interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ }; | |
+ | |
+ pcie@1,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0800 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ interrupt-map-mask = <0 0 0 0>; | |
+ interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ }; | |
+ | |
+ pcie@2,0 { | |
+ device_type = "pci"; | |
+ reg = <0x1000 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ interrupt-map-mask = <0 0 0 0>; | |
+ interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ }; | |
+ }; | |
+ | |
+Examples for MT2712: | |
+ pcie: pcie@11700000 { | |
+ compatible = "mediatek,mt2712-pcie"; | |
+ device_type = "pci"; | |
+ reg = <0 0x11700000 0 0x1000>, | |
+ <0 0x112ff000 0 0x1000>; | |
+ reg-names = "port0", "port1"; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, | |
+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; | |
+ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, | |
+ <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, | |
+ <&pericfg CLK_PERI_PCIE0>, | |
+ <&pericfg CLK_PERI_PCIE1>; | |
+ clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; | |
+ phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; | |
+ phy-names = "pcie-phy0", "pcie-phy1"; | |
+ bus-range = <0x00 0xff>; | |
+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; | |
+ | |
+ pcie0: pcie@0,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0000 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc0 0>, | |
+ <0 0 0 2 &pcie_intc0 1>, | |
+ <0 0 0 3 &pcie_intc0 2>, | |
+ <0 0 0 4 &pcie_intc0 3>; | |
+ pcie_intc0: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ | |
+ pcie1: pcie@1,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0800 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>, | |
+ <0 0 0 2 &pcie_intc1 1>, | |
+ <0 0 0 3 &pcie_intc1 2>, | |
+ <0 0 0 4 &pcie_intc1 3>; | |
+ pcie_intc1: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ }; | |
+ | |
+Examples for MT7622: | |
+ pcie: pcie@1a140000 { | |
+ compatible = "mediatek,mt7622-pcie"; | |
+ device_type = "pci"; | |
+ reg = <0 0x1a140000 0 0x1000>, | |
+ <0 0x1a143000 0 0x1000>, | |
+ <0 0x1a145000 0 0x1000>; | |
+ reg-names = "subsys", "port0", "port1"; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P1_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P0_AHB_EN>, | |
+ <&pciesys CLK_PCIE_P1_AHB_EN>, | |
+ <&pciesys CLK_PCIE_P0_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P1_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P0_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P1_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P0_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P1_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P0_PIPE_EN>, | |
+ <&pciesys CLK_PCIE_P1_PIPE_EN>; | |
+ clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", | |
+ "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", | |
+ "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; | |
+ phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; | |
+ phy-names = "pcie-phy0", "pcie-phy1"; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | |
+ bus-range = <0x00 0xff>; | |
+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; | |
+ | |
+ pcie0: pcie@0,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0000 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc0 0>, | |
+ <0 0 0 2 &pcie_intc0 1>, | |
+ <0 0 0 3 &pcie_intc0 2>, | |
+ <0 0 0 4 &pcie_intc0 3>; | |
+ pcie_intc0: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ | |
+ pcie1: pcie@1,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0800 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>, | |
+ <0 0 0 2 &pcie_intc1 1>, | |
+ <0 0 0 3 &pcie_intc1 2>, | |
+ <0 0 0 4 &pcie_intc1 3>; | |
+ pcie_intc1: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ }; | |
diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt | |
deleted file mode 100644 | |
index 33a2b1ee3f3e..000000000000 | |
--- a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt | |
+++ /dev/null | |
@@ -1,70 +0,0 @@ | |
-mt65xx USB3.0 PHY binding | |
--------------------------- | |
- | |
-This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC. | |
- | |
-Required properties (controller (parent) node): | |
- - compatible : should be one of | |
- "mediatek,mt2701-u3phy" | |
- "mediatek,mt8173-u3phy" | |
- - reg : offset and length of register for phy, exclude port's | |
- register. | |
- - clocks : a list of phandle + clock-specifier pairs, one for each | |
- entry in clock-names | |
- - clock-names : must contain | |
- "u3phya_ref": for reference clock of usb3.0 analog phy. | |
- | |
-Required nodes : a sub-node is required for each port the controller | |
- provides. Address range information including the usual | |
- 'reg' property is used inside these nodes to describe | |
- the controller's topology. | |
- | |
-Required properties (port (child) node): | |
-- reg : address and length of the register set for the port. | |
-- #phy-cells : should be 1 (See second example) | |
- cell after port phandle is phy type from: | |
- - PHY_TYPE_USB2 | |
- - PHY_TYPE_USB3 | |
- | |
-Example: | |
- | |
-u3phy: usb-phy@11290000 { | |
- compatible = "mediatek,mt8173-u3phy"; | |
- reg = <0 0x11290000 0 0x800>; | |
- clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; | |
- clock-names = "u3phya_ref"; | |
- #address-cells = <2>; | |
- #size-cells = <2>; | |
- ranges; | |
- status = "okay"; | |
- | |
- phy_port0: port@11290800 { | |
- reg = <0 0x11290800 0 0x800>; | |
- #phy-cells = <1>; | |
- status = "okay"; | |
- }; | |
- | |
- phy_port1: port@11291000 { | |
- reg = <0 0x11291000 0 0x800>; | |
- #phy-cells = <1>; | |
- status = "okay"; | |
- }; | |
-}; | |
- | |
-Specifying phy control of devices | |
---------------------------------- | |
- | |
-Device nodes should specify the configuration required in their "phys" | |
-property, containing a phandle to the phy port node and a device type; | |
-phy-names for each port are optional. | |
- | |
-Example: | |
- | |
-#include <dt-bindings/phy/phy.h> | |
- | |
-usb30: usb@11270000 { | |
- ... | |
- phys = <&phy_port0 PHY_TYPE_USB3>; | |
- phy-names = "usb3-0"; | |
- ... | |
-}; | |
diff --git a/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt | |
new file mode 100644 | |
index 000000000000..faf18084a33a | |
--- /dev/null | |
+++ b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt | |
@@ -0,0 +1,144 @@ | |
+MediaTek T-PHY binding | |
+-------------------------- | |
+ | |
+T-phy controller supports physical layer functionality for a number of | |
+controllers on MediaTek SoCs, such as, USB2.0, USB3.0, PCIe, and SATA. | |
+ | |
+Required properties (controller (parent) node): | |
+ - compatible : should be one of | |
+ "mediatek,generic-tphy-v1" | |
+ "mediatek,generic-tphy-v2" | |
+ "mediatek,mt2701-u3phy" (deprecated) | |
+ "mediatek,mt2712-u3phy" (deprecated) | |
+ "mediatek,mt8173-u3phy"; | |
+ make use of "mediatek,generic-tphy-v1" on mt2701 instead and | |
+ "mediatek,generic-tphy-v2" on mt2712 instead. | |
+ - clocks : (deprecated, use port's clocks instead) a list of phandle + | |
+ clock-specifier pairs, one for each entry in clock-names | |
+ - clock-names : (deprecated, use port's one instead) must contain | |
+ "u3phya_ref": for reference clock of usb3.0 analog phy. | |
+ | |
+Required nodes : a sub-node is required for each port the controller | |
+ provides. Address range information including the usual | |
+ 'reg' property is used inside these nodes to describe | |
+ the controller's topology. | |
+ | |
+Optional properties (controller (parent) node): | |
+ - reg : offset and length of register shared by multiple ports, | |
+ exclude port's private register. It is needed on mt2701 | |
+ and mt8173, but not on mt2712. | |
+ | |
+Required properties (port (child) node): | |
+- reg : address and length of the register set for the port. | |
+- clocks : a list of phandle + clock-specifier pairs, one for each | |
+ entry in clock-names | |
+- clock-names : must contain | |
+ "ref": 48M reference clock for HighSpeed analog phy; and 26M | |
+ reference clock for SuperSpeed analog phy, sometimes is | |
+ 24M, 25M or 27M, depended on platform. | |
+- #phy-cells : should be 1 (See second example) | |
+ cell after port phandle is phy type from: | |
+ - PHY_TYPE_USB2 | |
+ - PHY_TYPE_USB3 | |
+ - PHY_TYPE_PCIE | |
+ - PHY_TYPE_SATA | |
+ | |
+Example: | |
+ | |
+u3phy: usb-phy@11290000 { | |
+ compatible = "mediatek,mt8173-u3phy"; | |
+ reg = <0 0x11290000 0 0x800>; | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ ranges; | |
+ status = "okay"; | |
+ | |
+ u2port0: usb-phy@11290800 { | |
+ reg = <0 0x11290800 0 0x100>; | |
+ clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ status = "okay"; | |
+ }; | |
+ | |
+ u3port0: usb-phy@11290900 { | |
+ reg = <0 0x11290800 0 0x700>; | |
+ clocks = <&clk26m>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ status = "okay"; | |
+ }; | |
+ | |
+ u2port1: usb-phy@11291000 { | |
+ reg = <0 0x11291000 0 0x100>; | |
+ clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ status = "okay"; | |
+ }; | |
+}; | |
+ | |
+Specifying phy control of devices | |
+--------------------------------- | |
+ | |
+Device nodes should specify the configuration required in their "phys" | |
+property, containing a phandle to the phy port node and a device type; | |
+phy-names for each port are optional. | |
+ | |
+Example: | |
+ | |
+#include <dt-bindings/phy/phy.h> | |
+ | |
+usb30: usb@11270000 { | |
+ ... | |
+ phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; | |
+ phy-names = "usb2-0", "usb3-0"; | |
+ ... | |
+}; | |
+ | |
+ | |
+Layout differences of banks between mt8173/mt2701 and mt2712 | |
+------------------------------------------------------------- | |
+mt8173 and mt2701: | |
+port offset bank | |
+shared 0x0000 SPLLC | |
+ 0x0100 FMREG | |
+u2 port0 0x0800 U2PHY_COM | |
+u3 port0 0x0900 U3PHYD | |
+ 0x0a00 U3PHYD_BANK2 | |
+ 0x0b00 U3PHYA | |
+ 0x0c00 U3PHYA_DA | |
+u2 port1 0x1000 U2PHY_COM | |
+u3 port1 0x1100 U3PHYD | |
+ 0x1200 U3PHYD_BANK2 | |
+ 0x1300 U3PHYA | |
+ 0x1400 U3PHYA_DA | |
+u2 port2 0x1800 U2PHY_COM | |
+ ... | |
+ | |
+mt2712: | |
+port offset bank | |
+u2 port0 0x0000 MISC | |
+ 0x0100 FMREG | |
+ 0x0300 U2PHY_COM | |
+u3 port0 0x0700 SPLLC | |
+ 0x0800 CHIP | |
+ 0x0900 U3PHYD | |
+ 0x0a00 U3PHYD_BANK2 | |
+ 0x0b00 U3PHYA | |
+ 0x0c00 U3PHYA_DA | |
+u2 port1 0x1000 MISC | |
+ 0x1100 FMREG | |
+ 0x1300 U2PHY_COM | |
+u3 port1 0x1700 SPLLC | |
+ 0x1800 CHIP | |
+ 0x1900 U3PHYD | |
+ 0x1a00 U3PHYD_BANK2 | |
+ 0x1b00 U3PHYA | |
+ 0x1c00 U3PHYA_DA | |
+u2 port2 0x2000 MISC | |
+ ... | |
+ | |
+ SPLLC shared by u3 ports and FMREG shared by u2 ports on | |
+mt8173/mt2701 are put back into each port; a new bank MISC for | |
+u2 ports and CHIP for u3 ports are added on mt2712. | |
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | |
index e8f15e34027f..16fe94d7783c 100644 | |
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | |
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | |
@@ -9,17 +9,20 @@ domain control. | |
The driver implements the Generic PM domain bindings described in | |
power/power_domain.txt. It provides the power domains defined in | |
-include/dt-bindings/power/mt8173-power.h. | |
+include/dt-bindings/power/mt8173-power.h and mt2701-power.h. | |
Required properties: | |
-- compatible: Must be "mediatek,mt8173-scpsys" | |
+- compatible: Should be one of: | |
+ - "mediatek,mt2701-scpsys" | |
+ - "mediatek,mt8173-scpsys" | |
- #power-domain-cells: Must be 1 | |
- reg: Address range of the SCPSYS unit | |
- infracfg: must contain a phandle to the infracfg controller | |
- clock, clock-names: clocks according to the common clock binding. | |
- The clocks needed "mm", "mfg", "venc" and "venc_lt". | |
- These are the clocks which hardware needs to be enabled | |
- before enabling certain power domains. | |
+ These are clocks which hardware needs to be | |
+ enabled before enabling certain power domains. | |
+ Required clocks for MT2701: "mm", "mfg", "ethif" | |
+ Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" | |
Optional properties: | |
- vdec-supply: Power supply for the vdec power domain | |
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | |
index 6a00939a059a..95bf107ed80a 100644 | |
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | |
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | |
@@ -9,9 +9,13 @@ Required properties: | |
- reg : Specifies base physical address and size of the registers. | |
+Optional properties: | |
+- timeout-sec: contains the watchdog timeout in seconds. | |
+ | |
Example: | |
-wdt: watchdog@010000000 { | |
+wdt: watchdog@10000000 { | |
compatible = "mediatek,mt6589-wdt"; | |
reg = <0x10000000 0x18>; | |
+ timeout-sec = <10>; | |
}; | |
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt | |
index 167070895498..1fa6c386ee59 100644 | |
--- a/Documentation/driver-model/devres.txt | |
+++ b/Documentation/driver-model/devres.txt | |
@@ -333,6 +333,7 @@ MFD | |
devm_mfd_add_devices() | |
PCI | |
+ devm_pci_alloc_host_bridge() : managed PCI host bridge allocation | |
pcim_enable_device() : after success, all PCI ops become managed | |
pcim_pin_device() : keep PCI device enabled after release | |
diff --git a/Makefile b/Makefile | |
index c6fbf52eff45..563eb571670f 100644 | |
--- a/Makefile | |
+++ b/Makefile | |
@@ -667,11 +667,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) | |
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) | |
KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias) | |
-ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | |
-KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) | |
-KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) | |
-endif | |
- | |
ifdef CONFIG_LTO_CLANG | |
lto-clang-flags := -flto -fvisibility=hidden | |
@@ -720,7 +715,7 @@ export DISABLE_CFI | |
endif | |
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE | |
-KBUILD_CFLAGS += -Os | |
+KBUILD_CFLAGS += -O2 -fno-caller-saves $(call cc-option,-fno-inline-functions) | |
else | |
KBUILD_CFLAGS += -O2 | |
endif | |
@@ -854,6 +849,11 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH | |
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) | |
endif | |
+ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | |
+KBUILD_CFLAGS_KERNEL += $(call cc-option,-ffunction-sections,) | |
+KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdata-sections,) | |
+endif | |
+ | |
# arch Makefile may override CC so keep this after arch Makefile is included | |
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) | |
CHECKFLAGS += $(NOSTDINC_FLAGS) | |
@@ -1103,7 +1103,8 @@ $(vmlinux-dirs): prepare scripts | |
$(Q)$(MAKE) $(build)=$@ | |
define filechk_kernel.release | |
- echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" | |
+ (echo -n "$(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL))$(EXTRAVERSION)"; \ | |
+ echo "$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))";) | |
endef | |
# Store (new) KERNELRELEASE string in include/config/kernel.release | |
@@ -1341,7 +1342,6 @@ endif | |
PHONY += modules | |
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin | |
- $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order | |
@$(kecho) ' Building modules, stage 2.'; | |
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost | |
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild | |
@@ -1371,7 +1371,6 @@ _modinst_: | |
rm -f $(MODLIB)/build ; \ | |
ln -s $(CURDIR) $(MODLIB)/build ; \ | |
fi | |
- @cp -f $(objtree)/modules.order $(MODLIB)/ | |
@cp -f $(objtree)/modules.builtin $(MODLIB)/ | |
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst | |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig | |
index 6c8aed4a296c..142825a938aa 100644 | |
--- a/arch/arm/Kconfig | |
+++ b/arch/arm/Kconfig | |
@@ -82,6 +82,7 @@ config ARM | |
select HAVE_UID16 | |
select HAVE_VIRT_CPU_ACCOUNTING_GEN | |
select IRQ_FORCED_THREADING | |
+ select LD_DEAD_CODE_DATA_ELIMINATION | |
select MODULES_USE_ELF_REL | |
select NO_BOOTMEM | |
select OF_EARLY_FLATTREE if OF | |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile | |
index 561dbc0ee2ba..9e7e681f8759 100644 | |
--- a/arch/arm/boot/compressed/Makefile | |
+++ b/arch/arm/boot/compressed/Makefile | |
@@ -104,6 +104,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y) | |
ORIG_CFLAGS := $(KBUILD_CFLAGS) | |
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) | |
endif | |
+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) | |
# -fstack-protector-strong triggers protection checks in this code, | |
# but it is being used too early to link to meaningful stack_chk logic. | |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S | |
index 0d560a24408f..1aadaeb5e051 100644 | |
--- a/arch/arm/kernel/vmlinux.lds.S | |
+++ b/arch/arm/kernel/vmlinux.lds.S | |
@@ -30,7 +30,7 @@ | |
#define PROC_INFO \ | |
. = ALIGN(4); \ | |
VMLINUX_SYMBOL(__proc_info_begin) = .; \ | |
- *(.proc.info.init) \ | |
+ KEEP(*(.proc.info.init)) \ | |
VMLINUX_SYMBOL(__proc_info_end) = .; | |
#define HYPERVISOR_TEXT \ | |
@@ -41,11 +41,11 @@ | |
#define IDMAP_TEXT \ | |
ALIGN_FUNCTION(); \ | |
VMLINUX_SYMBOL(__idmap_text_start) = .; \ | |
- *(.idmap.text) \ | |
+ KEEP(*(.idmap.text)) \ | |
VMLINUX_SYMBOL(__idmap_text_end) = .; \ | |
. = ALIGN(PAGE_SIZE); \ | |
VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ | |
- *(.hyp.idmap.text) \ | |
+ KEEP(*(.hyp.idmap.text)) \ | |
VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; | |
#ifdef CONFIG_HOTPLUG_CPU | |
@@ -118,7 +118,7 @@ SECTIONS | |
_stext = .; /* Text and read-only data */ | |
IDMAP_TEXT | |
__exception_text_start = .; | |
- *(.exception.text) | |
+ KEEP(*(.exception.text)) | |
__exception_text_end = .; | |
IRQENTRY_TEXT | |
SOFTIRQENTRY_TEXT | |
@@ -147,7 +147,7 @@ SECTIONS | |
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { | |
__start___ex_table = .; | |
#ifdef CONFIG_MMU | |
- *(__ex_table) | |
+ KEEP(*(__ex_table)) | |
#endif | |
__stop___ex_table = .; | |
} | |
@@ -159,12 +159,12 @@ SECTIONS | |
. = ALIGN(8); | |
.ARM.unwind_idx : { | |
__start_unwind_idx = .; | |
- *(.ARM.exidx*) | |
+ KEEP(*(.ARM.exidx*)) | |
__stop_unwind_idx = .; | |
} | |
.ARM.unwind_tab : { | |
__start_unwind_tab = .; | |
- *(.ARM.extab*) | |
+ KEEP(*(.ARM.extab*)) | |
__stop_unwind_tab = .; | |
} | |
#endif | |
@@ -185,13 +185,13 @@ SECTIONS | |
__vectors_lma = .; | |
OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { | |
.vectors { | |
- *(.vectors) | |
+ KEEP(*(.vectors)) | |
} | |
.vectors.bhb.loop8 { | |
- *(.vectors.bhb.loop8) | |
+ KEEP(*(.vectors.bhb.loop8)) | |
} | |
.vectors.bhb.bpiall { | |
- *(.vectors.bhb.bpiall) | |
+ KEEP(*(.vectors.bhb.bpiall)) | |
} | |
} | |
ARM_LMA(__vectors, .vectors); | |
@@ -203,7 +203,7 @@ SECTIONS | |
__stubs_lma = .; | |
.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { | |
- *(.stubs) | |
+ KEEP(*(.stubs)) | |
} | |
ARM_LMA(__stubs, .stubs); | |
. = __stubs_lma + SIZEOF(.stubs); | |
@@ -219,24 +219,24 @@ SECTIONS | |
} | |
.init.arch.info : { | |
__arch_info_begin = .; | |
- *(.arch.info.init) | |
+ KEEP(*(.arch.info.init)) | |
__arch_info_end = .; | |
} | |
.init.tagtable : { | |
__tagtable_begin = .; | |
- *(.taglist.init) | |
+ KEEP(*(.taglist.init)) | |
__tagtable_end = .; | |
} | |
#ifdef CONFIG_SMP_ON_UP | |
.init.smpalt : { | |
__smpalt_begin = .; | |
- *(.alt.smp.init) | |
+ KEEP(*(.alt.smp.init)) | |
__smpalt_end = .; | |
} | |
#endif | |
.init.pv_table : { | |
__pv_table_begin = .; | |
- *(.pv_table) | |
+ KEEP(*(.pv_table)) | |
__pv_table_end = .; | |
} | |
.init.data : { | |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig | |
index 26e802db9e84..e60896a64236 100644 | |
--- a/arch/arm64/Kconfig | |
+++ b/arch/arm64/Kconfig | |
@@ -111,6 +111,7 @@ config ARM64 | |
select SPARSE_IRQ | |
select SYSCTL_EXCEPTION_TRACE | |
select THREAD_INFO_IN_TASK | |
+ select LD_DEAD_CODE_DATA_ELIMINATION | |
help | |
ARM 64-bit (AArch64) Linux support. | |
@@ -1077,6 +1078,7 @@ config EFI_STUB | |
config EFI | |
bool "UEFI runtime support" | |
depends on OF && !CPU_BIG_ENDIAN | |
+ depends on KERNEL_MODE_NEON | |
select LIBFDT | |
select UCS2_STRING | |
select EFI_PARAMS_FROM_FDT | |
@@ -1219,3 +1221,5 @@ source "arch/arm64/crypto/Kconfig" | |
endif | |
source "lib/Kconfig" | |
+ | |
+source "ndm/Kconfig" | |
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms | |
index 2f9c2a95c40e..e40e39fa418d 100644 | |
--- a/arch/arm64/Kconfig.platforms | |
+++ b/arch/arm64/Kconfig.platforms | |
@@ -92,6 +92,14 @@ config ARCH_MEDIATEK | |
help | |
Support for Mediatek MT65xx & MT81xx ARMv8 SoCs | |
+if ARCH_MEDIATEK | |
+ | |
+config MACH_MT7622 | |
+ bool "MediaTek MT7622 SoCs support" | |
+ default ARCH_MEDIATEK | |
+ | |
+endif | |
+ | |
config ARCH_MESON | |
bool "Amlogic Platforms" | |
select PINCTRL | |
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile | |
index 9fbfd3238469..66753cc6513a 100644 | |
--- a/arch/arm64/boot/dts/mediatek/Makefile | |
+++ b/arch/arm64/boot/dts/mediatek/Makefile | |
@@ -1,6 +1,14 @@ | |
+ifeq ($(CONFIG_MACH_MT7622),y) | |
+#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-evb.dtb | |
+#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb | |
+#dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb2.dtb | |
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-ac2600rfb1.dtb | |
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-ac4300rfb1.dtb | |
+else | |
dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb | |
dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb | |
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb | |
+endif | |
always := $(dtb-y) | |
subdir-y := $(dts-dirs) | |
diff --git a/arch/arm64/boot/dts/mediatek/mt6380.dtsi b/arch/arm64/boot/dts/mediatek/mt6380.dtsi | |
new file mode 100644 | |
index 000000000000..a4b911738c0f | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt6380.dtsi | |
@@ -0,0 +1,96 @@ | |
+/* | |
+ * Mediatek's PMIC mt6380 device tree source | |
+ * Copyright (c) 2016 MediaTek Inc. | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+&pwrap { | |
+ status = "okay"; | |
+ | |
+ pmic: mt6380 { | |
+ compatible = "mediatek,mt6380"; | |
+ }; | |
+ | |
+ mt6380regulator: mt6380regulator { | |
+ compatible = "mediatek,mt6380-regulator"; | |
+ | |
+ mt6380_vcpu_reg: buck_vcore1 { | |
+ regulator-name = "vcpu"; | |
+ regulator-min-microvolt = < 600000>; | |
+ regulator-max-microvolt = <1393750>; | |
+ regulator-ramp-delay = <6250>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vcore_reg: buck_vcore { | |
+ regulator-name = "vcore"; | |
+ regulator-min-microvolt = <600000>; | |
+ regulator-max-microvolt = <1393750>; | |
+ regulator-ramp-delay = <6250>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vrf_reg: buck_vrf { | |
+ regulator-name = "vrf"; | |
+ regulator-min-microvolt = <1200000>; | |
+ regulator-max-microvolt = <1575000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vm_reg: ldo_vmldo { | |
+ regulator-name = "vmldo"; | |
+ regulator-min-microvolt = <1050000>; | |
+ regulator-max-microvolt = <1400000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_va_reg: ldo_valdo { | |
+ regulator-name = "valdo"; | |
+ regulator-min-microvolt = <2200000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vphy_reg: ldo_vphyldo { | |
+ regulator-name = "vphyldo"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vddr_reg: ldo_vddrldo { | |
+ regulator-name = "vddr"; | |
+ regulator-min-microvolt = <1240000>; | |
+ regulator-max-microvolt = <1840000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ | |
+ mt6380_vt_reg: ldo_vtldo { | |
+ regulator-name = "vadc18"; | |
+ regulator-min-microvolt = <2200000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-ramp-delay = <0>; | |
+ regulator-always-on; | |
+ regulator-boot-on; | |
+ }; | |
+ }; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-ac2600rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-ac2600rfb1.dts | |
new file mode 100644 | |
index 000000000000..b2e9ac29e624 | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-ac2600rfb1.dts | |
@@ -0,0 +1,406 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Ming Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+/dts-v1/; | |
+#include <dt-bindings/gpio/gpio.h> | |
+#include <dt-bindings/input/input.h> | |
+#include "mt7622.dtsi" | |
+#include "mt6380.dtsi" | |
+ | |
+/ { | |
+ model = "MediaTek MT7622 AC2600rfb1 board"; | |
+ compatible = "mediatek,mt7622-ac2600rfb1", "mediatek,mt7622"; | |
+ | |
+ chosen { | |
+ bootargs = "console=ttyS0,115200n1 loglevel=8 swiotlb=512 rootfstype=squashfs"; | |
+ }; | |
+ | |
+ gpio-keys { | |
+ compatible = "gpio-keys"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ | |
+ reset { | |
+ label = "reset"; | |
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>; | |
+ linux,code = <KEY_RESTART>; | |
+ }; | |
+ | |
+ wps { | |
+ label = "wps"; | |
+ gpios = <&pio 102 GPIO_ACTIVE_LOW>; | |
+ linux,code = <KEY_WPS_BUTTON>; | |
+ }; | |
+ }; | |
+ | |
+ mmc_fixed_1v8_io: fixedregulator-1v8 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_io"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ mmc_fixed_3v3_power: fixedregulator-3v3 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_power"; | |
+ regulator-min-microvolt = <3300000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ memory@40000000 { | |
+ device_type = "memory"; | |
+ reg = <0 0x40000000 0 0x3F000000>; | |
+ }; | |
+ | |
+ sound: sound { | |
+ compatible = "mediatek,mt7622-wm8960-machine"; | |
+ mediatek,platform = <&afe>; | |
+ audio-routing = | |
+ "Headphone", "HP_L", | |
+ "Headphone", "HP_R", | |
+ "LINPUT2", "AMIC", | |
+ "RINPUT2", "AMIC"; | |
+ mediatek,audio-codec = <&wm8960>; | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&aud_pins_default>; | |
+ status = "disabled"; | |
+ }; | |
+}; | |
+ | |
+&auxadc { | |
+ status = "okay"; | |
+}; | |
+ | |
+&bch { | |
+ status = "disabled"; | |
+}; | |
+ | |
+&cpu0 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&cpu1 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&efuse { | |
+ status = "okay"; | |
+}; | |
+ | |
+&raeth { | |
+ mac-address = [00 00 00 00 00 00]; | |
+ dma-coherent; | |
+ wan_at = "p4"; | |
+ gmac1-support = "sgmii-1"; | |
+ sgmii-mode-1 = "force-2500"; | |
+ #gmac1-support = "rgmii-1"; | |
+ #rgmii-mode-1 = "force-1000"; | |
+ #gmac1-phy-address = <0x1f>; | |
+ gmac2-support = "rgmii-2"; | |
+ rgmii-mode-2 = "force-1000"; | |
+ #rgmii-mode-2 = "an"; | |
+ #gmac2-phy-address = <0x1e>; | |
+ gmac1_txq_num = <1>; | |
+ gmac1_txq_txd_num = <2048>; | |
+ gmac2_txq_num = <1>; | |
+ gmac2_txq_txd_num = <1024>; | |
+ num_rx_desc = <2048>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c0 { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&i2c0_pins>; | |
+ status = "disabled"; | |
+ | |
+ wm8960: wm8960@1a { | |
+ compatible = "wlf,wm8960"; | |
+ reg = <0x1a>; | |
+ }; | |
+}; | |
+ | |
+&i2c1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c2 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&mmc0 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc0_pins_default>; | |
+ pinctrl-1 = <&mmc0_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <8>; | |
+ max-frequency = <50000000>; | |
+ cap-mmc-highspeed; | |
+ mmc-hs200-1_8v; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_1v8_io>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+ non-removable; | |
+}; | |
+ | |
+&mmc1 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc1_pins_default>; | |
+ pinctrl-1 = <&mmc1_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <4>; | |
+ max-frequency = <50000000>; | |
+ cap-sd-highspeed; | |
+ r_smpl = <1>; | |
+ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_3v3_power>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+}; | |
+ | |
+&nandc { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&nand_pins_default>; | |
+ status = "disabled"; | |
+ reg = <0>; | |
+ nand-ecc-mode = "hw"; | |
+}; | |
+ | |
+&nor_flash { | |
+ status = "disabled"; | |
+ compatible = "jedec,spi-nor"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+}; | |
+ | |
+&pio { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&state_default>; | |
+ state_default:pinconf_default { | |
+ }; | |
+ | |
+ aud_pins_default: audiodefault { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_3_I2S_BCLK__FUNC_I2S_BCLK_OUT>, | |
+ <MT7622_PIN_4_I2S_WS__FUNC_I2S_WS_OUT>, | |
+ <MT7622_PIN_5_I2S_MCLK__FUNC_I2S_MCLK>, | |
+ <MT7622_PIN_2_I2S1_OUT__FUNC_I2S1_OUT>, | |
+ <MT7622_PIN_1_I2S1_IN__FUNC_I2S1_IN>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ i2c0_pins: i2c0-pins { | |
+ pins_bus { | |
+ pinmux = <MT7622_PIN_14_I2C_SDA__FUNC_I2C0_SDA>, | |
+ <MT7622_PIN_15_I2C_SCL__FUNC_I2C0_SCL>; | |
+ bias-disable; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_default: mmc0default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ bias-pull-up; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_uhs: mmc0-pins-uhs { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_default: mmc1default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ | |
+ pins_insert { | |
+ pinmux = <MT7622_PIN_81_TXD3__FUNC_GPIO81>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_uhs: mmc1-pins-uhs { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ nand_pins_default: nanddefault { | |
+ pins_dat { | |
+ pinmux = <MT7622_PIN_37_NCEB__FUNC_ND_CS_N>, | |
+ <MT7622_PIN_38_NWEB__FUNC_ND_WE_N>, | |
+ <MT7622_PIN_39_NREB__FUNC_ND_RE_N>, | |
+ <MT7622_PIN_40_NDL4__FUNC_ND_D4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_ND_D5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_ND_D6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_ND_D7>, | |
+ <MT7622_PIN_44_NRB__FUNC_ND_RB_N>, | |
+ <MT7622_PIN_45_NCLE__FUNC_ND_CLE>, | |
+ <MT7622_PIN_46_NALE__FUNC_ND_ALE>, | |
+ <MT7622_PIN_47_NDL0__FUNC_ND_D0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_ND_D1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_ND_D2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_ND_D3>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ snand_pins_default: snand-pins-default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_8_SPI_WP__FUNC_SNFI_WP>, | |
+ <MT7622_PIN_9_SPI_HOLD__FUNC_SNFI_HOLD>, | |
+ <MT7622_PIN_11_SPI_MOSI__FUNC_SNFI_MOSI>, | |
+ <MT7622_PIN_12_SPI_MISO__FUNC_SNFI_MISO>, | |
+ <MT7622_PIN_13_SPI_CS__FUNC_SNFI_CS>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_10_SPI_CLK__FUNC_SNFI_CLK>; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ wbsys_pins_default: wbsysdefault { | |
+ }; | |
+ | |
+ wbsys_pins_epa: wbsysepa { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_91_TXD4__FUNC_ANTSEL0>, | |
+ <MT7622_PIN_92_RXD4__FUNC_ANTSEL1>, | |
+ <MT7622_PIN_93_RTS4_N__FUNC_ANTSEL2>, | |
+ <MT7622_PIN_94_CTS4_N__FUNC_ANTSEL3>, | |
+ <MT7622_PIN_95_PWM1__FUNC_ANTSEL4>, | |
+ <MT7622_PIN_96_PWM2__FUNC_ANTSEL5>, | |
+ <MT7622_PIN_97_PWM3__FUNC_ANTSEL6>, | |
+ <MT7622_PIN_98_PWM4__FUNC_ANTSEL7>, | |
+ <MT7622_PIN_99_PWM5__FUNC_ANTSEL8>, | |
+ <MT7622_PIN_100_PWM6__FUNC_ANTSEL9>, | |
+ <MT7622_PIN_73_SPIC1_CLK__FUNC_ANTSEL12>, | |
+ <MT7622_PIN_74_SPIC1_MOSI__FUNC_ANTSEL13>, | |
+ <MT7622_PIN_75_SPIC1_MISO__FUNC_ANTSEL14>, | |
+ <MT7622_PIN_76_SPIC1_CS__FUNC_ANTSEL15>, | |
+ <MT7622_PIN_77_GPIO_D__FUNC_ANTSEL16>, | |
+ <MT7622_PIN_22_GPIO_B__FUNC_ANTSEL17>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pwm { | |
+ status = "okay"; | |
+}; | |
+ | |
+&snand { | |
+ pinctrl-0 = <&snand_pins_default>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&svs { | |
+ vproc-supply = <&mt6380_vcpu_reg>; | |
+}; | |
+ | |
+&uart0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&usb1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&u3phy1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&sata { | |
+ status = "okay"; | |
+}; | |
+ | |
+&sata_phy { | |
+ status = "okay"; | |
+}; | |
+ | |
+&wbsys { | |
+ pinctrl-names = "default", "state_epa"; | |
+ pinctrl-0 = <&wbsys_pins_default>; | |
+ pinctrl-1 = <&wbsys_pins_epa>; | |
+ status = "okay"; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-ac4300rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-ac4300rfb1.dts | |
new file mode 100644 | |
index 000000000000..36a9df4a9918 | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-ac4300rfb1.dts | |
@@ -0,0 +1,357 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Ming Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+/dts-v1/; | |
+#include <dt-bindings/gpio/gpio.h> | |
+#include <dt-bindings/input/input.h> | |
+#include "mt7622.dtsi" | |
+#include "mt6380.dtsi" | |
+ | |
+/ { | |
+ model = "MediaTek MT7622 AC4300rfb1 board"; | |
+ compatible = "mediatek,mt7622-ac4300rfb1", "mediatek,mt7622"; | |
+ | |
+ chosen { | |
+ bootargs = "console=ttyS0,115200n1 loglevel=8 swiotlb=512 rootfstype=squashfs"; | |
+ }; | |
+ | |
+ gpio-keys { | |
+ compatible = "gpio-keys"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ | |
+ reset { | |
+ label = "reset"; | |
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>; | |
+ linux,code = <KEY_RESTART>; | |
+ }; | |
+ | |
+ wps { | |
+ label = "wps"; | |
+ gpios = <&pio 102 GPIO_ACTIVE_LOW>; | |
+ linux,code = <KEY_WPS_BUTTON>; | |
+ }; | |
+ }; | |
+ | |
+ mmc_fixed_1v8_io: fixedregulator-1v8 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_io"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ mmc_fixed_3v3_power: fixedregulator-3v3 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_power"; | |
+ regulator-min-microvolt = <3300000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ memory@40000000 { | |
+ device_type = "memory"; | |
+ reg = <0 0x40000000 0 0x3F000000>; | |
+ }; | |
+}; | |
+ | |
+&auxadc { | |
+ status = "okay"; | |
+}; | |
+ | |
+&bch { | |
+ status = "disabled"; | |
+}; | |
+ | |
+&cpu0 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&cpu1 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&efuse { | |
+ status = "okay"; | |
+}; | |
+ | |
+&raeth { | |
+ mac-address = [00 00 00 00 00 00]; | |
+ dma-coherent; | |
+ wan_at = "p4"; | |
+ gmac1-support = "sgmii-1"; | |
+ sgmii-mode-1 = "force-2500"; | |
+ #gmac1-support = "rgmii-1"; | |
+ #rgmii-mode-1 = "force-1000"; | |
+ #gmac1-phy-address = <0x1f>; | |
+ gmac2-support = "rgmii-2"; | |
+ rgmii-mode-2 = "force-1000"; | |
+ #rgmii-mode-2 = "an"; | |
+ #gmac2-phy-address = <0x1e>; | |
+ gmac1_txq_num = <1>; | |
+ gmac1_txq_txd_num = <2048>; | |
+ gmac2_txq_num = <1>; | |
+ gmac2_txq_txd_num = <1024>; | |
+ num_rx_desc = <2048>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c2 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&mmc0 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc0_pins_default>; | |
+ pinctrl-1 = <&mmc0_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <8>; | |
+ max-frequency = <50000000>; | |
+ cap-mmc-highspeed; | |
+ mmc-hs200-1_8v; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_1v8_io>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+ non-removable; | |
+}; | |
+ | |
+&mmc1 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc1_pins_default>; | |
+ pinctrl-1 = <&mmc1_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <4>; | |
+ max-frequency = <50000000>; | |
+ cap-sd-highspeed; | |
+ r_smpl = <1>; | |
+ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_3v3_power>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+}; | |
+ | |
+&nandc { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&nand_pins_default>; | |
+ status = "disabled"; | |
+ reg = <0>; | |
+ nand-ecc-mode = "hw"; | |
+}; | |
+ | |
+&nor_flash { | |
+ status = "disabled"; | |
+ compatible = "jedec,spi-nor"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+}; | |
+ | |
+&pio { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&state_default>; | |
+ state_default:pinconf_default { | |
+ }; | |
+ | |
+ mmc0_pins_default: mmc0default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ bias-pull-up; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_uhs: mmc0-pins-uhs { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_default: mmc1default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ | |
+ pins_insert { | |
+ pinmux = <MT7622_PIN_81_TXD3__FUNC_GPIO81>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_uhs: mmc1-pins-uhs { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ nand_pins_default: nanddefault { | |
+ pins_dat { | |
+ pinmux = <MT7622_PIN_37_NCEB__FUNC_ND_CS_N>, | |
+ <MT7622_PIN_38_NWEB__FUNC_ND_WE_N>, | |
+ <MT7622_PIN_39_NREB__FUNC_ND_RE_N>, | |
+ <MT7622_PIN_40_NDL4__FUNC_ND_D4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_ND_D5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_ND_D6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_ND_D7>, | |
+ <MT7622_PIN_44_NRB__FUNC_ND_RB_N>, | |
+ <MT7622_PIN_45_NCLE__FUNC_ND_CLE>, | |
+ <MT7622_PIN_46_NALE__FUNC_ND_ALE>, | |
+ <MT7622_PIN_47_NDL0__FUNC_ND_D0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_ND_D1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_ND_D2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_ND_D3>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ snand_pins_default: snand-pins-default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_8_SPI_WP__FUNC_SNFI_WP>, | |
+ <MT7622_PIN_9_SPI_HOLD__FUNC_SNFI_HOLD>, | |
+ <MT7622_PIN_11_SPI_MOSI__FUNC_SNFI_MOSI>, | |
+ <MT7622_PIN_12_SPI_MISO__FUNC_SNFI_MISO>, | |
+ <MT7622_PIN_13_SPI_CS__FUNC_SNFI_CS>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_10_SPI_CLK__FUNC_SNFI_CLK>; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ wbsys_pins_default: wbsysdefault { | |
+ }; | |
+ | |
+ wbsys_pins_epa: wbsysepa { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_91_TXD4__FUNC_ANTSEL0>, | |
+ <MT7622_PIN_92_RXD4__FUNC_ANTSEL1>, | |
+ <MT7622_PIN_93_RTS4_N__FUNC_ANTSEL2>, | |
+ <MT7622_PIN_94_CTS4_N__FUNC_ANTSEL3>, | |
+ <MT7622_PIN_95_PWM1__FUNC_ANTSEL4>, | |
+ <MT7622_PIN_96_PWM2__FUNC_ANTSEL5>, | |
+ <MT7622_PIN_97_PWM3__FUNC_ANTSEL6>, | |
+ <MT7622_PIN_98_PWM4__FUNC_ANTSEL7>, | |
+ <MT7622_PIN_99_PWM5__FUNC_ANTSEL8>, | |
+ <MT7622_PIN_100_PWM6__FUNC_ANTSEL9>, | |
+ <MT7622_PIN_73_SPIC1_CLK__FUNC_ANTSEL12>, | |
+ <MT7622_PIN_74_SPIC1_MOSI__FUNC_ANTSEL13>, | |
+ <MT7622_PIN_75_SPIC1_MISO__FUNC_ANTSEL14>, | |
+ <MT7622_PIN_76_SPIC1_CS__FUNC_ANTSEL15>, | |
+ <MT7622_PIN_77_GPIO_D__FUNC_ANTSEL16>, | |
+ <MT7622_PIN_22_GPIO_B__FUNC_ANTSEL17>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pwm { | |
+ status = "okay"; | |
+}; | |
+ | |
+&snand { | |
+ pinctrl-0 = <&snand_pins_default>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&svs { | |
+ vproc-supply = <&mt6380_vcpu_reg>; | |
+}; | |
+ | |
+&uart0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&usb1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&u3phy1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&wbsys { | |
+ pinctrl-names = "default", "state_epa"; | |
+ pinctrl-0 = <&wbsys_pins_default>; | |
+ pinctrl-1 = <&wbsys_pins_epa>; | |
+ status = "okay"; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-clkao.dtsi b/arch/arm64/boot/dts/mediatek/mt7622-clkao.dtsi | |
new file mode 100644 | |
index 000000000000..5442ea59fdbf | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-clkao.dtsi | |
@@ -0,0 +1,166 @@ | |
+&clkao { | |
+ status = "disabled"; | |
+ | |
+ bring-up { | |
+ compatible = "mediatek,clk-bring-up"; | |
+ clocks = | |
+ <&apmixedsys CLK_APMIXED_ARMPLL>, | |
+ <&apmixedsys CLK_APMIXED_MAINPLL>, | |
+ <&apmixedsys CLK_APMIXED_UNIV2PLL>, | |
+ <&apmixedsys CLK_APMIXED_ETH1PLL>, | |
+ <&apmixedsys CLK_APMIXED_ETH2PLL>, | |
+ <&apmixedsys CLK_APMIXED_AUD1PLL>, | |
+ <&apmixedsys CLK_APMIXED_AUD2PLL>, | |
+ <&apmixedsys CLK_APMIXED_TRGPLL>, | |
+ <&apmixedsys CLK_APMIXED_SGMIPLL>, | |
+ <&infracfg CLK_INFRA_DBGCLK_PD>, | |
+ <&infracfg CLK_INFRA_AUDIO_PD>, | |
+ <&infracfg CLK_INFRA_IRRX_PD>, | |
+ <&infracfg CLK_INFRA_APXGPT_PD>, | |
+ <&infracfg CLK_INFRA_PMIC_PD>, | |
+ <&pericfg CLK_PERI_THERM_PD>, | |
+ <&pericfg CLK_PERI_PWM1_PD>, | |
+ <&pericfg CLK_PERI_PWM2_PD>, | |
+ <&pericfg CLK_PERI_PWM3_PD>, | |
+ <&pericfg CLK_PERI_PWM4_PD>, | |
+ <&pericfg CLK_PERI_PWM5_PD>, | |
+ <&pericfg CLK_PERI_PWM6_PD>, | |
+ <&pericfg CLK_PERI_PWM7_PD>, | |
+ <&pericfg CLK_PERI_PWM_PD>, | |
+ <&pericfg CLK_PERI_AP_DMA_PD>, | |
+ <&pericfg CLK_PERI_MSDC30_0_PD>, | |
+ <&pericfg CLK_PERI_MSDC30_1_PD>, | |
+ <&pericfg CLK_PERI_UART0_PD>, | |
+ <&pericfg CLK_PERI_UART1_PD>, | |
+ <&pericfg CLK_PERI_UART2_PD>, | |
+ <&pericfg CLK_PERI_UART3_PD>, | |
+ <&pericfg CLK_PERI_UART4_PD>, | |
+ <&pericfg CLK_PERI_BTIF_PD>, | |
+ <&pericfg CLK_PERI_I2C0_PD>, | |
+ <&pericfg CLK_PERI_I2C1_PD>, | |
+ <&pericfg CLK_PERI_I2C2_PD>, | |
+ <&pericfg CLK_PERI_SPI1_PD>, | |
+ <&pericfg CLK_PERI_AUXADC_PD>, | |
+ <&pericfg CLK_PERI_SPI0_PD>, | |
+ <&pericfg CLK_PERI_SNFI_PD>, | |
+ <&pericfg CLK_PERI_NFI_PD>, | |
+ <&pericfg CLK_PERI_NFIECC_PD>, | |
+ <&pericfg CLK_PERI_FLASH_PD>, | |
+ <&pericfg CLK_PERI_IRTX_PD>, | |
+ <&topckgen CLK_TOP_MSDC50_0_SEL>, | |
+ <&topckgen CLK_TOP_MSDC30_0_SEL>, | |
+ <&topckgen CLK_TOP_APLL1_DIV_PD>, | |
+ <&topckgen CLK_TOP_APLL2_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S0_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S1_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S2_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S3_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_A1SYS_HP_DIV_PD>, | |
+ <&topckgen CLK_TOP_A2SYS_HP_DIV_PD>, | |
+ <&audiosys CLK_AUDIO_AFE>, | |
+ <&audiosys CLK_AUDIO_HDMI>, | |
+ <&audiosys CLK_AUDIO_SPDF>, | |
+ <&audiosys CLK_AUDIO_APLL>, | |
+ <&audiosys CLK_AUDIO_I2SIN1>, | |
+ <&audiosys CLK_AUDIO_I2SIN2>, | |
+ <&audiosys CLK_AUDIO_I2SIN3>, | |
+ <&audiosys CLK_AUDIO_I2SIN4>, | |
+ <&audiosys CLK_AUDIO_I2SO1>, | |
+ <&audiosys CLK_AUDIO_I2SO2>, | |
+ <&audiosys CLK_AUDIO_I2SO3>, | |
+ <&audiosys CLK_AUDIO_I2SO4>, | |
+ <&audiosys CLK_AUDIO_ASRCI1>, | |
+ <&audiosys CLK_AUDIO_ASRCI2>, | |
+ <&audiosys CLK_AUDIO_ASRCO1>, | |
+ <&audiosys CLK_AUDIO_ASRCO2>, | |
+ <&audiosys CLK_AUDIO_INTDIR>, | |
+ <&audiosys CLK_AUDIO_A1SYS>, | |
+ <&audiosys CLK_AUDIO_A2SYS>, | |
+ <&audiosys CLK_AUDIO_UL1>, | |
+ <&audiosys CLK_AUDIO_UL2>, | |
+ <&audiosys CLK_AUDIO_UL3>, | |
+ <&audiosys CLK_AUDIO_UL4>, | |
+ <&audiosys CLK_AUDIO_UL5>, | |
+ <&audiosys CLK_AUDIO_UL6>, | |
+ <&audiosys CLK_AUDIO_DL1>, | |
+ <&audiosys CLK_AUDIO_DL2>, | |
+ <&audiosys CLK_AUDIO_DL3>, | |
+ <&audiosys CLK_AUDIO_DL4>, | |
+ <&audiosys CLK_AUDIO_DL5>, | |
+ <&audiosys CLK_AUDIO_DL6>, | |
+ <&audiosys CLK_AUDIO_DLMCH>, | |
+ <&audiosys CLK_AUDIO_ARB1>, | |
+ <&audiosys CLK_AUDIO_AWB>, | |
+ <&audiosys CLK_AUDIO_AWB2>, | |
+ <&audiosys CLK_AUDIO_DAI>, | |
+ <&audiosys CLK_AUDIO_MOD>, | |
+ <&audiosys CLK_AUDIO_ASRCI3>, | |
+ <&audiosys CLK_AUDIO_ASRCI4>, | |
+ <&audiosys CLK_AUDIO_ASRCO3>, | |
+ <&audiosys CLK_AUDIO_ASRCO4>, | |
+ <&audiosys CLK_AUDIO_MEM_ASRC1>, | |
+ <&audiosys CLK_AUDIO_MEM_ASRC2>, | |
+ <&audiosys CLK_AUDIO_MEM_ASRC3>, | |
+ <&audiosys CLK_AUDIO_MEM_ASRC4>, | |
+ <&audiosys CLK_AUDIO_MEM_ASRC5>, | |
+ <&ssusbsys CLK_SSUSB_U2_PHY_1P_EN>, | |
+ <&ssusbsys CLK_SSUSB_U2_PHY_EN>, | |
+ <&ssusbsys CLK_SSUSB_REF_EN>, | |
+ <&ssusbsys CLK_SSUSB_SYS_EN>, | |
+ <&ssusbsys CLK_SSUSB_MCU_EN>, | |
+ <&ssusbsys CLK_SSUSB_DMA_EN>, | |
+ <&pciesys CLK_PCIE_P1_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P1_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P1_AHB_EN>, | |
+ <&pciesys CLK_PCIE_P1_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P1_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P1_PIPE_EN>, | |
+ <&pciesys CLK_PCIE_P0_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P0_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P0_AHB_EN>, | |
+ <&pciesys CLK_PCIE_P0_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P0_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P0_PIPE_EN>, | |
+ <&pciesys CLK_SATA_AHB_EN>, | |
+ <&pciesys CLK_SATA_AXI_EN>, | |
+ <&pciesys CLK_SATA_ASIC_EN>, | |
+ <&pciesys CLK_SATA_RBC_EN>, | |
+ <&pciesys CLK_SATA_PM_EN>, | |
+ <ðsys CLK_ETH_HSDMA_EN>, | |
+ <ðsys CLK_ETH_ESW_EN>, | |
+ <ðsys CLK_ETH_GP2_EN>, | |
+ <ðsys CLK_ETH_GP1_EN>, | |
+ <ðsys CLK_ETH_GP0_EN>, | |
+ <&sgmiisys CLK_SGMII_TX250M_EN>, | |
+ <&sgmiisys CLK_SGMII_RX250M_EN>, | |
+ <&sgmiisys CLK_SGMII_CDR_REF>, | |
+ <&sgmiisys CLK_SGMII_CDR_FB>; | |
+ | |
+ clock-names = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", | |
+ "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", | |
+ "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", | |
+ "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", | |
+ "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", | |
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", | |
+ "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", | |
+ "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", | |
+ "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", | |
+ "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", | |
+ "118", "119", "120", "121", "122", "123", "124", "125"; | |
+ }; | |
+ | |
+ bring-up-pd-ethsys { | |
+ compatible = "mediatek,scpsys-bring-up"; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; | |
+ }; | |
+ | |
+ bring-up-pd-hif0 { | |
+ compatible = "mediatek,scpsys-bring-up"; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | |
+ }; | |
+ | |
+ bring-up-pd-hif1 { | |
+ compatible = "mediatek,scpsys-bring-up"; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>; | |
+ }; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-evb.dts b/arch/arm64/boot/dts/mediatek/mt7622-evb.dts | |
new file mode 100644 | |
index 000000000000..4690d32a5eba | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-evb.dts | |
@@ -0,0 +1,494 @@ | |
+/* | |
+ * Copyright (c) 2016 MediaTek Inc. | |
+ * Author: Ming Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+/dts-v1/; | |
+#include <dt-bindings/gpio/gpio.h> | |
+#include "mt7622.dtsi" | |
+#include "mt6380.dtsi" | |
+ | |
+/ { | |
+ model = "MediaTek MT7622 EVB board"; | |
+ compatible = "mediatek,mt7622-evb", "mediatek,mt7622"; | |
+ | |
+ chosen { | |
+ bootargs = "console=ttyS0,115200n1 root=/dev/ram \ | |
+ initrd=0x44000000,0x615E36 loglevel=8 androidboot.hardware=mt7622 swiotlb=512"; | |
+ }; | |
+ | |
+ dummy_codec:dummy_codec { | |
+ compatible = "mediatek,dummy-codec"; | |
+ }; | |
+ | |
+ mmc_fixed_1v8_io: fixedregulator@0 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_io"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ mmc_fixed_3v3_power: fixedregulator@1 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_power"; | |
+ regulator-min-microvolt = <3300000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ memory { | |
+ reg = <0 0x40000000 0 0x3F000000>; | |
+ }; | |
+ | |
+ sound: sound { | |
+ compatible = "mediatek,mt7622-soc-machine"; | |
+ mediatek,platform = <&afe>; | |
+ mediatek,audio-codec = <&dummy_codec>; | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&aud_pins_default>; | |
+ status = "okay"; | |
+ }; | |
+}; | |
+ | |
+&bch { | |
+ status = "disabled"; | |
+}; | |
+ | |
+&cpu0 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&cpu1 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&auxadc { | |
+ status = "okay"; | |
+}; | |
+ | |
+&efuse { | |
+ status = "okay"; | |
+}; | |
+ | |
+ð { | |
+ mac-address = [00 00 00 00 00 00]; | |
+ dma-coherent; | |
+ gmac1-support = "esw"; | |
+ gmac2-support = "rgmii-2"; | |
+ rgmii-mode-2 = "an"; | |
+ gmac2-phy-address = <0x05>; | |
+ gmac1_txq_num = <1>; | |
+ gmac1_txq_txd_num = <2048>; | |
+ gmac2_txq_num = <1>; | |
+ gmac2_txq_txd_num = <1024>; | |
+ num_rx_desc = <2048>; | |
+ status = "okay"; | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&ephy_default>; | |
+}; | |
+ | |
+&gsw { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c0 { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&i2c0_pins>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c2 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&irrx { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&irrx_pins_ir_input>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&mmc0 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc0_pins_default>; | |
+ pinctrl-1 = <&mmc0_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <8>; | |
+ max-frequency = <50000000>; | |
+ cap-mmc-highspeed; | |
+ mmc-hs200-1_8v; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_1v8_io>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+ non-removable; | |
+}; | |
+ | |
+&mmc1 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc1_pins_default>; | |
+ pinctrl-1 = <&mmc1_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <4>; | |
+ max-frequency = <50000000>; | |
+ cap-sd-highspeed; | |
+ r_smpl = <1>; | |
+ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_3v3_power>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+}; | |
+ | |
+&nandc { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&nand_pins_default>; | |
+ status = "disabled"; | |
+ flash@0 { | |
+ reg = <0>; | |
+ nand-ecc-mode = "hw"; | |
+ partitions { | |
+ compatible = "fixed-partitions"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ | |
+ partition@0 { | |
+ label = "Preloader"; | |
+ reg = <0x00000 0x0080000>; | |
+ read-only; | |
+ }; | |
+ | |
+ partition@80000 { | |
+ label = "ATF"; | |
+ reg = <0x80000 0x0040000>; | |
+ }; | |
+ | |
+ partition@c0000 { | |
+ label = "Bootloader"; | |
+ reg = <0xc0000 0x0080000>; | |
+ }; | |
+ | |
+ partition@140000 { | |
+ label = "Config"; | |
+ reg = <0x140000 0x0080000>; | |
+ }; | |
+ | |
+ partition@1c0000 { | |
+ label = "Factory"; | |
+ reg = <0x1c0000 0x0040000>; | |
+ }; | |
+ | |
+ partition@200000 { | |
+ label = "Kernel"; | |
+ reg = <0x200000 0x2000000>; | |
+ }; | |
+ | |
+ partition@2200000 { | |
+ label = "User_data"; | |
+ reg = <0x2200000 0x4000000>; | |
+ }; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&nor_flash { | |
+ status = "okay"; | |
+ flash@0 { | |
+ compatible = "jedec,spi-nor"; | |
+ }; | |
+}; | |
+ | |
+&pio { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&state_default>; | |
+ state_default:pinconf_default { | |
+ }; | |
+ | |
+ irrx_pins_ir_input: irrx_pin_ir { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_100_PWM6__FUNC_IR_R>; | |
+ bias-disable; | |
+ }; | |
+ }; | |
+ | |
+ aud_pins_default: audiodefault { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_3_I2S_BCLK__FUNC_I2S_BCLK_OUT>, | |
+ <MT7622_PIN_4_I2S_WS__FUNC_I2S_WS_OUT>, | |
+ <MT7622_PIN_5_I2S_MCLK__FUNC_I2S_MCLK>, | |
+ <MT7622_PIN_2_I2S1_OUT__FUNC_I2S1_OUT>, | |
+ <MT7622_PIN_1_I2S1_IN__FUNC_I2S1_IN>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ i2c0_pins: i2c0@0 { | |
+ pins_bus { | |
+ pinmux = <MT7622_PIN_14_I2C_SDA__FUNC_I2C0_SDA>, | |
+ <MT7622_PIN_15_I2C_SCL__FUNC_I2C0_SCL>; | |
+ bias-disable; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_default: mmc0default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ bias-pull-up; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_uhs: mmc0@0{ | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_default: mmc1default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ | |
+ pins_insert { | |
+ pinmux = <MT7622_PIN_81_TXD3__FUNC_GPIO81>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_uhs: mmc1@0 { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ nand_pins_default: nanddefault { | |
+ pins_dat { | |
+ pinmux = <MT7622_PIN_37_NCEB__FUNC_ND_CS_N>, | |
+ <MT7622_PIN_38_NWEB__FUNC_ND_WE_N>, | |
+ <MT7622_PIN_39_NREB__FUNC_ND_RE_N>, | |
+ <MT7622_PIN_40_NDL4__FUNC_ND_D4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_ND_D5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_ND_D6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_ND_D7>, | |
+ <MT7622_PIN_44_NRB__FUNC_ND_RB_N>, | |
+ <MT7622_PIN_45_NCLE__FUNC_ND_CLE>, | |
+ <MT7622_PIN_46_NALE__FUNC_ND_ALE>, | |
+ <MT7622_PIN_47_NDL0__FUNC_ND_D0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_ND_D1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_ND_D2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_ND_D3>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ snand_pins_default: snand@0 { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_8_SPI_WP__FUNC_SNFI_WP>, | |
+ <MT7622_PIN_9_SPI_HOLD__FUNC_SNFI_HOLD>, | |
+ <MT7622_PIN_11_SPI_MOSI__FUNC_SNFI_MOSI>, | |
+ <MT7622_PIN_12_SPI_MISO__FUNC_SNFI_MISO>, | |
+ <MT7622_PIN_13_SPI_CS__FUNC_SNFI_CS>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_10_SPI_CLK__FUNC_SNFI_CLK>; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pwm { | |
+ status = "okay"; | |
+}; | |
+ | |
+&sata { | |
+ status = "okay"; | |
+}; | |
+ | |
+&sata_phy { | |
+ status = "okay"; | |
+}; | |
+ | |
+&snand { | |
+ pinctrl-0 = <&snand_pins_default>; | |
+ status = "okay"; | |
+ flash@0 { | |
+ partitions { | |
+ compatible = "fixed-partitions"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ | |
+ partition@0 { | |
+ label = "Preloader"; | |
+ reg = <0x00000 0x0080000>; | |
+ read-only; | |
+ }; | |
+ | |
+ partition@80000 { | |
+ label = "ATF"; | |
+ reg = <0x80000 0x0040000>; | |
+ }; | |
+ | |
+ partition@c0000 { | |
+ label = "Bootloader"; | |
+ reg = <0xc0000 0x0080000>; | |
+ }; | |
+ | |
+ partition@140000 { | |
+ label = "Config"; | |
+ reg = <0x140000 0x0080000>; | |
+ }; | |
+ | |
+ partition@1c0000 { | |
+ label = "Factory"; | |
+ reg = <0x1c0000 0x0040000>; | |
+ }; | |
+ | |
+ partition@200000 { | |
+ label = "Kernel"; | |
+ reg = <0x200000 0x2000000>; | |
+ }; | |
+ | |
+ partition@2200000 { | |
+ label = "User_data"; | |
+ reg = <0x2200000 0x4000000>; | |
+ }; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&uart0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&pcie0 { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&pcie_pinctl0>; | |
+}; | |
+ | |
+&pcie1 { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&pcie_pinctl1>; | |
+}; | |
+ | |
+&pio { | |
+ ephy_default: ephy_default { | |
+ pins_eth { | |
+ pinmux = <MT7622_PIN_23_MDC__FUNC_MDC>, | |
+ <MT7622_PIN_24_MDIO__FUNC_MDIO>, | |
+ <MT7622_PIN_25_G2_TXD0__FUNC_G2_TXD0>, | |
+ <MT7622_PIN_26_G2_TXD1__FUNC_G2_TXD1>, | |
+ <MT7622_PIN_27_G2_TXD2__FUNC_G2_TXD2>, | |
+ <MT7622_PIN_28_G2_TXD3__FUNC_G2_TXD3>, | |
+ <MT7622_PIN_29_G2_TXEN__FUNC_G2_TXEN>, | |
+ <MT7622_PIN_30_G2_TXC__FUNC_G2_TXC>, | |
+ <MT7622_PIN_31_G2_RXD0__FUNC_G2_RXD0>, | |
+ <MT7622_PIN_32_G2_RXD1__FUNC_G2_RXD1>, | |
+ <MT7622_PIN_33_G2_RXD2__FUNC_G2_RXD2>, | |
+ <MT7622_PIN_34_G2_RXD3__FUNC_G2_RXD3>, | |
+ <MT7622_PIN_35_G2_RXDV__FUNC_G2_RXDV>, | |
+ <MT7622_PIN_36_G2_RXC__FUNC_G2_RXC>; | |
+ }; | |
+ }; | |
+ | |
+ pcie_pinctl0: pcie0 { | |
+ pcie0 { | |
+ pinmux = <MT7622_PIN_80_CTS3_N__FUNC_PCIE0_PAD_CLKREQ_N>, | |
+ <MT7622_PIN_79_RTS3_N__FUNC_PCIE0_PAD_WAKE_N>; | |
+ }; | |
+ }; | |
+ | |
+ pcie_pinctl1: pcie1 { | |
+ pcie1 { | |
+ pinmux = <MT7622_PIN_15_I2C_SCL__FUNC_PCIE0_PAD_CLKREQ_N>, | |
+ <MT7622_PIN_14_I2C_SDA__FUNC_PCIE0_PAD_WAKE_N>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&svs { | |
+ vproc-supply = <&mt6380_vcpu_reg>; | |
+}; | |
+ | |
+&usb1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&u3phy1 { | |
+ status = "okay"; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt7622-pinfunc.h | |
new file mode 100644 | |
index 000000000000..c34d3ae5e5d5 | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-pinfunc.h | |
@@ -0,0 +1,582 @@ | |
+/* | |
+ * Copyright (C) 2016 MediaTek Inc. | |
+ * | |
+ * This program is free software: you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#ifndef __DTS_MT7622_PINFUNC_H | |
+#define __DTS_MT7622_PINFUNC_H | |
+ | |
+#include <dt-bindings/pinctrl/mt65xx.h> | |
+ | |
+#define MT7622_PIN_0_GPIO_A__FUNC_GPIO0 (MTK_PIN_NO(0) | 1) | |
+ | |
+#define MT7622_PIN_1_I2S1_IN__FUNC_I2S1_IN (MTK_PIN_NO(1) | 0) | |
+#define MT7622_PIN_1_I2S1_IN__FUNC_GPIO1 (MTK_PIN_NO(1) | 1) | |
+#define MT7622_PIN_1_I2S1_IN__FUNC_RTS2_N (MTK_PIN_NO(1) | 2) | |
+ | |
+#define MT7622_PIN_2_I2S1_OUT__FUNC_I2S1_OUT (MTK_PIN_NO(2) | 0) | |
+#define MT7622_PIN_2_I2S1_OUT__FUNC_GPIO2 (MTK_PIN_NO(2) | 1) | |
+#define MT7622_PIN_2_I2S1_OUT__FUNC_CTS2_N (MTK_PIN_NO(2) | 2) | |
+ | |
+#define MT7622_PIN_3_I2S_BCLK__FUNC_I2S_BCLK_OUT (MTK_PIN_NO(3) | 0) | |
+#define MT7622_PIN_3_I2S_BCLK__FUNC_GPIO3 (MTK_PIN_NO(3) | 1) | |
+#define MT7622_PIN_3_I2S_BCLK__FUNC_TXD2 (MTK_PIN_NO(3) | 2) | |
+#define MT7622_PIN_3_I2S_BCLK__FUNC_I2S_BCLK_IN (MTK_PIN_NO(3) | 3) | |
+ | |
+#define MT7622_PIN_4_I2S_WS__FUNC_I2S_WS_OUT (MTK_PIN_NO(4) | 0) | |
+#define MT7622_PIN_4_I2S_WS__FUNC_GPIO4 (MTK_PIN_NO(4) | 1) | |
+#define MT7622_PIN_4_I2S_WS__FUNC_RXD2 (MTK_PIN_NO(4) | 2) | |
+#define MT7622_PIN_4_I2S_WS__FUNC_I2S_WS_IN (MTK_PIN_NO(4) | 3) | |
+ | |
+#define MT7622_PIN_5_I2S_MCLK__FUNC_I2S_MCLK (MTK_PIN_NO(5) | 0) | |
+#define MT7622_PIN_5_I2S_MCLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 1) | |
+#define MT7622_PIN_5_I2S_MCLK__FUNC_DBG_UTIF17 (MTK_PIN_NO(5) | 7) | |
+ | |
+#define MT7622_PIN_6_TXD0__FUNC_TXD0 (MTK_PIN_NO(6) | 0) | |
+#define MT7622_PIN_6_TXD0__FUNC_GPIO6 (MTK_PIN_NO(6) | 1) | |
+#define MT7622_PIN_6_TXD0__FUNC_TM_SUTIF_TXD (MTK_PIN_NO(6) | 7) | |
+ | |
+#define MT7622_PIN_7_RXD0__FUNC_RXD0 (MTK_PIN_NO(7) | 0) | |
+#define MT7622_PIN_7_RXD0__FUNC_GPIO7 (MTK_PIN_NO(7) | 1) | |
+#define MT7622_PIN_7_RXD0__FUNC_TM_SUTIF_RXD (MTK_PIN_NO(7) | 7) | |
+ | |
+#define MT7622_PIN_8_SPI_WP__FUNC_SPI_WP (MTK_PIN_NO(8) | 0) | |
+#define MT7622_PIN_8_SPI_WP__FUNC_GPIO8 (MTK_PIN_NO(8) | 1) | |
+#define MT7622_PIN_8_SPI_WP__FUNC_SNFI_WP (MTK_PIN_NO(8) | 2) | |
+#define MT7622_PIN_8_SPI_WP__FUNC_TDM_OUT_MCLK (MTK_PIN_NO(8) | 3) | |
+#define MT7622_PIN_8_SPI_WP__FUNC_FPC_DAT_STS (MTK_PIN_NO(8) | 6) | |
+ | |
+#define MT7622_PIN_9_SPI_HOLD__FUNC_SPI_HOLD (MTK_PIN_NO(9) | 0) | |
+#define MT7622_PIN_9_SPI_HOLD__FUNC_GPIO9 (MTK_PIN_NO(9) | 1) | |
+#define MT7622_PIN_9_SPI_HOLD__FUNC_SNFI_HOLD (MTK_PIN_NO(9) | 2) | |
+#define MT7622_PIN_9_SPI_HOLD__FUNC_TDM_OUT_BCLK (MTK_PIN_NO(9) | 3) | |
+#define MT7622_PIN_9_SPI_HOLD__FUNC_FPC_DL_STS (MTK_PIN_NO(9) | 6) | |
+ | |
+#define MT7622_PIN_10_SPI_CLK__FUNC_SPI_CLK (MTK_PIN_NO(10) | 0) | |
+#define MT7622_PIN_10_SPI_CLK__FUNC_GPIO10 (MTK_PIN_NO(10) | 1) | |
+#define MT7622_PIN_10_SPI_CLK__FUNC_SNFI_CLK (MTK_PIN_NO(10) | 2) | |
+#define MT7622_PIN_10_SPI_CLK__FUNC_TDM_OUT_WS (MTK_PIN_NO(10) | 3) | |
+ | |
+#define MT7622_PIN_11_SPI_MOSI__FUNC_SPI_MOSI (MTK_PIN_NO(11) | 0) | |
+#define MT7622_PIN_11_SPI_MOSI__FUNC_GPIO11 (MTK_PIN_NO(11) | 1) | |
+#define MT7622_PIN_11_SPI_MOSI__FUNC_SNFI_MOSI (MTK_PIN_NO(11) | 2) | |
+#define MT7622_PIN_11_SPI_MOSI__FUNC_TDM_IN_MCLK (MTK_PIN_NO(11) | 3) | |
+ | |
+#define MT7622_PIN_12_SPI_MISO__FUNC_SPI_MISO (MTK_PIN_NO(12) | 0) | |
+#define MT7622_PIN_12_SPI_MISO__FUNC_GPIO12 (MTK_PIN_NO(12) | 1) | |
+#define MT7622_PIN_12_SPI_MISO__FUNC_SNFI_MISO (MTK_PIN_NO(12) | 2) | |
+#define MT7622_PIN_12_SPI_MISO__FUNC_TDM_IN_BCLK (MTK_PIN_NO(12) | 3) | |
+ | |
+#define MT7622_PIN_13_SPI_CS__FUNC_SPI_CS (MTK_PIN_NO(13) | 0) | |
+#define MT7622_PIN_13_SPI_CS__FUNC_GPIO13 (MTK_PIN_NO(13) | 1) | |
+#define MT7622_PIN_13_SPI_CS__FUNC_SNFI_CS (MTK_PIN_NO(13) | 2) | |
+#define MT7622_PIN_13_SPI_CS__FUNC_TDM_IN_WS (MTK_PIN_NO(13) | 3) | |
+ | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_I2C0_SDA (MTK_PIN_NO(14) | 0) | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_GPIO14 (MTK_PIN_NO(14) | 1) | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_PCIE0_PAD_WAKE_N (MTK_PIN_NO(14) | 2) | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_PCIE1_PAD_WAKE_N (MTK_PIN_NO(14) | 3) | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_ANTSEL22 (MTK_PIN_NO(14) | 5) | |
+#define MT7622_PIN_14_I2C_SDA__FUNC_TM_EXT_BGCK (MTK_PIN_NO(14) | 7) | |
+ | |
+#define MT7622_PIN_15_I2C_SCL__FUNC_I2C0_SCL (MTK_PIN_NO(15) | 0) | |
+#define MT7622_PIN_15_I2C_SCL__FUNC_GPIO15 (MTK_PIN_NO(15) | 1) | |
+#define MT7622_PIN_15_I2C_SCL__FUNC_PCIE0_PAD_CLKREQ_N (MTK_PIN_NO(15) | 2) | |
+#define MT7622_PIN_15_I2C_SCL__FUNC_PCIE1_PAD_CLKREQ_N (MTK_PIN_NO(15) | 3) | |
+#define MT7622_PIN_15_I2C_SCL__FUNC_ANTSEL23 (MTK_PIN_NO(15) | 5) | |
+ | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_I2S2_IN (MTK_PIN_NO(16) | 0) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_GPIO16 (MTK_PIN_NO(16) | 1) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_SD_D3 (MTK_PIN_NO(16) | 2) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_IR_T (MTK_PIN_NO(16) | 4) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_ANTSEL24 (MTK_PIN_NO(16) | 5) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_BT_EPA_EN (MTK_PIN_NO(16) | 6) | |
+#define MT7622_PIN_16_I2S2_IN__FUNC_DBG_UTIF10 (MTK_PIN_NO(16) | 7) | |
+ | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_I2S3_IN (MTK_PIN_NO(17) | 0) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_GPIO17 (MTK_PIN_NO(17) | 1) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_SD_D2 (MTK_PIN_NO(17) | 2) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_IR_R (MTK_PIN_NO(17) | 4) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_ANTSEL25 (MTK_PIN_NO(17) | 5) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_BT_ELNA_EN (MTK_PIN_NO(17) | 6) | |
+#define MT7622_PIN_17_I2S3_IN__FUNC_DBG_UTIF11 (MTK_PIN_NO(17) | 7) | |
+ | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_I2S4_IN (MTK_PIN_NO(18) | 0) | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_GPIO18 (MTK_PIN_NO(18) | 1) | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_SD_D1 (MTK_PIN_NO(18) | 2) | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_ANTSEL26 (MTK_PIN_NO(18) | 5) | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_BT_ERX_EN (MTK_PIN_NO(18) | 6) | |
+#define MT7622_PIN_18_I2S4_IN__FUNC_DBG_UTIF12 (MTK_PIN_NO(18) | 7) | |
+ | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_I2S2_OUT (MTK_PIN_NO(19) | 0) | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_GPIO19 (MTK_PIN_NO(19) | 1) | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0 (MTK_PIN_NO(19) | 2) | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_ANTSEL27 (MTK_PIN_NO(19) | 5) | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_BT_IPATH_EN (MTK_PIN_NO(19) | 6) | |
+#define MT7622_PIN_19_I2S2_OUT__FUNC_DBG_UTIF13 (MTK_PIN_NO(19) | 7) | |
+ | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_I2S3_OUT (MTK_PIN_NO(20) | 0) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_GPIO20 (MTK_PIN_NO(20) | 1) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK (MTK_PIN_NO(20) | 2) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_TDM_OUT_DATA (MTK_PIN_NO(20) | 3) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_ANTSEL28 (MTK_PIN_NO(20) | 5) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_BT_SPXT_C1 (MTK_PIN_NO(20) | 6) | |
+#define MT7622_PIN_20_I2S3_OUT__FUNC_DBG_UTIF14 (MTK_PIN_NO(20) | 7) | |
+ | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_I2S4_OUT (MTK_PIN_NO(21) | 0) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_GPIO21 (MTK_PIN_NO(21) | 1) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD (MTK_PIN_NO(21) | 2) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_TDM_IN_DATA (MTK_PIN_NO(21) | 3) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_ANTSEL29 (MTK_PIN_NO(21) | 5) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_BT_SPXT_C0 (MTK_PIN_NO(21) | 6) | |
+#define MT7622_PIN_21_I2S4_OUT__FUNC_DBG_UTIF15 (MTK_PIN_NO(21) | 7) | |
+ | |
+#define MT7622_PIN_22_GPIO_B__FUNC_GPIO22 (MTK_PIN_NO(22) | 1) | |
+#define MT7622_PIN_22_GPIO_B__FUNC_TSF_INTR (MTK_PIN_NO(22) | 3) | |
+#define MT7622_PIN_22_GPIO_B__FUNC_ANTSEL17 (MTK_PIN_NO(22) | 5) | |
+#define MT7622_PIN_22_GPIO_B__FUNC_DBG_UTIF16 (MTK_PIN_NO(22) | 7) | |
+ | |
+#define MT7622_PIN_23_MDC__FUNC_MDC (MTK_PIN_NO(23) | 0) | |
+#define MT7622_PIN_23_MDC__FUNC_GPIO23 (MTK_PIN_NO(23) | 1) | |
+ | |
+#define MT7622_PIN_24_MDIO__FUNC_MDIO (MTK_PIN_NO(24) | 0) | |
+#define MT7622_PIN_24_MDIO__FUNC_GPIO24 (MTK_PIN_NO(24) | 1) | |
+ | |
+#define MT7622_PIN_25_G2_TXD0__FUNC_G2_TXD0 (MTK_PIN_NO(25) | 0) | |
+#define MT7622_PIN_25_G2_TXD0__FUNC_GPIO25 (MTK_PIN_NO(25) | 1) | |
+#define MT7622_PIN_25_G2_TXD0__FUNC_SD_D3 (MTK_PIN_NO(25) | 2) | |
+ | |
+#define MT7622_PIN_26_G2_TXD1__FUNC_G2_TXD1 (MTK_PIN_NO(26) | 0) | |
+#define MT7622_PIN_26_G2_TXD1__FUNC_GPIO26 (MTK_PIN_NO(26) | 1) | |
+#define MT7622_PIN_26_G2_TXD1__FUNC_SD_D2 (MTK_PIN_NO(26) | 2) | |
+ | |
+#define MT7622_PIN_27_G2_TXD2__FUNC_G2_TXD2 (MTK_PIN_NO(27) | 0) | |
+#define MT7622_PIN_27_G2_TXD2__FUNC_GPIO27 (MTK_PIN_NO(27) | 1) | |
+#define MT7622_PIN_27_G2_TXD2__FUNC_SD_D1 (MTK_PIN_NO(27) | 2) | |
+ | |
+#define MT7622_PIN_28_G2_TXD3__FUNC_G2_TXD3 (MTK_PIN_NO(28) | 0) | |
+#define MT7622_PIN_28_G2_TXD3__FUNC_GPIO28 (MTK_PIN_NO(28) | 1) | |
+#define MT7622_PIN_28_G2_TXD3__FUNC_SD_D0 (MTK_PIN_NO(28) | 2) | |
+ | |
+#define MT7622_PIN_29_G2_TXEN__FUNC_G2_TXEN (MTK_PIN_NO(29) | 0) | |
+#define MT7622_PIN_29_G2_TXEN__FUNC_GPIO29 (MTK_PIN_NO(29) | 1) | |
+#define MT7622_PIN_29_G2_TXEN__FUNC_SD_CLK (MTK_PIN_NO(29) | 2) | |
+ | |
+#define MT7622_PIN_30_G2_TXC__FUNC_G2_TXC (MTK_PIN_NO(30) | 0) | |
+#define MT7622_PIN_30_G2_TXC__FUNC_GPIO30 (MTK_PIN_NO(30) | 1) | |
+#define MT7622_PIN_30_G2_TXC__FUNC_SD_CMD (MTK_PIN_NO(30) | 2) | |
+ | |
+#define MT7622_PIN_31_G2_RXD0__FUNC_G2_RXD0 (MTK_PIN_NO(31) | 0) | |
+#define MT7622_PIN_31_G2_RXD0__FUNC_GPIO31 (MTK_PIN_NO(31) | 1) | |
+#define MT7622_PIN_31_G2_RXD0__FUNC_G2_GPIO31 (MTK_PIN_NO(31) | 2) | |
+ | |
+#define MT7622_PIN_32_G2_RXD1__FUNC_G2_RXD1 (MTK_PIN_NO(32) | 0) | |
+#define MT7622_PIN_32_G2_RXD1__FUNC_GPIO32 (MTK_PIN_NO(32) | 1) | |
+#define MT7622_PIN_32_G2_RXD1__FUNC_G2_GPIO32 (MTK_PIN_NO(32) | 2) | |
+ | |
+#define MT7622_PIN_33_G2_RXD2__FUNC_G2_RXD2 (MTK_PIN_NO(33) | 0) | |
+#define MT7622_PIN_33_G2_RXD2__FUNC_GPIO33 (MTK_PIN_NO(33) | 1) | |
+#define MT7622_PIN_33_G2_RXD2__FUNC_G2_GPIO33 (MTK_PIN_NO(33) | 2) | |
+ | |
+#define MT7622_PIN_34_G2_RXD3__FUNC_G2_RXD3 (MTK_PIN_NO(34) | 0) | |
+#define MT7622_PIN_34_G2_RXD3__FUNC_GPIO34 (MTK_PIN_NO(34) | 1) | |
+#define MT7622_PIN_34_G2_RXD3__FUNC_G2_GPIO34 (MTK_PIN_NO(34) | 2) | |
+ | |
+#define MT7622_PIN_35_G2_RXDV__FUNC_G2_RXDV (MTK_PIN_NO(35) | 0) | |
+#define MT7622_PIN_35_G2_RXDV__FUNC_GPIO35 (MTK_PIN_NO(35) | 1) | |
+#define MT7622_PIN_35_G2_RXDV__FUNC_G2_GPIO35 (MTK_PIN_NO(35) | 2) | |
+ | |
+#define MT7622_PIN_36_G2_RXC__FUNC_G2_RXC (MTK_PIN_NO(36) | 0) | |
+#define MT7622_PIN_36_G2_RXC__FUNC_GPIO36 (MTK_PIN_NO(36) | 1) | |
+#define MT7622_PIN_36_G2_RXC__FUNC_G2_GPIO36 (MTK_PIN_NO(36) | 2) | |
+ | |
+#define MT7622_PIN_37_NCEB__FUNC_ND_CS_N (MTK_PIN_NO(37) | 0) | |
+#define MT7622_PIN_37_NCEB__FUNC_GPIO37 (MTK_PIN_NO(37) | 1) | |
+#define MT7622_PIN_37_NCEB__FUNC_G2_GPIO37 (MTK_PIN_NO(37) | 2) | |
+#define MT7622_PIN_37_NCEB__FUNC_DBG_UTIF18 (MTK_PIN_NO(37) | 7) | |
+ | |
+#define MT7622_PIN_38_NWEB__FUNC_ND_WE_N (MTK_PIN_NO(38) | 0) | |
+#define MT7622_PIN_38_NWEB__FUNC_GPIO38 (MTK_PIN_NO(38) | 1) | |
+#define MT7622_PIN_38_NWEB__FUNC_G2_GPIO38 (MTK_PIN_NO(38) | 2) | |
+#define MT7622_PIN_38_NWEB__FUNC_DBG_UTIF19 (MTK_PIN_NO(38) | 7) | |
+ | |
+#define MT7622_PIN_39_NREB__FUNC_ND_RE_N (MTK_PIN_NO(39) | 0) | |
+#define MT7622_PIN_39_NREB__FUNC_GPIO39 (MTK_PIN_NO(39) | 1) | |
+#define MT7622_PIN_39_NREB__FUNC_G2_GPIO39 (MTK_PIN_NO(39) | 2) | |
+#define MT7622_PIN_39_NREB__FUNC_DBG_UTIF20 (MTK_PIN_NO(39) | 7) | |
+ | |
+#define MT7622_PIN_40_NDL4__FUNC_ND_D4 (MTK_PIN_NO(40) | 0) | |
+#define MT7622_PIN_40_NDL4__FUNC_GPIO40 (MTK_PIN_NO(40) | 1) | |
+#define MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4 (MTK_PIN_NO(40) | 2) | |
+#define MT7622_PIN_40_NDL4__FUNC_DBG_UTIF21 (MTK_PIN_NO(40) | 7) | |
+ | |
+#define MT7622_PIN_41_NDL5__FUNC_ND_D5 (MTK_PIN_NO(41) | 0) | |
+#define MT7622_PIN_41_NDL5__FUNC_GPIO41 (MTK_PIN_NO(41) | 1) | |
+#define MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5 (MTK_PIN_NO(41) | 2) | |
+#define MT7622_PIN_41_NDL5__FUNC_DBG_UTIF22 (MTK_PIN_NO(41) | 7) | |
+ | |
+#define MT7622_PIN_42_NDL6__FUNC_ND_D6 (MTK_PIN_NO(42) | 0) | |
+#define MT7622_PIN_42_NDL6__FUNC_GPIO42 (MTK_PIN_NO(42) | 1) | |
+#define MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6 (MTK_PIN_NO(42) | 2) | |
+#define MT7622_PIN_42_NDL6__FUNC_DBG_UTIF23 (MTK_PIN_NO(42) | 7) | |
+ | |
+#define MT7622_PIN_43_NDL7__FUNC_ND_D7 (MTK_PIN_NO(43) | 0) | |
+#define MT7622_PIN_43_NDL7__FUNC_GPIO43 (MTK_PIN_NO(43) | 1) | |
+#define MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7 (MTK_PIN_NO(43) | 2) | |
+#define MT7622_PIN_43_NDL7__FUNC_DBG_UTIF24 (MTK_PIN_NO(43) | 7) | |
+ | |
+#define MT7622_PIN_44_NRB__FUNC_ND_RB_N (MTK_PIN_NO(44) | 0) | |
+#define MT7622_PIN_44_NRB__FUNC_GPIO44 (MTK_PIN_NO(44) | 1) | |
+#define MT7622_PIN_44_NRB__FUNC_EMMC_CMD (MTK_PIN_NO(44) | 2) | |
+#define MT7622_PIN_44_NRB__FUNC_DBG_UTIF25 (MTK_PIN_NO(44) | 7) | |
+ | |
+#define MT7622_PIN_45_NCLE__FUNC_ND_CLE (MTK_PIN_NO(45) | 0) | |
+#define MT7622_PIN_45_NCLE__FUNC_GPIO45 (MTK_PIN_NO(45) | 1) | |
+#define MT7622_PIN_45_NCLE__FUNC_EMMC_CK (MTK_PIN_NO(45) | 2) | |
+#define MT7622_PIN_45_NCLE__FUNC_DBG_UTIF26 (MTK_PIN_NO(45) | 7) | |
+ | |
+#define MT7622_PIN_46_NALE__FUNC_ND_ALE (MTK_PIN_NO(46) | 0) | |
+#define MT7622_PIN_46_NALE__FUNC_GPIO46 (MTK_PIN_NO(46) | 1) | |
+#define MT7622_PIN_46_NALE__FUNC_G2_GPIO46 (MTK_PIN_NO(46) | 2) | |
+#define MT7622_PIN_46_NALE__FUNC_DBG_UTIF27 (MTK_PIN_NO(46) | 7) | |
+ | |
+#define MT7622_PIN_47_NDL0__FUNC_ND_D0 (MTK_PIN_NO(47) | 0) | |
+#define MT7622_PIN_47_NDL0__FUNC_GPIO47 (MTK_PIN_NO(47) | 1) | |
+#define MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0 (MTK_PIN_NO(47) | 2) | |
+#define MT7622_PIN_47_NDL0__FUNC_DBG_UTIF28 (MTK_PIN_NO(47) | 7) | |
+ | |
+#define MT7622_PIN_48_NDL1__FUNC_ND_D1 (MTK_PIN_NO(48) | 0) | |
+#define MT7622_PIN_48_NDL1__FUNC_GPIO48 (MTK_PIN_NO(48) | 1) | |
+#define MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1 (MTK_PIN_NO(48) | 2) | |
+#define MT7622_PIN_48_NDL1__FUNC_DBG_UTIF29 (MTK_PIN_NO(48) | 7) | |
+ | |
+#define MT7622_PIN_49_NDL2__FUNC_ND_D2 (MTK_PIN_NO(49) | 0) | |
+#define MT7622_PIN_49_NDL2__FUNC_GPIO49 (MTK_PIN_NO(49) | 1) | |
+#define MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2 (MTK_PIN_NO(49) | 2) | |
+#define MT7622_PIN_49_NDL2__FUNC_DBG_UTIF30 (MTK_PIN_NO(49) | 7) | |
+ | |
+#define MT7622_PIN_50_NDL3__FUNC_ND_D3 (MTK_PIN_NO(50) | 0) | |
+#define MT7622_PIN_50_NDL3__FUNC_GPIO50 (MTK_PIN_NO(50) | 1) | |
+#define MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3 (MTK_PIN_NO(50) | 2) | |
+#define MT7622_PIN_50_NDL3__FUNC_DBG_UTIF31 (MTK_PIN_NO(50) | 7) | |
+ | |
+#define MT7622_PIN_51_MDI_TP_P0__FUNC_TXD2 (MTK_PIN_NO(51) | 0) | |
+#define MT7622_PIN_51_MDI_TP_P0__FUNC_GPIO51 (MTK_PIN_NO(51) | 1) | |
+#define MT7622_PIN_51_MDI_TP_P0__FUNC_PWM_CH1 (MTK_PIN_NO(51) | 3) | |
+ | |
+#define MT7622_PIN_52_MDI_TN_P0__FUNC_RXD2 (MTK_PIN_NO(52) | 0) | |
+#define MT7622_PIN_52_MDI_TN_P0__FUNC_GPIO52 (MTK_PIN_NO(52) | 1) | |
+#define MT7622_PIN_52_MDI_TN_P0__FUNC_PWM_CH2 (MTK_PIN_NO(52) | 3) | |
+ | |
+#define MT7622_PIN_53_MDI_RP_P0__FUNC_RTS2_N (MTK_PIN_NO(53) | 0) | |
+#define MT7622_PIN_53_MDI_RP_P0__FUNC_GPIO53 (MTK_PIN_NO(53) | 1) | |
+#define MT7622_PIN_53_MDI_RP_P0__FUNC_PWM_CH3 (MTK_PIN_NO(53) | 3) | |
+ | |
+#define MT7622_PIN_54_MDI_RN_P0__FUNC_CTS2_N (MTK_PIN_NO(54) | 0) | |
+#define MT7622_PIN_54_MDI_RN_P0__FUNC_GPIO54 (MTK_PIN_NO(54) | 1) | |
+#define MT7622_PIN_54_MDI_RN_P0__FUNC_PWM_CH4 (MTK_PIN_NO(54) | 3) | |
+ | |
+#define MT7622_PIN_55_MDI_TP_P1__FUNC_I2C1_SCL (MTK_PIN_NO(55) | 0) | |
+#define MT7622_PIN_55_MDI_TP_P1__FUNC_GPIO55 (MTK_PIN_NO(55) | 1) | |
+#define MT7622_PIN_55_MDI_TP_P1__FUNC_TXD1 (MTK_PIN_NO(55) | 2) | |
+#define MT7622_PIN_55_MDI_TP_P1__FUNC_TDM_OUT_DATA (MTK_PIN_NO(55) | 3) | |
+ | |
+#define MT7622_PIN_56_MDI_TN_P1__FUNC_I2C1_SDA (MTK_PIN_NO(56) | 0) | |
+#define MT7622_PIN_56_MDI_TN_P1__FUNC_GPIO56 (MTK_PIN_NO(56) | 1) | |
+#define MT7622_PIN_56_MDI_TN_P1__FUNC_RXD1 (MTK_PIN_NO(56) | 2) | |
+#define MT7622_PIN_56_MDI_TN_P1__FUNC_TDM_IN_DATA (MTK_PIN_NO(56) | 3) | |
+ | |
+#define MT7622_PIN_57_MDI_RP_P1__FUNC_I2C2_SCL (MTK_PIN_NO(57) | 0) | |
+#define MT7622_PIN_57_MDI_RP_P1__FUNC_GPIO57 (MTK_PIN_NO(57) | 1) | |
+#define MT7622_PIN_57_MDI_RP_P1__FUNC_RTS1_N (MTK_PIN_NO(57) | 2) | |
+#define MT7622_PIN_57_MDI_RP_P1__FUNC_TDM_OUT_MCLK (MTK_PIN_NO(57) | 3) | |
+#define MT7622_PIN_57_MDI_RP_P1__FUNC_TXD3 (MTK_PIN_NO(57) | 5) | |
+ | |
+#define MT7622_PIN_58_MDI_RN_P1__FUNC_I2C2_SDA (MTK_PIN_NO(58) | 0) | |
+#define MT7622_PIN_58_MDI_RN_P1__FUNC_GPIO58 (MTK_PIN_NO(58) | 1) | |
+#define MT7622_PIN_58_MDI_RN_P1__FUNC_CTS1_N (MTK_PIN_NO(58) | 2) | |
+#define MT7622_PIN_58_MDI_RN_P1__FUNC_TDM_OUT_BCLK (MTK_PIN_NO(58) | 3) | |
+#define MT7622_PIN_58_MDI_RN_P1__FUNC_RXD3 (MTK_PIN_NO(58) | 5) | |
+ | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_ESW_TXD0 (MTK_PIN_NO(59) | 0) | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_GPIO59 (MTK_PIN_NO(59) | 1) | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_G1_TXD0 (MTK_PIN_NO(59) | 2) | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_TDM_OUT_WS (MTK_PIN_NO(59) | 3) | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_TXD2 (MTK_PIN_NO(59) | 4) | |
+#define MT7622_PIN_59_MDI_RP_P2__FUNC_IR_T (MTK_PIN_NO(59) | 5) | |
+ | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_ESW_TXD1 (MTK_PIN_NO(60) | 0) | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_GPIO60 (MTK_PIN_NO(60) | 1) | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_G1_TXD1 (MTK_PIN_NO(60) | 2) | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_TDM_IN_MCLK (MTK_PIN_NO(60) | 3) | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_RXD2 (MTK_PIN_NO(60) | 4) | |
+#define MT7622_PIN_60_MDI_RN_P2__FUNC_IR_R (MTK_PIN_NO(60) | 5) | |
+ | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_ESW_TXD2 (MTK_PIN_NO(61) | 0) | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_GPIO61 (MTK_PIN_NO(61) | 1) | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_G1_TXD2 (MTK_PIN_NO(61) | 2) | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_TDM_IN_BCLK (MTK_PIN_NO(61) | 3) | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_RTS2_N (MTK_PIN_NO(61) | 4) | |
+#define MT7622_PIN_61_MDI_TP_P2__FUNC_TXD4 (MTK_PIN_NO(61) | 5) | |
+ | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_ESW_TXD3 (MTK_PIN_NO(62) | 0) | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_GPIO62 (MTK_PIN_NO(62) | 1) | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_G1_TXD3 (MTK_PIN_NO(62) | 2) | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_TDM_IN_WS (MTK_PIN_NO(62) | 3) | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_CTS2_N (MTK_PIN_NO(62) | 4) | |
+#define MT7622_PIN_62_MDI_TN_P2__FUNC_RXD4 (MTK_PIN_NO(62) | 5) | |
+ | |
+#define MT7622_PIN_63_MDI_TP_P3__FUNC_ESW_TXEN (MTK_PIN_NO(63) | 0) | |
+#define MT7622_PIN_63_MDI_TP_P3__FUNC_GPIO63 (MTK_PIN_NO(63) | 1) | |
+#define MT7622_PIN_63_MDI_TP_P3__FUNC_G1_TXEN (MTK_PIN_NO(63) | 2) | |
+#define MT7622_PIN_63_MDI_TP_P3__FUNC_SPIC0_CLK (MTK_PIN_NO(63) | 4) | |
+ | |
+#define MT7622_PIN_64_MDI_TN_P3__FUNC_ESW_TXC (MTK_PIN_NO(64) | 0) | |
+#define MT7622_PIN_64_MDI_TN_P3__FUNC_GPIO64 (MTK_PIN_NO(64) | 1) | |
+#define MT7622_PIN_64_MDI_TN_P3__FUNC_G1_TXC (MTK_PIN_NO(64) | 2) | |
+#define MT7622_PIN_64_MDI_TN_P3__FUNC_SPIC0_MOSI (MTK_PIN_NO(64) | 4) | |
+ | |
+#define MT7622_PIN_65_MDI_RP_P3__FUNC_ESW_RXD0 (MTK_PIN_NO(65) | 0) | |
+#define MT7622_PIN_65_MDI_RP_P3__FUNC_GPIO65 (MTK_PIN_NO(65) | 1) | |
+#define MT7622_PIN_65_MDI_RP_P3__FUNC_G1_RXD0 (MTK_PIN_NO(65) | 2) | |
+#define MT7622_PIN_65_MDI_RP_P3__FUNC_SPIC0_MISO (MTK_PIN_NO(65) | 4) | |
+ | |
+#define MT7622_PIN_66_MDI_RN_P3__FUNC_ESW_RXD1 (MTK_PIN_NO(66) | 0) | |
+#define MT7622_PIN_66_MDI_RN_P3__FUNC_GPIO66 (MTK_PIN_NO(66) | 1) | |
+#define MT7622_PIN_66_MDI_RN_P3__FUNC_G1_RXD1 (MTK_PIN_NO(66) | 2) | |
+#define MT7622_PIN_66_MDI_RN_P3__FUNC_SPIC0_CS (MTK_PIN_NO(66) | 4) | |
+ | |
+#define MT7622_PIN_67_MDI_RP_P4__FUNC_ESW_RXD2 (MTK_PIN_NO(67) | 0) | |
+#define MT7622_PIN_67_MDI_RP_P4__FUNC_GPIO67 (MTK_PIN_NO(67) | 1) | |
+#define MT7622_PIN_67_MDI_RP_P4__FUNC_G1_RXD2 (MTK_PIN_NO(67) | 2) | |
+#define MT7622_PIN_67_MDI_RP_P4__FUNC_PWM_CH4 (MTK_PIN_NO(67) | 3) | |
+#define MT7622_PIN_67_MDI_RP_P4__FUNC_SPIC1_CLK (MTK_PIN_NO(67) | 4) | |
+ | |
+#define MT7622_PIN_68_MDI_RN_P4__FUNC_ESW_RXD3 (MTK_PIN_NO(68) | 0) | |
+#define MT7622_PIN_68_MDI_RN_P4__FUNC_GPIO68 (MTK_PIN_NO(68) | 1) | |
+#define MT7622_PIN_68_MDI_RN_P4__FUNC_G1_RXD3 (MTK_PIN_NO(68) | 2) | |
+#define MT7622_PIN_68_MDI_RN_P4__FUNC_PWM_CH5 (MTK_PIN_NO(68) | 3) | |
+#define MT7622_PIN_68_MDI_RN_P4__FUNC_SPIC1_MOSI (MTK_PIN_NO(68) | 4) | |
+ | |
+#define MT7622_PIN_69_MDI_TP_P4__FUNC_ESW_RXDV (MTK_PIN_NO(69) | 0) | |
+#define MT7622_PIN_69_MDI_TP_P4__FUNC_GPIO69 (MTK_PIN_NO(69) | 1) | |
+#define MT7622_PIN_69_MDI_TP_P4__FUNC_G1_RXDV (MTK_PIN_NO(69) | 2) | |
+#define MT7622_PIN_69_MDI_TP_P4__FUNC_PWM_CH6 (MTK_PIN_NO(69) | 3) | |
+#define MT7622_PIN_69_MDI_TP_P4__FUNC_SPIC1_MISO (MTK_PIN_NO(69) | 4) | |
+ | |
+#define MT7622_PIN_70_MDI_TN_P4__FUNC_ESW_RXC (MTK_PIN_NO(70) | 0) | |
+#define MT7622_PIN_70_MDI_TN_P4__FUNC_GPIO70 (MTK_PIN_NO(70) | 1) | |
+#define MT7622_PIN_70_MDI_TN_P4__FUNC_G1_RXC (MTK_PIN_NO(70) | 2) | |
+#define MT7622_PIN_70_MDI_TN_P4__FUNC_PWM_CH7 (MTK_PIN_NO(70) | 3) | |
+#define MT7622_PIN_70_MDI_TN_P4__FUNC_SPIC1_CS (MTK_PIN_NO(70) | 4) | |
+ | |
+#define MT7622_PIN_71_SPI2_CK__FUNC_SPI2_CK (MTK_PIN_NO(71) | 0) | |
+#define MT7622_PIN_71_SPI2_CK__FUNC_GPIO71 (MTK_PIN_NO(71) | 1) | |
+ | |
+#define MT7622_PIN_72_SPI2_DATA__FUNC_SPI2_DATA (MTK_PIN_NO(72) | 0) | |
+#define MT7622_PIN_72_SPI2_DATA__FUNC_GPIO72 (MTK_PIN_NO(72) | 1) | |
+ | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_SPIC1_CLK (MTK_PIN_NO(73) | 0) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_GPIO73 (MTK_PIN_NO(73) | 1) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_TXD1 (MTK_PIN_NO(73) | 2) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_I2C1_SCL (MTK_PIN_NO(73) | 3) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_PWM_CH1 (MTK_PIN_NO(73) | 4) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_ANTSEL12 (MTK_PIN_NO(73) | 5) | |
+#define MT7622_PIN_73_SPIC1_CLK__FUNC_DBG_UTIF0 (MTK_PIN_NO(73) | 7) | |
+ | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_SPIC1_MOSI (MTK_PIN_NO(74) | 0) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_GPIO74 (MTK_PIN_NO(74) | 1) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_RXD1 (MTK_PIN_NO(74) | 2) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_I2C1_SDA (MTK_PIN_NO(74) | 3) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_PWM_CH2 (MTK_PIN_NO(74) | 4) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_ANTSEL13 (MTK_PIN_NO(74) | 5) | |
+#define MT7622_PIN_74_SPIC1_MOSI__FUNC_DBG_UTIF1 (MTK_PIN_NO(74) | 7) | |
+ | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_SPIC1_MISO (MTK_PIN_NO(75) | 0) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_GPIO75 (MTK_PIN_NO(75) | 1) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_RTS1_N (MTK_PIN_NO(75) | 2) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_I2C2_SCL (MTK_PIN_NO(75) | 3) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_PWM_CH3 (MTK_PIN_NO(75) | 4) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_ANTSEL14 (MTK_PIN_NO(75) | 5) | |
+#define MT7622_PIN_75_SPIC1_MISO__FUNC_DBG_UTIF2 (MTK_PIN_NO(75) | 7) | |
+ | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_SPIC1_CS (MTK_PIN_NO(76) | 0) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_GPIO76 (MTK_PIN_NO(76) | 1) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_CTS1_N (MTK_PIN_NO(76) | 2) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_I2C2_SDA (MTK_PIN_NO(76) | 3) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_PWM_CH4 (MTK_PIN_NO(76) | 4) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_ANTSEL15 (MTK_PIN_NO(76) | 5) | |
+#define MT7622_PIN_76_SPIC1_CS__FUNC_DBG_UTIF3 (MTK_PIN_NO(76) | 7) | |
+ | |
+#define MT7622_PIN_77_GPIO_D__FUNC_GPIO77 (MTK_PIN_NO(77) | 1) | |
+#define MT7622_PIN_77_GPIO_D__FUNC_PWM_CH5 (MTK_PIN_NO(77) | 4) | |
+#define MT7622_PIN_77_GPIO_D__FUNC_ANTSEL16 (MTK_PIN_NO(77) | 5) | |
+#define MT7622_PIN_77_GPIO_D__FUNC_DBG_UTIF4 (MTK_PIN_NO(77) | 7) | |
+ | |
+#define MT7622_PIN_78_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(78) | 0) | |
+#define MT7622_PIN_78_WATCHDOG__FUNC_GPIO78 (MTK_PIN_NO(78) | 1) | |
+#define MT7622_PIN_78_WATCHDOG__FUNC_PWM_CH6 (MTK_PIN_NO(78) | 4) | |
+#define MT7622_PIN_78_WATCHDOG__FUNC_ANTSEL17 (MTK_PIN_NO(78) | 5) | |
+#define MT7622_PIN_78_WATCHDOG__FUNC_DBG_UTIF5 (MTK_PIN_NO(78) | 7) | |
+ | |
+#define MT7622_PIN_79_RTS3_N__FUNC_RTS3_N (MTK_PIN_NO(79) | 0) | |
+#define MT7622_PIN_79_RTS3_N__FUNC_GPIO79 (MTK_PIN_NO(79) | 1) | |
+#define MT7622_PIN_79_RTS3_N__FUNC_SPIC0_MISO (MTK_PIN_NO(79) | 3) | |
+#define MT7622_PIN_79_RTS3_N__FUNC_PCIE0_PAD_WAKE_N (MTK_PIN_NO(79) | 4) | |
+#define MT7622_PIN_79_RTS3_N__FUNC_ANTSEL18 (MTK_PIN_NO(79) | 5) | |
+#define MT7622_PIN_79_RTS3_N__FUNC_DBG_UTIF6 (MTK_PIN_NO(79) | 7) | |
+ | |
+#define MT7622_PIN_80_CTS3_N__FUNC_CTS3_N (MTK_PIN_NO(80) | 0) | |
+#define MT7622_PIN_80_CTS3_N__FUNC_GPIO80 (MTK_PIN_NO(80) | 1) | |
+#define MT7622_PIN_80_CTS3_N__FUNC_SPIC0_CS (MTK_PIN_NO(80) | 3) | |
+#define MT7622_PIN_80_CTS3_N__FUNC_PCIE0_PAD_CLKREQ_N (MTK_PIN_NO(80) | 4) | |
+#define MT7622_PIN_80_CTS3_N__FUNC_ANTSEL19 (MTK_PIN_NO(80) | 5) | |
+#define MT7622_PIN_80_CTS3_N__FUNC_DBG_UTIF7 (MTK_PIN_NO(80) | 7) | |
+ | |
+#define MT7622_PIN_81_TXD3__FUNC_TXD3 (MTK_PIN_NO(81) | 0) | |
+#define MT7622_PIN_81_TXD3__FUNC_GPIO81 (MTK_PIN_NO(81) | 1) | |
+#define MT7622_PIN_81_TXD3__FUNC_SPDIF_T (MTK_PIN_NO(81) | 2) | |
+#define MT7622_PIN_81_TXD3__FUNC_SPIC0_CLK (MTK_PIN_NO(81) | 3) | |
+#define MT7622_PIN_81_TXD3__FUNC_PWM_CH6 (MTK_PIN_NO(81) | 4) | |
+#define MT7622_PIN_81_TXD3__FUNC_ANTSEL20 (MTK_PIN_NO(81) | 5) | |
+#define MT7622_PIN_81_TXD3__FUNC_DBG_UTIF8 (MTK_PIN_NO(81) | 7) | |
+ | |
+#define MT7622_PIN_82_RXD3__FUNC_RXD3 (MTK_PIN_NO(82) | 0) | |
+#define MT7622_PIN_82_RXD3__FUNC_GPIO82 (MTK_PIN_NO(82) | 1) | |
+#define MT7622_PIN_82_RXD3__FUNC_SPDIF_R (MTK_PIN_NO(82) | 2) | |
+#define MT7622_PIN_82_RXD3__FUNC_SPIC0_MOSI (MTK_PIN_NO(82) | 3) | |
+#define MT7622_PIN_82_RXD3__FUNC_PWM_CH7 (MTK_PIN_NO(82) | 4) | |
+#define MT7622_PIN_82_RXD3__FUNC_ANTSEL21 (MTK_PIN_NO(82) | 5) | |
+#define MT7622_PIN_82_RXD3__FUNC_DBG_UTIF9 (MTK_PIN_NO(82) | 7) | |
+ | |
+#define MT7622_PIN_83_PERST0_N__FUNC_PCIE0_PAD_PERST_N (MTK_PIN_NO(83) | 0) | |
+#define MT7622_PIN_83_PERST0_N__FUNC_GPIO83 (MTK_PIN_NO(83) | 1) | |
+ | |
+#define MT7622_PIN_84_PERST1_N__FUNC_PCIE1_PAD_PERST_N (MTK_PIN_NO(84) | 0) | |
+#define MT7622_PIN_84_PERST1_N__FUNC_GPIO84 (MTK_PIN_NO(84) | 1) | |
+ | |
+#define MT7622_PIN_85_WLED_N__FUNC_WLED_N (MTK_PIN_NO(85) | 0) | |
+#define MT7622_PIN_85_WLED_N__FUNC_GPIO85 (MTK_PIN_NO(85) | 1) | |
+ | |
+#define MT7622_PIN_86_EPHY_LED0_N__FUNC_EPHY_LED0_N (MTK_PIN_NO(86) | 0) | |
+#define MT7622_PIN_86_EPHY_LED0_N__FUNC_GPIO86 (MTK_PIN_NO(86) | 1) | |
+#define MT7622_PIN_86_EPHY_LED0_N__FUNC_CPUM_HW_SEL (MTK_PIN_NO(86) | 4) | |
+#define MT7622_PIN_86_EPHY_LED0_N__FUNC_FPC_CTL0 (MTK_PIN_NO(86) | 6) | |
+#define MT7622_PIN_86_EPHY_LED0_N__FUNC_JTRST_N (MTK_PIN_NO(86) | 7) | |
+ | |
+#define MT7622_PIN_87_AUXIN0__FUNC_I2C1_SCL (MTK_PIN_NO(87) | 0) | |
+#define MT7622_PIN_87_AUXIN0__FUNC_GPIO87 (MTK_PIN_NO(87) | 1) | |
+ | |
+#define MT7622_PIN_88_AUXIN1__FUNC_I2C1_SDA (MTK_PIN_NO(88) | 0) | |
+#define MT7622_PIN_88_AUXIN1__FUNC_GPIO88 (MTK_PIN_NO(88) | 1) | |
+ | |
+#define MT7622_PIN_89_AUXIN2__FUNC_I2C2_SCL (MTK_PIN_NO(89) | 0) | |
+#define MT7622_PIN_89_AUXIN2__FUNC_GPIO89 (MTK_PIN_NO(89) | 1) | |
+ | |
+#define MT7622_PIN_90_AUXIN3__FUNC_I2C2_SDA (MTK_PIN_NO(90) | 0) | |
+#define MT7622_PIN_90_AUXIN3__FUNC_GPIO90 (MTK_PIN_NO(90) | 1) | |
+ | |
+#define MT7622_PIN_91_TXD4__FUNC_TXD4 (MTK_PIN_NO(91) | 0) | |
+#define MT7622_PIN_91_TXD4__FUNC_GPIO91 (MTK_PIN_NO(91) | 1) | |
+#define MT7622_PIN_91_TXD4__FUNC_EPHY_LED1_N (MTK_PIN_NO(91) | 2) | |
+#define MT7622_PIN_91_TXD4__FUNC_DFD_TDI (MTK_PIN_NO(91) | 3) | |
+#define MT7622_PIN_91_TXD4__FUNC_CPUM_2B_SEL (MTK_PIN_NO(91) | 4) | |
+#define MT7622_PIN_91_TXD4__FUNC_ANTSEL0 (MTK_PIN_NO(91) | 5) | |
+#define MT7622_PIN_91_TXD4__FUNC_FPC_CK_XI (MTK_PIN_NO(91) | 6) | |
+#define MT7622_PIN_91_TXD4__FUNC_JTDI (MTK_PIN_NO(91) | 7) | |
+ | |
+#define MT7622_PIN_92_RXD4__FUNC_RXD4 (MTK_PIN_NO(92) | 0) | |
+#define MT7622_PIN_92_RXD4__FUNC_GPIO92 (MTK_PIN_NO(92) | 1) | |
+#define MT7622_PIN_92_RXD4__FUNC_EPHY_LED2_N (MTK_PIN_NO(92) | 2) | |
+#define MT7622_PIN_92_RXD4__FUNC_DFD_TDO (MTK_PIN_NO(92) | 3) | |
+#define MT7622_PIN_92_RXD4__FUNC_CPUM0 (MTK_PIN_NO(92) | 4) | |
+#define MT7622_PIN_92_RXD4__FUNC_ANTSEL1 (MTK_PIN_NO(92) | 5) | |
+#define MT7622_PIN_92_RXD4__FUNC_FPC_CTL1 (MTK_PIN_NO(92) | 6) | |
+#define MT7622_PIN_92_RXD4__FUNC_JTDO (MTK_PIN_NO(92) | 7) | |
+ | |
+#define MT7622_PIN_93_RTS4_N__FUNC_RTS4_N (MTK_PIN_NO(93) | 0) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_GPIO93 (MTK_PIN_NO(93) | 1) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_EPHY_LED3_N (MTK_PIN_NO(93) | 2) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_DFD_TCK (MTK_PIN_NO(93) | 3) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_CPUM1 (MTK_PIN_NO(93) | 4) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_ANTSEL2 (MTK_PIN_NO(93) | 5) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_FPC_CTL2 (MTK_PIN_NO(93) | 6) | |
+#define MT7622_PIN_93_RTS4_N__FUNC_JTCLK (MTK_PIN_NO(93) | 7) | |
+ | |
+#define MT7622_PIN_94_CTS4_N__FUNC_CTS4_N (MTK_PIN_NO(94) | 0) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_GPIO94 (MTK_PIN_NO(94) | 1) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_EPHY_LED4_N (MTK_PIN_NO(94) | 2) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_DFD_TMS (MTK_PIN_NO(94) | 3) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_CPUM2 (MTK_PIN_NO(94) | 4) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_ANTSEL3 (MTK_PIN_NO(94) | 5) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_FPC_CTL3 (MTK_PIN_NO(94) | 6) | |
+#define MT7622_PIN_94_CTS4_N__FUNC_JTMS (MTK_PIN_NO(94) | 7) | |
+ | |
+#define MT7622_PIN_95_PWM1__FUNC_PWM_CH1 (MTK_PIN_NO(95) | 0) | |
+#define MT7622_PIN_95_PWM1__FUNC_GPIO95 (MTK_PIN_NO(95) | 1) | |
+#define MT7622_PIN_95_PWM1__FUNC_RTS4_N (MTK_PIN_NO(95) | 2) | |
+#define MT7622_PIN_95_PWM1__FUNC_TXD2 (MTK_PIN_NO(95) | 3) | |
+#define MT7622_PIN_95_PWM1__FUNC_CPUM3 (MTK_PIN_NO(95) | 4) | |
+#define MT7622_PIN_95_PWM1__FUNC_ANTSEL4 (MTK_PIN_NO(95) | 5) | |
+#define MT7622_PIN_95_PWM1__FUNC_FPC_DATA0 (MTK_PIN_NO(95) | 6) | |
+#define MT7622_PIN_95_PWM1__FUNC_W_DBGIN (MTK_PIN_NO(95) | 7) | |
+ | |
+#define MT7622_PIN_96_PWM2__FUNC_PWM_CH2 (MTK_PIN_NO(96) | 0) | |
+#define MT7622_PIN_96_PWM2__FUNC_GPIO96 (MTK_PIN_NO(96) | 1) | |
+#define MT7622_PIN_96_PWM2__FUNC_CTS4_N (MTK_PIN_NO(96) | 2) | |
+#define MT7622_PIN_96_PWM2__FUNC_RXD2 (MTK_PIN_NO(96) | 3) | |
+#define MT7622_PIN_96_PWM2__FUNC_CPUM_CK_XI (MTK_PIN_NO(96) | 4) | |
+#define MT7622_PIN_96_PWM2__FUNC_ANTSEL5 (MTK_PIN_NO(96) | 5) | |
+#define MT7622_PIN_96_PWM2__FUNC_FPC_DATA1 (MTK_PIN_NO(96) | 6) | |
+#define MT7622_PIN_96_PWM2__FUNC_W_DBGACK (MTK_PIN_NO(96) | 7) | |
+ | |
+#define MT7622_PIN_97_PWM3__FUNC_PWM_CH3 (MTK_PIN_NO(97) | 0) | |
+#define MT7622_PIN_97_PWM3__FUNC_GPIO97 (MTK_PIN_NO(97) | 1) | |
+#define MT7622_PIN_97_PWM3__FUNC_TXD4 (MTK_PIN_NO(97) | 2) | |
+#define MT7622_PIN_97_PWM3__FUNC_AICE_TCKC (MTK_PIN_NO(97) | 4) | |
+#define MT7622_PIN_97_PWM3__FUNC_ANTSEL6 (MTK_PIN_NO(97) | 5) | |
+#define MT7622_PIN_97_PWM3__FUNC_FPC_DATA2 (MTK_PIN_NO(97) | 6) | |
+#define MT7622_PIN_97_PWM3__FUNC_W_JTCLK (MTK_PIN_NO(97) | 7) | |
+ | |
+#define MT7622_PIN_98_PWM4__FUNC_PWM_CH4 (MTK_PIN_NO(98) | 0) | |
+#define MT7622_PIN_98_PWM4__FUNC_GPIO98 (MTK_PIN_NO(98) | 1) | |
+#define MT7622_PIN_98_PWM4__FUNC_RXD4 (MTK_PIN_NO(98) | 2) | |
+#define MT7622_PIN_98_PWM4__FUNC_ANTSEL7 (MTK_PIN_NO(98) | 5) | |
+#define MT7622_PIN_98_PWM4__FUNC_FPC_DATA3 (MTK_PIN_NO(98) | 6) | |
+#define MT7622_PIN_98_PWM4__FUNC_W_JTDI (MTK_PIN_NO(98) | 7) | |
+ | |
+#define MT7622_PIN_99_PWM5__FUNC_PWM_CH5 (MTK_PIN_NO(99) | 0) | |
+#define MT7622_PIN_99_PWM5__FUNC_GPIO99 (MTK_PIN_NO(99) | 1) | |
+#define MT7622_PIN_99_PWM5__FUNC_IR_T (MTK_PIN_NO(99) | 3) | |
+#define MT7622_PIN_99_PWM5__FUNC_AICE_TMSC (MTK_PIN_NO(99) | 4) | |
+#define MT7622_PIN_99_PWM5__FUNC_ANTSEL8 (MTK_PIN_NO(99) | 5) | |
+#define MT7622_PIN_99_PWM5__FUNC_FPC_DATA4 (MTK_PIN_NO(99) | 6) | |
+#define MT7622_PIN_99_PWM5__FUNC_W_JTMS (MTK_PIN_NO(99) | 7) | |
+ | |
+#define MT7622_PIN_100_PWM6__FUNC_PWM_CH6 (MTK_PIN_NO(100) | 0) | |
+#define MT7622_PIN_100_PWM6__FUNC_GPIO100 (MTK_PIN_NO(100) | 1) | |
+#define MT7622_PIN_100_PWM6__FUNC_IR_R (MTK_PIN_NO(100) | 3) | |
+#define MT7622_PIN_100_PWM6__FUNC_ANTSEL9 (MTK_PIN_NO(100) | 5) | |
+#define MT7622_PIN_100_PWM6__FUNC_FPC_DATA5 (MTK_PIN_NO(100) | 6) | |
+#define MT7622_PIN_100_PWM6__FUNC_W_JTRST_N (MTK_PIN_NO(100) | 7) | |
+ | |
+#define MT7622_PIN_101_PWM7__FUNC_PWM_CH7 (MTK_PIN_NO(101) | 0) | |
+#define MT7622_PIN_101_PWM7__FUNC_GPIO101 (MTK_PIN_NO(101) | 1) | |
+#define MT7622_PIN_101_PWM7__FUNC_ANTSEL10 (MTK_PIN_NO(101) | 5) | |
+#define MT7622_PIN_101_PWM7__FUNC_FPC_DATA6 (MTK_PIN_NO(101) | 6) | |
+#define MT7622_PIN_101_PWM7__FUNC_DBG_UART_TXD (MTK_PIN_NO(101) | 7) | |
+ | |
+#define MT7622_PIN_102_GPIO_E__FUNC_GPIO102 (MTK_PIN_NO(102) | 1) | |
+#define MT7622_PIN_102_GPIO_E__FUNC_ANTSEL11 (MTK_PIN_NO(102) | 5) | |
+#define MT7622_PIN_102_GPIO_E__FUNC_FPC_DATA7 (MTK_PIN_NO(102) | 6) | |
+#define MT7622_PIN_102_GPIO_E__FUNC_W_JTDO (MTK_PIN_NO(102) | 7) | |
+ | |
+#endif /* __DTS_MT7622_PINFUNC_H */ | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | |
new file mode 100644 | |
index 000000000000..b7a677502a0b | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | |
@@ -0,0 +1,346 @@ | |
+/* | |
+ * Copyright (c) 2016 MediaTek Inc. | |
+ * Author: Ming Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+/dts-v1/; | |
+#include <dt-bindings/gpio/gpio.h> | |
+#include "mt7622.dtsi" | |
+#include "mt6380.dtsi" | |
+ | |
+/ { | |
+ model = "MediaTek MT7622 RFB1 board"; | |
+ compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; | |
+ | |
+ chosen { | |
+ bootargs = "console=ttyS0,115200n1 root=/dev/ram \ | |
+ initrd=0x44000000,0x615E36 loglevel=8 androidboot.hardware=mt7622 swiotlb=512"; | |
+ }; | |
+ | |
+ mmc_fixed_1v8_io: fixedregulator@0 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_io"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ mmc_fixed_3v3_power: fixedregulator@1 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_power"; | |
+ regulator-min-microvolt = <3300000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ memory { | |
+ reg = <0 0x40000000 0 0x3F000000>; | |
+ }; | |
+}; | |
+ | |
+&auxadc { | |
+ status = "okay"; | |
+}; | |
+ | |
+&cpu0 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&cpu1 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&efuse { | |
+ status = "okay"; | |
+}; | |
+ | |
+ð { | |
+ mac-address = [00 00 00 00 00 00]; | |
+ dma-coherent; | |
+ wan_at = "p4"; | |
+ gmac1-support = "sgmii-1"; | |
+ sgmii-mode-1 = "force-2500"; | |
+ #gmac1-support = "rgmii-1"; | |
+ #rgmii-mode-1 = "force-1000"; | |
+ #gmac1-phy-address = <0x1f>; | |
+ gmac2-support = "rgmii-2"; | |
+ rgmii-mode-2 = "force-1000"; | |
+ #rgmii-mode-2 = "an"; | |
+ #gmac2-phy-address = <0x1e>; | |
+ gmac1_txq_num = <1>; | |
+ gmac1_txq_txd_num = <2048>; | |
+ gmac2_txq_num = <1>; | |
+ gmac2_txq_txd_num = <1024>; | |
+ num_rx_desc = <2048>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&gsw { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c2 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&mmc0 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc0_pins_default>; | |
+ pinctrl-1 = <&mmc0_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <8>; | |
+ max-frequency = <50000000>; | |
+ cap-mmc-highspeed; | |
+ mmc-hs200-1_8v; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_1v8_io>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+ non-removable; | |
+}; | |
+ | |
+&mmc1 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc1_pins_default>; | |
+ pinctrl-1 = <&mmc1_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <4>; | |
+ max-frequency = <50000000>; | |
+ cap-sd-highspeed; | |
+ r_smpl = <1>; | |
+ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_3v3_power>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+}; | |
+ | |
+&nor_flash { | |
+ status = "okay"; | |
+ flash@0 { | |
+ compatible = "jedec,spi-nor"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ partition@00000 { | |
+ label = "Preloader"; | |
+ reg = <0x00000 0x0040000>; | |
+ }; | |
+ partition@40000 { | |
+ label = "ATF"; | |
+ reg = <0x40000 0x0020000>; | |
+ }; | |
+ partition@60000 { | |
+ label = "Bootloader"; | |
+ reg = <0x60000 0x0040000>; | |
+ }; | |
+ partition@A0000 { | |
+ label = "Config"; | |
+ reg = <0xA0000 0x0020000>; | |
+ }; | |
+ partition@C0000 { | |
+ label = "Factory"; | |
+ reg = <0xC0000 0x0020000>; | |
+ }; | |
+ partition@E0000 { | |
+ label = "Kernel"; | |
+ reg = <0xE0000 0xF20000>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pio { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&state_default>; | |
+ state_default:pinconf_default { | |
+ }; | |
+ | |
+ mmc0_pins_default: mmc0default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ bias-pull-up; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_uhs: mmc0@0{ | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_default: mmc1default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ | |
+ pins_insert { | |
+ pinmux = <MT7622_PIN_81_TXD3__FUNC_GPIO81>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_uhs: mmc1@0 { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_19_I2S2_OUT__FUNC_SD_D0>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_SD_D1>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_SD_D2>, | |
+ <MT7622_PIN_16_I2S2_IN__FUNC_SD_D3>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_SD_CMD>; | |
+ input-enable; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_20_I2S3_OUT__FUNC_SD_CLK>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ snand_pins_default: snand@0 { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_8_SPI_WP__FUNC_SNFI_WP>, | |
+ <MT7622_PIN_9_SPI_HOLD__FUNC_SNFI_HOLD>, | |
+ <MT7622_PIN_11_SPI_MOSI__FUNC_SNFI_MOSI>, | |
+ <MT7622_PIN_12_SPI_MISO__FUNC_SNFI_MISO>, | |
+ <MT7622_PIN_13_SPI_CS__FUNC_SNFI_CS>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_10_SPI_CLK__FUNC_SNFI_CLK>; | |
+ drive-strength = <MTK_DRIVE_16mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pwm { | |
+ status = "okay"; | |
+}; | |
+ | |
+&snand { | |
+ pinctrl-0 = <&snand_pins_default>; | |
+ status = "okay"; | |
+ flash@0 { | |
+ partitions { | |
+ compatible = "fixed-partitions"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ | |
+ partition@0 { | |
+ label = "Preloader"; | |
+ reg = <0x00000 0x0080000>; | |
+ read-only; | |
+ }; | |
+ | |
+ partition@80000 { | |
+ label = "ATF"; | |
+ reg = <0x80000 0x0040000>; | |
+ }; | |
+ | |
+ partition@c0000 { | |
+ label = "Bootloader"; | |
+ reg = <0xc0000 0x0080000>; | |
+ }; | |
+ | |
+ partition@140000 { | |
+ label = "Config"; | |
+ reg = <0x140000 0x0080000>; | |
+ }; | |
+ | |
+ partition@1c0000 { | |
+ label = "Factory"; | |
+ reg = <0x1c0000 0x0040000>; | |
+ }; | |
+ | |
+ partition@200000 { | |
+ label = "Kernel"; | |
+ reg = <0x200000 0x2000000>; | |
+ }; | |
+ | |
+ partition@2200000 { | |
+ label = "User_data"; | |
+ reg = <0x2200000 0x4000000>; | |
+ }; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&svs { | |
+ vproc-supply = <&mt6380_vcpu_reg>; | |
+}; | |
+ | |
+&uart0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&usb1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&u3phy1 { | |
+ status = "okay"; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb2.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb2.dts | |
new file mode 100644 | |
index 000000000000..bdabfa645c85 | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb2.dts | |
@@ -0,0 +1,318 @@ | |
+/* | |
+ * Copyright (c) 2016 MediaTek Inc. | |
+ * Author: Ming Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+/dts-v1/; | |
+#include "mt7622.dtsi" | |
+#include "mt6380.dtsi" | |
+ | |
+/ { | |
+ model = "MediaTek MT7622 RFB2 board"; | |
+ compatible = "mediatek,mt7622-rfb2", "mediatek,mt7622"; | |
+ | |
+ chosen { | |
+ bootargs = "console=ttyS0,115200n1 root=/dev/ram \ | |
+ initrd=0x44000000,0x615E36 loglevel=8 androidboot.hardware=mt7622 swiotlb=512"; | |
+ }; | |
+ | |
+ dummy_codec:dummy_codec { | |
+ compatible = "mediatek,dummy-codec"; | |
+ }; | |
+ | |
+ mmc_fixed_1v8_io: fixedregulator@0 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_io"; | |
+ regulator-min-microvolt = <1800000>; | |
+ regulator-max-microvolt = <1800000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ mmc_fixed_3v3_power: fixedregulator@1 { | |
+ compatible = "regulator-fixed"; | |
+ regulator-name = "mmc_power"; | |
+ regulator-min-microvolt = <3300000>; | |
+ regulator-max-microvolt = <3300000>; | |
+ regulator-always-on; | |
+ }; | |
+ | |
+ memory { | |
+ reg = <0 0x40000000 0 0x3F000000>; | |
+ }; | |
+ | |
+ sound: sound { | |
+ compatible = "mediatek,mt7622-soc-machine"; | |
+ mediatek,platform = <&afe>; | |
+ mediatek,audio-codec = <&dummy_codec>; | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&aud_pins_default>; | |
+ status = "okay"; | |
+ }; | |
+}; | |
+ | |
+&auxadc { | |
+ status = "okay"; | |
+}; | |
+ | |
+&btif { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&btif_default>; | |
+}; | |
+ | |
+&cpu0 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&cpu1 { | |
+ proc-supply = <&mt6380_vcpu_reg>; | |
+ sram-supply = <&mt6380_vm_reg>; | |
+}; | |
+ | |
+&efuse { | |
+ status = "okay"; | |
+}; | |
+ | |
+ð { | |
+ mac-address = [00 00 00 00 00 00]; | |
+ dma-coherent; | |
+ wan_at = "p0"; | |
+ gmac1-support = "esw"; | |
+ gmac1_txq_num = <1>; | |
+ gmac1_txq_txd_num = <2048>; | |
+ gmac2_txq_num = <1>; | |
+ gmac2_txq_txd_num = <1024>; | |
+ num_rx_desc = <2048>; | |
+ status = "okay"; | |
+}; | |
+ | |
+&gsw { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&i2c2 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&mmc0 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc0_pins_default>; | |
+ pinctrl-1 = <&mmc0_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <8>; | |
+ max-frequency = <50000000>; | |
+ cap-mmc-highspeed; | |
+ mmc-hs200-1_8v; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_1v8_io>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+ non-removable; | |
+}; | |
+ | |
+&mmc1 { | |
+ pinctrl-names = "default", "state_uhs"; | |
+ pinctrl-0 = <&mmc1_pins_default>; | |
+ pinctrl-1 = <&mmc1_pins_uhs>; | |
+ status = "okay"; | |
+ bus-width = <4>; | |
+ max-frequency = <50000000>; | |
+ cap-sd-highspeed; | |
+ r_smpl = <1>; | |
+ cd-gpios = <&pio 32 0>; | |
+ vmmc-supply = <&mmc_fixed_3v3_power>; | |
+ vqmmc-supply = <&mmc_fixed_3v3_power>; | |
+ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; | |
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; | |
+}; | |
+ | |
+&nor_flash { | |
+ status = "okay"; | |
+ flash@0 { | |
+ compatible = "jedec,spi-nor"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ partition@00000 { | |
+ label = "Preloader"; | |
+ reg = <0x00000 0x0040000>; | |
+ }; | |
+ partition@40000 { | |
+ label = "ATF"; | |
+ reg = <0x40000 0x0020000>; | |
+ }; | |
+ partition@60000 { | |
+ label = "Bootloader"; | |
+ reg = <0x60000 0x0040000>; | |
+ }; | |
+ partition@A0000 { | |
+ label = "Config"; | |
+ reg = <0xA0000 0x0020000>; | |
+ }; | |
+ partition@C0000 { | |
+ label = "Factory"; | |
+ reg = <0xC0000 0x0020000>; | |
+ }; | |
+ partition@E0000 { | |
+ label = "Kernel"; | |
+ reg = <0xE0000 0xF20000>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pio { | |
+ pinctrl-names = "default"; | |
+ pinctrl-0 = <&state_default>; | |
+ state_default:pinconf_default { | |
+ }; | |
+ | |
+ aud_pins_default: audiodefault { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_3_I2S_BCLK__FUNC_I2S_BCLK_OUT>, | |
+ <MT7622_PIN_4_I2S_WS__FUNC_I2S_WS_OUT>, | |
+ <MT7622_PIN_5_I2S_MCLK__FUNC_I2S_MCLK>, | |
+ <MT7622_PIN_2_I2S1_OUT__FUNC_I2S1_OUT>, | |
+ <MT7622_PIN_1_I2S1_IN__FUNC_I2S1_IN>, | |
+ <MT7622_PIN_8_SPI_WP__FUNC_TDM_OUT_MCLK>, | |
+ <MT7622_PIN_9_SPI_HOLD__FUNC_TDM_OUT_BCLK>, | |
+ <MT7622_PIN_10_SPI_CLK__FUNC_TDM_OUT_WS>, | |
+ <MT7622_PIN_11_SPI_MOSI__FUNC_TDM_IN_MCLK>, | |
+ <MT7622_PIN_12_SPI_MISO__FUNC_TDM_IN_BCLK>, | |
+ <MT7622_PIN_13_SPI_CS__FUNC_TDM_IN_WS>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ btif_default:btif_default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_16_I2S2_IN__FUNC_BT_EPA_EN>, | |
+ <MT7622_PIN_17_I2S3_IN__FUNC_BT_ELNA_EN>, | |
+ <MT7622_PIN_18_I2S4_IN__FUNC_BT_ERX_EN>, | |
+ <MT7622_PIN_19_I2S2_OUT__FUNC_BT_IPATH_EN>, | |
+ <MT7622_PIN_20_I2S3_OUT__FUNC_BT_SPXT_C1>, | |
+ <MT7622_PIN_21_I2S4_OUT__FUNC_BT_SPXT_C0>; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_default: mmc0default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ bias-pull-up; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ bias-pull-down; | |
+ }; | |
+ }; | |
+ | |
+ mmc0_pins_uhs: mmc0@0{ | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_47_NDL0__FUNC_EMMC_DATA0>, | |
+ <MT7622_PIN_48_NDL1__FUNC_EMMC_DATA1>, | |
+ <MT7622_PIN_49_NDL2__FUNC_EMMC_DATA2>, | |
+ <MT7622_PIN_50_NDL3__FUNC_EMMC_DATA3>, | |
+ <MT7622_PIN_40_NDL4__FUNC_EMMC_DATA4>, | |
+ <MT7622_PIN_41_NDL5__FUNC_EMMC_DATA5>, | |
+ <MT7622_PIN_42_NDL6__FUNC_EMMC_DATA6>, | |
+ <MT7622_PIN_43_NDL7__FUNC_EMMC_DATA7>, | |
+ <MT7622_PIN_44_NRB__FUNC_EMMC_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_45_NCLE__FUNC_EMMC_CK>; | |
+ drive-strength = <MTK_DRIVE_4mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_default: mmc1default { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_28_G2_TXD3__FUNC_SD_D0>, | |
+ <MT7622_PIN_27_G2_TXD2__FUNC_SD_D1>, | |
+ <MT7622_PIN_26_G2_TXD1__FUNC_SD_D2>, | |
+ <MT7622_PIN_25_G2_TXD0__FUNC_SD_D3>, | |
+ <MT7622_PIN_30_G2_TXC__FUNC_SD_CMD>; | |
+ input-enable; | |
+ drive-strength = <MTK_DRIVE_8mA>; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_29_G2_TXEN__FUNC_SD_CLK>; | |
+ drive-strength = <MTK_DRIVE_12mA>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ | |
+ pins_insert { | |
+ pinmux = <MT7622_PIN_32_G2_RXD1__FUNC_G2_GPIO32>; | |
+ bias-pull-up; | |
+ }; | |
+ }; | |
+ | |
+ mmc1_pins_uhs: mmc1@0 { | |
+ pins_cmd_dat { | |
+ pinmux = <MT7622_PIN_28_G2_TXD3__FUNC_SD_D0>, | |
+ <MT7622_PIN_27_G2_TXD2__FUNC_SD_D1>, | |
+ <MT7622_PIN_26_G2_TXD1__FUNC_SD_D2>, | |
+ <MT7622_PIN_25_G2_TXD0__FUNC_SD_D3>, | |
+ <MT7622_PIN_30_G2_TXC__FUNC_SD_CMD>; | |
+ input-enable; | |
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | |
+ }; | |
+ | |
+ pins_clk { | |
+ pinmux = <MT7622_PIN_29_G2_TXEN__FUNC_SD_CLK>; | |
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | |
+ }; | |
+ }; | |
+}; | |
+ | |
+&pwm { | |
+ status = "okay"; | |
+}; | |
+ | |
+&svs { | |
+ vproc-supply = <&mt6380_vcpu_reg>; | |
+}; | |
+ | |
+&uart0 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&usb1 { | |
+ status = "okay"; | |
+}; | |
+ | |
+&u3phy1 { | |
+ status = "okay"; | |
+}; | |
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi | |
new file mode 100644 | |
index 000000000000..baf78212ebbe | |
--- /dev/null | |
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi | |
@@ -0,0 +1,1109 @@ | |
+/* | |
+ * Copyright (c) 2016 MediaTek Inc. | |
+ * Author: Ming.Huang <ming.huang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <dt-bindings/clock/mt7622-clk.h> | |
+#include <dt-bindings/interrupt-controller/irq.h> | |
+#include <dt-bindings/interrupt-controller/arm-gic.h> | |
+#include <dt-bindings/power/mt7622-power.h> | |
+#include <dt-bindings/reset/mt7622-resets.h> | |
+#include <dt-bindings/phy/phy.h> | |
+#include "mt7622-pinfunc.h" | |
+ | |
+/ { | |
+ compatible = "mediatek,mt7622"; | |
+ interrupt-parent = <&sysirq>; | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ | |
+ mtcpufreq { | |
+ compatible = "mediatek,mt7622-cpufreq"; | |
+ }; | |
+ | |
+ cluster0_opp: opp_table0 { | |
+ compatible = "operating-points-v2"; | |
+ opp-shared; | |
+ opp00 { | |
+ opp-hz = /bits/ 64 <300000000>; | |
+ opp-microvolt = <950000>; | |
+ }; | |
+ opp01 { | |
+ opp-hz = /bits/ 64 <437500000>; | |
+ opp-microvolt = <1000000>; | |
+ }; | |
+ opp02 { | |
+ opp-hz = /bits/ 64 <600000000>; | |
+ opp-microvolt = <1050000>; | |
+ }; | |
+ opp03 { | |
+ opp-hz = /bits/ 64 <812500000>; | |
+ opp-microvolt = <1100000>; | |
+ }; | |
+ opp04 { | |
+ opp-hz = /bits/ 64 <1025000000>; | |
+ opp-microvolt = <1150000>; | |
+ }; | |
+ opp05 { | |
+ opp-hz = /bits/ 64 <1137500000>; | |
+ opp-microvolt = <1200000>; | |
+ }; | |
+ opp06 { | |
+ opp-hz = /bits/ 64 <1262500000>; | |
+ opp-microvolt = <1250000>; | |
+ }; | |
+ opp07 { | |
+ opp-hz = /bits/ 64 <1350000000>; | |
+ opp-microvolt = <1310000>; | |
+ }; | |
+ }; | |
+ | |
+ cpus { | |
+ #address-cells = <2>; | |
+ #size-cells = <0>; | |
+ | |
+ cpu0: cpu@0 { | |
+ device_type = "cpu"; | |
+ compatible = "arm,cortex-a53"; | |
+ reg = <0x0 0x0>; | |
+ enable-method = "psci"; | |
+ next-level-cache = <&L2_CA53>; | |
+ cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, | |
+ <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; | |
+ clocks = <&infracfg CLK_INFRA_MUX1_SEL>, | |
+ <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>, | |
+ <&apmixedsys CLK_APMIXED_ARMPLL>; | |
+ clock-names = "cpu", "intermediate", "armpll"; | |
+ operating-points-v2 = <&cluster0_opp>; | |
+ cpu-release-addr = <0x0 0x40000200>; | |
+ clock-frequency = <1300000000>; | |
+ cci-control-port = <&cci_control2>; | |
+ }; | |
+ | |
+ cpu1: cpu@1 { | |
+ device_type = "cpu"; | |
+ compatible = "arm,cortex-a53"; | |
+ reg = <0x0 0x1>; | |
+ enable-method = "psci"; | |
+ next-level-cache = <&L2_CA53>; | |
+ cpu-idle-states = <&CLUSTER_SLEEP_0 &CLUSTER_SLEEP_0>, | |
+ <&CPU_SLEEP_0_0 &CPU_SLEEP_0_0 &CPU_SLEEP_0_0>; | |
+ clocks = <&infracfg CLK_INFRA_MUX1_SEL>, | |
+ <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>, | |
+ <&apmixedsys CLK_APMIXED_ARMPLL>; | |
+ clock-names = "cpu", "intermediate", "armpll"; | |
+ operating-points-v2 = <&cluster0_opp>; | |
+ cpu-release-addr = <0x0 0x40000200>; | |
+ clock-frequency = <1300000000>; | |
+ cci-control-port = <&cci_control2>; | |
+ }; | |
+ | |
+ L2_CA53: l2-cache0 { | |
+ compatible = "cache"; | |
+ cache-level = <2>; | |
+ }; | |
+ | |
+ idle-states { | |
+ entry-method = "arm,psci"; | |
+ | |
+ CPU_SLEEP_0_0: cpu-sleep-0-0 { | |
+ compatible = "arm,idle-state"; | |
+ arm,psci-suspend-param = <0x0010000>; | |
+ entry-latency-us = <600>; | |
+ exit-latency-us = <600>; | |
+ min-residency-us = <1200>; | |
+ }; | |
+ | |
+ CLUSTER_SLEEP_0: cluster-sleep-0 { | |
+ compatible = "arm,idle-state"; | |
+ arm,psci-suspend-param = <0x1010000>; | |
+ entry-latency-us = <800>; | |
+ exit-latency-us = <1000>; | |
+ min-residency-us = <2000>; | |
+ }; | |
+ | |
+ }; | |
+ }; | |
+ | |
+ reserved-memory { | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ ranges; | |
+ | |
+ atf-reserved-memory@43000000 { | |
+ compatible = "mediatek,mt7622-atf-reserved-memory"; | |
+ no-map; | |
+ reg = <0 0x43000000 0 0x30000>; | |
+ }; | |
+ }; | |
+ | |
+ psci { | |
+ compatible = "arm,psci-0.2"; | |
+ method = "smc"; | |
+ }; | |
+ | |
+ pmu { | |
+ compatible = "arm,cortex-a53-pmu"; | |
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>; | |
+ interrupt-affinity = <&cpu0>, <&cpu1>; | |
+ }; | |
+ | |
+ clk25m: oscillator-clk25m { | |
+ compatible = "fixed-clock"; | |
+ #clock-cells = <0>; | |
+ clock-frequency = <25000000>; | |
+ clock-output-names = "clkxtal"; | |
+ }; | |
+ | |
+ clksrc_pll: oscillator-clksrc_pll { | |
+ compatible = "fixed-clock"; | |
+ #clock-cells = <0>; | |
+ clock-frequency = <25000000>; | |
+ clock-output-names = "clksrc_pll"; | |
+ }; | |
+ | |
+ flash_peri_clk: dummy133m { | |
+ compatible = "fixed-clocks"; | |
+ clock-frequency = <133000000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ nfiecc_top_clk: dummy98m { | |
+ compatible = "fixed-clocks"; | |
+ clock-frequency = <48000000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ flash_top_clk: dummy48m { | |
+ compatible = "fixed-clocks"; | |
+ clock-frequency = <48000000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ system_clk: dummy13m { | |
+ compatible = "fixed-clock"; | |
+ clock-frequency = <12500000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ rtc_clk: dummy32k { | |
+ compatible = "fixed-clock"; | |
+ clock-frequency = <32000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ pwrap_clk: dummy40m { | |
+ compatible = "fixed-clock"; | |
+ clock-frequency = <40000000>; | |
+ #clock-cells = <0>; | |
+ }; | |
+ | |
+ chipid: chipid@08000000 { | |
+ compatible = "mediatek,chipid"; | |
+ reg = <0 0x08000000 0 0x0004>, | |
+ <0 0x08000004 0 0x0004>, | |
+ <0 0x08000008 0 0x0004>, | |
+ <0 0x0800000c 0 0x0004>; | |
+ }; | |
+ | |
+ infracfg: infracfg@10000000 { | |
+ compatible = "mediatek,mt7622-infracfg", "syscon"; | |
+ reg = <0 0x10000000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ pwrap: pwrap@10001000 { | |
+ compatible = "mediatek,mt7622-pwrap"; | |
+ reg = <0 0x10001000 0 0x250>; | |
+ reg-names = "pwrap"; | |
+ clocks = <&infracfg CLK_INFRA_PMIC_PD>,<&pwrap_clk>; | |
+ clock-names = "spi","wrap"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ pericfg: pericfg@10002000 { | |
+ compatible = "mediatek,mt7622-pericfg", "syscon"; | |
+ reg = <0 0x10002000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ ice: ice_debug { | |
+ compatible ="mediatek,mt7622-ice_debug", | |
+ "mediatek,mt2701-ice_debug"; | |
+ clocks = <&infracfg CLK_INFRA_DBGCLK_PD>; | |
+ clock-names = "ice_dbg"; | |
+ }; | |
+ | |
+ timer { | |
+ compatible = "arm,armv8-timer"; | |
+ interrupt-parent = <&gic>; | |
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | |
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | |
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | |
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; | |
+ }; | |
+ | |
+ pcie_mirror: pcie_mirror@10000400 { | |
+ compatible = "mediatek,pcie-mirror"; | |
+ reg = <0 0x10000400 0 0x10>; | |
+ }; | |
+ | |
+ timer: timer@10004000 { | |
+ compatible = "mediatek,mt7622-timer", | |
+ "mediatek,mt6577-timer"; | |
+ reg = <0 0x10004000 0 0x80>; | |
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&infracfg CLK_INFRA_APXGPT_PD>, <&topckgen CLK_TOP_RTC>; | |
+ clock-names = "system-clk", "rtc-clk"; | |
+ }; | |
+ | |
+ scpsys: scpsys@10006000 { | |
+ compatible = "mediatek,mt7622-scpsys", "syscon"; | |
+ #power-domain-cells = <1>; | |
+ reg = <0 0x10006000 0 0x1000>; | |
+ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 166 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 167 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>; | |
+ infracfg = <&infracfg>; | |
+ clocks = <&topckgen CLK_TOP_RTC>, <&topckgen CLK_TOP_HIF_SEL>; | |
+ clock-names = "spm_rtc", "hif_sel"; | |
+ }; | |
+ | |
+ irrx: irrx@10009000 { | |
+ compatible = "mediatek,mt7622-irrx"; | |
+ reg = <0 0x10009000 0 0x1000>; | |
+ interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&infracfg CLK_INFRA_IRRX_PD>; | |
+ clock-names = "irrx_clock"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ sysirq: interrupt-controller@10200620 { | |
+ compatible = "mediatek,mt7622-sysirq", | |
+ "mediatek,mt6577-sysirq"; | |
+ interrupt-controller; | |
+ #interrupt-cells = <3>; | |
+ interrupt-parent = <&gic>; | |
+ reg = <0 0x10200620 0 0x20>; | |
+ }; | |
+ | |
+ emi: emi@10203000 { | |
+ compatible = "mediatek,mt7622-emi", | |
+ "mediatek,mt8127-emi"; | |
+ reg = <0 0x10203000 0 0x1000>; | |
+ }; | |
+ | |
+ sys_cirq: sys_cirq@10204000 { | |
+ compatible = "mediatek,mt7622-sys_cirq", | |
+ "mediatek,sys_cirq"; | |
+ reg = <0 0x10204000 0 0x1000>; | |
+ interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_LOW>; | |
+ mediatek,cirq_num = <169>; | |
+ mediatek,spi_start_offset = <72>; | |
+ }; | |
+ | |
+ efuse: efuse@10206000 { | |
+ compatible = "mediatek,mt7622-efuse", | |
+ "mediatek,efuse"; | |
+ reg = <0 0x10206000 0 0x1000>; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ status = "disabled"; | |
+ svs_calibration: calib@180 { | |
+ reg = <0x180 0x8>; | |
+ }; | |
+ thermal_calibration: calib@198 { | |
+ reg = <0x198 0x8>; | |
+ }; | |
+ }; | |
+ | |
+ apmixedsys: apmixedsys@10209000 { | |
+ compatible = "mediatek,mt7622-apmixedsys", "syscon"; | |
+ reg = <0 0x10209000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ wed: wed@1020b000 { | |
+ compatible = "mediatek,wed"; | |
+ wed_num = <2>; | |
+ /* add this property for wed get the pci slot number. */ | |
+ pci_slot_map = <0>, <1>; | |
+ reg = <0 0x1020a000 0 0x1000>, | |
+ <0 0x1020b000 0 0x1000>; | |
+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>; | |
+ }; | |
+ | |
+ wed2: wed2@1020b000 { | |
+ compatible = "mediatek,wed2"; | |
+ wed_num = <2>; | |
+ reg = <0 0x1020a000 0 0x1000>, | |
+ <0 0x1020b000 0 0x1000>; | |
+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>; | |
+ }; | |
+ | |
+ rng: rng@1020f000 { | |
+ compatible = "mediatek,mt7622-rng", | |
+ "mediatek,mt7623-rng"; | |
+ reg = <0 0x1020f000 0 0x100>; | |
+ clocks = <&infracfg CLK_INFRA_TRNG_PD>; | |
+ clock-names = "rng"; | |
+ | |
+ }; | |
+ | |
+ dramc_nao: dramc_nao@0x1020e000 { | |
+ compatible = "mediatek,mt7622-dramc_nao"; | |
+ reg = <0 0x1020E000 0 0x1000>; | |
+ }; | |
+ | |
+ topckgen: topckgen@10210000 { | |
+ compatible = "mediatek,mt7622-topckgen", "syscon"; | |
+ reg = <0 0x10210000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ syscfg_pctl_a: syscfg_pctl_a@10211000 { | |
+ compatible = "mediatek,mt7622-pctl-a-syscfg", "syscon"; | |
+ reg = <0 0x10211000 0 0x1000>; | |
+ }; | |
+ | |
+ pio: pinctrl@10211000 { | |
+ compatible = "mediatek,mt7622-pinctrl"; | |
+ reg = <0 0x10005000 0 0x1000>; | |
+ mediatek,pctl-regmap = <&syscfg_pctl_a>; | |
+ pins-are-numbered; | |
+ gpio-controller; | |
+ #gpio-cells = <2>; | |
+ interrupt-controller; | |
+ #interrupt-cells = <2>; | |
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; | |
+ }; | |
+ | |
+ watchdog: watchdog@10212000 { | |
+ compatible = "mediatek,mt7622-wdt", | |
+ "mediatek,mt6589-wdt"; | |
+ reg = <0 0x10212000 0 0x1000>; | |
+ timeout-sec = <30>; | |
+ mediatek,timer = <&timer>; | |
+ #reset-cells = <1>; | |
+ }; | |
+ | |
+ dramc: dramc@10214000 { | |
+ compatible = "mediatek,mt7622-dramc"; | |
+ reg = <0 0x10214000 0 0x1000>; | |
+ }; | |
+ | |
+ gic: interrupt-controller@10300000 { | |
+ compatible = "arm,gic-400"; | |
+ interrupt-controller; | |
+ #interrupt-cells = <3>; | |
+ interrupt-parent = <&gic>; | |
+ reg = <0 0x10310000 0 0x1000>, | |
+ <0 0x10320000 0 0x1000>, | |
+ <0 0x10340000 0 0x2000>, | |
+ <0 0x10360000 0 0x2000>; | |
+ }; | |
+ | |
+ cci: cci@10390000 { | |
+ compatible = "arm,cci-400"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ reg = <0 0x10390000 0 0x1000>; | |
+ ranges = <0 0 0x10390000 0x10000>; | |
+ | |
+ cci_control0: slave-if@1000 { | |
+ compatible = "arm,cci-400-ctrl-if"; | |
+ interface-type = "ace-lite"; | |
+ reg = <0x1000 0x1000>; | |
+ }; | |
+ | |
+ cci_control1: slave-if@4000 { | |
+ compatible = "arm,cci-400-ctrl-if"; | |
+ interface-type = "ace"; | |
+ reg = <0x4000 0x1000>; | |
+ }; | |
+ | |
+ cci_control2: slave-if@5000 { | |
+ compatible = "arm,cci-400-ctrl-if"; | |
+ interface-type = "ace"; | |
+ reg = <0x5000 0x1000>; | |
+ }; | |
+ | |
+ pmu@9000 { | |
+ compatible = "arm,cci-400-pmu,r1"; | |
+ reg = <0x9000 0x5000>; | |
+ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>, | |
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>, | |
+ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>, | |
+ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>, | |
+ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; | |
+ }; | |
+ }; | |
+ | |
+ btif_tx: btif_tx@11000780 { | |
+ compatible = "mediatek,btif_tx"; | |
+ reg = <0 0x11000780 0 0x80>; | |
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_LOW>; | |
+ }; | |
+ | |
+ btif_rx: btif_rx@11000800 { | |
+ compatible = "mediatek,btif_rx"; | |
+ reg = <0 0x11000800 0 0x80>; | |
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>; | |
+ }; | |
+ | |
+ auxadc: adc@11001000 { | |
+ compatible = "mediatek,mt7622-auxadc"; | |
+ reg = <0 0x11001000 0 0x1000>; | |
+ clocks = <&pericfg CLK_PERI_AUXADC_PD>; | |
+ clock-names = "main"; | |
+ #io-channel-cells = <1>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ uart0: serial@11002000 { | |
+ compatible = "mediatek,mt7622-uart", | |
+ "mediatek,mt6577-uart"; | |
+ reg = <0 0x11002000 0 0x400>; | |
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_UART_SEL>, <&pericfg CLK_PERI_UART0_PD>; | |
+ clock-names = "baud", "bus"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ uart1: serial@11003000 { | |
+ compatible = "mediatek,mt7622-uart", | |
+ "mediatek,mt6577-uart"; | |
+ reg = <0 0x11003000 0 0x400>; | |
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_UART_SEL>, <&pericfg CLK_PERI_UART1_PD>; | |
+ clock-names = "baud", "bus"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ uart2: serial@11004000 { | |
+ compatible = "mediatek,mt7622-uart", | |
+ "mediatek,mt6577-uart"; | |
+ reg = <0 0x11004000 0 0x400>; | |
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_UART_SEL>, <&pericfg CLK_PERI_UART2_PD>; | |
+ clock-names = "baud", "bus"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ uart3: serial@11005000 { | |
+ compatible = "mediatek,mt7622-uart", | |
+ "mediatek,mt6577-uart"; | |
+ reg = <0 0x11005000 0 0x400>; | |
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_UART_SEL>, <&pericfg CLK_PERI_UART3_PD>; | |
+ clock-names = "baud", "bus"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ pwm: pwm@11006000 { | |
+ compatible = "mediatek,mt7622-pwm"; | |
+ reg = <0 0x11006000 0 0x1000>; | |
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_PWM_SEL>, | |
+ <&pericfg CLK_PERI_PWM_PD>, | |
+ <&pericfg CLK_PERI_PWM1_PD>, | |
+ <&pericfg CLK_PERI_PWM2_PD>, | |
+ <&pericfg CLK_PERI_PWM3_PD>, | |
+ <&pericfg CLK_PERI_PWM4_PD>, | |
+ <&pericfg CLK_PERI_PWM5_PD>, | |
+ <&pericfg CLK_PERI_PWM6_PD>; | |
+ clock-names = "top", | |
+ "main", | |
+ "pwm1", | |
+ "pwm2", | |
+ "pwm3", | |
+ "pwm4", | |
+ "pwm5", | |
+ "pwm6"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ i2c0: i2c@11007000 { | |
+ compatible = "mediatek,mt7622-i2c"; | |
+ reg = <0 0x11007000 0 0x90>, | |
+ <0 0x11000100 0 0x80>; | |
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>; | |
+ clock-div = <16>; | |
+ clocks = <&pericfg CLK_PERI_I2C0_PD>, | |
+ <&pericfg CLK_PERI_AP_DMA_PD>; | |
+ clock-names = "main", "dma"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ i2c1: i2c@11008000 { | |
+ compatible = "mediatek,mt7622-i2c"; | |
+ reg = <0 0x11008000 0 0x90>, | |
+ <0 0x11000180 0 0x80>; | |
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>; | |
+ clock-div = <16>; | |
+ clocks = <&pericfg CLK_PERI_I2C1_PD>, | |
+ <&pericfg CLK_PERI_AP_DMA_PD>; | |
+ clock-names = "main", "dma"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ i2c2: i2c@11009000 { | |
+ compatible = "mediatek,mt7622-i2c"; | |
+ reg = <0 0x11009000 0 0x90>, | |
+ <0 0x11000200 0 0x80>; | |
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>; | |
+ clock-div = <16>; | |
+ clocks = <&pericfg CLK_PERI_I2C2_PD>, | |
+ <&pericfg CLK_PERI_AP_DMA_PD>; | |
+ clock-names = "main", "dma"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ spi0: spi@1100a000 { | |
+ compatible = "mediatek,mt7622-spi"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ reg = <0 0x1100a000 0 0x100>; | |
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, | |
+ <&topckgen CLK_TOP_SPI0_SEL>, | |
+ <&pericfg CLK_PERI_SPI0_PD>; | |
+ clock-names = "parent-clk", "sel-clk", "spi-clk"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ thermal: thermal@1100b000 { | |
+ compatible = "mediatek,mt7622-thermal"; | |
+ reg = <0 0x1100b000 0 0x1000>; | |
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_THERM_PD>, <&pericfg CLK_PERI_AUXADC_PD>; | |
+ clock-names = "therm", "auxadc"; | |
+ auxadc = <&auxadc>; | |
+ apmixedsys = <&apmixedsys>; | |
+ pericfg = <&pericfg>; | |
+ nvmem-cells = <&thermal_calibration>; | |
+ nvmem-cell-names = "calibration-data"; | |
+ }; | |
+ | |
+ svs: svs@1100b000 { | |
+ compatible = "mediatek,mt7622-svs"; | |
+ reg = <0 0x1100b000 0 0x1000>; | |
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_LOW>; | |
+ nvmem-cells = <&svs_calibration>; | |
+ nvmem-cell-names = "svs_calibration"; | |
+ }; | |
+ | |
+ btif: btif@1100c000 { | |
+ compatible = "mediatek,btif"; | |
+ reg = <0 0x1100c000 0 0x1000>; | |
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_LOW>, <GIC_SPI 126 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_BTIF_PD>, <&pericfg CLK_PERI_AP_DMA_PD>; | |
+ clock-names = "btifc", "apdmac"; | |
+ }; | |
+ | |
+ nandc: nfi@1100d000 { | |
+ compatible = "mediatek,mt7622-nfc"; | |
+ reg = <0 0x1100D000 0 0x1000>; | |
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>; | |
+ clock-names = "nfi_clk", "pad_clk"; | |
+ ecc-engine = <&bch>; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ snand: snfi@1100d000 { | |
+ compatible = "mediatek,mt7622-snand"; | |
+ reg = <0 0x1100d000 0 0x2000>; | |
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_NFI_PD>, | |
+ <&pericfg CLK_PERI_SNFI_PD>, | |
+ <&pericfg CLK_PERI_NFIECC_PD>; | |
+ clock-names = "nfi_clk", "pad_clk", "nfiecc_clk"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ bch: ecc@1100e000 { | |
+ compatible = "mediatek,mt7622-ecc"; | |
+ reg = <0 0x1100e000 0 0x1000>; | |
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_NFIECC_PD>; | |
+ clock-names = "nfiecc_clk"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ nor_flash: spi@11014000 { | |
+ compatible = "mediatek,mt7622-nor", | |
+ "mediatek,mt8173-nor"; | |
+ reg = <0 0x11014000 0 0xe0>; | |
+ clocks = <&pericfg CLK_PERI_FLASH_PD>, | |
+ <&topckgen CLK_TOP_FLASH_SEL>; | |
+ clock-names = "spi", "sf"; | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ spi1: spi@11016000 { | |
+ compatible = "mediatek,mt7622-spi"; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ reg = <0 0x11016000 0 0x100>; | |
+ interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, | |
+ <&topckgen CLK_TOP_SPI1_SEL>, | |
+ <&pericfg CLK_PERI_SPI1_PD>; | |
+ clock-names = "parent-clk", "sel-clk", "spi-clk"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ uart4: serial@11019000 { | |
+ compatible = "mediatek,mt7622-uart", | |
+ "mediatek,mt6577-uart"; | |
+ reg = <0 0x11019000 0 0x400>; | |
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_UART_SEL>, <&pericfg CLK_PERI_UART4_PD>; | |
+ clock-names = "baud", "bus"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ audiosys: audiosys@11220000 { | |
+ compatible = "mediatek,mt7622-audiosys", "syscon"; | |
+ reg = <0 0x11220000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ afe: audio-controller@11220000 { | |
+ compatible = "mediatek,mt7622-audio"; | |
+ reg = <0 0x11220000 0 0x2000>, | |
+ <0 0x112a0000 0 0x10000>; | |
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&infracfg CLK_INFRA_AUDIO_PD>, | |
+ <&topckgen CLK_TOP_A1SYS_HP_SEL>, | |
+ <&topckgen CLK_TOP_A2SYS_HP_SEL>, | |
+ <&topckgen CLK_TOP_A1SYS_HP_DIV>, | |
+ <&topckgen CLK_TOP_A2SYS_HP_DIV>, | |
+ <&topckgen CLK_TOP_AUD1PLL>, | |
+ <&topckgen CLK_TOP_AUD2PLL>, | |
+ <&topckgen CLK_TOP_A1SYS_HP_DIV_PD>, | |
+ <&topckgen CLK_TOP_A2SYS_HP_DIV_PD>, | |
+ <&topckgen CLK_TOP_AUD_INTBUS_SEL>, | |
+ <&topckgen CLK_TOP_SYSPLL1_D4>, | |
+ <&topckgen CLK_TOP_INTDIR_SEL>, | |
+ <&topckgen CLK_TOP_UNIVPLL_D2>, | |
+ <&topckgen CLK_TOP_APLL1_SEL>, | |
+ <&topckgen CLK_TOP_APLL2_SEL>, | |
+ <&topckgen CLK_TOP_I2S0_MCK_SEL>, | |
+ <&topckgen CLK_TOP_I2S1_MCK_SEL>, | |
+ <&topckgen CLK_TOP_I2S2_MCK_SEL>, | |
+ <&topckgen CLK_TOP_I2S3_MCK_SEL>, | |
+ <&topckgen CLK_TOP_APLL1_DIV>, | |
+ <&topckgen CLK_TOP_APLL2_DIV>, | |
+ <&topckgen CLK_TOP_I2S0_MCK_DIV>, | |
+ <&topckgen CLK_TOP_I2S1_MCK_DIV>, | |
+ <&topckgen CLK_TOP_I2S2_MCK_DIV>, | |
+ <&topckgen CLK_TOP_I2S3_MCK_DIV>, | |
+ <&topckgen CLK_TOP_APLL1_DIV_PD>, | |
+ <&topckgen CLK_TOP_APLL2_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S0_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S1_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S2_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_I2S3_MCK_DIV_PD>, | |
+ <&topckgen CLK_TOP_AUD1_SEL>, | |
+ <&topckgen CLK_TOP_AUD2_SEL>, | |
+ <&topckgen CLK_TOP_ASM_H_SEL>, | |
+ <&topckgen CLK_TOP_ASM_M_SEL>, | |
+ <&topckgen CLK_TOP_SYSPLL_D5>, | |
+ <&topckgen CLK_TOP_UNIVPLL2_D2>, | |
+ <&audiosys CLK_AUDIO_AFE>, | |
+ <&audiosys CLK_AUDIO_APLL>, | |
+ <&audiosys CLK_AUDIO_A1SYS>, | |
+ <&audiosys CLK_AUDIO_A2SYS>; | |
+ | |
+ clock-names = "infra_audio_pd", | |
+ "top_a1sys_hp_sel", | |
+ "top_a2sys_hp_sel", | |
+ "top_a1sys_div", | |
+ "top_a2sys_div", | |
+ "top_aud1pll_ck", | |
+ "top_aud2pll_ck", | |
+ "top_a1sys_div_pd", | |
+ "top_a2sys_div_pd", | |
+ "top_aud_intbus_sel", | |
+ "top_syspll1_d4", | |
+ "top_intdir_sel", | |
+ "top_univpll_d2", | |
+ "top_apll1_ck_sel", | |
+ "top_apll2_ck_sel", | |
+ "top_i2s0_mck_sel", | |
+ "top_i2s1_mck_sel", | |
+ "top_i2s2_mck_sel", | |
+ "top_i2s3_mck_sel", | |
+ "top_apll1_ck_div", | |
+ "top_apll2_ck_div", | |
+ "top_i2s0_mck_div", | |
+ "top_i2s1_mck_div", | |
+ "top_i2s2_mck_div", | |
+ "top_i2s3_mck_div", | |
+ "top_apll1_ck_div_pd", | |
+ "top_apll2_ck_div_pd", | |
+ "top_i2s0_mck_div_pd", | |
+ "top_i2s1_mck_div_pd", | |
+ "top_i2s2_mck_div_pd", | |
+ "top_i2s3_mck_div_pd", | |
+ "top_aud1_sel", | |
+ "top_aud2_sel", | |
+ "top_asm_h_sel", | |
+ "top_asm_m_sel", | |
+ "top_syspll_d5", | |
+ "top_univpll2_d2", | |
+ "top_audio_afe", | |
+ "top_audio_apll", | |
+ "top_audio_a1sys", | |
+ "top_audio_a2sys"; | |
+ }; | |
+ | |
+ mmc0: mmc@11230000 { | |
+ compatible = "mediatek,mt7622-mmc"; | |
+ reg = <0 0x11230000 0 0x1000>; | |
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_MSDC30_0_PD>, | |
+ <&topckgen CLK_TOP_MSDC50_0_SEL>; | |
+ clock-names = "source", "hclk"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ mmc1: mmc@11240000 { | |
+ compatible = "mediatek,mt7622-mmc"; | |
+ reg = <0 0x11240000 0 0x1000>; | |
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pericfg CLK_PERI_MSDC30_1_PD>, | |
+ <&topckgen CLK_TOP_AXI_SEL>; | |
+ clock-names = "source", "hclk"; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ wbsys: wbsys@18000000 { | |
+ compatible = "mediatek,wbsys"; | |
+ reg = <0 0x18000000 0 0x100000>; | |
+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_LOW>; | |
+ #interrupt-cells = <1>; | |
+ dma-coherent; | |
+ }; | |
+ | |
+ ssusbsys: ssusbsys@1a000000 { | |
+ compatible = "mediatek,mt7622-ssusbsys", "syscon"; | |
+ reg = <0 0x1a000000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ usb1: usb@1a0c0000 { | |
+ compatible = "mediatek,mt7622-xhci", "mediatek,mtk-xhci"; | |
+ reg = <0 0x1a0c0000 0 0x01000>, | |
+ <0 0x1a0c4700 0 0x0100>; | |
+ reg-names = "mac", "ippc"; | |
+ interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>; | |
+ clocks = <&ssusbsys CLK_SSUSB_SYS_EN>, | |
+ <&ssusbsys CLK_SSUSB_REF_EN>, | |
+ <&ssusbsys CLK_SSUSB_MCU_EN>, | |
+ <&ssusbsys CLK_SSUSB_DMA_EN>; | |
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck"; | |
+ phys = <&u2port0 PHY_TYPE_USB2>, | |
+ <&u3port0 PHY_TYPE_USB3>, | |
+ <&u2port1 PHY_TYPE_USB2>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ u3phy1: usb-phy@1a0c4000 { | |
+ compatible = "mediatek,mt7622-u3phy", "mediatek,generic-tphy-v1"; | |
+ reg = <0 0x1a0c4000 0 0x700>; | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ ranges; | |
+ status = "disabled"; | |
+ | |
+ u2port0: usb-phy@1a0c4800 { | |
+ reg = <0 0x1a0c4800 0 0x0100>; | |
+ #phy-cells = <1>; | |
+ clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>; | |
+ clock-names = "ref"; | |
+ }; | |
+ | |
+ u3port0: usb-phy@1a0c4900 { | |
+ reg = <0 0x1a0c4900 0 0x0700>; | |
+ #phy-cells = <1>; | |
+ clocks = <&clk25m>; | |
+ clock-names = "ref"; | |
+ }; | |
+ | |
+ u2port1: usb-phy@1a0c5000 { | |
+ reg = <0 0x1a0c5000 0 0x0100>; | |
+ #phy-cells = <1>; | |
+ clocks = <&ssusbsys CLK_SSUSB_U2_PHY_1P_EN>; | |
+ clock-names = "ref"; | |
+ }; | |
+ }; | |
+ | |
+ pciesys: pciesys@1a100800 { | |
+ compatible = "mediatek,mt7622-pciesys", "syscon"; | |
+ reg = <0 0x1a100800 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ #reset-cells = <1>; | |
+ }; | |
+ | |
+ pcie: pcie@1a140000 { | |
+ compatible = "mediatek,mt7622-pcie"; | |
+ device_type = "pci"; | |
+ reg = <0 0x1a140000 0 0x1000>, | |
+ <0 0x1a143000 0 0x1000>, | |
+ <0 0x1a145000 0 0x1000>; | |
+ reg-names = "subsys", "port0", "port1"; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P1_MAC_EN>, | |
+ <&pciesys CLK_PCIE_P0_AHB_EN>, | |
+ /* designer has connect rc1 with p0_ahb clock */ | |
+ <&pciesys CLK_PCIE_P0_AHB_EN>, | |
+ <&pciesys CLK_PCIE_P0_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P1_AUX_EN>, | |
+ <&pciesys CLK_PCIE_P0_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P1_AXI_EN>, | |
+ <&pciesys CLK_PCIE_P0_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P1_OBFF_EN>, | |
+ <&pciesys CLK_PCIE_P0_PIPE_EN>, | |
+ <&pciesys CLK_PCIE_P1_PIPE_EN>; | |
+ clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", | |
+ "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", | |
+ "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; | |
+ | |
+ phys = <&pcieport0 PHY_TYPE_PCIE>, | |
+ <&pcieport1 PHY_TYPE_PCIE>; | |
+ phy-names = "pcie-phy0", "pcie-phy1"; | |
+ | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | |
+ bus-range = <0x00 0xff>; | |
+ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; | |
+ pcie0: pcie@0,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0000 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc0 0>, | |
+ <0 0 0 2 &pcie_intc0 1>, | |
+ <0 0 0 3 &pcie_intc0 2>, | |
+ <0 0 0 4 &pcie_intc0 3>; | |
+ pcie_intc0: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ | |
+ pcie1: pcie@1,0 { | |
+ device_type = "pci"; | |
+ reg = <0x0800 0 0 0 0>; | |
+ #address-cells = <3>; | |
+ #size-cells = <2>; | |
+ #interrupt-cells = <1>; | |
+ ranges; | |
+ num-lanes = <1>; | |
+ interrupt-map-mask = <0 0 0 7>; | |
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>, | |
+ <0 0 0 2 &pcie_intc1 1>, | |
+ <0 0 0 3 &pcie_intc1 2>, | |
+ <0 0 0 4 &pcie_intc1 3>; | |
+ pcie_intc1: interrupt-controller { | |
+ interrupt-controller; | |
+ #address-cells = <0>; | |
+ #interrupt-cells = <1>; | |
+ }; | |
+ }; | |
+ }; | |
+ | |
+ pciephy: pcie-phy@1a148000 { | |
+ compatible = "mediatek,generic-tphy-v2"; | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ ranges; | |
+ | |
+ pcieport0: port0phy { | |
+ reg = <0 0x1a148000 0 0x1000>; | |
+ clocks = <&clk25m>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ }; | |
+ | |
+ pcieport1: port1phy { | |
+ reg = <0 0x1a14a000 0 0x1000>; | |
+ clocks = <&clk25m>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ }; | |
+ }; | |
+ | |
+ sata: sata@1a200000 { | |
+ compatible = "mediatek,mt7622-ahci", | |
+ "mediatek,mtk-ahci"; | |
+ reg = <0 0x1a200000 0 0x1100>; | |
+ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>; | |
+ interrupt-names = "hostc"; | |
+ clocks = <&apmixedsys CLK_APMIXED_ETH1PLL>, | |
+ <&pciesys CLK_SATA_AHB_EN>, | |
+ <&pciesys CLK_SATA_AXI_EN>, | |
+ <&pciesys CLK_SATA_ASIC_EN>, | |
+ <&pciesys CLK_SATA_RBC_EN>, | |
+ <&pciesys CLK_SATA_PM_EN>; | |
+ clock-names = "pll", "ahb", "axi", "asic", "rbc", "pm"; | |
+ phys = <&sata_port PHY_TYPE_SATA>; | |
+ phy-names = "sata-phy"; | |
+ ports-implemented = <0x1>; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | |
+ resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, | |
+ <&pciesys MT7622_SATA_PHY_SW_RST>, | |
+ <&pciesys MT7622_SATA_PHY_REG_RST>; | |
+ reset-names = "axi", "sw", "reg"; | |
+ mediatek,phy-mode = <&pciesys>; | |
+ }; | |
+ | |
+ sata_phy: sata-phy@1a242000 { | |
+ compatible = "mediatek,generic-tphy-v1"; | |
+ reg = <0 0x1a242000 0 0x0100>; | |
+ #address-cells = <2>; | |
+ #size-cells = <2>; | |
+ ranges; | |
+ status = "disabled"; | |
+ | |
+ sata_port: sata-phy@1a243000 { | |
+ reg = <0 0x1a243000 0 0x0100>; | |
+ clocks = <&pciesys CLK_SATA_AHB_EN>; | |
+ clock-names = "ref"; | |
+ #phy-cells = <1>; | |
+ }; | |
+ }; | |
+ | |
+ hifsys: syscon@1af00000 { | |
+ compatible = "mediatek,mt7622-hifsys", "syscon"; | |
+ reg = <0 0x1af00000 0 0x70>; | |
+ }; | |
+ | |
+ ethsys: syscon@1b000000 { | |
+ #address-cells = <1>; | |
+ #size-cells = <1>; | |
+ compatible = "mediatek,mt7622-ethsys", | |
+ "syscon"; | |
+ reg = <0 0x1b000000 0 0x1000>; | |
+ #clock-cells = <1>; | |
+ #reset-cells = <1>; | |
+ }; | |
+ | |
+ gsw: gsw@1b100000 { | |
+ compatible = "mediatek,rtk-gsw", | |
+ "mediatek,mt753x"; | |
+ mediatek,ethsys = <ðsys>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ raeth: raeth@1b100000 { | |
+ compatible = "mediatek,mt7622-raeth"; | |
+ reg = <0 0x1b100000 0 0x20000>; | |
+ interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 240 IRQ_TYPE_LEVEL_LOW>; | |
+ clocks = <&topckgen CLK_TOP_ETH_SEL>, | |
+ <&apmixedsys CLK_APMIXED_ETH1PLL>, | |
+ <&apmixedsys CLK_APMIXED_ETH2PLL>, | |
+ <&apmixedsys CLK_APMIXED_SGMIPLL>, | |
+ <&clk25m>, | |
+ <ðsys CLK_ETH_ESW_EN>, | |
+ <ðsys CLK_ETH_GP2_EN>, | |
+ <ðsys CLK_ETH_GP1_EN>, | |
+ <ðsys CLK_ETH_GP0_EN>, | |
+ <&sgmiisys CLK_SGMII_TX250M_EN>, | |
+ <&sgmiisys CLK_SGMII_RX250M_EN>, | |
+ <&sgmiisys CLK_SGMII_CDR_REF>, | |
+ <&sgmiisys CLK_SGMII_CDR_FB>; | |
+ clock-names = "ethif", "eth1pll", "eth2pll", | |
+ "sgmipll", "trgpll", "esw", "gp2", | |
+ "gp1", "gp0", "sgmii_tx250m", | |
+ "sgmii_rx250m", "sgmii_cdr_ref", | |
+ "sgmii_cdr_fb"; | |
+ power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; | |
+ mediatek,ethsys = <ðsys>; | |
+ mediatek,gsw = <&gsw>; | |
+ #reset-cells = <1>; | |
+ #address-cells = <1>; | |
+ #size-cells = <0>; | |
+ status = "disabled"; | |
+ }; | |
+ | |
+ wdma: wdma@1b102800 { | |
+ compatible = "mediatek,wed-wdma"; | |
+ reg = <0 0x1b102800 0 0x400>, | |
+ <0 0x1b102c00 0 0x400>; | |
+ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 218 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 219 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_LOW>, | |
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_LOW>; | |
+ }; | |
+ | |
+ sgmiisys: sgmiisys@1b128000 { | |
+ compatible = "mediatek,mt7622-sgmiisys", "syscon"; | |
+ reg = <0 0x1b128000 0 0x3000>; | |
+ mediatek,physpeed = "2500"; | |
+ #clock-cells = <1>; | |
+ }; | |
+ | |
+ clkao: clkao { | |
+ compatible = "simple-bus"; | |
+ }; | |
+ | |
+ ioc: ioc { | |
+ compatible = "mediatek,mt7622-subsys-ioc"; | |
+ arm,cci-400-s4 = <&cci_control2>; | |
+ mediatek,wbsys = <&infracfg>; | |
+ mediatek,hifsys = <&hifsys>; | |
+ mediatek,ethsys = <ðsys>; | |
+ mediatek,eth = <&raeth>; | |
+ mediatek,wifi = <&wbsys>; | |
+ | |
+ mediatek,en_usb; | |
+ mediatek,en_pcie_sata; | |
+ }; | |
+}; | |
+ | |
+#include "mt7622-clkao.dtsi" | |
diff --git a/arch/arm64/configs/mt7622_defconfig b/arch/arm64/configs/mt7622_defconfig | |
new file mode 100644 | |
index 000000000000..6252edb21ac3 | |
--- /dev/null | |
+++ b/arch/arm64/configs/mt7622_defconfig | |
@@ -0,0 +1,222 @@ | |
+# CONFIG_LOCALVERSION_AUTO is not set | |
+CONFIG_SYSVIPC=y | |
+CONFIG_POSIX_MQUEUE=y | |
+CONFIG_FHANDLE=y | |
+CONFIG_AUDIT=y | |
+CONFIG_NO_HZ_IDLE=y | |
+CONFIG_HIGH_RES_TIMERS=y | |
+CONFIG_BSD_PROCESS_ACCT=y | |
+CONFIG_BSD_PROCESS_ACCT_V3=y | |
+CONFIG_TASKSTATS=y | |
+CONFIG_TASK_DELAY_ACCT=y | |
+CONFIG_TASK_XACCT=y | |
+CONFIG_TASK_IO_ACCOUNTING=y | |
+CONFIG_IKCONFIG=y | |
+CONFIG_IKCONFIG_PROC=y | |
+CONFIG_MEMCG=y | |
+CONFIG_MEMCG_SWAP=y | |
+CONFIG_MEMCG_KMEM=y | |
+CONFIG_CGROUP_HUGETLB=y | |
+# CONFIG_UTS_NS is not set | |
+# CONFIG_IPC_NS is not set | |
+# CONFIG_NET_NS is not set | |
+CONFIG_SCHED_AUTOGROUP=y | |
+CONFIG_BLK_DEV_INITRD=y | |
+CONFIG_KALLSYMS_ALL=y | |
+# CONFIG_COMPAT_BRK is not set | |
+CONFIG_PROFILING=y | |
+CONFIG_JUMP_LABEL=y | |
+CONFIG_MODULES=y | |
+CONFIG_MODULE_UNLOAD=y | |
+# CONFIG_BLK_DEV_BSG is not set | |
+# CONFIG_IOSCHED_DEADLINE is not set | |
+CONFIG_ARCH_MEDIATEK=y | |
+CONFIG_MACH_MT7622=y | |
+CONFIG_PCI=y | |
+CONFIG_PCI_MSI=y | |
+CONFIG_PCI_HOST_GENERIC=y | |
+CONFIG_PCI_XGENE=y | |
+CONFIG_PCIE_MEDIATEK=y | |
+CONFIG_SCHED_MC=y | |
+CONFIG_PREEMPT=y | |
+CONFIG_KSM=y | |
+CONFIG_TRANSPARENT_HUGEPAGE=y | |
+CONFIG_CMA=y | |
+CONFIG_CMDLINE="console=ttyAMA0" | |
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | |
+CONFIG_COMPAT=y | |
+CONFIG_CPU_IDLE=y | |
+CONFIG_ARM_CPUIDLE=y | |
+CONFIG_NET=y | |
+CONFIG_PACKET=y | |
+CONFIG_UNIX=y | |
+CONFIG_INET=y | |
+CONFIG_IP_PNP=y | |
+CONFIG_IP_PNP_DHCP=y | |
+CONFIG_IP_PNP_BOOTP=y | |
+# CONFIG_INET_LRO is not set | |
+# CONFIG_IPV6 is not set | |
+CONFIG_BPF_JIT=y | |
+# CONFIG_WIRELESS is not set | |
+CONFIG_NET_9P=y | |
+CONFIG_NET_9P_VIRTIO=y | |
+# CONFIG_TEGRA_AHB is not set | |
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |
+CONFIG_DEVTMPFS=y | |
+CONFIG_DEVTMPFS_MOUNT=y | |
+CONFIG_DMA_CMA=y | |
+CONFIG_MTK_SUBSYS_IOC=y | |
+CONFIG_MTD=y | |
+CONFIG_MTD_NAND=y | |
+CONFIG_MTD_NAND_MTK=y | |
+CONFIG_MTD_UBI=y | |
+CONFIG_BLK_DEV_LOOP=y | |
+CONFIG_VIRTIO_BLK=y | |
+CONFIG_MTK_ICE_DEBUG=y | |
+CONFIG_MTK_EMI_BWL=y | |
+CONFIG_MTK_EMI_7622=y | |
+# CONFIG_SCSI_PROC_FS is not set | |
+CONFIG_BLK_DEV_SD=y | |
+# CONFIG_SCSI_LOWLEVEL is not set | |
+CONFIG_ATA=y | |
+CONFIG_SATA_AHCI=y | |
+CONFIG_SATA_AHCI_PLATFORM=y | |
+CONFIG_AHCI_CEVA=y | |
+CONFIG_AHCI_MTK=y | |
+CONFIG_AHCI_XGENE=y | |
+CONFIG_PATA_PLATFORM=y | |
+CONFIG_PATA_OF_PLATFORM=y | |
+CONFIG_NETDEVICES=y | |
+CONFIG_TUN=y | |
+CONFIG_VIRTIO_NET=y | |
+CONFIG_NET_XGENE=y | |
+CONFIG_SKY2=y | |
+CONFIG_SMC91X=y | |
+CONFIG_SMSC911X=y | |
+# CONFIG_WLAN is not set | |
+CONFIG_INPUT_EVDEV=y | |
+CONFIG_KEYBOARD_GPIO=y | |
+# CONFIG_SERIO_SERPORT is not set | |
+CONFIG_SERIO_AMBAKMI=y | |
+CONFIG_LEGACY_PTY_COUNT=16 | |
+CONFIG_SERIAL_8250=y | |
+CONFIG_SERIAL_8250_CONSOLE=y | |
+CONFIG_SERIAL_8250_DW=y | |
+CONFIG_SERIAL_8250_MT6577=y | |
+CONFIG_SERIAL_AMBA_PL011=y | |
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | |
+CONFIG_SERIAL_SAMSUNG=y | |
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y | |
+CONFIG_SERIAL_MSM=y | |
+CONFIG_SERIAL_MSM_CONSOLE=y | |
+CONFIG_SERIAL_OF_PLATFORM=y | |
+CONFIG_SERIAL_XILINX_PS_UART=y | |
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y | |
+CONFIG_VIRTIO_CONSOLE=y | |
+# CONFIG_HW_RANDOM is not set | |
+CONFIG_I2C=y | |
+CONFIG_I2C_MT65XX=y | |
+CONFIG_I2C_QUP=y | |
+CONFIG_SPI=y | |
+CONFIG_SPI_PL022=y | |
+CONFIG_SPI_QUP=y | |
+CONFIG_PINCTRL_MSM8916=y | |
+# CONFIG_PINCTRL_MT2712 is not set | |
+# CONFIG_PINCTRL_MT8173 is not set | |
+CONFIG_GPIO_PL061=y | |
+CONFIG_GPIO_XGENE=y | |
+CONFIG_POWER_RESET_XGENE=y | |
+CONFIG_POWER_RESET_SYSCON=y | |
+# CONFIG_HWMON is not set | |
+CONFIG_WATCHDOG=y | |
+CONFIG_MEDIATEK_WATCHDOG=y | |
+CONFIG_REGULATOR=y | |
+CONFIG_REGULATOR_FIXED_VOLTAGE=y | |
+CONFIG_REGULATOR_QCOM_SMD_RPM=y | |
+CONFIG_FB=y | |
+CONFIG_FB_ARMCLCD=y | |
+CONFIG_FRAMEBUFFER_CONSOLE=y | |
+CONFIG_LOGO=y | |
+# CONFIG_LOGO_LINUX_MONO is not set | |
+# CONFIG_LOGO_LINUX_VGA16 is not set | |
+CONFIG_USB=y | |
+CONFIG_USB_EHCI_HCD=y | |
+CONFIG_USB_EHCI_HCD_PLATFORM=y | |
+CONFIG_USB_OHCI_HCD=y | |
+CONFIG_USB_OHCI_HCD_PLATFORM=y | |
+CONFIG_USB_STORAGE=y | |
+CONFIG_USB_ISP1760=y | |
+CONFIG_USB_ULPI=y | |
+CONFIG_MMC=y | |
+CONFIG_MMC_ARMMMCI=y | |
+CONFIG_MMC_SDHCI=y | |
+CONFIG_MMC_SDHCI_PLTFM=y | |
+CONFIG_MMC_SPI=y | |
+CONFIG_MMC_DW=y | |
+CONFIG_MMC_DW_EXYNOS=y | |
+CONFIG_MMC_MTK=y | |
+CONFIG_NEW_LEDS=y | |
+CONFIG_LEDS_CLASS=y | |
+CONFIG_LEDS_SYSCON=y | |
+CONFIG_LEDS_TRIGGERS=y | |
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y | |
+CONFIG_LEDS_TRIGGER_CPU=y | |
+CONFIG_RTC_CLASS=y | |
+CONFIG_RTC_DRV_EFI=y | |
+CONFIG_RTC_DRV_XGENE=y | |
+CONFIG_DMADEVICES=y | |
+CONFIG_QCOM_BAM_DMA=y | |
+CONFIG_VIRTIO_PCI=y | |
+CONFIG_VIRTIO_BALLOON=y | |
+CONFIG_VIRTIO_MMIO=y | |
+CONFIG_HWSPINLOCK_QCOM=y | |
+# CONFIG_IOMMU_SUPPORT is not set | |
+CONFIG_QCOM_SMEM=y | |
+CONFIG_QCOM_SMD=y | |
+CONFIG_QCOM_SMD_RPM=y | |
+CONFIG_IIO=y | |
+CONFIG_MEDIATEK_MT6577_AUXADC=y | |
+CONFIG_PWM=y | |
+CONFIG_PWM_MEDIATEK=y | |
+CONFIG_PHY_XGENE=y | |
+CONFIG_NVMEM=y | |
+CONFIG_MTK_EFUSE=y | |
+CONFIG_EXT2_FS=y | |
+CONFIG_EXT3_FS=y | |
+CONFIG_FANOTIFY=y | |
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y | |
+CONFIG_QUOTA=y | |
+CONFIG_AUTOFS4_FS=y | |
+CONFIG_FUSE_FS=y | |
+CONFIG_CUSE=y | |
+CONFIG_VFAT_FS=y | |
+CONFIG_TMPFS=y | |
+CONFIG_HUGETLBFS=y | |
+CONFIG_EFIVAR_FS=y | |
+# CONFIG_MISC_FILESYSTEMS is not set | |
+CONFIG_NFS_FS=y | |
+CONFIG_NFS_V4=y | |
+CONFIG_ROOT_NFS=y | |
+CONFIG_9P_FS=y | |
+CONFIG_NLS_CODEPAGE_437=y | |
+CONFIG_NLS_ISO8859_1=y | |
+CONFIG_VIRTUALIZATION=y | |
+CONFIG_KVM=y | |
+CONFIG_DEBUG_INFO=y | |
+CONFIG_DEBUG_FS=y | |
+CONFIG_MAGIC_SYSRQ=y | |
+CONFIG_DEBUG_KERNEL=y | |
+# CONFIG_SCHED_DEBUG is not set | |
+# CONFIG_DEBUG_PREEMPT is not set | |
+# CONFIG_FTRACE is not set | |
+CONFIG_MEMTEST=y | |
+CONFIG_SECURITY=y | |
+CONFIG_CRYPTO_ANSI_CPRNG=y | |
+CONFIG_ARM64_CRYPTO=y | |
+CONFIG_CRYPTO_SHA1_ARM64_CE=y | |
+CONFIG_CRYPTO_SHA2_ARM64_CE=y | |
+CONFIG_CRYPTO_GHASH_ARM64_CE=y | |
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y | |
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y | |
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y | |
+CONFIG_CRYPTO_CRC32_ARM64=y | |
diff --git a/arch/arm64/configs/mt7622_rfb1_defconfig b/arch/arm64/configs/mt7622_rfb1_defconfig | |
new file mode 100644 | |
index 000000000000..3235de32cb98 | |
--- /dev/null | |
+++ b/arch/arm64/configs/mt7622_rfb1_defconfig | |
@@ -0,0 +1,75 @@ | |
+# CONFIG_LOCALVERSION_AUTO is not set | |
+CONFIG_DEFAULT_HOSTNAME="(mt7622)" | |
+# CONFIG_SWAP is not set | |
+CONFIG_SYSVIPC=y | |
+# CONFIG_CROSS_MEMORY_ATTACH is not set | |
+# CONFIG_USELIB is not set | |
+CONFIG_NO_HZ_IDLE=y | |
+CONFIG_HIGH_RES_TIMERS=y | |
+CONFIG_IRQ_TIME_ACCOUNTING=y | |
+CONFIG_BSD_PROCESS_ACCT=y | |
+CONFIG_BSD_PROCESS_ACCT_V3=y | |
+CONFIG_IKCONFIG=y | |
+CONFIG_IKCONFIG_PROC=y | |
+# CONFIG_UTS_NS is not set | |
+CONFIG_BLK_DEV_INITRD=y | |
+CONFIG_INITRAMFS_SOURCE="../prebuilt/bootable/7622_loader/rootfs.cpio.gz" | |
+# CONFIG_RD_BZIP2 is not set | |
+# CONFIG_RD_XZ is not set | |
+# CONFIG_RD_LZO is not set | |
+# CONFIG_RD_LZ4 is not set | |
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y | |
+CONFIG_PERF_EVENTS=y | |
+# CONFIG_COMPAT_BRK is not set | |
+CONFIG_JUMP_LABEL=y | |
+CONFIG_MODULES=y | |
+CONFIG_MODULE_UNLOAD=y | |
+CONFIG_MODULE_FORCE_UNLOAD=y | |
+# CONFIG_BLK_DEV_BSG is not set | |
+# CONFIG_IOSCHED_DEADLINE is not set | |
+CONFIG_ARCH_MEDIATEK=y | |
+CONFIG_MACH_MT7622=y | |
+CONFIG_SCHED_MC=y | |
+CONFIG_NR_CPUS=2 | |
+CONFIG_HOTPLUG_CPU=y | |
+CONFIG_PREEMPT=y | |
+# CONFIG_COMPACTION is not set | |
+# CONFIG_BOUNCE is not set | |
+CONFIG_CMDLINE="console=ttyS0" | |
+# CONFIG_EFI is not set | |
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | |
+CONFIG_COMPAT=y | |
+# CONFIG_SUSPEND is not set | |
+# CONFIG_WAKELOCK is not set | |
+CONFIG_CPU_IDLE=y | |
+# CONFIG_CPU_IDLE_GOV_LADDER is not set | |
+CONFIG_DEVTMPFS=y | |
+CONFIG_DEVTMPFS_MOUNT=y | |
+# CONFIG_BLK_DEV is not set | |
+# CONFIG_GPS is not set | |
+# CONFIG_INPUT_MOUSEDEV is not set | |
+# CONFIG_INPUT_KEYBOARD is not set | |
+# CONFIG_INPUT_MOUSE is not set | |
+# CONFIG_SERIO is not set | |
+CONFIG_VT_HW_CONSOLE_BINDING=y | |
+CONFIG_LEGACY_PTY_COUNT=16 | |
+CONFIG_SERIAL_8250=y | |
+CONFIG_SERIAL_8250_CONSOLE=y | |
+CONFIG_SERIAL_8250_MT6577=y | |
+CONFIG_SERIAL_OF_PLATFORM=y | |
+# CONFIG_HW_RANDOM is not set | |
+CONFIG_POWER_RESET_SYSCON=y | |
+# CONFIG_HWMON is not set | |
+# CONFIG_HID is not set | |
+# CONFIG_USB_SUPPORT is not set | |
+# CONFIG_COMMON_CLK_MT2701 is not set | |
+# CONFIG_COMMON_CLK_MT8135 is not set | |
+# CONFIG_COMMON_CLK_MT8173 is not set | |
+# CONFIG_IOMMU_SUPPORT is not set | |
+CONFIG_TMPFS=y | |
+# CONFIG_MISC_FILESYSTEMS is not set | |
+# CONFIG_ENABLE_WARN_DEPRECATED is not set | |
+# CONFIG_ENABLE_MUST_CHECK is not set | |
+CONFIG_STACKTRACE=y | |
+# CONFIG_DEBUG_RODATA is not set | |
+CONFIG_CRC16=y | |
diff --git a/arch/arm64/crypto/.gitignore b/arch/arm64/crypto/.gitignore | |
new file mode 100644 | |
index 000000000000..879df8781ed5 | |
--- /dev/null | |
+++ b/arch/arm64/crypto/.gitignore | |
@@ -0,0 +1,2 @@ | |
+sha256-core.S | |
+sha512-core.S | |
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig | |
index 2cf32e9887e1..d92ae2e3a779 100644 | |
--- a/arch/arm64/crypto/Kconfig | |
+++ b/arch/arm64/crypto/Kconfig | |
@@ -8,31 +8,48 @@ menuconfig ARM64_CRYPTO | |
if ARM64_CRYPTO | |
+config CRYPTO_SHA256_ARM64 | |
+ tristate "SHA-224/SHA-256 digest algorithm for arm64" | |
+ select CRYPTO_HASH | |
+ | |
+config CRYPTO_SHA512_ARM64 | |
+ tristate "SHA-384/SHA-512 digest algorithm for arm64" | |
+ select CRYPTO_HASH | |
+ | |
config CRYPTO_SHA1_ARM64_CE | |
tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)" | |
- depends on ARM64 && KERNEL_MODE_NEON | |
+ depends on KERNEL_MODE_NEON | |
select CRYPTO_HASH | |
+ select CRYPTO_SHA1 | |
config CRYPTO_SHA2_ARM64_CE | |
tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)" | |
- depends on ARM64 && KERNEL_MODE_NEON | |
+ depends on KERNEL_MODE_NEON | |
select CRYPTO_HASH | |
+ select CRYPTO_SHA256_ARM64 | |
config CRYPTO_GHASH_ARM64_CE | |
tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions" | |
- depends on ARM64 && KERNEL_MODE_NEON | |
+ depends on KERNEL_MODE_NEON | |
select CRYPTO_HASH | |
+ select CRYPTO_GF128MUL | |
+ | |
+config CRYPTO_AES_ARM64 | |
+ tristate "AES core cipher using scalar instructions" | |
+ select CRYPTO_AES | |
config CRYPTO_AES_ARM64_CE | |
tristate "AES core cipher using ARMv8 Crypto Extensions" | |
depends on ARM64 && KERNEL_MODE_NEON | |
select CRYPTO_ALGAPI | |
+ select CRYPTO_AES_ARM64 | |
config CRYPTO_AES_ARM64_CE_CCM | |
tristate "AES in CCM mode using ARMv8 Crypto Extensions" | |
depends on ARM64 && KERNEL_MODE_NEON | |
select CRYPTO_ALGAPI | |
select CRYPTO_AES_ARM64_CE | |
+ select CRYPTO_AES_ARM64 | |
select CRYPTO_AEAD | |
config CRYPTO_AES_ARM64_CE_BLK | |
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile | |
index 550e02a5aa32..94a75cac554f 100644 | |
--- a/arch/arm64/crypto/Makefile | |
+++ b/arch/arm64/crypto/Makefile | |
@@ -30,6 +30,15 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o | |
obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o | |
aes-neon-blk-y := aes-glue-neon.o aes-neon.o | |
+obj-$(CONFIG_CRYPTO_SHA256_ARM64) += sha256-arm64.o | |
+sha256-arm64-y := sha256-glue.o sha256-core.o | |
+ | |
+obj-$(CONFIG_CRYPTO_SHA512_ARM64) += sha512-arm64.o | |
+sha512-arm64-y := sha512-glue.o sha512-core.o | |
+ | |
+obj-$(CONFIG_CRYPTO_AES_ARM64) += aes-arm64.o | |
+aes-arm64-y := aes-cipher-core.o aes-cipher-glue.o | |
+ | |
AFLAGS_aes-ce.o := -DINTERLEAVE=4 | |
AFLAGS_aes-neon.o := -DINTERLEAVE=4 | |
@@ -41,3 +50,14 @@ CFLAGS_crc32-arm64.o := -mcpu=generic+crc | |
$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE | |
$(call if_changed_rule,cc_o_c) | |
+ | |
+quiet_cmd_perlasm = PERLASM $@ | |
+ cmd_perlasm = $(PERL) $(<) void $(@) | |
+ | |
+$(obj)/sha256-core.S: $(src)/sha512-armv8.pl | |
+ $(call cmd,perlasm) | |
+ | |
+$(obj)/sha512-core.S: $(src)/sha512-armv8.pl | |
+ $(call cmd,perlasm) | |
+ | |
+.PRECIOUS: $(obj)/sha256-core.S $(obj)/sha512-core.S | |
diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S | |
index 7bc459d9235c..1b151442dac1 100644 | |
--- a/arch/arm64/crypto/aes-ce-ccm-core.S | |
+++ b/arch/arm64/crypto/aes-ce-ccm-core.S | |
@@ -1,7 +1,7 @@ | |
/* | |
* aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions | |
* | |
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -32,7 +32,7 @@ ENTRY(ce_aes_ccm_auth_data) | |
beq 8f /* out of input? */ | |
cbnz w8, 0b | |
eor v0.16b, v0.16b, v1.16b | |
-1: ld1 {v3.16b}, [x4] /* load first round key */ | |
+1: ld1 {v3.4s}, [x4] /* load first round key */ | |
prfm pldl1strm, [x1] | |
cmp w5, #12 /* which key size? */ | |
add x6, x4, #16 | |
@@ -42,17 +42,17 @@ ENTRY(ce_aes_ccm_auth_data) | |
mov v5.16b, v3.16b | |
b 4f | |
2: mov v4.16b, v3.16b | |
- ld1 {v5.16b}, [x6], #16 /* load 2nd round key */ | |
+ ld1 {v5.4s}, [x6], #16 /* load 2nd round key */ | |
3: aese v0.16b, v4.16b | |
aesmc v0.16b, v0.16b | |
-4: ld1 {v3.16b}, [x6], #16 /* load next round key */ | |
+4: ld1 {v3.4s}, [x6], #16 /* load next round key */ | |
aese v0.16b, v5.16b | |
aesmc v0.16b, v0.16b | |
-5: ld1 {v4.16b}, [x6], #16 /* load next round key */ | |
+5: ld1 {v4.4s}, [x6], #16 /* load next round key */ | |
subs w7, w7, #3 | |
aese v0.16b, v3.16b | |
aesmc v0.16b, v0.16b | |
- ld1 {v5.16b}, [x6], #16 /* load next round key */ | |
+ ld1 {v5.4s}, [x6], #16 /* load next round key */ | |
bpl 3b | |
aese v0.16b, v4.16b | |
subs w2, w2, #16 /* last data? */ | |
@@ -91,7 +91,7 @@ ENDPROC(ce_aes_ccm_auth_data) | |
* u32 rounds); | |
*/ | |
ENTRY(ce_aes_ccm_final) | |
- ld1 {v3.16b}, [x2], #16 /* load first round key */ | |
+ ld1 {v3.4s}, [x2], #16 /* load first round key */ | |
ld1 {v0.16b}, [x0] /* load mac */ | |
cmp w3, #12 /* which key size? */ | |
sub w3, w3, #2 /* modified # of rounds */ | |
@@ -101,17 +101,17 @@ ENTRY(ce_aes_ccm_final) | |
mov v5.16b, v3.16b | |
b 2f | |
0: mov v4.16b, v3.16b | |
-1: ld1 {v5.16b}, [x2], #16 /* load next round key */ | |
+1: ld1 {v5.4s}, [x2], #16 /* load next round key */ | |
aese v0.16b, v4.16b | |
aesmc v0.16b, v0.16b | |
aese v1.16b, v4.16b | |
aesmc v1.16b, v1.16b | |
-2: ld1 {v3.16b}, [x2], #16 /* load next round key */ | |
+2: ld1 {v3.4s}, [x2], #16 /* load next round key */ | |
aese v0.16b, v5.16b | |
aesmc v0.16b, v0.16b | |
aese v1.16b, v5.16b | |
aesmc v1.16b, v1.16b | |
-3: ld1 {v4.16b}, [x2], #16 /* load next round key */ | |
+3: ld1 {v4.4s}, [x2], #16 /* load next round key */ | |
subs w3, w3, #3 | |
aese v0.16b, v3.16b | |
aesmc v0.16b, v0.16b | |
@@ -138,31 +138,31 @@ CPU_LE( rev x8, x8 ) /* keep swabbed ctr in reg */ | |
cmp w4, #12 /* which key size? */ | |
sub w7, w4, #2 /* get modified # of rounds */ | |
ins v1.d[1], x9 /* no carry in lower ctr */ | |
- ld1 {v3.16b}, [x3] /* load first round key */ | |
+ ld1 {v3.4s}, [x3] /* load first round key */ | |
add x10, x3, #16 | |
bmi 1f | |
bne 4f | |
mov v5.16b, v3.16b | |
b 3f | |
1: mov v4.16b, v3.16b | |
- ld1 {v5.16b}, [x10], #16 /* load 2nd round key */ | |
+ ld1 {v5.4s}, [x10], #16 /* load 2nd round key */ | |
2: /* inner loop: 3 rounds, 2x interleaved */ | |
aese v0.16b, v4.16b | |
aesmc v0.16b, v0.16b | |
aese v1.16b, v4.16b | |
aesmc v1.16b, v1.16b | |
-3: ld1 {v3.16b}, [x10], #16 /* load next round key */ | |
+3: ld1 {v3.4s}, [x10], #16 /* load next round key */ | |
aese v0.16b, v5.16b | |
aesmc v0.16b, v0.16b | |
aese v1.16b, v5.16b | |
aesmc v1.16b, v1.16b | |
-4: ld1 {v4.16b}, [x10], #16 /* load next round key */ | |
+4: ld1 {v4.4s}, [x10], #16 /* load next round key */ | |
subs w7, w7, #3 | |
aese v0.16b, v3.16b | |
aesmc v0.16b, v0.16b | |
aese v1.16b, v3.16b | |
aesmc v1.16b, v1.16b | |
- ld1 {v5.16b}, [x10], #16 /* load next round key */ | |
+ ld1 {v5.4s}, [x10], #16 /* load next round key */ | |
bpl 2b | |
aese v0.16b, v4.16b | |
aese v1.16b, v4.16b | |
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c | |
index f4bf2f2a014c..915c661e6d34 100644 | |
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c | |
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c | |
@@ -1,7 +1,7 @@ | |
/* | |
* aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions | |
* | |
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -9,6 +9,7 @@ | |
*/ | |
#include <asm/neon.h> | |
+#include <asm/simd.h> | |
#include <asm/unaligned.h> | |
#include <crypto/aes.h> | |
#include <crypto/algapi.h> | |
@@ -44,6 +45,8 @@ asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes, | |
asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[], | |
u32 rounds); | |
+asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); | |
+ | |
static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key, | |
unsigned int key_len) | |
{ | |
@@ -103,7 +106,43 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen) | |
return 0; | |
} | |
-static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) | |
+static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[], | |
+ u32 abytes, u32 *macp, bool use_neon) | |
+{ | |
+ if (likely(use_neon)) { | |
+ ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc, | |
+ num_rounds(key)); | |
+ } else { | |
+ if (*macp > 0 && *macp < AES_BLOCK_SIZE) { | |
+ int added = min(abytes, AES_BLOCK_SIZE - *macp); | |
+ | |
+ crypto_xor(&mac[*macp], in, added); | |
+ | |
+ *macp += added; | |
+ in += added; | |
+ abytes -= added; | |
+ } | |
+ | |
+ while (abytes >= AES_BLOCK_SIZE) { | |
+ __aes_arm64_encrypt(key->key_enc, mac, mac, | |
+ num_rounds(key)); | |
+ crypto_xor(mac, in, AES_BLOCK_SIZE); | |
+ | |
+ in += AES_BLOCK_SIZE; | |
+ abytes -= AES_BLOCK_SIZE; | |
+ } | |
+ | |
+ if (abytes > 0) { | |
+ __aes_arm64_encrypt(key->key_enc, mac, mac, | |
+ num_rounds(key)); | |
+ crypto_xor(mac, in, abytes); | |
+ *macp = abytes; | |
+ } | |
+ } | |
+} | |
+ | |
+static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[], | |
+ bool use_neon) | |
{ | |
struct crypto_aead *aead = crypto_aead_reqtfm(req); | |
struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead); | |
@@ -122,8 +161,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) | |
ltag.len = 6; | |
} | |
- ce_aes_ccm_auth_data(mac, (u8 *)<ag, ltag.len, &macp, ctx->key_enc, | |
- num_rounds(ctx)); | |
+ ccm_update_mac(ctx, mac, (u8 *)<ag, ltag.len, &macp, use_neon); | |
scatterwalk_start(&walk, req->src); | |
do { | |
@@ -135,8 +173,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) | |
n = scatterwalk_clamp(&walk, len); | |
} | |
p = scatterwalk_map(&walk); | |
- ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc, | |
- num_rounds(ctx)); | |
+ ccm_update_mac(ctx, mac, p, n, &macp, use_neon); | |
len -= n; | |
scatterwalk_unmap(p); | |
@@ -145,6 +182,61 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) | |
} while (len); | |
} | |
+static int ccm_crypt_fallback(struct blkcipher_desc *desc, | |
+ struct blkcipher_walk *walk, u8 mac[], u8 iv0[], | |
+ struct crypto_aes_ctx *ctx, bool enc) | |
+{ | |
+ u8 buf[AES_BLOCK_SIZE]; | |
+ int err = 0; | |
+ | |
+ while (walk->nbytes) { | |
+ int blocks = walk->nbytes / AES_BLOCK_SIZE; | |
+ u32 tail = walk->nbytes % AES_BLOCK_SIZE; | |
+ u8 *dst = walk->dst.virt.addr; | |
+ u8 *src = walk->src.virt.addr; | |
+ u32 nbytes = walk->nbytes; | |
+ | |
+ if (nbytes == walk->total && tail > 0) { | |
+ blocks++; | |
+ tail = 0; | |
+ } | |
+ | |
+ do { | |
+ u32 bsize = AES_BLOCK_SIZE; | |
+ | |
+ if (nbytes < AES_BLOCK_SIZE) | |
+ bsize = nbytes; | |
+ | |
+ crypto_inc(walk->iv, AES_BLOCK_SIZE); | |
+ __aes_arm64_encrypt(ctx->key_enc, buf, walk->iv, | |
+ num_rounds(ctx)); | |
+ __aes_arm64_encrypt(ctx->key_enc, mac, mac, | |
+ num_rounds(ctx)); | |
+ if (enc) | |
+ crypto_xor(mac, src, bsize); | |
+ | |
+ if (dst != src) | |
+ memcpy(dst, src, bsize); | |
+ crypto_xor(dst, buf, bsize); | |
+ | |
+ if (!enc) | |
+ crypto_xor(mac, dst, bsize); | |
+ dst += bsize; | |
+ src += bsize; | |
+ nbytes -= bsize; | |
+ } while (--blocks); | |
+ | |
+ err = blkcipher_walk_done(desc, walk, tail); | |
+ } | |
+ | |
+ if (!err) { | |
+ __aes_arm64_encrypt(ctx->key_enc, buf, iv0, num_rounds(ctx)); | |
+ __aes_arm64_encrypt(ctx->key_enc, mac, mac, num_rounds(ctx)); | |
+ crypto_xor(mac, buf, AES_BLOCK_SIZE); | |
+ } | |
+ return err; | |
+} | |
+ | |
static int ccm_encrypt(struct aead_request *req) | |
{ | |
struct crypto_aead *aead = crypto_aead_reqtfm(req); | |
@@ -158,16 +250,18 @@ static int ccm_encrypt(struct aead_request *req) | |
u8 __aligned(8) mac[AES_BLOCK_SIZE]; | |
u8 buf[AES_BLOCK_SIZE]; | |
u32 len = req->cryptlen; | |
+ bool use_neon = may_use_simd(); | |
int err; | |
err = ccm_init_mac(req, mac, len); | |
if (err) | |
return err; | |
- kernel_neon_begin_partial(6); | |
+ if (likely(use_neon)) | |
+ kernel_neon_begin(); | |
if (req->assoclen) | |
- ccm_calculate_auth_mac(req, mac); | |
+ ccm_calculate_auth_mac(req, mac, use_neon); | |
/* preserve the original iv for the final round */ | |
memcpy(buf, req->iv, AES_BLOCK_SIZE); | |
@@ -181,23 +275,29 @@ static int ccm_encrypt(struct aead_request *req) | |
err = blkcipher_aead_walk_virt_block(&desc, &walk, aead, | |
AES_BLOCK_SIZE); | |
- while (walk.nbytes) { | |
- u32 tail = walk.nbytes % AES_BLOCK_SIZE; | |
+ if (likely(use_neon)) { | |
+ while (walk.nbytes) { | |
+ u32 tail = walk.nbytes % AES_BLOCK_SIZE; | |
- if (walk.nbytes == len) | |
- tail = 0; | |
+ if (walk.nbytes == len) | |
+ tail = 0; | |
- ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr, | |
- walk.nbytes - tail, ctx->key_enc, | |
- num_rounds(ctx), mac, walk.iv); | |
+ ce_aes_ccm_encrypt(walk.dst.virt.addr, | |
+ walk.src.virt.addr, | |
+ walk.nbytes - tail, ctx->key_enc, | |
+ num_rounds(ctx), mac, walk.iv); | |
- len -= walk.nbytes - tail; | |
- err = blkcipher_walk_done(&desc, &walk, tail); | |
- } | |
- if (!err) | |
- ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); | |
+ len -= walk.nbytes - tail; | |
+ err = blkcipher_walk_done(&desc, &walk, tail); | |
+ } | |
+ if (!err) | |
+ ce_aes_ccm_final(mac, buf, ctx->key_enc, | |
+ num_rounds(ctx)); | |
- kernel_neon_end(); | |
+ kernel_neon_end(); | |
+ } else { | |
+ err = ccm_crypt_fallback(&desc, &walk, mac, buf, ctx, true); | |
+ } | |
if (err) | |
return err; | |
@@ -223,16 +323,18 @@ static int ccm_decrypt(struct aead_request *req) | |
u8 __aligned(8) mac[AES_BLOCK_SIZE]; | |
u8 buf[AES_BLOCK_SIZE]; | |
u32 len = req->cryptlen - authsize; | |
+ bool use_neon = may_use_simd(); | |
int err; | |
err = ccm_init_mac(req, mac, len); | |
if (err) | |
return err; | |
- kernel_neon_begin_partial(6); | |
+ if (likely(use_neon)) | |
+ kernel_neon_begin(); | |
if (req->assoclen) | |
- ccm_calculate_auth_mac(req, mac); | |
+ ccm_calculate_auth_mac(req, mac, use_neon); | |
/* preserve the original iv for the final round */ | |
memcpy(buf, req->iv, AES_BLOCK_SIZE); | |
@@ -246,23 +348,29 @@ static int ccm_decrypt(struct aead_request *req) | |
err = blkcipher_aead_walk_virt_block(&desc, &walk, aead, | |
AES_BLOCK_SIZE); | |
- while (walk.nbytes) { | |
- u32 tail = walk.nbytes % AES_BLOCK_SIZE; | |
+ if (likely(use_neon)) { | |
+ while (walk.nbytes) { | |
+ u32 tail = walk.nbytes % AES_BLOCK_SIZE; | |
- if (walk.nbytes == len) | |
- tail = 0; | |
+ if (walk.nbytes == len) | |
+ tail = 0; | |
- ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr, | |
- walk.nbytes - tail, ctx->key_enc, | |
- num_rounds(ctx), mac, walk.iv); | |
+ ce_aes_ccm_decrypt(walk.dst.virt.addr, | |
+ walk.src.virt.addr, | |
+ walk.nbytes - tail, ctx->key_enc, | |
+ num_rounds(ctx), mac, walk.iv); | |
- len -= walk.nbytes - tail; | |
- err = blkcipher_walk_done(&desc, &walk, tail); | |
- } | |
- if (!err) | |
- ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); | |
+ len -= walk.nbytes - tail; | |
+ err = blkcipher_walk_done(&desc, &walk, tail); | |
+ } | |
+ if (!err) | |
+ ce_aes_ccm_final(mac, buf, ctx->key_enc, | |
+ num_rounds(ctx)); | |
- kernel_neon_end(); | |
+ kernel_neon_end(); | |
+ } else { | |
+ err = ccm_crypt_fallback(&desc, &walk, mac, buf, ctx, false); | |
+ } | |
if (err) | |
return err; | |
diff --git a/arch/arm64/crypto/aes-ce-cipher-core.c b/arch/arm64/crypto/aes-ce-cipher-core.c | |
index 9f4191774b35..d857b0f01fc9 100644 | |
--- a/arch/arm64/crypto/aes-ce-cipher-core.c | |
+++ b/arch/arm64/crypto/aes-ce-cipher-core.c | |
@@ -1,7 +1,7 @@ | |
/* | |
* aes-ce-cipher-core.c - core AES cipher using ARMv8 Crypto Extensions | |
* | |
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -9,11 +9,16 @@ | |
*/ | |
#include <asm/neon.h> | |
+#include <asm/simd.h> | |
+#include <asm/unaligned.h> | |
#include <crypto/aes.h> | |
#include <linux/crypto.h> | |
#include "aes-ce-setkey.h" | |
+asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); | |
+asmlinkage void __aes_arm64_decrypt(u32 *rk, u8 *out, const u8 *in, int rounds); | |
+ | |
struct aes_block { | |
u8 b[AES_BLOCK_SIZE]; | |
}; | |
@@ -38,27 +43,32 @@ void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) | |
void *dummy0; | |
int dummy1; | |
- kernel_neon_begin_partial(4); | |
+ if (!may_use_simd()) { | |
+ __aes_arm64_encrypt(ctx->key_enc, dst, src, num_rounds(ctx)); | |
+ return; | |
+ } | |
+ | |
+ kernel_neon_begin(); | |
__asm__(" ld1 {v0.16b}, %[in] ;" | |
- " ld1 {v1.16b}, [%[key]], #16 ;" | |
+ " ld1 {v1.4s}, [%[key]], #16 ;" | |
" cmp %w[rounds], #10 ;" | |
" bmi 0f ;" | |
" bne 3f ;" | |
" mov v3.16b, v1.16b ;" | |
" b 2f ;" | |
"0: mov v2.16b, v1.16b ;" | |
- " ld1 {v3.16b}, [%[key]], #16 ;" | |
+ " ld1 {v3.4s}, [%[key]], #16 ;" | |
"1: aese v0.16b, v2.16b ;" | |
" aesmc v0.16b, v0.16b ;" | |
- "2: ld1 {v1.16b}, [%[key]], #16 ;" | |
+ "2: ld1 {v1.4s}, [%[key]], #16 ;" | |
" aese v0.16b, v3.16b ;" | |
" aesmc v0.16b, v0.16b ;" | |
- "3: ld1 {v2.16b}, [%[key]], #16 ;" | |
+ "3: ld1 {v2.4s}, [%[key]], #16 ;" | |
" subs %w[rounds], %w[rounds], #3 ;" | |
" aese v0.16b, v1.16b ;" | |
" aesmc v0.16b, v0.16b ;" | |
- " ld1 {v3.16b}, [%[key]], #16 ;" | |
+ " ld1 {v3.4s}, [%[key]], #16 ;" | |
" bpl 1b ;" | |
" aese v0.16b, v2.16b ;" | |
" eor v0.16b, v0.16b, v3.16b ;" | |
@@ -83,27 +93,32 @@ void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) | |
void *dummy0; | |
int dummy1; | |
- kernel_neon_begin_partial(4); | |
+ if (!may_use_simd()) { | |
+ __aes_arm64_decrypt(ctx->key_dec, dst, src, num_rounds(ctx)); | |
+ return; | |
+ } | |
+ | |
+ kernel_neon_begin(); | |
__asm__(" ld1 {v0.16b}, %[in] ;" | |
- " ld1 {v1.16b}, [%[key]], #16 ;" | |
+ " ld1 {v1.4s}, [%[key]], #16 ;" | |
" cmp %w[rounds], #10 ;" | |
" bmi 0f ;" | |
" bne 3f ;" | |
" mov v3.16b, v1.16b ;" | |
" b 2f ;" | |
"0: mov v2.16b, v1.16b ;" | |
- " ld1 {v3.16b}, [%[key]], #16 ;" | |
+ " ld1 {v3.4s}, [%[key]], #16 ;" | |
"1: aesd v0.16b, v2.16b ;" | |
" aesimc v0.16b, v0.16b ;" | |
- "2: ld1 {v1.16b}, [%[key]], #16 ;" | |
+ "2: ld1 {v1.4s}, [%[key]], #16 ;" | |
" aesd v0.16b, v3.16b ;" | |
" aesimc v0.16b, v0.16b ;" | |
- "3: ld1 {v2.16b}, [%[key]], #16 ;" | |
+ "3: ld1 {v2.4s}, [%[key]], #16 ;" | |
" subs %w[rounds], %w[rounds], #3 ;" | |
" aesd v0.16b, v1.16b ;" | |
" aesimc v0.16b, v0.16b ;" | |
- " ld1 {v3.16b}, [%[key]], #16 ;" | |
+ " ld1 {v3.4s}, [%[key]], #16 ;" | |
" bpl 1b ;" | |
" aesd v0.16b, v2.16b ;" | |
" eor v0.16b, v0.16b, v3.16b ;" | |
@@ -159,20 +174,16 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, | |
key_len != AES_KEYSIZE_256) | |
return -EINVAL; | |
- memcpy(ctx->key_enc, in_key, key_len); | |
ctx->key_length = key_len; | |
+ for (i = 0; i < kwords; i++) | |
+ ctx->key_enc[i] = get_unaligned_le32(in_key + i * sizeof(u32)); | |
- kernel_neon_begin_partial(2); | |
+ kernel_neon_begin(); | |
for (i = 0; i < sizeof(rcon); i++) { | |
u32 *rki = ctx->key_enc + (i * kwords); | |
u32 *rko = rki + kwords; | |
-#ifndef CONFIG_CPU_BIG_ENDIAN | |
rko[0] = ror32(aes_sub(rki[kwords - 1]), 8) ^ rcon[i] ^ rki[0]; | |
-#else | |
- rko[0] = rol32(aes_sub(rki[kwords - 1]), 8) ^ (rcon[i] << 24) ^ | |
- rki[0]; | |
-#endif | |
rko[1] = rko[0] ^ rki[1]; | |
rko[2] = rko[1] ^ rki[2]; | |
rko[3] = rko[2] ^ rki[3]; | |
@@ -204,9 +215,9 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, | |
key_dec[0] = key_enc[j]; | |
for (i = 1, j--; j > 0; i++, j--) | |
- __asm__("ld1 {v0.16b}, %[in] ;" | |
+ __asm__("ld1 {v0.4s}, %[in] ;" | |
"aesimc v1.16b, v0.16b ;" | |
- "st1 {v1.16b}, %[out] ;" | |
+ "st1 {v1.4s}, %[out] ;" | |
: [out] "=Q"(key_dec[i]) | |
: [in] "Q"(key_enc[j]) | |
diff --git a/arch/arm64/crypto/aes-ce.S b/arch/arm64/crypto/aes-ce.S | |
index b46093d567e5..50330f5c3adc 100644 | |
--- a/arch/arm64/crypto/aes-ce.S | |
+++ b/arch/arm64/crypto/aes-ce.S | |
@@ -2,7 +2,7 @@ | |
* linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with | |
* Crypto Extensions | |
* | |
- * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -22,11 +22,11 @@ | |
cmp \rounds, #12 | |
blo 2222f /* 128 bits */ | |
beq 1111f /* 192 bits */ | |
- ld1 {v17.16b-v18.16b}, [\rk], #32 | |
-1111: ld1 {v19.16b-v20.16b}, [\rk], #32 | |
-2222: ld1 {v21.16b-v24.16b}, [\rk], #64 | |
- ld1 {v25.16b-v28.16b}, [\rk], #64 | |
- ld1 {v29.16b-v31.16b}, [\rk] | |
+ ld1 {v17.4s-v18.4s}, [\rk], #32 | |
+1111: ld1 {v19.4s-v20.4s}, [\rk], #32 | |
+2222: ld1 {v21.4s-v24.4s}, [\rk], #64 | |
+ ld1 {v25.4s-v28.4s}, [\rk], #64 | |
+ ld1 {v29.4s-v31.4s}, [\rk] | |
.endm | |
/* prepare for encryption with key in rk[] */ | |
diff --git a/arch/arm64/crypto/aes-cipher-core.S b/arch/arm64/crypto/aes-cipher-core.S | |
new file mode 100644 | |
index 000000000000..3a44eada2347 | |
--- /dev/null | |
+++ b/arch/arm64/crypto/aes-cipher-core.S | |
@@ -0,0 +1,173 @@ | |
+/* | |
+ * Scalar AES core transform | |
+ * | |
+ * Copyright (C) 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ */ | |
+ | |
+#include <linux/linkage.h> | |
+#include <asm/assembler.h> | |
+#include <asm/cache.h> | |
+ | |
+ .text | |
+ | |
+ rk .req x0 | |
+ out .req x1 | |
+ in .req x2 | |
+ rounds .req x3 | |
+ tt .req x2 | |
+ | |
+ .macro __pair1, sz, op, reg0, reg1, in0, in1e, in1d, shift | |
+ .ifc \op\shift, b0 | |
+ ubfiz \reg0, \in0, #2, #8 | |
+ ubfiz \reg1, \in1e, #2, #8 | |
+ .else | |
+ ubfx \reg0, \in0, #\shift, #8 | |
+ ubfx \reg1, \in1e, #\shift, #8 | |
+ .endif | |
+ | |
+ /* | |
+ * AArch64 cannot do byte size indexed loads from a table containing | |
+ * 32-bit quantities, i.e., 'ldrb w12, [tt, w12, uxtw #2]' is not a | |
+ * valid instruction. So perform the shift explicitly first for the | |
+ * high bytes (the low byte is shifted implicitly by using ubfiz rather | |
+ * than ubfx above) | |
+ */ | |
+ .ifnc \op, b | |
+ ldr \reg0, [tt, \reg0, uxtw #2] | |
+ ldr \reg1, [tt, \reg1, uxtw #2] | |
+ .else | |
+ .if \shift > 0 | |
+ lsl \reg0, \reg0, #2 | |
+ lsl \reg1, \reg1, #2 | |
+ .endif | |
+ ldrb \reg0, [tt, \reg0, uxtw] | |
+ ldrb \reg1, [tt, \reg1, uxtw] | |
+ .endif | |
+ .endm | |
+ | |
+ .macro __pair0, sz, op, reg0, reg1, in0, in1e, in1d, shift | |
+ ubfx \reg0, \in0, #\shift, #8 | |
+ ubfx \reg1, \in1d, #\shift, #8 | |
+ ldr\op \reg0, [tt, \reg0, uxtw #\sz] | |
+ ldr\op \reg1, [tt, \reg1, uxtw #\sz] | |
+ .endm | |
+ | |
+ .macro __hround, out0, out1, in0, in1, in2, in3, t0, t1, enc, sz, op | |
+ ldp \out0, \out1, [rk], #8 | |
+ | |
+ __pair\enc \sz, \op, w12, w13, \in0, \in1, \in3, 0 | |
+ __pair\enc \sz, \op, w14, w15, \in1, \in2, \in0, 8 | |
+ __pair\enc \sz, \op, w16, w17, \in2, \in3, \in1, 16 | |
+ __pair\enc \sz, \op, \t0, \t1, \in3, \in0, \in2, 24 | |
+ | |
+ eor \out0, \out0, w12 | |
+ eor \out1, \out1, w13 | |
+ eor \out0, \out0, w14, ror #24 | |
+ eor \out1, \out1, w15, ror #24 | |
+ eor \out0, \out0, w16, ror #16 | |
+ eor \out1, \out1, w17, ror #16 | |
+ eor \out0, \out0, \t0, ror #8 | |
+ eor \out1, \out1, \t1, ror #8 | |
+ .endm | |
+ | |
+ .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op | |
+ __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op | |
+ __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op | |
+ .endm | |
+ | |
+ .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op | |
+ __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op | |
+ __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op | |
+ .endm | |
+ | |
+ .macro do_crypt, round, ttab, ltab, bsz | |
+ ldp w4, w5, [in] | |
+ ldp w6, w7, [in, #8] | |
+ ldp w8, w9, [rk], #16 | |
+ ldp w10, w11, [rk, #-8] | |
+ | |
+CPU_BE( rev w4, w4 ) | |
+CPU_BE( rev w5, w5 ) | |
+CPU_BE( rev w6, w6 ) | |
+CPU_BE( rev w7, w7 ) | |
+ | |
+ eor w4, w4, w8 | |
+ eor w5, w5, w9 | |
+ eor w6, w6, w10 | |
+ eor w7, w7, w11 | |
+ | |
+ adr_l tt, \ttab | |
+ | |
+ tbnz rounds, #1, 1f | |
+ | |
+0: \round w8, w9, w10, w11, w4, w5, w6, w7 | |
+ \round w4, w5, w6, w7, w8, w9, w10, w11 | |
+ | |
+1: subs rounds, rounds, #4 | |
+ \round w8, w9, w10, w11, w4, w5, w6, w7 | |
+ b.ls 3f | |
+2: \round w4, w5, w6, w7, w8, w9, w10, w11 | |
+ b 0b | |
+3: adr_l tt, \ltab | |
+ \round w4, w5, w6, w7, w8, w9, w10, w11, \bsz, b | |
+ | |
+CPU_BE( rev w4, w4 ) | |
+CPU_BE( rev w5, w5 ) | |
+CPU_BE( rev w6, w6 ) | |
+CPU_BE( rev w7, w7 ) | |
+ | |
+ stp w4, w5, [out] | |
+ stp w6, w7, [out, #8] | |
+ ret | |
+ .endm | |
+ | |
+ENTRY(__aes_arm64_encrypt) | |
+ do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 | |
+ENDPROC(__aes_arm64_encrypt) | |
+ | |
+ .align 5 | |
+ENTRY(__aes_arm64_decrypt) | |
+ do_crypt iround, crypto_it_tab, __aes_arm64_inverse_sbox, 0 | |
+ENDPROC(__aes_arm64_decrypt) | |
+ | |
+ .section ".rodata", "a" | |
+ .align L1_CACHE_SHIFT | |
+ .type __aes_arm64_inverse_sbox, %object | |
+__aes_arm64_inverse_sbox: | |
+ .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 | |
+ .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb | |
+ .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 | |
+ .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb | |
+ .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d | |
+ .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e | |
+ .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 | |
+ .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 | |
+ .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 | |
+ .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 | |
+ .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda | |
+ .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 | |
+ .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a | |
+ .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 | |
+ .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 | |
+ .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b | |
+ .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea | |
+ .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 | |
+ .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 | |
+ .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e | |
+ .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 | |
+ .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b | |
+ .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 | |
+ .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 | |
+ .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 | |
+ .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f | |
+ .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d | |
+ .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef | |
+ .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 | |
+ .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 | |
+ .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 | |
+ .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d | |
+ .size __aes_arm64_inverse_sbox, . - __aes_arm64_inverse_sbox | |
diff --git a/arch/arm64/crypto/aes-cipher-glue.c b/arch/arm64/crypto/aes-cipher-glue.c | |
new file mode 100644 | |
index 000000000000..0e90b06ebcec | |
--- /dev/null | |
+++ b/arch/arm64/crypto/aes-cipher-glue.c | |
@@ -0,0 +1,69 @@ | |
+/* | |
+ * Scalar AES core transform | |
+ * | |
+ * Copyright (C) 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ */ | |
+ | |
+#include <crypto/aes.h> | |
+#include <linux/crypto.h> | |
+#include <linux/module.h> | |
+ | |
+asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); | |
+EXPORT_SYMBOL(__aes_arm64_encrypt); | |
+ | |
+asmlinkage void __aes_arm64_decrypt(u32 *rk, u8 *out, const u8 *in, int rounds); | |
+EXPORT_SYMBOL(__aes_arm64_decrypt); | |
+ | |
+static void aes_arm64_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | |
+{ | |
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); | |
+ int rounds = 6 + ctx->key_length / 4; | |
+ | |
+ __aes_arm64_encrypt(ctx->key_enc, out, in, rounds); | |
+} | |
+ | |
+static void aes_arm64_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | |
+{ | |
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); | |
+ int rounds = 6 + ctx->key_length / 4; | |
+ | |
+ __aes_arm64_decrypt(ctx->key_dec, out, in, rounds); | |
+} | |
+ | |
+static struct crypto_alg aes_alg = { | |
+ .cra_name = "aes", | |
+ .cra_driver_name = "aes-arm64", | |
+ .cra_priority = 200, | |
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | |
+ .cra_blocksize = AES_BLOCK_SIZE, | |
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx), | |
+ .cra_module = THIS_MODULE, | |
+ | |
+ .cra_cipher.cia_min_keysize = AES_MIN_KEY_SIZE, | |
+ .cra_cipher.cia_max_keysize = AES_MAX_KEY_SIZE, | |
+ .cra_cipher.cia_setkey = crypto_aes_set_key, | |
+ .cra_cipher.cia_encrypt = aes_arm64_encrypt, | |
+ .cra_cipher.cia_decrypt = aes_arm64_decrypt | |
+}; | |
+ | |
+static int __init aes_init(void) | |
+{ | |
+ return crypto_register_alg(&aes_alg); | |
+} | |
+ | |
+static void __exit aes_fini(void) | |
+{ | |
+ crypto_unregister_alg(&aes_alg); | |
+} | |
+ | |
+module_init(aes_init); | |
+module_exit(aes_fini); | |
+ | |
+MODULE_DESCRIPTION("Scalar AES cipher for arm64"); | |
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); | |
+MODULE_LICENSE("GPL v2"); | |
+MODULE_ALIAS_CRYPTO("aes"); | |
diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c | |
index 833ec1e3f3e9..30221ef56e70 100644 | |
--- a/arch/arm64/crypto/ghash-ce-glue.c | |
+++ b/arch/arm64/crypto/ghash-ce-glue.c | |
@@ -1,7 +1,7 @@ | |
/* | |
* Accelerated GHASH implementation with ARMv8 PMULL instructions. | |
* | |
- * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2014 - 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify it | |
* under the terms of the GNU General Public License version 2 as published | |
@@ -9,7 +9,9 @@ | |
*/ | |
#include <asm/neon.h> | |
+#include <asm/simd.h> | |
#include <asm/unaligned.h> | |
+#include <crypto/gf128mul.h> | |
#include <crypto/internal/hash.h> | |
#include <linux/cpufeature.h> | |
#include <linux/crypto.h> | |
@@ -25,6 +27,7 @@ MODULE_LICENSE("GPL v2"); | |
struct ghash_key { | |
u64 a; | |
u64 b; | |
+ be128 k; | |
}; | |
struct ghash_desc_ctx { | |
@@ -44,6 +47,36 @@ static int ghash_init(struct shash_desc *desc) | |
return 0; | |
} | |
+static void ghash_do_update(int blocks, u64 dg[], const char *src, | |
+ struct ghash_key *key, const char *head) | |
+{ | |
+ if (likely(may_use_simd())) { | |
+ kernel_neon_begin(); | |
+ pmull_ghash_update(blocks, dg, src, key, head); | |
+ kernel_neon_end(); | |
+ } else { | |
+ be128 dst = { cpu_to_be64(dg[1]), cpu_to_be64(dg[0]) }; | |
+ | |
+ do { | |
+ const u8 *in = src; | |
+ | |
+ if (head) { | |
+ in = head; | |
+ blocks++; | |
+ head = NULL; | |
+ } else { | |
+ src += GHASH_BLOCK_SIZE; | |
+ } | |
+ | |
+ crypto_xor((u8 *)&dst, in, GHASH_BLOCK_SIZE); | |
+ gf128mul_lle(&dst, &key->k); | |
+ } while (--blocks); | |
+ | |
+ dg[0] = be64_to_cpu(dst.b); | |
+ dg[1] = be64_to_cpu(dst.a); | |
+ } | |
+} | |
+ | |
static int ghash_update(struct shash_desc *desc, const u8 *src, | |
unsigned int len) | |
{ | |
@@ -67,10 +100,9 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, | |
blocks = len / GHASH_BLOCK_SIZE; | |
len %= GHASH_BLOCK_SIZE; | |
- kernel_neon_begin_partial(8); | |
- pmull_ghash_update(blocks, ctx->digest, src, key, | |
- partial ? ctx->buf : NULL); | |
- kernel_neon_end(); | |
+ ghash_do_update(blocks, ctx->digest, src, key, | |
+ partial ? ctx->buf : NULL); | |
+ | |
src += blocks * GHASH_BLOCK_SIZE; | |
partial = 0; | |
} | |
@@ -89,9 +121,7 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) | |
memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial); | |
- kernel_neon_begin_partial(8); | |
- pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL); | |
- kernel_neon_end(); | |
+ ghash_do_update(1, ctx->digest, ctx->buf, key, NULL); | |
} | |
put_unaligned_be64(ctx->digest[1], dst); | |
put_unaligned_be64(ctx->digest[0], dst + 8); | |
@@ -111,6 +141,9 @@ static int ghash_setkey(struct crypto_shash *tfm, | |
return -EINVAL; | |
} | |
+ /* needed for the fallback */ | |
+ memcpy(&key->k, inkey, GHASH_BLOCK_SIZE); | |
+ | |
/* perform multiplication by 'x' in GF(2^128) */ | |
b = get_unaligned_be64(inkey); | |
a = get_unaligned_be64(inkey + 8); | |
diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c | |
index 3431bb514fd4..fb7a9caf51c8 100644 | |
--- a/arch/arm64/crypto/sha1-ce-glue.c | |
+++ b/arch/arm64/crypto/sha1-ce-glue.c | |
@@ -1,7 +1,7 @@ | |
/* | |
* sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions | |
* | |
- * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2014 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -9,6 +9,7 @@ | |
*/ | |
#include <asm/neon.h> | |
+#include <asm/simd.h> | |
#include <asm/unaligned.h> | |
#include <crypto/internal/hash.h> | |
#include <crypto/sha.h> | |
@@ -45,8 +46,11 @@ static int sha1_ce_update(struct shash_desc *desc, const u8 *data, | |
{ | |
struct sha1_ce_state *sctx = shash_desc_ctx(desc); | |
+ if (!may_use_simd()) | |
+ return crypto_sha1_update(desc, data, len); | |
+ | |
sctx->finalize = 0; | |
- kernel_neon_begin_partial(16); | |
+ kernel_neon_begin(); | |
sha1_base_do_update(desc, data, len, | |
(sha1_block_fn *)sha1_ce_transform); | |
kernel_neon_end(); | |
@@ -60,13 +64,16 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data, | |
struct sha1_ce_state *sctx = shash_desc_ctx(desc); | |
bool finalize = !sctx->sst.count && !(len % SHA1_BLOCK_SIZE) && len; | |
+ if (!may_use_simd()) | |
+ return crypto_sha1_finup(desc, data, len, out); | |
+ | |
/* | |
* Allow the asm code to perform the finalization if there is no | |
* partial data and the input is a round multiple of the block size. | |
*/ | |
sctx->finalize = finalize; | |
- kernel_neon_begin_partial(16); | |
+ kernel_neon_begin(); | |
sha1_base_do_update(desc, data, len, | |
(sha1_block_fn *)sha1_ce_transform); | |
if (!finalize) | |
@@ -79,8 +86,11 @@ static int sha1_ce_final(struct shash_desc *desc, u8 *out) | |
{ | |
struct sha1_ce_state *sctx = shash_desc_ctx(desc); | |
+ if (!may_use_simd()) | |
+ return crypto_sha1_finup(desc, NULL, 0, out); | |
+ | |
sctx->finalize = 0; | |
- kernel_neon_begin_partial(16); | |
+ kernel_neon_begin(); | |
sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform); | |
kernel_neon_end(); | |
return sha1_base_finish(desc, out); | |
diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c | |
index 42d96ddd35c3..9141184d89e4 100644 | |
--- a/arch/arm64/crypto/sha2-ce-glue.c | |
+++ b/arch/arm64/crypto/sha2-ce-glue.c | |
@@ -1,7 +1,7 @@ | |
/* | |
* sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions | |
* | |
- * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org> | |
+ * Copyright (C) 2014 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org> | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
@@ -9,6 +9,7 @@ | |
*/ | |
#include <asm/neon.h> | |
+#include <asm/simd.h> | |
#include <asm/unaligned.h> | |
#include <crypto/internal/hash.h> | |
#include <crypto/sha.h> | |
@@ -42,13 +43,19 @@ const u32 sha256_ce_offsetof_count = offsetof(struct sha256_ce_state, | |
const u32 sha256_ce_offsetof_finalize = offsetof(struct sha256_ce_state, | |
finalize); | |
+asmlinkage void sha256_block_data_order(u32 *digest, u8 const *src, int blocks); | |
+ | |
static int sha256_ce_update(struct shash_desc *desc, const u8 *data, | |
unsigned int len) | |
{ | |
struct sha256_ce_state *sctx = shash_desc_ctx(desc); | |
+ if (!may_use_simd()) | |
+ return sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ | |
sctx->finalize = 0; | |
- kernel_neon_begin_partial(28); | |
+ kernel_neon_begin(); | |
sha256_base_do_update(desc, data, len, | |
(sha256_block_fn *)sha2_ce_transform); | |
kernel_neon_end(); | |
@@ -62,13 +69,22 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data, | |
struct sha256_ce_state *sctx = shash_desc_ctx(desc); | |
bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE) && len; | |
+ if (!may_use_simd()) { | |
+ if (len) | |
+ sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ sha256_base_do_finalize(desc, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ return sha256_base_finish(desc, out); | |
+ } | |
+ | |
/* | |
* Allow the asm code to perform the finalization if there is no | |
* partial data and the input is a round multiple of the block size. | |
*/ | |
sctx->finalize = finalize; | |
- kernel_neon_begin_partial(28); | |
+ kernel_neon_begin(); | |
sha256_base_do_update(desc, data, len, | |
(sha256_block_fn *)sha2_ce_transform); | |
if (!finalize) | |
@@ -82,8 +98,14 @@ static int sha256_ce_final(struct shash_desc *desc, u8 *out) | |
{ | |
struct sha256_ce_state *sctx = shash_desc_ctx(desc); | |
+ if (!may_use_simd()) { | |
+ sha256_base_do_finalize(desc, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ return sha256_base_finish(desc, out); | |
+ } | |
+ | |
sctx->finalize = 0; | |
- kernel_neon_begin_partial(28); | |
+ kernel_neon_begin(); | |
sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform); | |
kernel_neon_end(); | |
return sha256_base_finish(desc, out); | |
diff --git a/arch/arm64/crypto/sha256-glue.c b/arch/arm64/crypto/sha256-glue.c | |
new file mode 100644 | |
index 000000000000..2e6a323d1b93 | |
--- /dev/null | |
+++ b/arch/arm64/crypto/sha256-glue.c | |
@@ -0,0 +1,196 @@ | |
+/* | |
+ * Linux/arm64 port of the OpenSSL SHA256 implementation for AArch64 | |
+ * | |
+ * Copyright (c) 2016 Linaro Ltd. <ard.biesheuvel@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the Free | |
+ * Software Foundation; either version 2 of the License, or (at your option) | |
+ * any later version. | |
+ * | |
+ */ | |
+ | |
+#include <asm/hwcap.h> | |
+#include <asm/neon.h> | |
+#include <asm/simd.h> | |
+#include <crypto/internal/hash.h> | |
+#include <crypto/sha.h> | |
+#include <crypto/sha256_base.h> | |
+#include <linux/cryptohash.h> | |
+#include <linux/types.h> | |
+#include <linux/string.h> | |
+ | |
+MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash for arm64"); | |
+MODULE_AUTHOR("Andy Polyakov <appro@openssl.org>"); | |
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); | |
+MODULE_LICENSE("GPL v2"); | |
+MODULE_ALIAS_CRYPTO("sha224"); | |
+MODULE_ALIAS_CRYPTO("sha256"); | |
+ | |
+asmlinkage void sha256_block_data_order(u32 *digest, const void *data, | |
+ unsigned int num_blks); | |
+EXPORT_SYMBOL(sha256_block_data_order); | |
+ | |
+asmlinkage void sha256_block_neon(u32 *digest, const void *data, | |
+ unsigned int num_blks); | |
+ | |
+static int crypto_sha256_arm64_update(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len) | |
+{ | |
+ return sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+} | |
+ | |
+static int crypto_sha256_arm64_finup(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len, u8 *out) | |
+{ | |
+ if (len) | |
+ sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ sha256_base_do_finalize(desc, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ | |
+ return sha256_base_finish(desc, out); | |
+} | |
+ | |
+static int crypto_sha256_arm64_final(struct shash_desc *desc, u8 *out) | |
+{ | |
+ return crypto_sha256_arm64_finup(desc, NULL, 0, out); | |
+} | |
+ | |
+static struct shash_alg algs[] = { { | |
+ .digestsize = SHA256_DIGEST_SIZE, | |
+ .init = sha256_base_init, | |
+ .update = crypto_sha256_arm64_update, | |
+ .final = crypto_sha256_arm64_final, | |
+ .finup = crypto_sha256_arm64_finup, | |
+ .descsize = sizeof(struct sha256_state), | |
+ .base.cra_name = "sha256", | |
+ .base.cra_driver_name = "sha256-arm64", | |
+ .base.cra_priority = 125, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA256_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+}, { | |
+ .digestsize = SHA224_DIGEST_SIZE, | |
+ .init = sha224_base_init, | |
+ .update = crypto_sha256_arm64_update, | |
+ .final = crypto_sha256_arm64_final, | |
+ .finup = crypto_sha256_arm64_finup, | |
+ .descsize = sizeof(struct sha256_state), | |
+ .base.cra_name = "sha224", | |
+ .base.cra_driver_name = "sha224-arm64", | |
+ .base.cra_priority = 125, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA224_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+} }; | |
+ | |
+static int sha256_update_neon(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len) | |
+{ | |
+ struct sha256_state *sctx = shash_desc_ctx(desc); | |
+ | |
+ if (!may_use_simd()) | |
+ return sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ | |
+ while (len > 0) { | |
+ unsigned int chunk = len; | |
+ | |
+ /* | |
+ * Don't hog the CPU for the entire time it takes to process all | |
+ * input when running on a preemptible kernel, but process the | |
+ * data block by block instead. | |
+ */ | |
+ if (IS_ENABLED(CONFIG_PREEMPT) && | |
+ chunk + sctx->count % SHA256_BLOCK_SIZE > SHA256_BLOCK_SIZE) | |
+ chunk = SHA256_BLOCK_SIZE - | |
+ sctx->count % SHA256_BLOCK_SIZE; | |
+ | |
+ kernel_neon_begin(); | |
+ sha256_base_do_update(desc, data, chunk, | |
+ (sha256_block_fn *)sha256_block_neon); | |
+ kernel_neon_end(); | |
+ data += chunk; | |
+ len -= chunk; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+static int sha256_finup_neon(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len, u8 *out) | |
+{ | |
+ if (!may_use_simd()) { | |
+ if (len) | |
+ sha256_base_do_update(desc, data, len, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ sha256_base_do_finalize(desc, | |
+ (sha256_block_fn *)sha256_block_data_order); | |
+ } else { | |
+ if (len) | |
+ sha256_update_neon(desc, data, len); | |
+ kernel_neon_begin(); | |
+ sha256_base_do_finalize(desc, | |
+ (sha256_block_fn *)sha256_block_neon); | |
+ kernel_neon_end(); | |
+ } | |
+ return sha256_base_finish(desc, out); | |
+} | |
+ | |
+static int sha256_final_neon(struct shash_desc *desc, u8 *out) | |
+{ | |
+ return sha256_finup_neon(desc, NULL, 0, out); | |
+} | |
+ | |
+static struct shash_alg neon_algs[] = { { | |
+ .digestsize = SHA256_DIGEST_SIZE, | |
+ .init = sha256_base_init, | |
+ .update = sha256_update_neon, | |
+ .final = sha256_final_neon, | |
+ .finup = sha256_finup_neon, | |
+ .descsize = sizeof(struct sha256_state), | |
+ .base.cra_name = "sha256", | |
+ .base.cra_driver_name = "sha256-arm64-neon", | |
+ .base.cra_priority = 150, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA256_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+}, { | |
+ .digestsize = SHA224_DIGEST_SIZE, | |
+ .init = sha224_base_init, | |
+ .update = sha256_update_neon, | |
+ .final = sha256_final_neon, | |
+ .finup = sha256_finup_neon, | |
+ .descsize = sizeof(struct sha256_state), | |
+ .base.cra_name = "sha224", | |
+ .base.cra_driver_name = "sha224-arm64-neon", | |
+ .base.cra_priority = 150, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA224_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+} }; | |
+ | |
+static int __init sha256_mod_init(void) | |
+{ | |
+ int ret = crypto_register_shashes(algs, ARRAY_SIZE(algs)); | |
+ if (ret) | |
+ return ret; | |
+ | |
+ if (elf_hwcap & HWCAP_ASIMD) { | |
+ ret = crypto_register_shashes(neon_algs, ARRAY_SIZE(neon_algs)); | |
+ if (ret) | |
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); | |
+ } | |
+ return ret; | |
+} | |
+ | |
+static void __exit sha256_mod_fini(void) | |
+{ | |
+ if (elf_hwcap & HWCAP_ASIMD) | |
+ crypto_unregister_shashes(neon_algs, ARRAY_SIZE(neon_algs)); | |
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); | |
+} | |
+ | |
+module_init(sha256_mod_init); | |
+module_exit(sha256_mod_fini); | |
diff --git a/arch/arm64/crypto/sha512-armv8.pl b/arch/arm64/crypto/sha512-armv8.pl | |
new file mode 100644 | |
index 000000000000..2d8655d5b1af | |
--- /dev/null | |
+++ b/arch/arm64/crypto/sha512-armv8.pl | |
@@ -0,0 +1,786 @@ | |
+#! /usr/bin/env perl | |
+# SPDX-License-Identifier: GPL-2.0 | |
+ | |
+# This code is taken from the OpenSSL project but the author (Andy Polyakov) | |
+# has relicensed it under the GPLv2. Therefore this program is free software; | |
+# you can redistribute it and/or modify it under the terms of the GNU General | |
+# Public License version 2 as published by the Free Software Foundation. | |
+# | |
+# The original headers, including the original license headers, are | |
+# included below for completeness. | |
+ | |
+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. | |
+# | |
+# Licensed under the OpenSSL license (the "License"). You may not use | |
+# this file except in compliance with the License. You can obtain a copy | |
+# in the file LICENSE in the source distribution or at | |
+# https://www.openssl.org/source/license.html | |
+ | |
+# ==================================================================== | |
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL | |
+# project. The module is, however, dual licensed under OpenSSL and | |
+# CRYPTOGAMS licenses depending on where you obtain it. For further | |
+# details see http://www.openssl.org/~appro/cryptogams/. | |
+# ==================================================================== | |
+# | |
+# SHA256/512 for ARMv8. | |
+# | |
+# Performance in cycles per processed byte and improvement coefficient | |
+# over code generated with "default" compiler: | |
+# | |
+# SHA256-hw SHA256(*) SHA512 | |
+# Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) | |
+# Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) | |
+# Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) | |
+# Denver 2.01 10.5 (+26%) 6.70 (+8%) | |
+# X-Gene 20.0 (+100%) 12.8 (+300%(***)) | |
+# Mongoose 2.36 13.0 (+50%) 8.36 (+33%) | |
+# | |
+# (*) Software SHA256 results are of lesser relevance, presented | |
+# mostly for informational purposes. | |
+# (**) The result is a trade-off: it's possible to improve it by | |
+# 10% (or by 1 cycle per round), but at the cost of 20% loss | |
+# on Cortex-A53 (or by 4 cycles per round). | |
+# (***) Super-impressive coefficients over gcc-generated code are | |
+# indication of some compiler "pathology", most notably code | |
+# generated with -mgeneral-regs-only is significanty faster | |
+# and the gap is only 40-90%. | |
+# | |
+# October 2016. | |
+# | |
+# Originally it was reckoned that it makes no sense to implement NEON | |
+# version of SHA256 for 64-bit processors. This is because performance | |
+# improvement on most wide-spread Cortex-A5x processors was observed | |
+# to be marginal, same on Cortex-A53 and ~10% on A57. But then it was | |
+# observed that 32-bit NEON SHA256 performs significantly better than | |
+# 64-bit scalar version on *some* of the more recent processors. As | |
+# result 64-bit NEON version of SHA256 was added to provide best | |
+# all-round performance. For example it executes ~30% faster on X-Gene | |
+# and Mongoose. [For reference, NEON version of SHA512 is bound to | |
+# deliver much less improvement, likely *negative* on Cortex-A5x. | |
+# Which is why NEON support is limited to SHA256.] | |
+ | |
+$output=pop; | |
+$flavour=pop; | |
+ | |
+if ($flavour && $flavour ne "void") { | |
+ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | |
+ ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or | |
+ ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or | |
+ die "can't locate arm-xlate.pl"; | |
+ | |
+ open OUT,"| \"$^X\" $xlate $flavour $output"; | |
+ *STDOUT=*OUT; | |
+} else { | |
+ open STDOUT,">$output"; | |
+} | |
+ | |
+if ($output =~ /512/) { | |
+ $BITS=512; | |
+ $SZ=8; | |
+ @Sigma0=(28,34,39); | |
+ @Sigma1=(14,18,41); | |
+ @sigma0=(1, 8, 7); | |
+ @sigma1=(19,61, 6); | |
+ $rounds=80; | |
+ $reg_t="x"; | |
+} else { | |
+ $BITS=256; | |
+ $SZ=4; | |
+ @Sigma0=( 2,13,22); | |
+ @Sigma1=( 6,11,25); | |
+ @sigma0=( 7,18, 3); | |
+ @sigma1=(17,19,10); | |
+ $rounds=64; | |
+ $reg_t="w"; | |
+} | |
+ | |
+$func="sha${BITS}_block_data_order"; | |
+ | |
+($ctx,$inp,$num,$Ktbl)=map("x$_",(0..2,30)); | |
+ | |
+@X=map("$reg_t$_",(3..15,0..2)); | |
+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("$reg_t$_",(20..27)); | |
+($t0,$t1,$t2,$t3)=map("$reg_t$_",(16,17,19,28)); | |
+ | |
+sub BODY_00_xx { | |
+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; | |
+my $j=($i+1)&15; | |
+my ($T0,$T1,$T2)=(@X[($i-8)&15],@X[($i-9)&15],@X[($i-10)&15]); | |
+ $T0=@X[$i+3] if ($i<11); | |
+ | |
+$code.=<<___ if ($i<16); | |
+#ifndef __AARCH64EB__ | |
+ rev @X[$i],@X[$i] // $i | |
+#endif | |
+___ | |
+$code.=<<___ if ($i<13 && ($i&1)); | |
+ ldp @X[$i+1],@X[$i+2],[$inp],#2*$SZ | |
+___ | |
+$code.=<<___ if ($i==13); | |
+ ldp @X[14],@X[15],[$inp] | |
+___ | |
+$code.=<<___ if ($i>=14); | |
+ ldr @X[($i-11)&15],[sp,#`$SZ*(($i-11)%4)`] | |
+___ | |
+$code.=<<___ if ($i>0 && $i<16); | |
+ add $a,$a,$t1 // h+=Sigma0(a) | |
+___ | |
+$code.=<<___ if ($i>=11); | |
+ str @X[($i-8)&15],[sp,#`$SZ*(($i-8)%4)`] | |
+___ | |
+# While ARMv8 specifies merged rotate-n-logical operation such as | |
+# 'eor x,y,z,ror#n', it was found to negatively affect performance | |
+# on Apple A7. The reason seems to be that it requires even 'y' to | |
+# be available earlier. This means that such merged instruction is | |
+# not necessarily best choice on critical path... On the other hand | |
+# Cortex-A5x handles merged instructions much better than disjoint | |
+# rotate and logical... See (**) footnote above. | |
+$code.=<<___ if ($i<15); | |
+ ror $t0,$e,#$Sigma1[0] | |
+ add $h,$h,$t2 // h+=K[i] | |
+ eor $T0,$e,$e,ror#`$Sigma1[2]-$Sigma1[1]` | |
+ and $t1,$f,$e | |
+ bic $t2,$g,$e | |
+ add $h,$h,@X[$i&15] // h+=X[i] | |
+ orr $t1,$t1,$t2 // Ch(e,f,g) | |
+ eor $t2,$a,$b // a^b, b^c in next round | |
+ eor $t0,$t0,$T0,ror#$Sigma1[1] // Sigma1(e) | |
+ ror $T0,$a,#$Sigma0[0] | |
+ add $h,$h,$t1 // h+=Ch(e,f,g) | |
+ eor $t1,$a,$a,ror#`$Sigma0[2]-$Sigma0[1]` | |
+ add $h,$h,$t0 // h+=Sigma1(e) | |
+ and $t3,$t3,$t2 // (b^c)&=(a^b) | |
+ add $d,$d,$h // d+=h | |
+ eor $t3,$t3,$b // Maj(a,b,c) | |
+ eor $t1,$T0,$t1,ror#$Sigma0[1] // Sigma0(a) | |
+ add $h,$h,$t3 // h+=Maj(a,b,c) | |
+ ldr $t3,[$Ktbl],#$SZ // *K++, $t2 in next round | |
+ //add $h,$h,$t1 // h+=Sigma0(a) | |
+___ | |
+$code.=<<___ if ($i>=15); | |
+ ror $t0,$e,#$Sigma1[0] | |
+ add $h,$h,$t2 // h+=K[i] | |
+ ror $T1,@X[($j+1)&15],#$sigma0[0] | |
+ and $t1,$f,$e | |
+ ror $T2,@X[($j+14)&15],#$sigma1[0] | |
+ bic $t2,$g,$e | |
+ ror $T0,$a,#$Sigma0[0] | |
+ add $h,$h,@X[$i&15] // h+=X[i] | |
+ eor $t0,$t0,$e,ror#$Sigma1[1] | |
+ eor $T1,$T1,@X[($j+1)&15],ror#$sigma0[1] | |
+ orr $t1,$t1,$t2 // Ch(e,f,g) | |
+ eor $t2,$a,$b // a^b, b^c in next round | |
+ eor $t0,$t0,$e,ror#$Sigma1[2] // Sigma1(e) | |
+ eor $T0,$T0,$a,ror#$Sigma0[1] | |
+ add $h,$h,$t1 // h+=Ch(e,f,g) | |
+ and $t3,$t3,$t2 // (b^c)&=(a^b) | |
+ eor $T2,$T2,@X[($j+14)&15],ror#$sigma1[1] | |
+ eor $T1,$T1,@X[($j+1)&15],lsr#$sigma0[2] // sigma0(X[i+1]) | |
+ add $h,$h,$t0 // h+=Sigma1(e) | |
+ eor $t3,$t3,$b // Maj(a,b,c) | |
+ eor $t1,$T0,$a,ror#$Sigma0[2] // Sigma0(a) | |
+ eor $T2,$T2,@X[($j+14)&15],lsr#$sigma1[2] // sigma1(X[i+14]) | |
+ add @X[$j],@X[$j],@X[($j+9)&15] | |
+ add $d,$d,$h // d+=h | |
+ add $h,$h,$t3 // h+=Maj(a,b,c) | |
+ ldr $t3,[$Ktbl],#$SZ // *K++, $t2 in next round | |
+ add @X[$j],@X[$j],$T1 | |
+ add $h,$h,$t1 // h+=Sigma0(a) | |
+ add @X[$j],@X[$j],$T2 | |
+___ | |
+ ($t2,$t3)=($t3,$t2); | |
+} | |
+ | |
+$code.=<<___; | |
+#ifndef __KERNEL__ | |
+# include "arm_arch.h" | |
+#endif | |
+ | |
+.text | |
+ | |
+.extern OPENSSL_armcap_P | |
+.globl $func | |
+.type $func,%function | |
+.align 6 | |
+$func: | |
+___ | |
+$code.=<<___ if ($SZ==4); | |
+#ifndef __KERNEL__ | |
+# ifdef __ILP32__ | |
+ ldrsw x16,.LOPENSSL_armcap_P | |
+# else | |
+ ldr x16,.LOPENSSL_armcap_P | |
+# endif | |
+ adr x17,.LOPENSSL_armcap_P | |
+ add x16,x16,x17 | |
+ ldr w16,[x16] | |
+ tst w16,#ARMV8_SHA256 | |
+ b.ne .Lv8_entry | |
+ tst w16,#ARMV7_NEON | |
+ b.ne .Lneon_entry | |
+#endif | |
+___ | |
+$code.=<<___; | |
+ stp x29,x30,[sp,#-128]! | |
+ add x29,sp,#0 | |
+ | |
+ stp x19,x20,[sp,#16] | |
+ stp x21,x22,[sp,#32] | |
+ stp x23,x24,[sp,#48] | |
+ stp x25,x26,[sp,#64] | |
+ stp x27,x28,[sp,#80] | |
+ sub sp,sp,#4*$SZ | |
+ | |
+ ldp $A,$B,[$ctx] // load context | |
+ ldp $C,$D,[$ctx,#2*$SZ] | |
+ ldp $E,$F,[$ctx,#4*$SZ] | |
+ add $num,$inp,$num,lsl#`log(16*$SZ)/log(2)` // end of input | |
+ ldp $G,$H,[$ctx,#6*$SZ] | |
+ adr $Ktbl,.LK$BITS | |
+ stp $ctx,$num,[x29,#96] | |
+ | |
+.Loop: | |
+ ldp @X[0],@X[1],[$inp],#2*$SZ | |
+ ldr $t2,[$Ktbl],#$SZ // *K++ | |
+ eor $t3,$B,$C // magic seed | |
+ str $inp,[x29,#112] | |
+___ | |
+for ($i=0;$i<16;$i++) { &BODY_00_xx($i,@V); unshift(@V,pop(@V)); } | |
+$code.=".Loop_16_xx:\n"; | |
+for (;$i<32;$i++) { &BODY_00_xx($i,@V); unshift(@V,pop(@V)); } | |
+$code.=<<___; | |
+ cbnz $t2,.Loop_16_xx | |
+ | |
+ ldp $ctx,$num,[x29,#96] | |
+ ldr $inp,[x29,#112] | |
+ sub $Ktbl,$Ktbl,#`$SZ*($rounds+1)` // rewind | |
+ | |
+ ldp @X[0],@X[1],[$ctx] | |
+ ldp @X[2],@X[3],[$ctx,#2*$SZ] | |
+ add $inp,$inp,#14*$SZ // advance input pointer | |
+ ldp @X[4],@X[5],[$ctx,#4*$SZ] | |
+ add $A,$A,@X[0] | |
+ ldp @X[6],@X[7],[$ctx,#6*$SZ] | |
+ add $B,$B,@X[1] | |
+ add $C,$C,@X[2] | |
+ add $D,$D,@X[3] | |
+ stp $A,$B,[$ctx] | |
+ add $E,$E,@X[4] | |
+ add $F,$F,@X[5] | |
+ stp $C,$D,[$ctx,#2*$SZ] | |
+ add $G,$G,@X[6] | |
+ add $H,$H,@X[7] | |
+ cmp $inp,$num | |
+ stp $E,$F,[$ctx,#4*$SZ] | |
+ stp $G,$H,[$ctx,#6*$SZ] | |
+ b.ne .Loop | |
+ | |
+ ldp x19,x20,[x29,#16] | |
+ add sp,sp,#4*$SZ | |
+ ldp x21,x22,[x29,#32] | |
+ ldp x23,x24,[x29,#48] | |
+ ldp x25,x26,[x29,#64] | |
+ ldp x27,x28,[x29,#80] | |
+ ldp x29,x30,[sp],#128 | |
+ ret | |
+.size $func,.-$func | |
+ | |
+.align 6 | |
+.type .LK$BITS,%object | |
+.LK$BITS: | |
+___ | |
+$code.=<<___ if ($SZ==8); | |
+ .quad 0x428a2f98d728ae22,0x7137449123ef65cd | |
+ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc | |
+ .quad 0x3956c25bf348b538,0x59f111f1b605d019 | |
+ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 | |
+ .quad 0xd807aa98a3030242,0x12835b0145706fbe | |
+ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 | |
+ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 | |
+ .quad 0x9bdc06a725c71235,0xc19bf174cf692694 | |
+ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 | |
+ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 | |
+ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 | |
+ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 | |
+ .quad 0x983e5152ee66dfab,0xa831c66d2db43210 | |
+ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 | |
+ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 | |
+ .quad 0x06ca6351e003826f,0x142929670a0e6e70 | |
+ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 | |
+ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df | |
+ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 | |
+ .quad 0x81c2c92e47edaee6,0x92722c851482353b | |
+ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 | |
+ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 | |
+ .quad 0xd192e819d6ef5218,0xd69906245565a910 | |
+ .quad 0xf40e35855771202a,0x106aa07032bbd1b8 | |
+ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 | |
+ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 | |
+ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb | |
+ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 | |
+ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 | |
+ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec | |
+ .quad 0x90befffa23631e28,0xa4506cebde82bde9 | |
+ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b | |
+ .quad 0xca273eceea26619c,0xd186b8c721c0c207 | |
+ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 | |
+ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 | |
+ .quad 0x113f9804bef90dae,0x1b710b35131c471b | |
+ .quad 0x28db77f523047d84,0x32caab7b40c72493 | |
+ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c | |
+ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a | |
+ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 | |
+ .quad 0 // terminator | |
+___ | |
+$code.=<<___ if ($SZ==4); | |
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | |
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | |
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | |
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | |
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | |
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | |
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | |
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | |
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | |
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | |
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | |
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | |
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | |
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | |
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | |
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | |
+ .long 0 //terminator | |
+___ | |
+$code.=<<___; | |
+.size .LK$BITS,.-.LK$BITS | |
+#ifndef __KERNEL__ | |
+.align 3 | |
+.LOPENSSL_armcap_P: | |
+# ifdef __ILP32__ | |
+ .long OPENSSL_armcap_P-. | |
+# else | |
+ .quad OPENSSL_armcap_P-. | |
+# endif | |
+#endif | |
+.asciz "SHA$BITS block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>" | |
+.align 2 | |
+___ | |
+ | |
+if ($SZ==4) { | |
+my $Ktbl="x3"; | |
+ | |
+my ($ABCD,$EFGH,$abcd)=map("v$_.16b",(0..2)); | |
+my @MSG=map("v$_.16b",(4..7)); | |
+my ($W0,$W1)=("v16.4s","v17.4s"); | |
+my ($ABCD_SAVE,$EFGH_SAVE)=("v18.16b","v19.16b"); | |
+ | |
+$code.=<<___; | |
+#ifndef __KERNEL__ | |
+.type sha256_block_armv8,%function | |
+.align 6 | |
+sha256_block_armv8: | |
+.Lv8_entry: | |
+ stp x29,x30,[sp,#-16]! | |
+ add x29,sp,#0 | |
+ | |
+ ld1.32 {$ABCD,$EFGH},[$ctx] | |
+ adr $Ktbl,.LK256 | |
+ | |
+.Loop_hw: | |
+ ld1 {@MSG[0]-@MSG[3]},[$inp],#64 | |
+ sub $num,$num,#1 | |
+ ld1.32 {$W0},[$Ktbl],#16 | |
+ rev32 @MSG[0],@MSG[0] | |
+ rev32 @MSG[1],@MSG[1] | |
+ rev32 @MSG[2],@MSG[2] | |
+ rev32 @MSG[3],@MSG[3] | |
+ orr $ABCD_SAVE,$ABCD,$ABCD // offload | |
+ orr $EFGH_SAVE,$EFGH,$EFGH | |
+___ | |
+for($i=0;$i<12;$i++) { | |
+$code.=<<___; | |
+ ld1.32 {$W1},[$Ktbl],#16 | |
+ add.i32 $W0,$W0,@MSG[0] | |
+ sha256su0 @MSG[0],@MSG[1] | |
+ orr $abcd,$ABCD,$ABCD | |
+ sha256h $ABCD,$EFGH,$W0 | |
+ sha256h2 $EFGH,$abcd,$W0 | |
+ sha256su1 @MSG[0],@MSG[2],@MSG[3] | |
+___ | |
+ ($W0,$W1)=($W1,$W0); push(@MSG,shift(@MSG)); | |
+} | |
+$code.=<<___; | |
+ ld1.32 {$W1},[$Ktbl],#16 | |
+ add.i32 $W0,$W0,@MSG[0] | |
+ orr $abcd,$ABCD,$ABCD | |
+ sha256h $ABCD,$EFGH,$W0 | |
+ sha256h2 $EFGH,$abcd,$W0 | |
+ | |
+ ld1.32 {$W0},[$Ktbl],#16 | |
+ add.i32 $W1,$W1,@MSG[1] | |
+ orr $abcd,$ABCD,$ABCD | |
+ sha256h $ABCD,$EFGH,$W1 | |
+ sha256h2 $EFGH,$abcd,$W1 | |
+ | |
+ ld1.32 {$W1},[$Ktbl] | |
+ add.i32 $W0,$W0,@MSG[2] | |
+ sub $Ktbl,$Ktbl,#$rounds*$SZ-16 // rewind | |
+ orr $abcd,$ABCD,$ABCD | |
+ sha256h $ABCD,$EFGH,$W0 | |
+ sha256h2 $EFGH,$abcd,$W0 | |
+ | |
+ add.i32 $W1,$W1,@MSG[3] | |
+ orr $abcd,$ABCD,$ABCD | |
+ sha256h $ABCD,$EFGH,$W1 | |
+ sha256h2 $EFGH,$abcd,$W1 | |
+ | |
+ add.i32 $ABCD,$ABCD,$ABCD_SAVE | |
+ add.i32 $EFGH,$EFGH,$EFGH_SAVE | |
+ | |
+ cbnz $num,.Loop_hw | |
+ | |
+ st1.32 {$ABCD,$EFGH},[$ctx] | |
+ | |
+ ldr x29,[sp],#16 | |
+ ret | |
+.size sha256_block_armv8,.-sha256_block_armv8 | |
+#endif | |
+___ | |
+} | |
+ | |
+if ($SZ==4) { ######################################### NEON stuff # | |
+# You'll surely note a lot of similarities with sha256-armv4 module, | |
+# and of course it's not a coincidence. sha256-armv4 was used as | |
+# initial template, but was adapted for ARMv8 instruction set and | |
+# extensively re-tuned for all-round performance. | |
+ | |
+my @V = ($A,$B,$C,$D,$E,$F,$G,$H) = map("w$_",(3..10)); | |
+my ($t0,$t1,$t2,$t3,$t4) = map("w$_",(11..15)); | |
+my $Ktbl="x16"; | |
+my $Xfer="x17"; | |
+my @X = map("q$_",(0..3)); | |
+my ($T0,$T1,$T2,$T3,$T4,$T5,$T6,$T7) = map("q$_",(4..7,16..19)); | |
+my $j=0; | |
+ | |
+sub AUTOLOAD() # thunk [simplified] x86-style perlasm | |
+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./; | |
+ my $arg = pop; | |
+ $arg = "#$arg" if ($arg*1 eq $arg); | |
+ $code .= "\t$opcode\t".join(',',@_,$arg)."\n"; | |
+} | |
+ | |
+sub Dscalar { shift =~ m|[qv]([0-9]+)|?"d$1":""; } | |
+sub Dlo { shift =~ m|[qv]([0-9]+)|?"v$1.d[0]":""; } | |
+sub Dhi { shift =~ m|[qv]([0-9]+)|?"v$1.d[1]":""; } | |
+ | |
+sub Xupdate() | |
+{ use integer; | |
+ my $body = shift; | |
+ my @insns = (&$body,&$body,&$body,&$body); | |
+ my ($a,$b,$c,$d,$e,$f,$g,$h); | |
+ | |
+ &ext_8 ($T0,@X[0],@X[1],4); # X[1..4] | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ext_8 ($T3,@X[2],@X[3],4); # X[9..12] | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &mov (&Dscalar($T7),&Dhi(@X[3])); # X[14..15] | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T2,$T0,$sigma0[0]); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T1,$T0,$sigma0[2]); | |
+ eval(shift(@insns)); | |
+ &add_32 (@X[0],@X[0],$T3); # X[0..3] += X[9..12] | |
+ eval(shift(@insns)); | |
+ &sli_32 ($T2,$T0,32-$sigma0[0]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T3,$T0,$sigma0[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T1,$T1,$T2); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &sli_32 ($T3,$T0,32-$sigma0[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T4,$T7,$sigma1[0]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T1,$T1,$T3); # sigma0(X[1..4]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &sli_32 ($T4,$T7,32-$sigma1[0]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T5,$T7,$sigma1[2]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T3,$T7,$sigma1[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &add_32 (@X[0],@X[0],$T1); # X[0..3] += sigma0(X[1..4]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &sli_u32 ($T3,$T7,32-$sigma1[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T5,$T5,$T4); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T5,$T5,$T3); # sigma1(X[14..15]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &add_32 (@X[0],@X[0],$T5); # X[0..1] += sigma1(X[14..15]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T6,@X[0],$sigma1[0]); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T7,@X[0],$sigma1[2]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &sli_32 ($T6,@X[0],32-$sigma1[0]); | |
+ eval(shift(@insns)); | |
+ &ushr_32 ($T5,@X[0],$sigma1[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T7,$T7,$T6); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &sli_32 ($T5,@X[0],32-$sigma1[1]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ld1_32 ("{$T0}","[$Ktbl], #16"); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T7,$T7,$T5); # sigma1(X[16..17]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &eor_8 ($T5,$T5,$T5); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &mov (&Dhi($T5), &Dlo($T7)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &add_32 (@X[0],@X[0],$T5); # X[2..3] += sigma1(X[16..17]) | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &add_32 ($T0,$T0,@X[0]); | |
+ while($#insns>=1) { eval(shift(@insns)); } | |
+ &st1_32 ("{$T0}","[$Xfer], #16"); | |
+ eval(shift(@insns)); | |
+ | |
+ push(@X,shift(@X)); # "rotate" X[] | |
+} | |
+ | |
+sub Xpreload() | |
+{ use integer; | |
+ my $body = shift; | |
+ my @insns = (&$body,&$body,&$body,&$body); | |
+ my ($a,$b,$c,$d,$e,$f,$g,$h); | |
+ | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ld1_8 ("{@X[0]}","[$inp],#16"); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &ld1_32 ("{$T0}","[$Ktbl],#16"); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &rev32 (@X[0],@X[0]); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ eval(shift(@insns)); | |
+ &add_32 ($T0,$T0,@X[0]); | |
+ foreach (@insns) { eval; } # remaining instructions | |
+ &st1_32 ("{$T0}","[$Xfer], #16"); | |
+ | |
+ push(@X,shift(@X)); # "rotate" X[] | |
+} | |
+ | |
+sub body_00_15 () { | |
+ ( | |
+ '($a,$b,$c,$d,$e,$f,$g,$h)=@V;'. | |
+ '&add ($h,$h,$t1)', # h+=X[i]+K[i] | |
+ '&add ($a,$a,$t4);'. # h+=Sigma0(a) from the past | |
+ '&and ($t1,$f,$e)', | |
+ '&bic ($t4,$g,$e)', | |
+ '&eor ($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))', | |
+ '&add ($a,$a,$t2)', # h+=Maj(a,b,c) from the past | |
+ '&orr ($t1,$t1,$t4)', # Ch(e,f,g) | |
+ '&eor ($t0,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))', # Sigma1(e) | |
+ '&eor ($t4,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))', | |
+ '&add ($h,$h,$t1)', # h+=Ch(e,f,g) | |
+ '&ror ($t0,$t0,"#$Sigma1[0]")', | |
+ '&eor ($t2,$a,$b)', # a^b, b^c in next round | |
+ '&eor ($t4,$t4,$a,"ror#".($Sigma0[2]-$Sigma0[0]))', # Sigma0(a) | |
+ '&add ($h,$h,$t0)', # h+=Sigma1(e) | |
+ '&ldr ($t1,sprintf "[sp,#%d]",4*(($j+1)&15)) if (($j&15)!=15);'. | |
+ '&ldr ($t1,"[$Ktbl]") if ($j==15);'. | |
+ '&and ($t3,$t3,$t2)', # (b^c)&=(a^b) | |
+ '&ror ($t4,$t4,"#$Sigma0[0]")', | |
+ '&add ($d,$d,$h)', # d+=h | |
+ '&eor ($t3,$t3,$b)', # Maj(a,b,c) | |
+ '$j++; unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);' | |
+ ) | |
+} | |
+ | |
+$code.=<<___; | |
+#ifdef __KERNEL__ | |
+.globl sha256_block_neon | |
+#endif | |
+.type sha256_block_neon,%function | |
+.align 4 | |
+sha256_block_neon: | |
+.Lneon_entry: | |
+ stp x29, x30, [sp, #-16]! | |
+ mov x29, sp | |
+ sub sp,sp,#16*4 | |
+ | |
+ adr $Ktbl,.LK256 | |
+ add $num,$inp,$num,lsl#6 // len to point at the end of inp | |
+ | |
+ ld1.8 {@X[0]},[$inp], #16 | |
+ ld1.8 {@X[1]},[$inp], #16 | |
+ ld1.8 {@X[2]},[$inp], #16 | |
+ ld1.8 {@X[3]},[$inp], #16 | |
+ ld1.32 {$T0},[$Ktbl], #16 | |
+ ld1.32 {$T1},[$Ktbl], #16 | |
+ ld1.32 {$T2},[$Ktbl], #16 | |
+ ld1.32 {$T3},[$Ktbl], #16 | |
+ rev32 @X[0],@X[0] // yes, even on | |
+ rev32 @X[1],@X[1] // big-endian | |
+ rev32 @X[2],@X[2] | |
+ rev32 @X[3],@X[3] | |
+ mov $Xfer,sp | |
+ add.32 $T0,$T0,@X[0] | |
+ add.32 $T1,$T1,@X[1] | |
+ add.32 $T2,$T2,@X[2] | |
+ st1.32 {$T0-$T1},[$Xfer], #32 | |
+ add.32 $T3,$T3,@X[3] | |
+ st1.32 {$T2-$T3},[$Xfer] | |
+ sub $Xfer,$Xfer,#32 | |
+ | |
+ ldp $A,$B,[$ctx] | |
+ ldp $C,$D,[$ctx,#8] | |
+ ldp $E,$F,[$ctx,#16] | |
+ ldp $G,$H,[$ctx,#24] | |
+ ldr $t1,[sp,#0] | |
+ mov $t2,wzr | |
+ eor $t3,$B,$C | |
+ mov $t4,wzr | |
+ b .L_00_48 | |
+ | |
+.align 4 | |
+.L_00_48: | |
+___ | |
+ &Xupdate(\&body_00_15); | |
+ &Xupdate(\&body_00_15); | |
+ &Xupdate(\&body_00_15); | |
+ &Xupdate(\&body_00_15); | |
+$code.=<<___; | |
+ cmp $t1,#0 // check for K256 terminator | |
+ ldr $t1,[sp,#0] | |
+ sub $Xfer,$Xfer,#64 | |
+ bne .L_00_48 | |
+ | |
+ sub $Ktbl,$Ktbl,#256 // rewind $Ktbl | |
+ cmp $inp,$num | |
+ mov $Xfer, #64 | |
+ csel $Xfer, $Xfer, xzr, eq | |
+ sub $inp,$inp,$Xfer // avoid SEGV | |
+ mov $Xfer,sp | |
+___ | |
+ &Xpreload(\&body_00_15); | |
+ &Xpreload(\&body_00_15); | |
+ &Xpreload(\&body_00_15); | |
+ &Xpreload(\&body_00_15); | |
+$code.=<<___; | |
+ add $A,$A,$t4 // h+=Sigma0(a) from the past | |
+ ldp $t0,$t1,[$ctx,#0] | |
+ add $A,$A,$t2 // h+=Maj(a,b,c) from the past | |
+ ldp $t2,$t3,[$ctx,#8] | |
+ add $A,$A,$t0 // accumulate | |
+ add $B,$B,$t1 | |
+ ldp $t0,$t1,[$ctx,#16] | |
+ add $C,$C,$t2 | |
+ add $D,$D,$t3 | |
+ ldp $t2,$t3,[$ctx,#24] | |
+ add $E,$E,$t0 | |
+ add $F,$F,$t1 | |
+ ldr $t1,[sp,#0] | |
+ stp $A,$B,[$ctx,#0] | |
+ add $G,$G,$t2 | |
+ mov $t2,wzr | |
+ stp $C,$D,[$ctx,#8] | |
+ add $H,$H,$t3 | |
+ stp $E,$F,[$ctx,#16] | |
+ eor $t3,$B,$C | |
+ stp $G,$H,[$ctx,#24] | |
+ mov $t4,wzr | |
+ mov $Xfer,sp | |
+ b.ne .L_00_48 | |
+ | |
+ ldr x29,[x29] | |
+ add sp,sp,#16*4+16 | |
+ ret | |
+.size sha256_block_neon,.-sha256_block_neon | |
+___ | |
+} | |
+ | |
+$code.=<<___; | |
+#ifndef __KERNEL__ | |
+.comm OPENSSL_armcap_P,4,4 | |
+#endif | |
+___ | |
+ | |
+{ my %opcode = ( | |
+ "sha256h" => 0x5e004000, "sha256h2" => 0x5e005000, | |
+ "sha256su0" => 0x5e282800, "sha256su1" => 0x5e006000 ); | |
+ | |
+ sub unsha256 { | |
+ my ($mnemonic,$arg)=@_; | |
+ | |
+ $arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o | |
+ && | |
+ sprintf ".inst\t0x%08x\t//%s %s", | |
+ $opcode{$mnemonic}|$1|($2<<5)|($3<<16), | |
+ $mnemonic,$arg; | |
+ } | |
+} | |
+ | |
+open SELF,$0; | |
+while(<SELF>) { | |
+ next if (/^#!/); | |
+ last if (!s/^#/\/\// and !/^$/); | |
+ print; | |
+} | |
+close SELF; | |
+ | |
+foreach(split("\n",$code)) { | |
+ | |
+ s/\`([^\`]*)\`/eval($1)/ge; | |
+ | |
+ s/\b(sha256\w+)\s+([qv].*)/unsha256($1,$2)/ge; | |
+ | |
+ s/\bq([0-9]+)\b/v$1.16b/g; # old->new registers | |
+ | |
+ s/\.[ui]?8(\s)/$1/; | |
+ s/\.\w?32\b// and s/\.16b/\.4s/g; | |
+ m/(ld|st)1[^\[]+\[0\]/ and s/\.4s/\.s/g; | |
+ | |
+ print $_,"\n"; | |
+} | |
+ | |
+close STDOUT; | |
diff --git a/arch/arm64/crypto/sha512-glue.c b/arch/arm64/crypto/sha512-glue.c | |
new file mode 100644 | |
index 000000000000..aff35c9992a4 | |
--- /dev/null | |
+++ b/arch/arm64/crypto/sha512-glue.c | |
@@ -0,0 +1,94 @@ | |
+/* | |
+ * Linux/arm64 port of the OpenSSL SHA512 implementation for AArch64 | |
+ * | |
+ * Copyright (c) 2016 Linaro Ltd. <ard.biesheuvel@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the Free | |
+ * Software Foundation; either version 2 of the License, or (at your option) | |
+ * any later version. | |
+ * | |
+ */ | |
+ | |
+#include <crypto/internal/hash.h> | |
+#include <linux/cryptohash.h> | |
+#include <linux/types.h> | |
+#include <linux/string.h> | |
+#include <crypto/sha.h> | |
+#include <crypto/sha512_base.h> | |
+#include <asm/neon.h> | |
+ | |
+MODULE_DESCRIPTION("SHA-384/SHA-512 secure hash for arm64"); | |
+MODULE_AUTHOR("Andy Polyakov <appro@openssl.org>"); | |
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>"); | |
+MODULE_LICENSE("GPL v2"); | |
+MODULE_ALIAS_CRYPTO("sha384"); | |
+MODULE_ALIAS_CRYPTO("sha512"); | |
+ | |
+asmlinkage void sha512_block_data_order(u32 *digest, const void *data, | |
+ unsigned int num_blks); | |
+ | |
+static int sha512_update(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len) | |
+{ | |
+ return sha512_base_do_update(desc, data, len, | |
+ (sha512_block_fn *)sha512_block_data_order); | |
+} | |
+ | |
+static int sha512_finup(struct shash_desc *desc, const u8 *data, | |
+ unsigned int len, u8 *out) | |
+{ | |
+ if (len) | |
+ sha512_base_do_update(desc, data, len, | |
+ (sha512_block_fn *)sha512_block_data_order); | |
+ sha512_base_do_finalize(desc, | |
+ (sha512_block_fn *)sha512_block_data_order); | |
+ | |
+ return sha512_base_finish(desc, out); | |
+} | |
+ | |
+static int sha512_final(struct shash_desc *desc, u8 *out) | |
+{ | |
+ return sha512_finup(desc, NULL, 0, out); | |
+} | |
+ | |
+static struct shash_alg algs[] = { { | |
+ .digestsize = SHA512_DIGEST_SIZE, | |
+ .init = sha512_base_init, | |
+ .update = sha512_update, | |
+ .final = sha512_final, | |
+ .finup = sha512_finup, | |
+ .descsize = sizeof(struct sha512_state), | |
+ .base.cra_name = "sha512", | |
+ .base.cra_driver_name = "sha512-arm64", | |
+ .base.cra_priority = 150, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA512_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+}, { | |
+ .digestsize = SHA384_DIGEST_SIZE, | |
+ .init = sha384_base_init, | |
+ .update = sha512_update, | |
+ .final = sha512_final, | |
+ .finup = sha512_finup, | |
+ .descsize = sizeof(struct sha512_state), | |
+ .base.cra_name = "sha384", | |
+ .base.cra_driver_name = "sha384-arm64", | |
+ .base.cra_priority = 150, | |
+ .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, | |
+ .base.cra_blocksize = SHA384_BLOCK_SIZE, | |
+ .base.cra_module = THIS_MODULE, | |
+} }; | |
+ | |
+static int __init sha512_mod_init(void) | |
+{ | |
+ return crypto_register_shashes(algs, ARRAY_SIZE(algs)); | |
+} | |
+ | |
+static void __exit sha512_mod_fini(void) | |
+{ | |
+ crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); | |
+} | |
+ | |
+module_init(sha512_mod_init); | |
+module_exit(sha512_mod_fini); | |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild | |
index 28196b18e394..23b56135bca6 100644 | |
--- a/arch/arm64/include/asm/Kbuild | |
+++ b/arch/arm64/include/asm/Kbuild | |
@@ -32,7 +32,6 @@ generic-y += segment.h | |
generic-y += sembuf.h | |
generic-y += serial.h | |
generic-y += shmbuf.h | |
-generic-y += simd.h | |
generic-y += sizes.h | |
generic-y += socket.h | |
generic-y += sockios.h | |
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h | |
index f632bad491d6..74705faa29fb 100644 | |
--- a/arch/arm64/include/asm/cpufeature.h | |
+++ b/arch/arm64/include/asm/cpufeature.h | |
@@ -438,6 +438,12 @@ void arm64_set_ssbd_mitigation(bool state); | |
static inline void arm64_set_ssbd_mitigation(bool state) {} | |
#endif | |
+static inline bool system_supports_fpsimd(void) | |
+{ | |
+ /* fast stub for kernel-4.9 */ | |
+ return true; | |
+} | |
+ | |
/* Watch out, ordering is important here. */ | |
enum mitigation_state { | |
SPECTRE_UNAFFECTED, | |
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h | |
index e589811c5e23..49682a9b9f41 100644 | |
--- a/arch/arm64/include/asm/efi.h | |
+++ b/arch/arm64/include/asm/efi.h | |
@@ -2,6 +2,7 @@ | |
#define _ASM_EFI_H | |
#include <asm/cpufeature.h> | |
+#include <asm/fpsimd.h> | |
#include <asm/io.h> | |
#include <asm/mmu_context.h> | |
#include <asm/neon.h> | |
@@ -19,8 +20,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); | |
#define arch_efi_call_virt_setup() \ | |
({ \ | |
- kernel_neon_begin(); \ | |
efi_virtmap_load(); \ | |
+ __efi_fpsimd_begin(); \ | |
}) | |
#define arch_efi_call_virt(p, f, args...) \ | |
@@ -32,8 +33,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); | |
#define arch_efi_call_virt_teardown() \ | |
({ \ | |
+ __efi_fpsimd_end(); \ | |
efi_virtmap_unload(); \ | |
- kernel_neon_end(); \ | |
}) | |
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) | |
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h | |
index 50f559f574fe..410c48163c6a 100644 | |
--- a/arch/arm64/include/asm/fpsimd.h | |
+++ b/arch/arm64/include/asm/fpsimd.h | |
@@ -41,16 +41,6 @@ struct fpsimd_state { | |
unsigned int cpu; | |
}; | |
-/* | |
- * Struct for stacking the bottom 'n' FP/SIMD registers. | |
- */ | |
-struct fpsimd_partial_state { | |
- u32 fpsr; | |
- u32 fpcr; | |
- u32 num_regs; | |
- __uint128_t vregs[32]; | |
-}; | |
- | |
#if defined(__KERNEL__) && defined(CONFIG_COMPAT) | |
/* Masks for extracting the FPSR and FPCR from the FPSCR */ | |
@@ -77,9 +67,9 @@ extern void fpsimd_update_current_state(struct fpsimd_state *state); | |
extern void fpsimd_flush_task_state(struct task_struct *target); | |
-extern void fpsimd_save_partial_state(struct fpsimd_partial_state *state, | |
- u32 num_regs); | |
-extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state); | |
+/* For use by EFI runtime services calls only */ | |
+extern void __efi_fpsimd_begin(void); | |
+extern void __efi_fpsimd_end(void); | |
#endif | |
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h | |
index a2daf1293028..0f5fdd388b0d 100644 | |
--- a/arch/arm64/include/asm/fpsimdmacros.h | |
+++ b/arch/arm64/include/asm/fpsimdmacros.h | |
@@ -75,59 +75,3 @@ | |
ldr w\tmpnr, [\state, #16 * 2 + 4] | |
fpsimd_restore_fpcr x\tmpnr, \state | |
.endm | |
- | |
-.macro fpsimd_save_partial state, numnr, tmpnr1, tmpnr2 | |
- mrs x\tmpnr1, fpsr | |
- str w\numnr, [\state, #8] | |
- mrs x\tmpnr2, fpcr | |
- stp w\tmpnr1, w\tmpnr2, [\state] | |
- adr x\tmpnr1, 0f | |
- add \state, \state, x\numnr, lsl #4 | |
- sub x\tmpnr1, x\tmpnr1, x\numnr, lsl #1 | |
- br x\tmpnr1 | |
- stp q30, q31, [\state, #-16 * 30 - 16] | |
- stp q28, q29, [\state, #-16 * 28 - 16] | |
- stp q26, q27, [\state, #-16 * 26 - 16] | |
- stp q24, q25, [\state, #-16 * 24 - 16] | |
- stp q22, q23, [\state, #-16 * 22 - 16] | |
- stp q20, q21, [\state, #-16 * 20 - 16] | |
- stp q18, q19, [\state, #-16 * 18 - 16] | |
- stp q16, q17, [\state, #-16 * 16 - 16] | |
- stp q14, q15, [\state, #-16 * 14 - 16] | |
- stp q12, q13, [\state, #-16 * 12 - 16] | |
- stp q10, q11, [\state, #-16 * 10 - 16] | |
- stp q8, q9, [\state, #-16 * 8 - 16] | |
- stp q6, q7, [\state, #-16 * 6 - 16] | |
- stp q4, q5, [\state, #-16 * 4 - 16] | |
- stp q2, q3, [\state, #-16 * 2 - 16] | |
- stp q0, q1, [\state, #-16 * 0 - 16] | |
-0: | |
-.endm | |
- | |
-.macro fpsimd_restore_partial state, tmpnr1, tmpnr2 | |
- ldp w\tmpnr1, w\tmpnr2, [\state] | |
- msr fpsr, x\tmpnr1 | |
- fpsimd_restore_fpcr x\tmpnr2, x\tmpnr1 | |
- adr x\tmpnr1, 0f | |
- ldr w\tmpnr2, [\state, #8] | |
- add \state, \state, x\tmpnr2, lsl #4 | |
- sub x\tmpnr1, x\tmpnr1, x\tmpnr2, lsl #1 | |
- br x\tmpnr1 | |
- ldp q30, q31, [\state, #-16 * 30 - 16] | |
- ldp q28, q29, [\state, #-16 * 28 - 16] | |
- ldp q26, q27, [\state, #-16 * 26 - 16] | |
- ldp q24, q25, [\state, #-16 * 24 - 16] | |
- ldp q22, q23, [\state, #-16 * 22 - 16] | |
- ldp q20, q21, [\state, #-16 * 20 - 16] | |
- ldp q18, q19, [\state, #-16 * 18 - 16] | |
- ldp q16, q17, [\state, #-16 * 16 - 16] | |
- ldp q14, q15, [\state, #-16 * 14 - 16] | |
- ldp q12, q13, [\state, #-16 * 12 - 16] | |
- ldp q10, q11, [\state, #-16 * 10 - 16] | |
- ldp q8, q9, [\state, #-16 * 8 - 16] | |
- ldp q6, q7, [\state, #-16 * 6 - 16] | |
- ldp q4, q5, [\state, #-16 * 4 - 16] | |
- ldp q2, q3, [\state, #-16 * 2 - 16] | |
- ldp q0, q1, [\state, #-16 * 0 - 16] | |
-0: | |
-.endm | |
diff --git a/arch/arm64/include/asm/neon.h b/arch/arm64/include/asm/neon.h | |
index 13ce4cc18e26..fb9d137256a6 100644 | |
--- a/arch/arm64/include/asm/neon.h | |
+++ b/arch/arm64/include/asm/neon.h | |
@@ -8,11 +8,15 @@ | |
* published by the Free Software Foundation. | |
*/ | |
-#include <linux/types.h> | |
+#ifndef __ASM_NEON_H | |
+#define __ASM_NEON_H | |
-#define cpu_has_neon() (1) | |
+#include <linux/types.h> | |
+#include <asm/fpsimd.h> | |
-#define kernel_neon_begin() kernel_neon_begin_partial(32) | |
+#define cpu_has_neon() system_supports_fpsimd() | |
-void kernel_neon_begin_partial(u32 num_regs); | |
+void kernel_neon_begin(void); | |
void kernel_neon_end(void); | |
+ | |
+#endif /* ! __ASM_NEON_H */ | |
diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h | |
new file mode 100644 | |
index 000000000000..6495cc51246f | |
--- /dev/null | |
+++ b/arch/arm64/include/asm/simd.h | |
@@ -0,0 +1,51 @@ | |
+/* | |
+ * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License version 2 as published | |
+ * by the Free Software Foundation. | |
+ */ | |
+ | |
+#ifndef __ASM_SIMD_H | |
+#define __ASM_SIMD_H | |
+ | |
+#include <linux/compiler.h> | |
+#include <linux/irqflags.h> | |
+#include <linux/percpu.h> | |
+#include <linux/preempt.h> | |
+#include <linux/types.h> | |
+ | |
+#ifdef CONFIG_KERNEL_MODE_NEON | |
+ | |
+DECLARE_PER_CPU(bool, kernel_neon_busy); | |
+ | |
+/* | |
+ * may_use_simd - whether it is allowable at this time to issue SIMD | |
+ * instructions or access the SIMD register file | |
+ * | |
+ * Callers must not assume that the result remains true beyond the next | |
+ * preempt_enable() or return from softirq context. | |
+ */ | |
+static __must_check inline bool may_use_simd(void) | |
+{ | |
+ /* | |
+ * kernel_neon_busy is only set while preemption is disabled, | |
+ * and is clear whenever preemption is enabled. Since | |
+ * this_cpu_read() is atomic w.r.t. preemption, kernel_neon_busy | |
+ * cannot change under our feet -- if it's set we cannot be | |
+ * migrated, and if it's clear we cannot be migrated to a CPU | |
+ * where it is set. | |
+ */ | |
+ return !in_irq() && !irqs_disabled() && !in_nmi() && | |
+ !this_cpu_read(kernel_neon_busy); | |
+} | |
+ | |
+#else /* ! CONFIG_KERNEL_MODE_NEON */ | |
+ | |
+static __must_check inline bool may_use_simd(void) { | |
+ return false; | |
+} | |
+ | |
+#endif /* ! CONFIG_KERNEL_MODE_NEON */ | |
+ | |
+#endif | |
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S | |
index c44a82f146b1..6a27cd6dbfa6 100644 | |
--- a/arch/arm64/kernel/entry-fpsimd.S | |
+++ b/arch/arm64/kernel/entry-fpsimd.S | |
@@ -41,27 +41,3 @@ ENTRY(fpsimd_load_state) | |
fpsimd_restore x0, 8 | |
ret | |
ENDPROC(fpsimd_load_state) | |
- | |
-#ifdef CONFIG_KERNEL_MODE_NEON | |
- | |
-/* | |
- * Save the bottom n FP registers. | |
- * | |
- * x0 - pointer to struct fpsimd_partial_state | |
- */ | |
-ENTRY(fpsimd_save_partial_state) | |
- fpsimd_save_partial x0, 1, 8, 9 | |
- ret | |
-ENDPROC(fpsimd_save_partial_state) | |
- | |
-/* | |
- * Load the bottom n FP registers. | |
- * | |
- * x0 - pointer to struct fpsimd_partial_state | |
- */ | |
-ENTRY(fpsimd_load_partial_state) | |
- fpsimd_restore_partial x0, 8, 9 | |
- ret | |
-ENDPROC(fpsimd_load_partial_state) | |
- | |
-#endif | |
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c | |
index ee34be8bed03..59fc9db2fc09 100644 | |
--- a/arch/arm64/kernel/fpsimd.c | |
+++ b/arch/arm64/kernel/fpsimd.c | |
@@ -17,17 +17,21 @@ | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
+#include <linux/bottom_half.h> | |
#include <linux/cpu.h> | |
#include <linux/cpu_pm.h> | |
#include <linux/kernel.h> | |
+#include <linux/linkage.h> | |
#include <linux/init.h> | |
+#include <linux/percpu.h> | |
+#include <linux/preempt.h> | |
#include <linux/sched.h> | |
#include <linux/signal.h> | |
-#include <linux/hardirq.h> | |
#include <asm/fpsimd.h> | |
#include <asm/cpufeature.h> | |
#include <asm/cputype.h> | |
+#include <asm/simd.h> | |
#define FPEXC_IOF (1 << 0) | |
#define FPEXC_DZF (1 << 1) | |
@@ -63,6 +67,13 @@ | |
* CPU currently contain the most recent userland FPSIMD state of the current | |
* task. | |
* | |
+ * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may | |
+ * save the task's FPSIMD context back to task_struct from softirq context. | |
+ * To prevent this from racing with the manipulation of the task's FPSIMD state | |
+ * from task context and thereby corrupting the state, it is necessary to | |
+ * protect any manipulation of a task's fpsimd_state or TIF_FOREIGN_FPSTATE | |
+ * flag with local_bh_disable() unless softirqs are already masked. | |
+ * | |
* For a certain task, the sequence may look something like this: | |
* - the task gets scheduled in; if both the task's fpsimd_state.cpu field | |
* contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu | |
@@ -93,7 +104,7 @@ static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); | |
/* | |
* Trapped FP/ASIMD access. | |
*/ | |
-void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) | |
+asmlinkage void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) | |
{ | |
/* TODO: implement lazy context saving/restoring */ | |
WARN_ON(1); | |
@@ -102,7 +113,7 @@ void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) | |
/* | |
* Raise a SIGFPE for the current process. | |
*/ | |
-void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) | |
+asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) | |
{ | |
siginfo_t info; | |
unsigned int si_code = 0; | |
@@ -128,6 +139,8 @@ void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) | |
void fpsimd_thread_switch(struct task_struct *next) | |
{ | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
/* | |
* Save the current FPSIMD state to memory, but only if whatever is in | |
* the registers is in fact the most recent userland FPSIMD state of | |
@@ -148,21 +161,24 @@ void fpsimd_thread_switch(struct task_struct *next) | |
if (__this_cpu_read(fpsimd_last_state) == st | |
&& st->cpu == smp_processor_id()) | |
- clear_ti_thread_flag(task_thread_info(next), | |
- TIF_FOREIGN_FPSTATE); | |
+ clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); | |
else | |
- set_ti_thread_flag(task_thread_info(next), | |
- TIF_FOREIGN_FPSTATE); | |
+ set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); | |
} | |
} | |
void fpsimd_flush_thread(void) | |
{ | |
- preempt_disable(); | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ local_bh_disable(); | |
+ | |
memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); | |
fpsimd_flush_task_state(current); | |
set_thread_flag(TIF_FOREIGN_FPSTATE); | |
- preempt_enable(); | |
+ | |
+ local_bh_enable(); | |
} | |
/* | |
@@ -171,10 +187,15 @@ void fpsimd_flush_thread(void) | |
*/ | |
void fpsimd_preserve_current_state(void) | |
{ | |
- preempt_disable(); | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ local_bh_disable(); | |
+ | |
if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) | |
fpsimd_save_state(¤t->thread.fpsimd_state); | |
- preempt_enable(); | |
+ | |
+ local_bh_enable(); | |
} | |
/* | |
@@ -184,15 +205,20 @@ void fpsimd_preserve_current_state(void) | |
*/ | |
void fpsimd_restore_current_state(void) | |
{ | |
- preempt_disable(); | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ local_bh_disable(); | |
+ | |
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { | |
struct fpsimd_state *st = ¤t->thread.fpsimd_state; | |
fpsimd_load_state(st); | |
- this_cpu_write(fpsimd_last_state, st); | |
+ __this_cpu_write(fpsimd_last_state, st); | |
st->cpu = smp_processor_id(); | |
} | |
- preempt_enable(); | |
+ | |
+ local_bh_enable(); | |
} | |
/* | |
@@ -202,15 +228,20 @@ void fpsimd_restore_current_state(void) | |
*/ | |
void fpsimd_update_current_state(struct fpsimd_state *state) | |
{ | |
- preempt_disable(); | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ local_bh_disable(); | |
+ | |
fpsimd_load_state(state); | |
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { | |
struct fpsimd_state *st = ¤t->thread.fpsimd_state; | |
- this_cpu_write(fpsimd_last_state, st); | |
+ __this_cpu_write(fpsimd_last_state, st); | |
st->cpu = smp_processor_id(); | |
} | |
- preempt_enable(); | |
+ | |
+ local_bh_enable(); | |
} | |
/* | |
@@ -223,48 +254,126 @@ void fpsimd_flush_task_state(struct task_struct *t) | |
#ifdef CONFIG_KERNEL_MODE_NEON | |
-static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate); | |
-static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate); | |
+DEFINE_PER_CPU(bool, kernel_neon_busy); | |
+EXPORT_PER_CPU_SYMBOL(kernel_neon_busy); | |
/* | |
* Kernel-side NEON support functions | |
*/ | |
-void kernel_neon_begin_partial(u32 num_regs) | |
+ | |
+/* | |
+ * kernel_neon_begin(): obtain the CPU FPSIMD registers for use by the calling | |
+ * context | |
+ * | |
+ * Must not be called unless may_use_simd() returns true. | |
+ * Task context in the FPSIMD registers is saved back to memory as necessary. | |
+ * | |
+ * A matching call to kernel_neon_end() must be made before returning from the | |
+ * calling context. | |
+ * | |
+ * The caller may freely use the FPSIMD registers until kernel_neon_end() is | |
+ * called. | |
+ */ | |
+void kernel_neon_begin(void) | |
{ | |
- if (in_interrupt()) { | |
- struct fpsimd_partial_state *s = this_cpu_ptr( | |
- in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); | |
+ if (WARN_ON(!system_supports_fpsimd())) | |
+ return; | |
- BUG_ON(num_regs > 32); | |
- fpsimd_save_partial_state(s, roundup(num_regs, 2)); | |
- } else { | |
- /* | |
- * Save the userland FPSIMD state if we have one and if we | |
- * haven't done so already. Clear fpsimd_last_state to indicate | |
- * that there is no longer userland FPSIMD state in the | |
- * registers. | |
- */ | |
- preempt_disable(); | |
- if (current->mm && | |
- !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) | |
- fpsimd_save_state(¤t->thread.fpsimd_state); | |
- this_cpu_write(fpsimd_last_state, NULL); | |
- } | |
+ BUG_ON(!may_use_simd()); | |
+ | |
+ local_bh_disable(); | |
+ | |
+ __this_cpu_write(kernel_neon_busy, true); | |
+ | |
+ /* Save unsaved task fpsimd state, if any: */ | |
+ if (current->mm && !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) | |
+ fpsimd_save_state(¤t->thread.fpsimd_state); | |
+ | |
+ /* Invalidate any task state remaining in the fpsimd regs: */ | |
+ __this_cpu_write(fpsimd_last_state, NULL); | |
+ | |
+ preempt_disable(); | |
+ | |
+ local_bh_enable(); | |
} | |
-EXPORT_SYMBOL(kernel_neon_begin_partial); | |
+EXPORT_SYMBOL(kernel_neon_begin); | |
+/* | |
+ * kernel_neon_end(): give the CPU FPSIMD registers back to the current task | |
+ * | |
+ * Must be called from a context in which kernel_neon_begin() was previously | |
+ * called, with no call to kernel_neon_end() in the meantime. | |
+ * | |
+ * The caller must not use the FPSIMD registers after this function is called, | |
+ * unless kernel_neon_begin() is called again in the meantime. | |
+ */ | |
void kernel_neon_end(void) | |
{ | |
- if (in_interrupt()) { | |
- struct fpsimd_partial_state *s = this_cpu_ptr( | |
- in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); | |
- fpsimd_load_partial_state(s); | |
- } else { | |
- preempt_enable(); | |
- } | |
+ bool busy; | |
+ | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ busy = __this_cpu_xchg(kernel_neon_busy, false); | |
+ WARN_ON(!busy); /* No matching kernel_neon_begin()? */ | |
+ | |
+ preempt_enable(); | |
} | |
EXPORT_SYMBOL(kernel_neon_end); | |
+#ifdef CONFIG_EFI | |
+ | |
+static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state); | |
+static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); | |
+ | |
+/* | |
+ * EFI runtime services support functions | |
+ * | |
+ * The ABI for EFI runtime services allows EFI to use FPSIMD during the call. | |
+ * This means that for EFI (and only for EFI), we have to assume that FPSIMD | |
+ * is always used rather than being an optional accelerator. | |
+ * | |
+ * These functions provide the necessary support for ensuring FPSIMD | |
+ * save/restore in the contexts from which EFI is used. | |
+ * | |
+ * Do not use them for any other purpose -- if tempted to do so, you are | |
+ * either doing something wrong or you need to propose some refactoring. | |
+ */ | |
+ | |
+/* | |
+ * __efi_fpsimd_begin(): prepare FPSIMD for making an EFI runtime services call | |
+ */ | |
+void __efi_fpsimd_begin(void) | |
+{ | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ WARN_ON(preemptible()); | |
+ | |
+ if (may_use_simd()) | |
+ kernel_neon_begin(); | |
+ else { | |
+ fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state)); | |
+ __this_cpu_write(efi_fpsimd_state_used, true); | |
+ } | |
+} | |
+ | |
+/* | |
+ * __efi_fpsimd_end(): clean up FPSIMD after an EFI runtime services call | |
+ */ | |
+void __efi_fpsimd_end(void) | |
+{ | |
+ if (!system_supports_fpsimd()) | |
+ return; | |
+ | |
+ if (__this_cpu_xchg(efi_fpsimd_state_used, false)) | |
+ fpsimd_load_state(this_cpu_ptr(&efi_fpsimd_state)); | |
+ else | |
+ kernel_neon_end(); | |
+} | |
+ | |
+#endif /* CONFIG_EFI */ | |
+ | |
#endif /* CONFIG_KERNEL_MODE_NEON */ | |
#ifdef CONFIG_CPU_PM | |
@@ -335,4 +444,4 @@ static int __init fpsimd_init(void) | |
return 0; | |
} | |
-late_initcall(fpsimd_init); | |
+core_initcall(fpsimd_init); | |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c | |
index 1b3eb67edefb..3566556eea20 100644 | |
--- a/arch/arm64/kernel/pci.c | |
+++ b/arch/arm64/kernel/pci.c | |
@@ -39,20 +39,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |
return res->start; | |
} | |
+#ifdef CONFIG_ACPI | |
/* | |
* Try to assign the IRQ number when probing a new device | |
*/ | |
int pcibios_alloc_irq(struct pci_dev *dev) | |
{ | |
- if (acpi_disabled) | |
- dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | |
-#ifdef CONFIG_ACPI | |
- else | |
- return acpi_pci_irq_enable(dev); | |
-#endif | |
+ if (!acpi_disabled) | |
+ acpi_pci_irq_enable(dev); | |
return 0; | |
} | |
+#endif | |
/* | |
* raw_pci_read/write - Platform-specific PCI config space access. | |
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c | |
index 7990377dbbbc..16711313854c 100644 | |
--- a/arch/arm64/kernel/ptrace.c | |
+++ b/arch/arm64/kernel/ptrace.c | |
@@ -622,6 +622,10 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, | |
{ | |
struct user_fpsimd_state *uregs; | |
uregs = &target->thread.fpsimd_state.user_fpsimd; | |
+ | |
+ if (target == current) | |
+ fpsimd_preserve_current_state(); | |
+ | |
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1); | |
} | |
@@ -897,6 +901,9 @@ static int compat_vfp_get(struct task_struct *target, | |
uregs = &target->thread.fpsimd_state.user_fpsimd; | |
+ if (target == current) | |
+ fpsimd_preserve_current_state(); | |
+ | |
/* | |
* The VFP registers are packed into the fpsimd_state, so they all sit | |
* nicely together for us. We just need to create the fpscr separately. | |
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c | |
index b5222094ab52..4faec67e2f63 100644 | |
--- a/arch/arm64/kernel/setup.c | |
+++ b/arch/arm64/kernel/setup.c | |
@@ -180,6 +180,7 @@ static void __init smp_build_mpidr_hash(void) | |
static void __init setup_machine_fdt(phys_addr_t dt_phys) | |
{ | |
void *dt_virt = fixmap_remap_fdt(dt_phys); | |
+ const char *name; | |
if (!dt_virt || !early_init_dt_scan(dt_virt)) { | |
pr_crit("\n" | |
@@ -192,7 +193,12 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) | |
cpu_relax(); | |
} | |
- dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name()); | |
+ name = of_flat_dt_get_machine_name(); | |
+ if (!name) | |
+ return; | |
+ | |
+ pr_info("Machine model: %s\n", name); | |
+ dump_stack_set_arch_desc("%s (DT)", name); | |
} | |
static void __init request_standard_resources(void) | |
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c | |
index ed734264a516..312c2ff8d1be 100644 | |
--- a/arch/arm64/kernel/topology.c | |
+++ b/arch/arm64/kernel/topology.c | |
@@ -19,7 +19,6 @@ | |
#include <linux/nodemask.h> | |
#include <linux/of.h> | |
#include <linux/sched.h> | |
-#include <linux/sched.h> | |
#include <linux/sched_energy.h> | |
#include <asm/cputype.h> | |
@@ -227,7 +226,9 @@ const struct sched_group_energy * const cpu_cluster_energy(int cpu) | |
struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL1]; | |
if (!sge) { | |
+#ifndef CONFIG_MACH_MT7622 | |
pr_warn("Invalid sched_group_energy for Cluster%d\n", cpu); | |
+#endif | |
return NULL; | |
} | |
@@ -240,7 +241,9 @@ const struct sched_group_energy * const cpu_core_energy(int cpu) | |
struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL0]; | |
if (!sge) { | |
+#ifndef CONFIG_MACH_MT7622 | |
pr_warn("Invalid sched_group_energy for CPU%d\n", cpu); | |
+#endif | |
return NULL; | |
} | |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c | |
index c5c710d0b141..00e6295ec15e 100644 | |
--- a/arch/arm64/mm/init.c | |
+++ b/arch/arm64/mm/init.c | |
@@ -427,37 +427,37 @@ void __init mem_init(void) | |
#define MLG(b, t) b, t, ((t) - (b)) >> 30 | |
#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) | |
- pr_notice("Virtual kernel memory layout:\n"); | |
+ pr_info("Virtual kernel memory layout:\n"); | |
#ifdef CONFIG_KASAN | |
- pr_notice(" kasan : 0x%16lx - 0x%16lx (%6ld GB)\n", | |
+ pr_info(" kasan : 0x%16lx - 0x%16lx (%6ld GB)\n", | |
MLG(KASAN_SHADOW_START, KASAN_SHADOW_END)); | |
#endif | |
- pr_notice(" modules : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
+ pr_info(" modules : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
MLM(MODULES_VADDR, MODULES_END)); | |
- pr_notice(" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n", | |
+ pr_info(" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n", | |
MLG(VMALLOC_START, VMALLOC_END)); | |
- pr_notice(" .text : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
+ pr_info(" .text : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
MLK_ROUNDUP(_text, _etext)); | |
- pr_notice(" .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
+ pr_info(" .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
MLK_ROUNDUP(__start_rodata, __init_begin)); | |
- pr_notice(" .init : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
+ pr_info(" .init : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
MLK_ROUNDUP(__init_begin, __init_end)); | |
- pr_notice(" .data : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
+ pr_info(" .data : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
MLK_ROUNDUP(_sdata, _edata)); | |
- pr_notice(" .bss : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
+ pr_info(" .bss : 0x%p" " - 0x%p" " (%6ld KB)\n", | |
MLK_ROUNDUP(__bss_start, __bss_stop)); | |
- pr_notice(" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n", | |
+ pr_info(" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n", | |
MLK(FIXADDR_START, FIXADDR_TOP)); | |
- pr_notice(" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
+ pr_info(" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
MLM(PCI_IO_START, PCI_IO_END)); | |
#ifdef CONFIG_SPARSEMEM_VMEMMAP | |
- pr_notice(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n", | |
+ pr_info(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n", | |
MLG(VMEMMAP_START, VMEMMAP_START + VMEMMAP_SIZE)); | |
- pr_notice(" 0x%16lx - 0x%16lx (%6ld MB actual)\n", | |
+ pr_info(" 0x%16lx - 0x%16lx (%6ld MB actual)\n", | |
MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()), | |
(unsigned long)virt_to_page(high_memory))); | |
#endif | |
- pr_notice(" memory : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
+ pr_info(" memory : 0x%16lx - 0x%16lx (%6ld MB)\n", | |
MLM(__phys_to_virt(memblock_start_of_DRAM()), | |
(unsigned long)high_memory)); | |
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms | |
index f5f1bdb292de..b63da6b0a75c 100644 | |
--- a/arch/mips/Kbuild.platforms | |
+++ b/arch/mips/Kbuild.platforms | |
@@ -26,12 +26,14 @@ platforms += pistachio | |
platforms += pmcs-msp71xx | |
platforms += pnx833x | |
platforms += ralink | |
+platforms += rt2880 | |
platforms += rb532 | |
platforms += sgi-ip22 | |
platforms += sgi-ip27 | |
platforms += sgi-ip32 | |
platforms += sibyte | |
platforms += sni | |
+platforms += tc3262 | |
platforms += txx9 | |
platforms += vr41xx | |
platforms += xilfpga | |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig | |
index 9708c319a744..e51fda9949af 100644 | |
--- a/arch/mips/Kconfig | |
+++ b/arch/mips/Kconfig | |
@@ -2,13 +2,13 @@ config MIPS | |
bool | |
default y | |
select ARCH_SUPPORTS_UPROBES | |
- select ARCH_MIGHT_HAVE_PC_PARPORT | |
+# select ARCH_MIGHT_HAVE_PC_PARPORT | |
select ARCH_MIGHT_HAVE_PC_SERIO | |
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT | |
select ARCH_USE_BUILTIN_BSWAP | |
select HAVE_CONTEXT_TRACKING | |
- select HAVE_GENERIC_DMA_COHERENT | |
- select HAVE_IDE | |
+# select HAVE_GENERIC_DMA_COHERENT | |
+# select HAVE_IDE | |
select HAVE_IRQ_EXIT_ON_IRQ_STACK | |
select HAVE_OPROFILE | |
select HAVE_PERF_EVENTS | |
@@ -39,7 +39,7 @@ config MIPS | |
select GENERIC_PCI_IOMAP | |
select HAVE_ARCH_JUMP_LABEL | |
select ARCH_WANT_IPC_PARSE_VERSION | |
- select IRQ_FORCED_THREADING | |
+# select IRQ_FORCED_THREADING | |
select HAVE_MEMBLOCK | |
select HAVE_MEMBLOCK_NODE_MAP | |
select ARCH_DISCARD_MEMBLOCK | |
@@ -56,6 +56,7 @@ config MIPS | |
select CLONE_BACKWARDS | |
select HAVE_DEBUG_STACKOVERFLOW | |
select HAVE_CC_STACKPROTECTOR | |
+ select LD_DEAD_CODE_DATA_ELIMINATION | |
select CPU_PM if CPU_IDLE | |
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | |
select ARCH_BINFMT_ELF_STATE | |
@@ -68,12 +69,50 @@ config MIPS | |
select HAVE_EXIT_THREAD | |
select HAVE_REGS_AND_STACK_ACCESS_API | |
select HAVE_ARCH_HARDENED_USERCOPY | |
+ select ARCH_HAS_UBSAN_SANITIZE_ALL | |
menu "Machine selection" | |
+config ECONET_EN75XX_MP | |
+ bool | |
+ | |
+config MIPS_TC3262_34K | |
+ select SYS_SUPPORTS_MULTITHREADING | |
+ select SYS_SUPPORTS_SMP | |
+ bool | |
+ | |
+config MIPS_TC3262_1004K | |
+ select SYS_SUPPORTS_MULTITHREADING | |
+ select SYS_SUPPORTS_SMP | |
+ select SYS_SUPPORTS_MIPS_CMP | |
+ select SYS_SUPPORTS_MIPS_CPS | |
+ select SYS_SUPPORTS_HIGHMEM | |
+ select MIPS_CPU_SCACHE | |
+ select IRQ_GIC | |
+ select IRQ_GIC_EIC | |
+ select WEAK_REORDERING_BEYOND_LLSC | |
+ select TC3262_CPU_TIMER | |
+ bool | |
+ | |
+config MIPS_TC3262 | |
+ bool | |
+ select DMA_NONCOHERENT | |
+ select HW_HAS_PCI | |
+ select BOOT_RAW | |
+ select SYS_HAS_EARLY_PRINTK | |
+ select SYS_HAS_CPU_MIPS32_R1 | |
+ select SYS_HAS_CPU_MIPS32_R2 | |
+ select SYS_SUPPORTS_MIPS16 | |
+ select SYS_SUPPORTS_32BIT_KERNEL | |
+ select CSRC_R4K | |
+ select CEVT_R4K | |
+ select CPU_MIPSR2_IRQ_VI | |
+ select CPU_MIPSR2_IRQ_EI | |
+ select NO_EXCEPT_FILL | |
+ | |
choice | |
prompt "System type" | |
- default SGI_IP22 | |
+ default RALINK_MT7621 | |
config MIPS_GENERIC | |
bool "Generic board-agnostic MIPS kernel" | |
@@ -127,6 +166,89 @@ config MIPS_GENERIC | |
using the boot protocol defined in the UHI (Unified Hosting | |
Interface) specification. | |
+config RALINK_MT7621 | |
+ bool "Ralink MT7621 board" | |
+ select DMA_NONCOHERENT | |
+ select IRQ_MIPS_CPU | |
+ select HW_HAS_PCI | |
+ select SWAP_IO_SPACE | |
+ select BOOT_ELF32 | |
+ select SYS_HAS_CPU_MIPS32_R1 | |
+ select SYS_HAS_CPU_MIPS32_R2 | |
+ select SYS_HAS_EARLY_PRINTK | |
+ select SYS_SUPPORTS_LITTLE_ENDIAN | |
+ select SYS_SUPPORTS_32BIT_KERNEL | |
+ select SYS_SUPPORTS_MIPS16 | |
+ select SYS_SUPPORTS_HIGHMEM | |
+ select CSRC_R4K | |
+ select CEVT_R4K | |
+ select MIPS_CPU_SCACHE | |
+ select SYS_SUPPORTS_MULTITHREADING | |
+ select SYS_SUPPORTS_SMP | |
+ select SYS_SUPPORTS_MIPS_CMP | |
+ select SYS_SUPPORTS_MIPS_CPS | |
+ select IRQ_GIC | |
+# select MIPS_GIC | |
+ select WEAK_REORDERING_BEYOND_LLSC | |
+ select MIPS_L2_CACHE_ER35 | |
+ help | |
+ Ralink evaluation board based on MT7621 | |
+ | |
+config RALINK_MT7628 | |
+ bool "Ralink MT7628 board" | |
+ select DMA_NONCOHERENT | |
+ select IRQ_MIPS_CPU | |
+ select HW_HAS_PCI | |
+ select SWAP_IO_SPACE | |
+ select BOOT_ELF32 | |
+ select SYS_HAS_CPU_MIPS32_R1 | |
+ select SYS_HAS_CPU_MIPS32_R2 | |
+ select SYS_HAS_EARLY_PRINTK | |
+ select SYS_SUPPORTS_LITTLE_ENDIAN | |
+ select SYS_SUPPORTS_32BIT_KERNEL | |
+ select SYS_SUPPORTS_MIPS16 | |
+ select CSRC_R4K | |
+ select CEVT_R4K | |
+ select CPU_MIPSR2_IRQ_VI | |
+ help | |
+ Ralink evaluation board based on MT7628 | |
+ | |
+config ECONET_EN7512 | |
+ bool "EcoNET EN7512/3 board" | |
+ select MIPS_TC3262 | |
+ select MIPS_TC3262_34K | |
+ select ECONET_EN75XX_MP | |
+ select SYS_SUPPORTS_BIG_ENDIAN | |
+ help | |
+ EcoNET evaluation board based on EN7512/3 | |
+ | |
+config ECONET_EN7516 | |
+ bool "EcoNET EN7516 board" | |
+ select MIPS_TC3262 | |
+ select MIPS_TC3262_1004K | |
+ select ECONET_EN75XX_MP | |
+ select SYS_SUPPORTS_BIG_ENDIAN | |
+ help | |
+ EcoNET evaluation board based on EN7516 | |
+ | |
+config ECONET_EN7527 | |
+ bool "EcoNET EN7527/EN7561G board" | |
+ select MIPS_TC3262 | |
+ select MIPS_TC3262_1004K | |
+ select ECONET_EN75XX_MP | |
+ select SYS_SUPPORTS_BIG_ENDIAN | |
+ help | |
+ EcoNET evaluation board based on EN7527/EN7561G | |
+ | |
+config ECONET_EN7528 | |
+ bool "EcoNET EN7528DU/EN7561DU board" | |
+ select MIPS_TC3262 | |
+ select MIPS_TC3262_1004K | |
+ select ECONET_EN75XX_MP | |
+ select SYS_SUPPORTS_LITTLE_ENDIAN | |
+ help | |
+ EcoNET evaluation board based on EN7528DU/EN7561DU | |
+ | |
config MIPS_ALCHEMY | |
bool "Alchemy processor based machines" | |
select ARCH_PHYS_ADDR_T_64BIT | |
@@ -215,6 +337,7 @@ config BMIPS_GENERIC | |
select BRCMSTB_L2_IRQ | |
select IRQ_MIPS_CPU | |
select DMA_NONCOHERENT | |
+ select DMA_UNMAP_POST_FLUSH | |
select SYS_SUPPORTS_32BIT_KERNEL | |
select SYS_SUPPORTS_LITTLE_ENDIAN | |
select SYS_SUPPORTS_BIG_ENDIAN | |
@@ -343,6 +466,7 @@ config MACH_JAZZ | |
select CSRC_R4K | |
select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN | |
select GENERIC_ISA_DMA | |
+ select DMA_UNMAP_POST_FLUSH | |
select HAVE_PCSPKR_PLATFORM | |
select IRQ_MIPS_CPU | |
select I8253 | |
@@ -1022,8 +1146,10 @@ source "arch/mips/pic32/Kconfig" | |
source "arch/mips/pistachio/Kconfig" | |
source "arch/mips/pmcs-msp71xx/Kconfig" | |
source "arch/mips/ralink/Kconfig" | |
+source "arch/mips/rt2880/Kconfig" | |
source "arch/mips/sgi-ip27/Kconfig" | |
source "arch/mips/sibyte/Kconfig" | |
+source "arch/mips/tc3262/Kconfig" | |
source "arch/mips/txx9/Kconfig" | |
source "arch/mips/vr41xx/Kconfig" | |
source "arch/mips/cavium-octeon/Kconfig" | |
@@ -1135,6 +1261,9 @@ config DMA_NONCOHERENT | |
bool | |
select NEED_DMA_MAP_STATE | |
+config DMA_UNMAP_POST_FLUSH | |
+ bool | |
+ | |
config NEED_DMA_MAP_STATE | |
bool | |
@@ -1246,6 +1375,13 @@ config IRQ_TXX9 | |
config IRQ_GT641XX | |
bool | |
+config IRQ_GIC | |
+ bool | |
+ select MIPS_CM | |
+ | |
+config IRQ_GIC_EIC | |
+ bool | |
+ | |
config PCI_GT64XXX_PCI0 | |
bool | |
@@ -1337,6 +1473,10 @@ config MIPS_L1_CACHE_SHIFT | |
default "4" if MIPS_L1_CACHE_SHIFT_4 | |
default "5" | |
+config MIPS_L2_CACHE_ER35 | |
+ bool | |
+ select ZONE_DMA | |
+ | |
config HAVE_STD_PC_SERIAL_PORT | |
bool | |
@@ -1660,6 +1800,7 @@ config CPU_R10000 | |
select CPU_SUPPORTS_64BIT_KERNEL | |
select CPU_SUPPORTS_HIGHMEM | |
select CPU_SUPPORTS_HUGEPAGES | |
+ select DMA_UNMAP_POST_FLUSH | |
help | |
MIPS Technologies R10000-series processors. | |
@@ -1905,9 +2046,11 @@ config SYS_HAS_CPU_MIPS32_R3_5 | |
bool | |
config SYS_HAS_CPU_MIPS32_R5 | |
+ select DMA_UNMAP_POST_FLUSH | |
bool | |
config SYS_HAS_CPU_MIPS32_R6 | |
+ select DMA_UNMAP_POST_FLUSH | |
bool | |
config SYS_HAS_CPU_MIPS64_R1 | |
@@ -1917,6 +2060,7 @@ config SYS_HAS_CPU_MIPS64_R2 | |
bool | |
config SYS_HAS_CPU_MIPS64_R6 | |
+ select DMA_UNMAP_POST_FLUSH | |
bool | |
config SYS_HAS_CPU_R3000 | |
@@ -2207,6 +2351,22 @@ config FORCE_MAX_ZONEORDER | |
The page size is not necessarily 4KB. Keep this in mind | |
when choosing a value for this option. | |
+config THREAD_STACK_SIZE_ADJUSTMENT | |
+ bool "Enable adjustment of a kernel thread stack size" | |
+ | |
+config THREAD_SIZE_ORDER | |
+ int "An order of 2 for a multiplier of a thread info structure size" | |
+ default "2" | |
+ range 0 3 | |
+ depends on THREAD_STACK_SIZE_ADJUSTMENT | |
+ help | |
+ Set a size of a kernel thread stack to | |
+ | |
+ 2^(PAGE_SHIFT + THREAD_SIZE_ORDER) - sizeof(struct thread_info) | |
+ | |
+ It should be larger for preemptive kernels and systems with | |
+ drivers that require deeper stacks. | |
+ | |
config BOARD_SCACHE | |
bool | |
@@ -2509,6 +2669,11 @@ config MIPS_ASID_BITS | |
config MIPS_ASID_BITS_VARIABLE | |
bool | |
+config LONG_CALLS | |
+ bool "gcc must use -mlong-calls (RAM > 256MB)" | |
+ depends on 32BIT | |
+ default y if DYNAMIC_FTRACE | |
+ | |
# | |
# - Highmem only makes sense for the 32-bit kernel. | |
# - The current highmem code will only work properly on physically indexed | |
@@ -2525,6 +2690,7 @@ config MIPS_ASID_BITS_VARIABLE | |
config HIGHMEM | |
bool "High Memory Support" | |
depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA | |
+ select LONG_CALLS | |
config CPU_SUPPORTS_HIGHMEM | |
bool | |
@@ -2898,6 +3064,20 @@ config MIPS_O32_FP64_SUPPORT | |
If unsure, say N. | |
+config MIPS_FPU_EMULATOR | |
+ bool "MIPS FPU Emulator" | |
+ default y | |
+ help | |
+ This option lets you disable the built-in MIPS FPU (Coprocessor 1) | |
+ emulator, which handles floating-point instructions on processors | |
+ without a hardware FPU. It is generally a good idea to keep the | |
+ emulator built-in, unless you are perfectly sure you have a | |
+ complete soft-float environment. With the emulator disabled, all | |
+ users of float operations will be killed with an illegal instr- | |
+ uction exception. | |
+ | |
+ Say Y, please. | |
+ | |
config USE_OF | |
bool | |
select OF | |
@@ -3095,6 +3275,10 @@ config ZONE_DMA | |
config ZONE_DMA32 | |
bool | |
+config ZONE_DMA_SIZE | |
+ hex | |
+ default 0x1000000 if MIPS_L2_CACHE_ER35 | |
+ | |
source "drivers/pcmcia/Kconfig" | |
config RAPIDIO | |
@@ -3164,11 +3348,11 @@ endmenu | |
menu "Power management options" | |
config ARCH_HIBERNATION_POSSIBLE | |
- def_bool y | |
+ def_bool n | |
depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP | |
config ARCH_SUSPEND_POSSIBLE | |
- def_bool y | |
+ def_bool n | |
depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP | |
source "kernel/power/Kconfig" | |
@@ -3205,3 +3389,5 @@ source "crypto/Kconfig" | |
source "lib/Kconfig" | |
source "arch/mips/kvm/Kconfig" | |
+ | |
+source "ndm/Kconfig" | |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile | |
index af4eff7d22ec..57c873d8ce3a 100644 | |
--- a/arch/mips/Makefile | |
+++ b/arch/mips/Makefile | |
@@ -90,11 +90,21 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz | |
# machines may also. Since BFD is incredibly buggy with respect to | |
# crossformat linking we rely on the elf2ecoff tool for format conversion. | |
# | |
-cflags-y += -G 0 -mno-abicalls -fno-pic -pipe | |
+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely | |
cflags-y += -msoft-float | |
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib | |
+ifdef CONFIG_64BIT | |
+KBUILD_AFLAGS_MODULE += -mlong-calls | |
+KBUILD_CFLAGS_MODULE += -mlong-calls | |
+else | |
+ifdef CONFIG_LONG_CALLS | |
KBUILD_AFLAGS_MODULE += -mlong-calls | |
KBUILD_CFLAGS_MODULE += -mlong-calls | |
+else | |
+KBUILD_AFLAGS_MODULE += -mno-long-calls | |
+KBUILD_CFLAGS_MODULE += -mno-long-calls | |
+endif | |
+endif | |
ifeq ($(CONFIG_RELOCATABLE),y) | |
LDFLAGS_vmlinux += --emit-relocs | |
@@ -131,6 +141,21 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips. | |
cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ | |
-fno-omit-frame-pointer | |
+ | |
+# Some distribution-specific toolchains might pass the -fstack-check | |
+# option during the build, which adds a simple stack-probe at the beginning | |
+# of every function. This stack probe is to ensure that there is enough | |
+# stack space, else a SEGV is generated. This is not desirable for MIPS | |
+# as kernel stacks are small, placed in unmapped virtual memory, and do not | |
+# grow when overflowed. Especially on SGI IP27 platforms, this check will | |
+# lead to a NULL pointer dereference in _raw_spin_lock_irq. | |
+# | |
+# In disassembly, this stack probe appears at the top of a function as: | |
+# sd zero,<offset>(sp) | |
+# Where <offset> is a negative value. | |
+# | |
+cflags-y += -fno-stack-check | |
+ | |
# | |
# CPU-dependent compiler/assembler options for optimization. | |
# | |
@@ -298,7 +323,7 @@ OBJCOPYFLAGS += --remove-section=.reginfo | |
head-y := arch/mips/kernel/head.o | |
libs-y += arch/mips/lib/ | |
-libs-y += arch/mips/math-emu/ | |
+libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/ | |
# See arch/mips/Kbuild for content of core part of the kernel | |
core-y += arch/mips/ | |
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c | |
index 730c0b03060d..b816cb4a25ff 100644 | |
--- a/arch/mips/ath79/pci.c | |
+++ b/arch/mips/ath79/pci.c | |
@@ -22,10 +22,10 @@ | |
#include "pci.h" | |
static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); | |
-static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; | |
-static unsigned ath79_pci_nr_irqs __initdata; | |
+static const struct ath79_pci_irq *ath79_pci_irq_map; | |
+static unsigned ath79_pci_nr_irqs; | |
-static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { | |
+static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { | |
{ | |
.slot = 17, | |
.pin = 1, | |
@@ -41,7 +41,7 @@ static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { | |
} | |
}; | |
-static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { | |
+static const struct ath79_pci_irq ar724x_pci_irq_map[] = { | |
{ | |
.slot = 0, | |
.pin = 1, | |
@@ -49,7 +49,7 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { | |
} | |
}; | |
-static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { | |
+static const struct ath79_pci_irq qca955x_pci_irq_map[] = { | |
{ | |
.bus = 0, | |
.slot = 0, | |
@@ -64,7 +64,7 @@ static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { | |
}, | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |
{ | |
int irq = -1; | |
int i; | |
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile | |
index 3e93eea5a5f5..5a25767c048d 100644 | |
--- a/arch/mips/boot/compressed/Makefile | |
+++ b/arch/mips/boot/compressed/Makefile | |
@@ -23,7 +23,8 @@ KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//") | |
KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) | |
KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \ | |
- -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" | |
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \ | |
+ -D__ZBOOT__ | |
KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ | |
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ | |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c | |
index 256fe6f65cf2..80c0706e74bb 100644 | |
--- a/arch/mips/cavium-octeon/smp.c | |
+++ b/arch/mips/cavium-octeon/smp.c | |
@@ -184,7 +184,7 @@ static void __init octeon_smp_setup(void) | |
* Firmware CPU startup hook | |
* | |
*/ | |
-static void octeon_boot_secondary(int cpu, struct task_struct *idle) | |
+static int octeon_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
int count; | |
@@ -202,8 +202,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) | |
udelay(1); | |
count--; | |
} | |
- if (count == 0) | |
+ if (count == 0) { | |
pr_err("Secondary boot timeout\n"); | |
+ return -ETIMEDOUT; | |
+ } | |
+ | |
+ return 0; | |
} | |
/** | |
@@ -272,7 +276,6 @@ static int octeon_cpu_disable(void) | |
set_cpu_online(cpu, false); | |
calculate_cpu_foreign_map(); | |
- cpumask_clear_cpu(cpu, &cpu_callin_map); | |
octeon_fixup_irqs(); | |
__flush_cache_all(); | |
@@ -390,7 +393,7 @@ late_initcall(register_cavium_notifier); | |
#endif /* CONFIG_HOTPLUG_CPU */ | |
-struct plat_smp_ops octeon_smp_ops = { | |
+const struct plat_smp_ops octeon_smp_ops = { | |
.send_ipi_single = octeon_send_ipi_single, | |
.send_ipi_mask = octeon_send_ipi_mask, | |
.init_secondary = octeon_init_secondary, | |
@@ -467,7 +470,7 @@ static void octeon_78xx_send_ipi_mask(const struct cpumask *mask, | |
octeon_78xx_send_ipi_single(cpu, action); | |
} | |
-static struct plat_smp_ops octeon_78xx_smp_ops = { | |
+static const struct plat_smp_ops octeon_78xx_smp_ops = { | |
.send_ipi_single = octeon_78xx_send_ipi_single, | |
.send_ipi_mask = octeon_78xx_send_ipi_mask, | |
.init_secondary = octeon_init_secondary, | |
@@ -483,7 +486,7 @@ static struct plat_smp_ops octeon_78xx_smp_ops = { | |
void __init octeon_setup_smp(void) | |
{ | |
- struct plat_smp_ops *ops; | |
+ const struct plat_smp_ops *ops; | |
if (octeon_has_feature(OCTEON_FEATURE_CIU3)) | |
ops = &octeon_78xx_smp_ops; | |
diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c | |
index 629b24db0d3a..008555969534 100644 | |
--- a/arch/mips/fw/arc/init.c | |
+++ b/arch/mips/fw/arc/init.c | |
@@ -51,7 +51,7 @@ void __init prom_init(void) | |
#endif | |
#ifdef CONFIG_SGI_IP27 | |
{ | |
- extern struct plat_smp_ops ip27_smp_ops; | |
+ extern const struct plat_smp_ops ip27_smp_ops; | |
register_smp_ops(&ip27_smp_ops); | |
} | |
diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c | |
index 14064bdd91dd..b361ff91a77d 100644 | |
--- a/arch/mips/generic/irq.c | |
+++ b/arch/mips/generic/irq.c | |
@@ -16,15 +16,16 @@ | |
#include <linux/types.h> | |
#include <asm/irq.h> | |
+#include <asm/time.h> | |
int get_c0_fdc_int(void) | |
{ | |
int mips_cpu_fdc_irq; | |
- if (cpu_has_veic) | |
- panic("Unimplemented!"); | |
- else if (gic_present) | |
+ if (gic_present) | |
mips_cpu_fdc_irq = gic_get_c0_fdc_int(); | |
+ else if (cpu_has_veic) | |
+ panic("Unimplemented!"); | |
else if (cp0_fdc_irq >= 0) | |
mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; | |
else | |
@@ -37,10 +38,10 @@ int get_c0_perfcount_int(void) | |
{ | |
int mips_cpu_perf_irq; | |
- if (cpu_has_veic) | |
- panic("Unimplemented!"); | |
- else if (gic_present) | |
+ if (gic_present) | |
mips_cpu_perf_irq = gic_get_c0_perfcount_int(); | |
+ else if (cpu_has_veic) | |
+ panic("Unimplemented!"); | |
else if (cp0_perfcount_irq >= 0) | |
mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | |
else | |
@@ -53,10 +54,10 @@ unsigned int get_c0_compare_int(void) | |
{ | |
int mips_cpu_timer_irq; | |
- if (cpu_has_veic) | |
- panic("Unimplemented!"); | |
- else if (gic_present) | |
+ if (gic_present) | |
mips_cpu_timer_irq = gic_get_c0_compare_int(); | |
+ else if (cpu_has_veic) | |
+ panic("Unimplemented!"); | |
else | |
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h | |
index fa57cef12a46..da1b8718861e 100644 | |
--- a/arch/mips/include/asm/bitops.h | |
+++ b/arch/mips/include/asm/bitops.h | |
@@ -456,6 +456,7 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long * | |
{ | |
smp_mb__before_llsc(); | |
__clear_bit(nr, addr); | |
+ nudge_writes(); | |
} | |
/* | |
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h | |
index 23f55af7d6ba..a564915fddc4 100644 | |
--- a/arch/mips/include/asm/bmips.h | |
+++ b/arch/mips/include/asm/bmips.h | |
@@ -48,8 +48,8 @@ | |
#include <asm/r4kcache.h> | |
#include <asm/smp-ops.h> | |
-extern struct plat_smp_ops bmips43xx_smp_ops; | |
-extern struct plat_smp_ops bmips5000_smp_ops; | |
+extern const struct plat_smp_ops bmips43xx_smp_ops; | |
+extern const struct plat_smp_ops bmips5000_smp_ops; | |
static inline int register_bmips_smp_ops(void) | |
{ | |
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h | |
index 4812d1fed0c2..d687b40b9fbb 100644 | |
--- a/arch/mips/include/asm/cacheflush.h | |
+++ b/arch/mips/include/asm/cacheflush.h | |
@@ -25,7 +25,6 @@ | |
* | |
* MIPS specific flush operations: | |
* | |
- * - flush_cache_sigtramp() flush signal trampoline | |
* - flush_icache_all() flush the entire instruction cache | |
* - flush_data_cache_page() flushes a page from the data cache | |
* - __flush_icache_user_range(start, end) flushes range of user instructions | |
@@ -110,7 +109,6 @@ extern void copy_from_user_page(struct vm_area_struct *vma, | |
struct page *page, unsigned long vaddr, void *dst, const void *src, | |
unsigned long len); | |
-extern void (*flush_cache_sigtramp)(unsigned long addr); | |
extern void (*flush_icache_all)(void); | |
extern void (*local_flush_data_cache_page)(void * addr); | |
extern void (*flush_data_cache_page)(unsigned long addr); | |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h | |
index e961c8a7ea66..c9d245dcddc7 100644 | |
--- a/arch/mips/include/asm/cpu-features.h | |
+++ b/arch/mips/include/asm/cpu-features.h | |
@@ -181,9 +181,6 @@ | |
#ifndef cpu_has_pindexed_dcache | |
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) | |
#endif | |
-#ifndef cpu_has_local_ebase | |
-#define cpu_has_local_ebase 1 | |
-#endif | |
/* | |
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors | |
diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h | |
index 5b9ed1bffdbc..52f11bc3edb9 100644 | |
--- a/arch/mips/include/asm/dma.h | |
+++ b/arch/mips/include/asm/dma.h | |
@@ -86,6 +86,9 @@ | |
#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28) | |
/* don't care; ISA bus master won't work, ISA slave DMA supports 32bit addr */ | |
#define MAX_DMA_ADDRESS PAGE_OFFSET | |
+#elif defined(CONFIG_MIPS_L2_CACHE_ER35) | |
+/* Allocate low memory to DMA */ | |
+#define MAX_DMA_ADDRESS (PAGE_OFFSET + CONFIG_ZONE_DMA_SIZE) | |
#else | |
#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) | |
#endif | |
diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h | |
index a6e067801f23..d388fbe3bfbd 100644 | |
--- a/arch/mips/include/asm/dsemul.h | |
+++ b/arch/mips/include/asm/dsemul.h | |
@@ -41,6 +41,7 @@ struct task_struct; | |
extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, | |
unsigned long branch_pc, unsigned long cont_pc); | |
+#ifdef CONFIG_MIPS_FPU_EMULATOR | |
/** | |
* do_dsemulret() - Return from a delay slot 'emulation' frame | |
* @xcp: User thread register context. | |
@@ -88,5 +89,27 @@ extern bool dsemul_thread_rollback(struct pt_regs *regs); | |
* before @mm is freed in order to avoid memory leaks. | |
*/ | |
extern void dsemul_mm_cleanup(struct mm_struct *mm); | |
+#else | |
+static inline bool do_dsemulret(struct pt_regs *xcp) | |
+{ | |
+ return false; | |
+} | |
+ | |
+static inline bool dsemul_thread_cleanup(struct task_struct *tsk) | |
+{ | |
+ return false; | |
+} | |
+ | |
+static inline bool dsemul_thread_rollback(struct pt_regs *regs) | |
+{ | |
+ return false; | |
+} | |
+ | |
+static inline void dsemul_mm_cleanup(struct mm_struct *mm) | |
+{ | |
+ | |
+} | |
+ | |
+#endif | |
#endif /* __MIPS_ASM_DSEMUL_H__ */ | |
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h | |
index f06f97bd62df..f41f2387b9c5 100644 | |
--- a/arch/mips/include/asm/fpu.h | |
+++ b/arch/mips/include/asm/fpu.h | |
@@ -227,8 +227,10 @@ static inline int init_fpu(void) | |
/* Restore FRE */ | |
write_c0_config5(config5); | |
enable_fpu_hazard(); | |
- } else | |
+ } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) | |
fpu_emulator_init_fpu(); | |
+ else | |
+ ret = SIGILL; | |
return ret; | |
} | |
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h | |
index c05369e0b8d6..966891f71be2 100644 | |
--- a/arch/mips/include/asm/fpu_emulator.h | |
+++ b/arch/mips/include/asm/fpu_emulator.h | |
@@ -30,6 +30,7 @@ | |
#include <asm/local.h> | |
#include <asm/processor.h> | |
+#ifdef CONFIG_MIPS_FPU_EMULATOR | |
#ifdef CONFIG_DEBUG_FS | |
struct mips_fpu_emulator_stats { | |
@@ -63,6 +64,16 @@ do { \ | |
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | |
struct mips_fpu_struct *ctx, int has_fpu, | |
void *__user *fault_addr); | |
+#else /* no CONFIG_MIPS_FPU_EMULATOR */ | |
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp, | |
+ struct mips_fpu_struct *ctx, int has_fpu, | |
+ void *__user *fault_addr) | |
+{ | |
+ *fault_addr = NULL; | |
+ return SIGILL; /* we don't speak MIPS FPU */ | |
+} | |
+#endif /* CONFIG_MIPS_FPU_EMULATOR */ | |
+ | |
void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, | |
struct task_struct *tsk); | |
int process_fpemu_return(int sig, void __user *fault_addr, | |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h | |
new file mode 100644 | |
index 000000000000..0aac7d6f2a16 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/gic.h | |
@@ -0,0 +1,383 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc. | |
+ * | |
+ * GIC Register Definitions | |
+ * | |
+ */ | |
+#ifndef _ASM_GICREGS_H | |
+#define _ASM_GICREGS_H | |
+ | |
+#include <linux/bitmap.h> | |
+#include <linux/threads.h> | |
+ | |
+#include <irq.h> | |
+ | |
+#undef GICISBYTELITTLEENDIAN | |
+ | |
+/* Constants */ | |
+#define GIC_POL_POS 1 | |
+#define GIC_POL_NEG 0 | |
+#define GIC_TRIG_EDGE 1 | |
+#define GIC_TRIG_LEVEL 0 | |
+ | |
+#define MSK(n) ((1 << (n)) - 1) | |
+#define REG32(addr) (*(volatile unsigned int *) (addr)) | |
+#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) | |
+#define REGP(base, phys) REG32((unsigned long)(base) + (phys)) | |
+ | |
+/* Accessors */ | |
+#define GIC_REG(segment, offset) \ | |
+ REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | |
+#define GIC_REG_ADDR(segment, offset) \ | |
+ REG32(_gic_base + segment##_##SECTION_OFS + offset) | |
+ | |
+#define GIC_ABS_REG(segment, offset) \ | |
+ (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | |
+#define GIC_REG_ABS_ADDR(segment, offset) \ | |
+ (_gic_base + segment##_##SECTION_OFS + offset) | |
+ | |
+#ifdef GICISBYTELITTLEENDIAN | |
+#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) | |
+#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) | |
+#else | |
+#define GICREAD(reg, data) ((data) = (reg)) | |
+#define GICWRITE(reg, data) ((reg) = (data)) | |
+#endif | |
+#define GICBIS(reg, mask, bits) \ | |
+ do { u32 data; \ | |
+ GICREAD(reg, data); \ | |
+ data &= ~(mask); \ | |
+ data |= ((bits) & (mask)); \ | |
+ GICWRITE((reg), data); \ | |
+ } while (0) | |
+ | |
+ | |
+/* GIC Address Space */ | |
+#define SHARED_SECTION_OFS 0x0000 | |
+#define SHARED_SECTION_SIZE 0x8000 | |
+#define VPE_LOCAL_SECTION_OFS 0x8000 | |
+#define VPE_LOCAL_SECTION_SIZE 0x4000 | |
+#define VPE_OTHER_SECTION_OFS 0xc000 | |
+#define VPE_OTHER_SECTION_SIZE 0x4000 | |
+#define USM_VISIBLE_SECTION_OFS 0x10000 | |
+#define USM_VISIBLE_SECTION_SIZE 0x10000 | |
+ | |
+/* Register Map for Shared Section */ | |
+ | |
+#define GIC_SH_CONFIG_OFS 0x0000 | |
+ | |
+/* Shared Global Counter */ | |
+#define GIC_SH_COUNTER_31_00_OFS 0x0010 | |
+#define GIC_SH_COUNTER_63_32_OFS 0x0014 | |
+#define GIC_SH_REVISIONID_OFS 0x0020 | |
+ | |
+/* Interrupt Polarity */ | |
+#define GIC_SH_POL_31_0_OFS 0x0100 | |
+#define GIC_SH_POL_63_32_OFS 0x0104 | |
+#define GIC_SH_POL_95_64_OFS 0x0108 | |
+#define GIC_SH_POL_127_96_OFS 0x010c | |
+#define GIC_SH_POL_159_128_OFS 0x0110 | |
+#define GIC_SH_POL_191_160_OFS 0x0114 | |
+#define GIC_SH_POL_223_192_OFS 0x0118 | |
+#define GIC_SH_POL_255_224_OFS 0x011c | |
+ | |
+/* Edge/Level Triggering */ | |
+#define GIC_SH_TRIG_31_0_OFS 0x0180 | |
+#define GIC_SH_TRIG_63_32_OFS 0x0184 | |
+#define GIC_SH_TRIG_95_64_OFS 0x0188 | |
+#define GIC_SH_TRIG_127_96_OFS 0x018c | |
+#define GIC_SH_TRIG_159_128_OFS 0x0190 | |
+#define GIC_SH_TRIG_191_160_OFS 0x0194 | |
+#define GIC_SH_TRIG_223_192_OFS 0x0198 | |
+#define GIC_SH_TRIG_255_224_OFS 0x019c | |
+ | |
+/* Dual Edge Triggering */ | |
+#define GIC_SH_DUAL_31_0_OFS 0x0200 | |
+#define GIC_SH_DUAL_63_32_OFS 0x0204 | |
+#define GIC_SH_DUAL_95_64_OFS 0x0208 | |
+#define GIC_SH_DUAL_127_96_OFS 0x020c | |
+#define GIC_SH_DUAL_159_128_OFS 0x0210 | |
+#define GIC_SH_DUAL_191_160_OFS 0x0214 | |
+#define GIC_SH_DUAL_223_192_OFS 0x0218 | |
+#define GIC_SH_DUAL_255_224_OFS 0x021c | |
+ | |
+/* Set/Clear corresponding bit in Edge Detect Register */ | |
+#define GIC_SH_WEDGE_OFS 0x0280 | |
+ | |
+/* Reset Mask - Disables Interrupt */ | |
+#define GIC_SH_RMASK_31_0_OFS 0x0300 | |
+#define GIC_SH_RMASK_63_32_OFS 0x0304 | |
+#define GIC_SH_RMASK_95_64_OFS 0x0308 | |
+#define GIC_SH_RMASK_127_96_OFS 0x030c | |
+#define GIC_SH_RMASK_159_128_OFS 0x0310 | |
+#define GIC_SH_RMASK_191_160_OFS 0x0314 | |
+#define GIC_SH_RMASK_223_192_OFS 0x0318 | |
+#define GIC_SH_RMASK_255_224_OFS 0x031c | |
+ | |
+/* Set Mask (WO) - Enables Interrupt */ | |
+#define GIC_SH_SMASK_31_0_OFS 0x0380 | |
+#define GIC_SH_SMASK_63_32_OFS 0x0384 | |
+#define GIC_SH_SMASK_95_64_OFS 0x0388 | |
+#define GIC_SH_SMASK_127_96_OFS 0x038c | |
+#define GIC_SH_SMASK_159_128_OFS 0x0390 | |
+#define GIC_SH_SMASK_191_160_OFS 0x0394 | |
+#define GIC_SH_SMASK_223_192_OFS 0x0398 | |
+#define GIC_SH_SMASK_255_224_OFS 0x039c | |
+ | |
+/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ | |
+#define GIC_SH_MASK_31_0_OFS 0x0400 | |
+#define GIC_SH_MASK_63_32_OFS 0x0404 | |
+#define GIC_SH_MASK_95_64_OFS 0x0408 | |
+#define GIC_SH_MASK_127_96_OFS 0x040c | |
+#define GIC_SH_MASK_159_128_OFS 0x0410 | |
+#define GIC_SH_MASK_191_160_OFS 0x0414 | |
+#define GIC_SH_MASK_223_192_OFS 0x0418 | |
+#define GIC_SH_MASK_255_224_OFS 0x041c | |
+ | |
+/* Pending Global Interrupts (RO) */ | |
+#define GIC_SH_PEND_31_0_OFS 0x0480 | |
+#define GIC_SH_PEND_63_32_OFS 0x0484 | |
+#define GIC_SH_PEND_95_64_OFS 0x0488 | |
+#define GIC_SH_PEND_127_96_OFS 0x048c | |
+#define GIC_SH_PEND_159_128_OFS 0x0490 | |
+#define GIC_SH_PEND_191_160_OFS 0x0494 | |
+#define GIC_SH_PEND_223_192_OFS 0x0498 | |
+#define GIC_SH_PEND_255_224_OFS 0x049c | |
+ | |
+#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 | |
+ | |
+/* Maps Interrupt X to a Pin */ | |
+#define GIC_SH_MAP_TO_PIN(intr) \ | |
+ (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) | |
+ | |
+#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 | |
+ | |
+/* Maps Interrupt X to a VPE */ | |
+#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ | |
+ (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) | |
+#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) | |
+ | |
+/* Convert an interrupt number to a byte offset/bit for multi-word registers */ | |
+#define GIC_INTR_OFS(intr) (((intr) / 32)*4) | |
+#define GIC_INTR_BIT(intr) ((intr) % 32) | |
+ | |
+/* Polarity : Reset Value is always 0 */ | |
+#define GIC_SH_SET_POLARITY_OFS 0x0100 | |
+#define GIC_SET_POLARITY(intr, pol) \ | |
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ | |
+ GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | |
+ (pol) << GIC_INTR_BIT(intr)) | |
+ | |
+/* Triggering : Reset Value is always 0 */ | |
+#define GIC_SH_SET_TRIGGER_OFS 0x0180 | |
+#define GIC_SET_TRIGGER(intr, trig) \ | |
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ | |
+ GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | |
+ (trig) << GIC_INTR_BIT(intr)) | |
+ | |
+/* Mask manipulation */ | |
+#define GIC_SH_SMASK_OFS 0x0380 | |
+#define GIC_SET_INTR_MASK(intr) \ | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ | |
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | |
+#define GIC_SH_RMASK_OFS 0x0300 | |
+#define GIC_CLR_INTR_MASK(intr) \ | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ | |
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | |
+ | |
+/* Register Map for Local Section */ | |
+#define GIC_VPE_CTL_OFS 0x0000 | |
+#define GIC_VPE_PEND_OFS 0x0004 | |
+#define GIC_VPE_MASK_OFS 0x0008 | |
+#define GIC_VPE_RMASK_OFS 0x000c | |
+#define GIC_VPE_SMASK_OFS 0x0010 | |
+#define GIC_VPE_WD_MAP_OFS 0x0040 | |
+#define GIC_VPE_COMPARE_MAP_OFS 0x0044 | |
+#define GIC_VPE_TIMER_MAP_OFS 0x0048 | |
+#define GIC_VPE_PERFCTR_MAP_OFS 0x0050 | |
+#define GIC_VPE_SWINT0_MAP_OFS 0x0054 | |
+#define GIC_VPE_SWINT1_MAP_OFS 0x0058 | |
+#define GIC_VPE_OTHER_ADDR_OFS 0x0080 | |
+#define GIC_VP_IDENT_OFS 0x0088 | |
+#define GIC_VPE_WD_CONFIG0_OFS 0x0090 | |
+#define GIC_VPE_WD_COUNT0_OFS 0x0094 | |
+#define GIC_VPE_WD_INITIAL0_OFS 0x0098 | |
+#define GIC_VPE_COMPARE_LO_OFS 0x00a0 | |
+#define GIC_VPE_COMPARE_HI_OFS 0x00a4 | |
+ | |
+#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | |
+#define GIC_VPE_EIC_SS(intr) \ | |
+ (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) | |
+ | |
+#define GIC_VPE_EIC_VEC_BASE 0x0800 | |
+#define GIC_VPE_EIC_VEC(intr) \ | |
+ (GIC_VPE_EIC_VEC_BASE + (4 * intr)) | |
+ | |
+#define GIC_VPE_TENABLE_NMI_OFS 0x1000 | |
+#define GIC_VPE_TENABLE_YQ_OFS 0x1004 | |
+#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 | |
+#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 | |
+ | |
+/* User Mode Visible Section Register Map */ | |
+#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 | |
+#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 | |
+ | |
+/* Masks */ | |
+#define GIC_SH_CONFIG_COUNTSTOP_SHF 28 | |
+#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) | |
+ | |
+#define GIC_SH_CONFIG_COUNTBITS_SHF 24 | |
+#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF) | |
+ | |
+#define GIC_SH_CONFIG_NUMINTRS_SHF 16 | |
+#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF) | |
+ | |
+#define GIC_SH_CONFIG_NUMVPES_SHF 0 | |
+#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) | |
+ | |
+#define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) | |
+#define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) | |
+ | |
+#define GIC_MAP_TO_PIN_SHF 31 | |
+#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) | |
+#define GIC_MAP_TO_NMI_SHF 30 | |
+#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF) | |
+#define GIC_MAP_TO_YQ_SHF 29 | |
+#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF) | |
+#define GIC_MAP_SHF 0 | |
+#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) | |
+ | |
+/* GIC_VPE_CTL Masks */ | |
+#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 | |
+#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) | |
+#define GIC_VPE_CTL_TIMER_RTBL_SHF 1 | |
+#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF) | |
+#define GIC_VPE_CTL_EIC_MODE_SHF 0 | |
+#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF) | |
+ | |
+/* GIC_VPE_PEND Masks */ | |
+#define GIC_VPE_PEND_WD_SHF 0 | |
+#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF) | |
+#define GIC_VPE_PEND_CMP_SHF 1 | |
+#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF) | |
+#define GIC_VPE_PEND_TIMER_SHF 2 | |
+#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF) | |
+#define GIC_VPE_PEND_PERFCOUNT_SHF 3 | |
+#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF) | |
+#define GIC_VPE_PEND_SWINT0_SHF 4 | |
+#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF) | |
+#define GIC_VPE_PEND_SWINT1_SHF 5 | |
+#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF) | |
+ | |
+/* GIC_VPE_RMASK Masks */ | |
+#define GIC_VPE_RMASK_WD_SHF 0 | |
+#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF) | |
+#define GIC_VPE_RMASK_CMP_SHF 1 | |
+#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF) | |
+#define GIC_VPE_RMASK_TIMER_SHF 2 | |
+#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF) | |
+#define GIC_VPE_RMASK_PERFCNT_SHF 3 | |
+#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF) | |
+#define GIC_VPE_RMASK_SWINT0_SHF 4 | |
+#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF) | |
+#define GIC_VPE_RMASK_SWINT1_SHF 5 | |
+#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF) | |
+ | |
+/* GIC_VPE_SMASK Masks */ | |
+#define GIC_VPE_SMASK_WD_SHF 0 | |
+#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF) | |
+#define GIC_VPE_SMASK_CMP_SHF 1 | |
+#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF) | |
+#define GIC_VPE_SMASK_TIMER_SHF 2 | |
+#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF) | |
+#define GIC_VPE_SMASK_PERFCNT_SHF 3 | |
+#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF) | |
+#define GIC_VPE_SMASK_SWINT0_SHF 4 | |
+#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF) | |
+#define GIC_VPE_SMASK_SWINT1_SHF 5 | |
+#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) | |
+ | |
+/* GIC_VP_IDENT fields */ | |
+#define GIC_VP_IDENT_VCNUM_SHF 0 | |
+#define GIC_VP_IDENT_VCNUM_MSK (MSK(6) << GIC_VP_IDENT_VCNUM_SHF) | |
+ | |
+/* | |
+ * Set the Mapping of Interrupt X to a VPE. | |
+ */ | |
+#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ | |
+ GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) | |
+ | |
+/* | |
+ * Interrupt Meta-data specification. The ipiflag helps | |
+ * in building ipi_map. | |
+ */ | |
+struct gic_intr_map { | |
+ unsigned int cpunum; /* Directed to this CPU */ | |
+#define GIC_UNUSED 0xdead /* Dummy data */ | |
+ unsigned int pin; /* Directed to this Pin */ | |
+ unsigned int polarity; /* Polarity : +/- */ | |
+ unsigned int trigtype; /* Trigger : Edge/Levl */ | |
+ unsigned int flags; /* Misc flags */ | |
+#define GIC_FLAG_TRANSPARENT 0x01 | |
+#define GIC_FLAG_PERCPU 0x04 | |
+}; | |
+ | |
+/* | |
+ * This is only used in EIC mode. This helps to figure out which | |
+ * shared interrupts we need to process when we get a vector interrupt. | |
+ */ | |
+struct gic_shared_intr_map { | |
+ unsigned int shared_intr_flags; | |
+ unsigned int shared_intr_list[NR_CPUS]; | |
+ unsigned int local_intr_mask; | |
+}; | |
+ | |
+/* GIC nomenclature for Core Interrupt Pins. */ | |
+#define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | |
+#define GIC_CPU_INT1 1 /* . */ | |
+#define GIC_CPU_INT2 2 /* . */ | |
+#define GIC_CPU_INT3 3 /* . */ | |
+#define GIC_CPU_INT4 4 /* . */ | |
+#define GIC_CPU_INT5 5 /* Core Interrupt 7 */ | |
+ | |
+/* Local GIC interrupts. */ | |
+#define GIC_INT_TMR (GIC_CPU_INT5) | |
+#define GIC_INT_PERFCTR (GIC_CPU_INT5) | |
+ | |
+/* Add 2 to convert GIC CPU pin to core interrupt */ | |
+#define GIC_CPU_PIN_OFFSET 2 | |
+ | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+/* EN7516/7527/7528 GIC pins shifted by 1, pin_offset must be 0 */ | |
+#define GIC_CPU_TO_VEC_OFFSET (1) | |
+#else | |
+/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ | |
+#define GIC_CPU_TO_VEC_OFFSET (2) | |
+#endif | |
+ | |
+/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | |
+#define GIC_PIN_TO_VEC_OFFSET (1) | |
+ | |
+#include <linux/irq.h> | |
+ | |
+extern unsigned int gic_present; | |
+extern unsigned int gic_irq_base; | |
+extern unsigned long _gic_base; | |
+ | |
+void gic_init(unsigned long gic_base_addr, | |
+ unsigned long gic_addrspace_size, | |
+ const struct gic_intr_map *intrmap, | |
+ unsigned int intrmap_size, | |
+ unsigned int irqbase); | |
+ | |
+int gic_get_usm_range(struct resource *gic_usm_res); | |
+unsigned gic_read_local_vp_id(void); | |
+void gic_irq_dispatch(void); | |
+void gic_platform_init(int irqs, struct irq_chip *irq_controller); | |
+ | |
+#endif /* _ASM_GICREGS_H */ | |
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h | |
index 64f2500d891b..279b6d14ffeb 100644 | |
--- a/arch/mips/include/asm/highmem.h | |
+++ b/arch/mips/include/asm/highmem.h | |
@@ -25,9 +25,6 @@ | |
#include <asm/cpu-features.h> | |
#include <asm/kmap_types.h> | |
-/* undef for production */ | |
-#define HIGHMEM_DEBUG 1 | |
- | |
/* declarations for highmem.c */ | |
extern unsigned long highstart_pfn, highend_pfn; | |
@@ -38,7 +35,12 @@ extern pte_t *pkmap_page_table; | |
* easily, subsequent pte tables have to be allocated in one physical | |
* chunk of RAM. | |
*/ | |
+#ifdef CONFIG_PHYS_ADDR_T_64BIT | |
+#define LAST_PKMAP 512 | |
+#else | |
#define LAST_PKMAP 1024 | |
+#endif | |
+ | |
#define LAST_PKMAP_MASK (LAST_PKMAP-1) | |
#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) | |
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | |
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h | |
index 5dfae80264b9..408d8722ae1c 100644 | |
--- a/arch/mips/include/asm/io.h | |
+++ b/arch/mips/include/asm/io.h | |
@@ -297,7 +297,7 @@ static inline void iounmap(const volatile void __iomem *addr) | |
#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT) | |
#define war_io_reorder_wmb() wmb() | |
#else | |
-#define war_io_reorder_wmb() do { } while (0) | |
+#define war_io_reorder_wmb() barrier() | |
#endif | |
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ | |
@@ -367,6 +367,8 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ | |
BUG(); \ | |
} \ | |
\ | |
+ /* prevent prefetching of coherent DMA data prematurely */ \ | |
+ rmb(); \ | |
return pfx##ioswab##bwlq(__mem, __val); \ | |
} | |
diff --git a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h | |
index 21eae03d752a..c3395fa97c3f 100644 | |
--- a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h | |
+++ b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h | |
@@ -35,7 +35,6 @@ | |
#define cpu_has_vtag_icache 0 | |
#define cpu_has_ic_fills_f_dc 0 | |
#define cpu_has_pindexed_dcache 0 | |
-#define cpu_has_local_ebase 0 | |
#define cpu_icache_snoops_remote_store 1 | |
#define cpu_has_mips_4 0 | |
#define cpu_has_mips_5 0 | |
diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h | |
index 89328a3d44d8..f5cb3301e0ce 100644 | |
--- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h | |
+++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h | |
@@ -42,7 +42,6 @@ | |
#define cpu_has_vint 0 | |
#define cpu_has_vtag_icache 0 | |
#define cpu_has_watch 1 | |
-#define cpu_has_local_ebase 0 | |
#ifdef CONFIG_CPU_LOONGSON3 | |
#define cpu_has_wsbh 1 | |
diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h | |
index c68c0cc879c6..d0ae5d55413b 100644 | |
--- a/arch/mips/include/asm/mach-loongson64/loongson.h | |
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h | |
@@ -26,7 +26,7 @@ extern void mach_prepare_shutdown(void); | |
/* environment arguments from bootloader */ | |
extern u32 cpu_clock_freq; | |
extern u32 memsize, highmemsize; | |
-extern struct plat_smp_ops loongson3_smp_ops; | |
+extern const struct plat_smp_ops loongson3_smp_ops; | |
/* loongson-specific command line, env and memory initialization */ | |
extern void __init prom_init_memory(void); | |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h | |
index df78b2ca70eb..3ff9bbe0de07 100644 | |
--- a/arch/mips/include/asm/mipsregs.h | |
+++ b/arch/mips/include/asm/mipsregs.h | |
@@ -1612,6 +1612,9 @@ do { \ | |
#define read_c0_taglo() __read_32bit_c0_register($28, 0) | |
#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) | |
+#define read_c0_idatalo() __read_32bit_c0_register($28, 1) | |
+#define write_c0_idatalo(val) __write_32bit_c0_register($28, 1, val) | |
+ | |
#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) | |
#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) | |
@@ -1624,6 +1627,9 @@ do { \ | |
#define read_c0_taghi() __read_32bit_c0_register($29, 0) | |
#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) | |
+#define read_c0_idatahi() __read_32bit_c0_register($29, 1) | |
+#define write_c0_idatahi(val) __write_32bit_c0_register($29, 1, val) | |
+ | |
#define read_c0_errorepc() __read_ulong_c0_register($30, 0) | |
#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) | |
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h | |
index 702c273e67a9..1d4f3b37cefe 100644 | |
--- a/arch/mips/include/asm/module.h | |
+++ b/arch/mips/include/asm/module.h | |
@@ -11,6 +11,11 @@ struct mod_arch_specific { | |
const struct exception_table_entry *dbe_start; | |
const struct exception_table_entry *dbe_end; | |
struct mips_hi16 *r_mips_hi16_list; | |
+ | |
+ void *phys_plt_tbl; | |
+ void *virt_plt_tbl; | |
+ unsigned int phys_plt_offset; | |
+ unsigned int virt_plt_offset; | |
}; | |
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ | |
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h | |
index be52c2125d71..f1a301765066 100644 | |
--- a/arch/mips/include/asm/netlogic/common.h | |
+++ b/arch/mips/include/asm/netlogic/common.h | |
@@ -84,7 +84,7 @@ nlm_set_nmi_handler(void *handler) | |
*/ | |
void nlm_init_boot_cpu(void); | |
unsigned int nlm_get_cpu_frequency(void); | |
-extern struct plat_smp_ops nlm_smp_ops; | |
+extern const struct plat_smp_ops nlm_smp_ops; | |
extern char nlm_reset_entry[], nlm_reset_entry_end[]; | |
/* SWIOTLB */ | |
diff --git a/arch/mips/include/asm/pbus-timer.h b/arch/mips/include/asm/pbus-timer.h | |
new file mode 100644 | |
index 000000000000..0fe0f7f7e6e6 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/pbus-timer.h | |
@@ -0,0 +1,25 @@ | |
+#ifndef _ASM_PBUS_TIMER_H | |
+#define _ASM_PBUS_TIMER_H | |
+ | |
+enum pbus_timer_mode { | |
+ PBUS_TIMER_MODE_INTERVAL, | |
+ PBUS_TIMER_MODE_PERIODIC, | |
+ PBUS_TIMER_MODE_WATCHDOG | |
+}; | |
+ | |
+static bool pbus_timer_enable(const unsigned int n, | |
+ const unsigned int interval_ms, | |
+ const enum pbus_timer_mode mode); | |
+ | |
+static void pbus_timer_disable(const unsigned int n); | |
+ | |
+static void pbus_timer_restart(const unsigned int n); | |
+ | |
+static void pbus_timer_int_ack(const unsigned int n); | |
+ | |
+static unsigned int pbus_timer_get(const unsigned int n); | |
+ | |
+#include <pbus-timer.h> | |
+ | |
+#endif /* _ASM_PBUS_TIMER_H */ | |
+ | |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h | |
index 30d1129d8624..01e2a984922e 100644 | |
--- a/arch/mips/include/asm/pci.h | |
+++ b/arch/mips/include/asm/pci.h | |
@@ -39,7 +39,6 @@ struct pci_controller { | |
unsigned long io_offset; | |
unsigned long io_map_base; | |
struct resource *busn_resource; | |
- unsigned long busn_offset; | |
#ifndef CONFIG_PCI_DOMAINS_GENERIC | |
unsigned int index; | |
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h | |
index 667ca3c467b7..7f48c2b311c4 100644 | |
--- a/arch/mips/include/asm/r4kcache.h | |
+++ b/arch/mips/include/asm/r4kcache.h | |
@@ -48,58 +48,14 @@ extern void (*r4k_blast_icache)(void); | |
: \ | |
: "i" (op), "R" (*(unsigned char *)(addr))) | |
-#ifdef CONFIG_MIPS_MT | |
- | |
-#define __iflush_prologue \ | |
- unsigned long redundance; \ | |
- extern int mt_n_iflushes; \ | |
- for (redundance = 0; redundance < mt_n_iflushes; redundance++) { | |
- | |
-#define __iflush_epilogue \ | |
- } | |
- | |
-#define __dflush_prologue \ | |
- unsigned long redundance; \ | |
- extern int mt_n_dflushes; \ | |
- for (redundance = 0; redundance < mt_n_dflushes; redundance++) { | |
- | |
-#define __dflush_epilogue \ | |
- } | |
- | |
-#define __inv_dflush_prologue __dflush_prologue | |
-#define __inv_dflush_epilogue __dflush_epilogue | |
-#define __sflush_prologue { | |
-#define __sflush_epilogue } | |
-#define __inv_sflush_prologue __sflush_prologue | |
-#define __inv_sflush_epilogue __sflush_epilogue | |
- | |
-#else /* CONFIG_MIPS_MT */ | |
- | |
-#define __iflush_prologue { | |
-#define __iflush_epilogue } | |
-#define __dflush_prologue { | |
-#define __dflush_epilogue } | |
-#define __inv_dflush_prologue { | |
-#define __inv_dflush_epilogue } | |
-#define __sflush_prologue { | |
-#define __sflush_epilogue } | |
-#define __inv_sflush_prologue { | |
-#define __inv_sflush_epilogue } | |
- | |
-#endif /* CONFIG_MIPS_MT */ | |
- | |
static inline void flush_icache_line_indexed(unsigned long addr) | |
{ | |
- __iflush_prologue | |
cache_op(Index_Invalidate_I, addr); | |
- __iflush_epilogue | |
} | |
static inline void flush_dcache_line_indexed(unsigned long addr) | |
{ | |
- __dflush_prologue | |
cache_op(Index_Writeback_Inv_D, addr); | |
- __dflush_epilogue | |
} | |
static inline void flush_scache_line_indexed(unsigned long addr) | |
@@ -109,31 +65,27 @@ static inline void flush_scache_line_indexed(unsigned long addr) | |
static inline void flush_icache_line(unsigned long addr) | |
{ | |
- __iflush_prologue | |
switch (boot_cpu_type()) { | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
case CPU_LOONGSON2: | |
cache_op(Hit_Invalidate_I_Loongson2, addr); | |
break; | |
+#endif | |
default: | |
cache_op(Hit_Invalidate_I, addr); | |
break; | |
} | |
- __iflush_epilogue | |
} | |
static inline void flush_dcache_line(unsigned long addr) | |
{ | |
- __dflush_prologue | |
cache_op(Hit_Writeback_Inv_D, addr); | |
- __dflush_epilogue | |
} | |
static inline void invalidate_dcache_line(unsigned long addr) | |
{ | |
- __dflush_prologue | |
cache_op(Hit_Invalidate_D, addr); | |
- __dflush_epilogue | |
} | |
static inline void invalidate_scache_line(unsigned long addr) | |
@@ -179,9 +131,11 @@ static inline void flush_scache_line(unsigned long addr) | |
static inline void protected_flush_icache_line(unsigned long addr) | |
{ | |
switch (boot_cpu_type()) { | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
case CPU_LOONGSON2: | |
protected_cache_op(Hit_Invalidate_I_Loongson2, addr); | |
break; | |
+#endif | |
default: | |
#ifdef CONFIG_EVA | |
@@ -569,13 +523,9 @@ static inline void extra##blast_##pfx##cache##lsize(void) \ | |
current_cpu_data.desc.waybit; \ | |
unsigned long ws, addr; \ | |
\ | |
- __##pfx##flush_prologue \ | |
- \ | |
for (ws = 0; ws < ws_end; ws += ws_inc) \ | |
for (addr = start; addr < end; addr += lsize * 32) \ | |
cache##lsize##_unroll32(addr|ws, indexop); \ | |
- \ | |
- __##pfx##flush_epilogue \ | |
} \ | |
\ | |
static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \ | |
@@ -583,14 +533,10 @@ static inline void extra##blast_##pfx##cache##lsize##_page(unsigned long page) \ | |
unsigned long start = page; \ | |
unsigned long end = page + PAGE_SIZE; \ | |
\ | |
- __##pfx##flush_prologue \ | |
- \ | |
do { \ | |
cache##lsize##_unroll32(start, hitop); \ | |
start += lsize * 32; \ | |
} while (start < end); \ | |
- \ | |
- __##pfx##flush_epilogue \ | |
} \ | |
\ | |
static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ | |
@@ -603,13 +549,9 @@ static inline void extra##blast_##pfx##cache##lsize##_page_indexed(unsigned long | |
current_cpu_data.desc.waybit; \ | |
unsigned long ws, addr; \ | |
\ | |
- __##pfx##flush_prologue \ | |
- \ | |
for (ws = 0; ws < ws_end; ws += ws_inc) \ | |
for (addr = start; addr < end; addr += lsize * 32) \ | |
cache##lsize##_unroll32(addr|ws, indexop); \ | |
- \ | |
- __##pfx##flush_epilogue \ | |
} | |
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) | |
@@ -639,14 +581,10 @@ static inline void blast_##pfx##cache##lsize##_user_page(unsigned long page) \ | |
unsigned long start = page; \ | |
unsigned long end = page + PAGE_SIZE; \ | |
\ | |
- __##pfx##flush_prologue \ | |
- \ | |
do { \ | |
cache##lsize##_unroll32_user(start, hitop); \ | |
start += lsize * 32; \ | |
} while (start < end); \ | |
- \ | |
- __##pfx##flush_epilogue \ | |
} | |
__BUILD_BLAST_USER_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, | |
@@ -665,19 +603,47 @@ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, | |
unsigned long end) \ | |
{ \ | |
unsigned long lsize = cpu_##desc##_line_size(); \ | |
+ unsigned long lsize_2 = lsize * 2; \ | |
+ unsigned long lsize_3 = lsize * 3; \ | |
+ unsigned long lsize_4 = lsize * 4; \ | |
+ unsigned long lsize_5 = lsize * 5; \ | |
+ unsigned long lsize_6 = lsize * 6; \ | |
+ unsigned long lsize_7 = lsize * 7; \ | |
+ unsigned long lsize_8 = lsize * 8; \ | |
unsigned long addr = start & ~(lsize - 1); \ | |
- unsigned long aend = (end - 1) & ~(lsize - 1); \ | |
+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ | |
+ int lines = (aend - addr) / lsize; \ | |
\ | |
- __##pfx##flush_prologue \ | |
+ while (lines >= 8) { \ | |
+ prot##cache_op(hitop, addr); \ | |
+ prot##cache_op(hitop, addr + lsize); \ | |
+ prot##cache_op(hitop, addr + lsize_2); \ | |
+ prot##cache_op(hitop, addr + lsize_3); \ | |
+ prot##cache_op(hitop, addr + lsize_4); \ | |
+ prot##cache_op(hitop, addr + lsize_5); \ | |
+ prot##cache_op(hitop, addr + lsize_6); \ | |
+ prot##cache_op(hitop, addr + lsize_7); \ | |
+ addr += lsize_8; \ | |
+ lines -= 8; \ | |
+ } \ | |
+ \ | |
+ if (lines & 0x4) { \ | |
+ prot##cache_op(hitop, addr); \ | |
+ prot##cache_op(hitop, addr + lsize); \ | |
+ prot##cache_op(hitop, addr + lsize_2); \ | |
+ prot##cache_op(hitop, addr + lsize_3); \ | |
+ addr += lsize_4; \ | |
+ } \ | |
\ | |
- while (1) { \ | |
+ if (lines & 0x2) { \ | |
prot##cache_op(hitop, addr); \ | |
- if (addr == aend) \ | |
- break; \ | |
- addr += lsize; \ | |
+ prot##cache_op(hitop, addr + lsize); \ | |
+ addr += lsize_2; \ | |
} \ | |
\ | |
- __##pfx##flush_epilogue \ | |
+ if (lines & 0x1) { \ | |
+ prot##cache_op(hitop, addr); \ | |
+ } \ | |
} | |
#ifndef CONFIG_EVA | |
@@ -695,8 +661,6 @@ static inline void protected_blast_##pfx##cache##_range(unsigned long start,\ | |
unsigned long addr = start & ~(lsize - 1); \ | |
unsigned long aend = (end - 1) & ~(lsize - 1); \ | |
\ | |
- __##pfx##flush_prologue \ | |
- \ | |
if (segment_eq(get_fs(), USER_DS)) { \ | |
while (1) { \ | |
protected_cachee_op(hitop, addr); \ | |
@@ -713,7 +677,6 @@ static inline void protected_blast_##pfx##cache##_range(unsigned long start,\ | |
} \ | |
\ | |
} \ | |
- __##pfx##flush_epilogue \ | |
} | |
__BUILD_PROT_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D) | |
diff --git a/arch/mips/include/asm/rt2880/cpu-feature-overrides.h b/arch/mips/include/asm/rt2880/cpu-feature-overrides.h | |
new file mode 100644 | |
index 000000000000..6db2ecfaff15 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/cpu-feature-overrides.h | |
@@ -0,0 +1,83 @@ | |
+/* | |
+ * Ralink specific CPU feature overrides | |
+ * | |
+ * This file was derived from: include/asm-mips/cpu-features.h | |
+ * Copyright (C) 2003, 2004 Ralf Baechle | |
+ * Copyright (C) 2004 Maciej W. Rozycki | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License version 2 as published | |
+ * by the Free Software Foundation. | |
+ * | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_CPU_FEATURE_OVERRIDES_H | |
+#define __ASM_MACH_MIPS_RT2880_CPU_FEATURE_OVERRIDES_H | |
+ | |
+/* CPU options */ | |
+#define cpu_has_tlb 1 | |
+#define cpu_has_4kex 1 | |
+#define cpu_has_3k_cache 0 | |
+#define cpu_has_4k_cache 1 | |
+#define cpu_has_tx39_cache 0 | |
+#define cpu_has_fpu 0 | |
+#define cpu_has_32fpr 0 | |
+#define cpu_has_counter 1 | |
+ | |
+#define cpu_has_watch 1 | |
+#define cpu_has_divec 1 | |
+#define cpu_has_vce 0 | |
+#define cpu_has_cache_cdex_p 0 | |
+#define cpu_has_cache_cdex_s 0 | |
+#define cpu_has_mcheck 1 | |
+#define cpu_has_ejtag 1 | |
+#define cpu_has_nofpuex 0 | |
+ | |
+#define cpu_has_llsc 1 | |
+#define cpu_has_inclusive_pcaches 0 | |
+#define cpu_has_prefetch 1 | |
+//#define cpu_has_vint 1 // do not override, depend from CONFIG_CPU_MIPSR2_IRQ_VI | |
+#define cpu_has_veic 0 | |
+#define cpu_has_userlocal 1 | |
+#define cpu_has_perf_cntr_intr_bit 1 | |
+#define cpu_has_rixi 0 | |
+ | |
+/* CPU ases */ | |
+#define cpu_has_mips16 1 | |
+#define cpu_has_mdmx 0 | |
+#define cpu_has_mips3d 0 | |
+#define cpu_has_smartmips 0 | |
+#define cpu_has_dsp 1 | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#define cpu_has_mipsmt 1 | |
+#else | |
+#define cpu_has_mipsmt 0 | |
+#endif | |
+#define cpu_has_dsp2 0 | |
+#define cpu_has_vz 0 | |
+ | |
+/* CPU ISA level */ | |
+#define cpu_has_mips_2 1 | |
+#define cpu_has_mips_3 0 | |
+#define cpu_has_mips_4 0 | |
+#define cpu_has_mips_5 0 | |
+#define cpu_has_mips32r1 1 | |
+#define cpu_has_mips32r2 1 | |
+#define cpu_has_mips64r1 0 | |
+#define cpu_has_mips64r2 0 | |
+ | |
+#define cpu_has_mips32r6 0 | |
+#define cpu_has_mips64r6 0 | |
+ | |
+#define cpu_has_64bits 0 | |
+#define cpu_has_64bit_zero_reg 0 | |
+#define cpu_has_64bit_gp_regs 0 | |
+#define cpu_has_64bit_addresses 0 | |
+ | |
+/* CPU cache info */ | |
+#define cpu_has_vtag_icache 0 | |
+#define cpu_has_ic_fills_f_dc 0 | |
+#define cpu_has_dc_aliases 0 | |
+#define cpu_dcache_line_size() 32 | |
+#define cpu_icache_line_size() 32 | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/eureka_ep430.h b/arch/mips/include/asm/rt2880/eureka_ep430.h | |
new file mode 100644 | |
index 000000000000..aab29c961509 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/eureka_ep430.h | |
@@ -0,0 +1,107 @@ | |
+/************************************************************************** | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#ifndef __ASM_MACH_MIPS_RT2880_EUREKA_EP430_H | |
+#define __ASM_MACH_MIPS_RT2880_EUREKA_EP430_H | |
+ | |
+#include <asm/addrspace.h> /* for KSEG1ADDR() */ | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0000) | |
+#define RALINK_PCI_PCIRAW_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0004) | |
+#define RALINK_PCI_PCIINT_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0008) | |
+#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C) | |
+#define RALINK_PCI_IMBASEBAR1_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x001C) | |
+#define RALINK_PCI_PCR_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0020) | |
+#define RALINK_PCI_PCR_DATA *(volatile u32 *)(RALINK_PCI_BASE + 0x0024) | |
+#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028) | |
+#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C) | |
+#define RALINK_PCI_ARBCTL *(volatile u32 *)(RALINK_PCI_BASE + 0x0080) | |
+ | |
+#if defined(CONFIG_RALINK_MT7628) | |
+ | |
+#define RT6855_PCIE0_OFFSET 0x2000 | |
+ | |
+#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) | |
+#define RALINK_PCI0_BAR1SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0014) | |
+#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) | |
+#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) | |
+#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) | |
+#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) | |
+#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) | |
+#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) | |
+#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) | |
+ | |
+#define RALINK_PCIEPHY_P0_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) | |
+ | |
+#elif defined(CONFIG_RALINK_MT7621) | |
+ | |
+#define RT6855_PCIE0_OFFSET 0x2000 | |
+#define RT6855_PCIE1_OFFSET 0x3000 | |
+#define RT6855_PCIE2_OFFSET 0x4000 | |
+ | |
+#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010) | |
+#define RALINK_PCI0_BAR1SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0014) | |
+#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018) | |
+#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030) | |
+#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034) | |
+#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038) | |
+#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050) | |
+#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060) | |
+#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064) | |
+ | |
+#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010) | |
+#define RALINK_PCI1_BAR1SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0014) | |
+#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018) | |
+#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030) | |
+#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034) | |
+#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038) | |
+#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050) | |
+#define RALINK_PCI1_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060) | |
+#define RALINK_PCI1_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064) | |
+ | |
+#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010) | |
+#define RALINK_PCI2_BAR1SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0014) | |
+#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018) | |
+#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030) | |
+#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034) | |
+#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038) | |
+#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050) | |
+#define RALINK_PCI2_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060) | |
+#define RALINK_PCI2_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064) | |
+ | |
+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000) | |
+#define RALINK_PCIEPHY_P2_CTL_OFFSET (RALINK_PCI_BASE + 0xA000) | |
+ | |
+#elif defined(CONFIG_ECONET_EN75XX_MP) | |
+ | |
+/* pci_en75xx.c */ | |
+ | |
+#else | |
+#error "Ralink chip undefined for PCI MEM map" | |
+#endif | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/generic.h b/arch/mips/include/asm/rt2880/generic.h | |
new file mode 100644 | |
index 000000000000..12cd082cc335 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/generic.h | |
@@ -0,0 +1,42 @@ | |
+/* | |
+ * Copyright (C) 2001 Palmchip Corporation. All rights reserved. | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * Defines of the Palmchip boards specific address-MAP, registers, etc. | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_GENERIC_H | |
+#define __ASM_MACH_MIPS_RT2880_GENERIC_H | |
+ | |
+#include <asm/addrspace.h> | |
+#include <asm/byteorder.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+/* | |
+ * Reset register. | |
+ */ | |
+#define SOFTRES_REG (KSEG1ADDR(RALINK_SYSCTL_BASE+0x34)) | |
+#define GORESET (0x1) | |
+ | |
+/* | |
+ * Power-off register | |
+ */ | |
+#define POWER_DIR_REG (KSEG1ADDR(RALINK_PIO_BASE+0x24)) | |
+#define POWER_DIR_OUTPUT (0x80) /* GPIO 7 */ | |
+#define POWER_POL_REG (KSEG1ADDR(RALINK_PIO_BASE+0x28)) | |
+#define POWEROFF_REG (KSEG1ADDR(RALINK_PIO_BASE+0x20)) | |
+#define POWEROFF (0x0) /* drive low */ | |
+ | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/irq.h b/arch/mips/include/asm/rt2880/irq.h | |
new file mode 100644 | |
index 000000000000..036ec821ce0e | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/irq.h | |
@@ -0,0 +1,19 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2003 by Ralf Baechle | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_IRQ_H | |
+#define __ASM_MACH_MIPS_RT2880_IRQ_H | |
+ | |
+#define MIPS_CPU_IRQ_BASE 0 | |
+ | |
+#include <asm/rt2880/surfboardint.h> | |
+ | |
+#define NR_IRQS (SURFBOARDINT_END + 1) | |
+ | |
+#include_next <irq.h> | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/pbus-timer.h b/arch/mips/include/asm/rt2880/pbus-timer.h | |
new file mode 100644 | |
index 000000000000..d3eda497c31f | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/pbus-timer.h | |
@@ -0,0 +1,189 @@ | |
+#ifndef __ASM_MACH_RALINK_PBUS_TIMER_H | |
+#define __ASM_MACH_RALINK_PBUS_TIMER_H | |
+ | |
+#include <linux/io.h> | |
+#include <linux/kernel.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#define RSTSTAT (RALINK_SYSCTL_BASE + 0x38) | |
+ | |
+#define RSTSTAT_WDT2SYSRST_EN (1U << 31) | |
+#define RSTSTAT_WDT2RSTO_EN (1U << 30) | |
+#define RSTSTAT_SWSYSRST (1U << 2) | |
+#define RSTSTAT_WDRST (1U << 1) | |
+ | |
+#define RSTSTAT_WDT_EN \ | |
+ (RSTSTAT_WDT2SYSRST_EN | \ | |
+ RSTSTAT_WDT2RSTO_EN) | |
+ | |
+#define RSTSTAT_RST_STATE_MASK \ | |
+ (RSTSTAT_SWSYSRST | \ | |
+ RSTSTAT_WDRST) | |
+ | |
+#define PBUS_TIMER_0 (0) | |
+#define PBUS_TIMER_1 (1) | |
+#define PBUS_TIMER_2 (2) | |
+ | |
+#define PBUS_TIMER_WATCHDOG (PBUS_TIMER_1) | |
+ | |
+#define PBUS_TIMER_0_IRQ (SURFBOARDINT_TIMER0) | |
+#define PBUS_TIMER_1_IRQ (SURFBOARDINT_WDG) | |
+#define PBUS_TIMER_2_IRQ (SURFBOARDINT_TIMER1) | |
+ | |
+#define PBUS_TIMER_GLB (RALINK_TIMER_BASE + 0x00) | |
+#define PBUS_TIMER_GLB_RST_SHIFT (8) | |
+#define PBUS_TIMER_GLB_INT_SHIFT (0) | |
+ | |
+#define PBUS_TIMER_GLB_RST(n) \ | |
+ (1U << ((n) + PBUS_TIMER_GLB_RST_SHIFT)) | |
+#define PBUS_TIMER_GLB_INT_ACK(n) \ | |
+ (1U << ((n) + PBUS_TIMER_GLB_INT_SHIFT)) | |
+ | |
+#define PBUS_TIMER_GLB_RST_MASK \ | |
+ (PBUS_TIMER_GLB_RST(PBUS_TIMER_0) | \ | |
+ PBUS_TIMER_GLB_RST(PBUS_TIMER_1) | \ | |
+ PBUS_TIMER_GLB_RST(PBUS_TIMER_2)) | |
+ | |
+#define PBUS_TIMER_GLB_INT_ACK_MASK \ | |
+ (PBUS_TIMER_GLB_INT_ACK(PBUS_TIMER_0) | \ | |
+ PBUS_TIMER_GLB_INT_ACK(PBUS_TIMER_1) | \ | |
+ PBUS_TIMER_GLB_INT_ACK(PBUS_TIMER_2)) | |
+ | |
+#define PBUS_TIMER_CTL(n) \ | |
+ ((RALINK_TIMER_BASE) + 0x10 * (n) + 0x10) | |
+ | |
+#define PBUS_TIMER_LMT(n) \ | |
+ ((RALINK_TIMER_BASE) + 0x10 * (n) + 0x14) | |
+ | |
+#define PBUS_TIMER_VAL(n) \ | |
+ ((RALINK_TIMER_BASE) + 0x10 * (n) + 0x18) | |
+ | |
+#define PBUS_TIMER_SCALE_MS (1000) | |
+ | |
+#define PBUS_TIMER_CTL_PRES_MASK (0xffff0000) | |
+#define PBUS_TIMER_CTL_PRES(scale) \ | |
+ (((scale) << 16) & PBUS_TIMER_CTL_PRES_MASK) | |
+#define PBUS_TIMER_CTL_PRES_GET(ctl) \ | |
+ (((ctl) & PBUS_TIMER_CTL_PRES_MASK) >> 16) | |
+ | |
+#define PBUS_TIMER_CTL_EN (1U << 7) | |
+#define PBUS_TIMER_CTL_AL (1U << 4) | |
+ | |
+static inline void | |
+pbus_timer_w32(const u32 reg, const u32 val) | |
+{ | |
+ __raw_writel(val, (void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+static inline u32 | |
+pbus_timer_r32(const u32 reg) | |
+{ | |
+ return __raw_readl((void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+static inline bool | |
+pbus_timer_enable(const unsigned int n, | |
+ const unsigned int interval_ms, | |
+ const enum pbus_timer_mode mode) | |
+{ | |
+ const u32 ctl_reg = PBUS_TIMER_CTL(n); | |
+ u32 limit = interval_ms; | |
+ u32 scale = 1; | |
+ u32 ctl; | |
+ | |
+ if (mode == PBUS_TIMER_MODE_WATCHDOG) { | |
+ u32 val; | |
+ | |
+ /* enable a watchdog function for a timer | |
+ * that does not support it | |
+ */ | |
+ if (n != PBUS_TIMER_WATCHDOG) | |
+ return false; | |
+ | |
+ val = pbus_timer_r32(RSTSTAT); | |
+ | |
+ val &= ~RSTSTAT_RST_STATE_MASK; | |
+ val |= RSTSTAT_WDT_EN; | |
+ pbus_timer_w32(RSTSTAT, val); | |
+ } else { | |
+ /* use a watchdog timer as an interval or periodic timer | |
+ */ | |
+ if (n == PBUS_TIMER_WATCHDOG) { | |
+ u32 val = pbus_timer_r32(RSTSTAT); | |
+ | |
+ val &= ~RSTSTAT_RST_STATE_MASK; | |
+ val &= ~RSTSTAT_WDT_EN; | |
+ pbus_timer_w32(RSTSTAT, val); | |
+ } | |
+ } | |
+ | |
+ while (limit > U16_MAX) { | |
+ scale <<= 1; | |
+ limit >>= 1; | |
+ | |
+ /* an interval is too large */ | |
+ if (PBUS_TIMER_SCALE_MS * scale > U16_MAX) | |
+ return false; | |
+ } | |
+ | |
+ pbus_timer_w32(PBUS_TIMER_LMT(n), limit); | |
+ | |
+ ctl = pbus_timer_r32(ctl_reg); | |
+ | |
+ ctl &= PBUS_TIMER_CTL_PRES_MASK; | |
+ ctl |= PBUS_TIMER_CTL_PRES(PBUS_TIMER_SCALE_MS * scale); | |
+ ctl |= PBUS_TIMER_CTL_EN; | |
+ | |
+ if (mode == PBUS_TIMER_MODE_PERIODIC) | |
+ ctl |= PBUS_TIMER_CTL_AL; | |
+ else | |
+ ctl &= ~PBUS_TIMER_CTL_AL; | |
+ | |
+ pbus_timer_w32(ctl_reg, ctl); | |
+ | |
+ return true; | |
+} | |
+ | |
+static inline void | |
+pbus_timer_disable(const unsigned int n) | |
+{ | |
+ const u32 ctl_reg = PBUS_TIMER_CTL(n); | |
+ const u32 ctl = pbus_timer_r32(ctl_reg); | |
+ | |
+ pbus_timer_w32(ctl_reg, ctl & ~PBUS_TIMER_CTL_EN); | |
+} | |
+ | |
+static inline void | |
+pbus_timer_restart(const unsigned int n) | |
+{ | |
+ u32 glb = pbus_timer_r32(PBUS_TIMER_GLB); | |
+ | |
+ glb &= ~PBUS_TIMER_GLB_RST_MASK; | |
+ glb &= ~PBUS_TIMER_GLB_INT_ACK_MASK; | |
+ glb |= PBUS_TIMER_GLB_RST(n); | |
+ pbus_timer_w32(PBUS_TIMER_GLB, glb); | |
+} | |
+ | |
+static inline void | |
+pbus_timer_int_ack(const unsigned int n) | |
+{ | |
+ u32 glb = pbus_timer_r32(PBUS_TIMER_GLB); | |
+ | |
+ glb &= ~PBUS_TIMER_GLB_RST_MASK; | |
+ glb &= ~PBUS_TIMER_GLB_INT_ACK_MASK; | |
+ glb |= PBUS_TIMER_GLB_INT_ACK(n); | |
+ pbus_timer_w32(PBUS_TIMER_GLB, glb); | |
+} | |
+ | |
+static inline unsigned int | |
+pbus_timer_get(const unsigned int n) | |
+{ | |
+ const u32 val = pbus_timer_r32(PBUS_TIMER_VAL(n)); | |
+ const u32 ctl = pbus_timer_r32(PBUS_TIMER_CTL(n)); | |
+ const u32 pres = PBUS_TIMER_CTL_PRES_GET(ctl); | |
+ | |
+ return val * (pres / PBUS_TIMER_SCALE_MS); | |
+} | |
+ | |
+#endif /* __ASM_MACH_RALINK_PBUS_TIMER_H */ | |
+ | |
diff --git a/arch/mips/include/asm/rt2880/prom.h b/arch/mips/include/asm/rt2880/prom.h | |
new file mode 100644 | |
index 000000000000..ca6e214b2c3f | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/prom.h | |
@@ -0,0 +1,37 @@ | |
+/* | |
+ * Carsten Langgaard, carstenl@mips.com | |
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * MIPS boards bootprom interface for the Linux kernel. | |
+ * | |
+ */ | |
+ | |
+#ifndef _MIPS_PROM_H | |
+#define _MIPS_PROM_H | |
+ | |
+extern char *prom_getcmdline(void); | |
+extern char *prom_getenv(char *name); | |
+extern void prom_printf(char *fmt, ...); | |
+extern void prom_init_printf(int tty_no); | |
+extern void prom_init_cmdline(void); | |
+extern void prom_meminit(void); | |
+extern void prom_free_prom_memory(void); | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/rt_mmap.h b/arch/mips/include/asm/rt2880/rt_mmap.h | |
new file mode 100644 | |
index 000000000000..cc12625858a7 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/rt_mmap.h | |
@@ -0,0 +1,382 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * register definition for Ralink RT-series SoC | |
+ * | |
+ * Copyright 2007 Ralink Inc. | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#ifndef __ASM_MACH_MIPS_RT2880_RT_MMAP_H | |
+#define __ASM_MACH_MIPS_RT2880_RT_MMAP_H | |
+ | |
+#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) | |
+#define sysRegRead(phys) (*(volatile unsigned int *)PHYS_TO_K1(phys)) | |
+#define sysRegWrite(phys, val) ((*(volatile unsigned int *)PHYS_TO_K1(phys)) = (val)) | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ | |
+#define RALINK_SYSCTL_BASE 0xBE000000 | |
+#define RALINK_TIMER_BASE 0xBE000100 | |
+#define RALINK_INTCL_BASE 0xBE000200 | |
+#define RALINK_RBUS_MATRIXCTL_BASE 0xBE000400 | |
+#define RALINK_MIPS_CNT_BASE 0x1E000500 | |
+#define RALINK_PIO_BASE 0xBE000600 | |
+#define RALINK_SPDIF_BASE 0xBE000700 | |
+#define RALINK_I2C_BASE 0xBE000900 | |
+#define RALINK_I2S_BASE 0xBE000A00 | |
+#define RALINK_SPI_BASE 0xBE000B00 | |
+#define RALINK_UART_LITE1_BASE 0x1E000C00 | |
+#define RALINK_UART_LITE_BASE RALINK_UART_LITE1_BASE | |
+#define RALINK_UART_LITE2_BASE 0x1E000D00 | |
+#define RALINK_UART_BASE RALINK_UART_LITE2_BASE | |
+#define RALINK_UART_LITE3_BASE 0x1E000E00 | |
+#define RALINK_ANA_CTRL_BASE 0xBE000F00 | |
+#define RALINK_PCM_BASE 0xBE002000 | |
+#define RALINK_GDMA_BASE 0xBE002800 | |
+#define RALINK_NAND_CTRL_BASE 0xBE003000 | |
+#define RALINK_NANDECC_CTRL_BASE 0xBE003800 | |
+#define RALINK_CRYPTO_ENGINE_BASE 0xBE004000 | |
+#define RALINK_MEMCTRL_BASE 0xBE005000 | |
+#define RALINK_EXT_MC_ARB_BASE 0xBE006000 | |
+#define RALINK_HS_DMA_BASE 0xBE007000 | |
+#define RALINK_FRAME_ENGINE_BASE 0xBE100000 | |
+#define RALINK_PPE_BASE 0xBE100C00 | |
+#define RALINK_ETH_SW_BASE 0xBE110000 | |
+#define RALINK_ROM_BASE 0xBE118000 | |
+#define RALINK_MSDC_BASE 0xBE130000 | |
+#define RALINK_PCI_BASE 0xBE140000 | |
+#define RALINK_USB_HOST_BASE 0x1E1C0000 | |
+#define RALINK_USB_HOST_SIZE 0x00004000 | |
+#define RALINK_USB_IPPC_BASE 0x1E1D0700 | |
+#define RALINK_XHCI_HOST_BASE 0xBE1C0000 | |
+#define RALINK_XHCI_UPHY_BASE 0xBE1D0000 | |
+#define RALINK_11N_MAC_BASE 0xBE180000 // Unused | |
+ | |
+#define RALINK_MCNT_CFG 0xBE000500 | |
+#define RALINK_COMPARE 0xBE000504 | |
+#define RALINK_COUNT 0xBE000508 | |
+ | |
+// GIC | |
+#define RALINK_GIC_BASE 0x1FBC0000 | |
+#define RALINK_GIC_ADDRSPACE_SZ 0x20000 | |
+ | |
+// CPC | |
+#define RALINK_CPC_BASE 0x1FBF0000 | |
+#define RALINK_CPC_ADDRSPACE_SZ 0x8000 | |
+ | |
+// GCMP | |
+#define RALINK_GCMP_BASE 0x1FBF8000 | |
+#define RALINK_GCMP_ADDRSPACE_SZ 0x8000 | |
+ | |
+// CM | |
+#define CM_GCR_REG0_BASE_VALUE 0x1C000000 /* CM region 0 base address (Palmbus) */ | |
+#define CM_GCR_REG0_MASK_VALUE 0x0000FC00 /* CM region 0 mask (64M) */ | |
+ | |
+#define CM_GCR_REG1_BASE_VALUE 0x60000000 /* CM region 1 base address (PCIe) */ | |
+#define CM_GCR_REG1_MASK_VALUE 0x0000F000 /* CM region 1 mask (256M) */ | |
+ | |
+// Interrupt Controller | |
+#define RALINK_INTCTL_FE (1<<3) | |
+#define RALINK_INTCTL_PCIE0 (1<<4) | |
+#define RALINK_INTCTL_SYSCTL (1<<6) | |
+#define RALINK_INTCTL_I2C (1<<8) | |
+#define RALINK_INTCTL_DRAMC (1<<9) | |
+#define RALINK_INTCTL_PCM (1<<10) | |
+#define RALINK_INTCTL_HSDMA (1<<11) | |
+#define RALINK_INTCTL_PIO (1<<12) | |
+#define RALINK_INTCTL_DMA (1<<13) | |
+#define RALINK_INTCTL_NFI (1<<14) | |
+#define RALINK_INTCTL_NFIECC (1<<15) | |
+#define RALINK_INTCTL_I2S (1<<16) | |
+#define RALINK_INTCTL_SPI (1<<17) | |
+#define RALINK_INTCTL_SPDIF (1<<18) | |
+#define RALINK_INTCTL_CRYPTO (1<<19) | |
+#define RALINK_INTCTL_SDXC (1<<20) | |
+#define RALINK_INTCTL_PCTRL (1<<21) | |
+#define RALINK_INTCTL_USB (1<<22) | |
+#define RALINK_INTCTL_ESW (1<<23) | |
+#define RALINK_INTCTL_PCIE1 (1<<24) | |
+#define RALINK_INTCTL_PCIE2 (1<<25) | |
+#define RALINK_INTCTL_UART1 (1<<26) | |
+#define RALINK_INTCTL_UART2 (1<<27) | |
+#define RALINK_INTCTL_UART3 (1<<28) | |
+#define RALINK_INTCTL_WDTIMER (1<<29) | |
+#define RALINK_INTCTL_TIMER0 (1<<30) | |
+#define RALINK_INTCTL_TIMER1 (1<<31) | |
+ | |
+// Reset Control Register | |
+#define RALINK_SYS_RST (1<<0) | |
+#define RALINK_MCM_RST (1<<2) | |
+#define RALINK_HSDMA_RST (1<<5) | |
+#define RALINK_FE_RST (1<<6) | |
+#define RALINK_SPDIF_RST (1<<7) | |
+#define RALINK_TIMER_RST (1<<8) | |
+#define RALINK_INTC_RST (1<<9) | |
+#define RALINK_MC_RST (1<<10) | |
+#define RALINK_PCM_RST (1<<11) | |
+#define RALINK_PIO_RST (1<<13) | |
+#define RALINK_DMA_RST (1<<14) | |
+#define RALINK_NAND_RST (1<<15) | |
+#define RALINK_I2C_RST (1<<16) | |
+#define RALINK_I2S_RST (1<<17) | |
+#define RALINK_SPI_RST (1<<18) | |
+#define RALINK_UART1_RST (1<<19) | |
+#define RALINK_UART2_RST (1<<20) | |
+#define RALINK_UART3_RST (1<<21) | |
+#define RALINK_ETH_RST (1<<23) | |
+#define RALINK_PCIE0_RST (1<<24) | |
+#define RALINK_PCIE1_RST (1<<25) | |
+#define RALINK_PCIE2_RST (1<<26) | |
+#define RALINK_AUX_STCK_RST (1<<28) | |
+#define RALINK_CRYPTO_RST (1<<29) | |
+#define RALINK_SDXC_RST (1<<30) | |
+#define RALINK_PPE_RST (1<<31) | |
+ | |
+// Clock Conf Register | |
+#define RALINK_SPDIF_CLK_EN (1<<7) | |
+#define RALINK_PCM_CLK_EN (1<<11) | |
+#define RALINK_NAND_CLK_EN (1<<15) | |
+#define RALINK_I2S_CLK_EN (1<<17) | |
+#define RALINK_PCIE0_CLK_EN (1<<24) | |
+#define RALINK_PCIE1_CLK_EN (1<<25) | |
+#define RALINK_PCIE2_CLK_EN (1<<26) | |
+#define RALINK_CRYPTO_CLK_EN (1<<29) | |
+#define RALINK_SDXC_CLK_EN (1<<30) | |
+ | |
+// CPU PLL CFG Register | |
+#define CPLL_SW_CONFIG (0x1UL << 31) | |
+#define CPLL_MULT_RATIO_SHIFT 16 | |
+#define CPLL_MULT_RATIO (0x7UL << CPLL_MULT_RATIO_SHIFT) | |
+#define CPLL_DIV_RATIO_SHIFT 10 | |
+#define CPLL_DIV_RATIO (0x3UL << CPLL_DIV_RATIO_SHIFT) | |
+#define BASE_CLOCK 50 /* Mhz */ | |
+ | |
+#define RALINK_TESTSTAT 0xBE000018 | |
+#define RALINK_TESTSTAT2 0xBE00001C | |
+ | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ | |
+#define RALINK_SYSCTL_BASE 0xB0000000 | |
+#define RALINK_TIMER_BASE 0xB0000100 | |
+#define RALINK_INTCL_BASE 0xB0000200 | |
+#define RALINK_MEMCTRL_BASE 0xB0000300 | |
+#define RALINK_RBUS_MATRIXCTL_BASE 0xB0000400 | |
+#define RALINK_MIPS_CNT_BASE 0x10000500 | |
+#define RALINK_PIO_BASE 0xB0000600 | |
+#define RALINK_SPI_SLAVE_BASE 0xB0000700 | |
+#define RALINK_I2C_BASE 0xB0000900 | |
+#define RALINK_I2S_BASE 0xB0000A00 | |
+#define RALINK_SPI_BASE 0xB0000B00 | |
+#define RALINK_UART_LITE1_BASE 0x10000C00 | |
+#define RALINK_UART_LITE_BASE RALINK_UART_LITE1_BASE | |
+#define RALINK_UART_LITE2_BASE 0x10000D00 | |
+#define RALINK_UART_BASE RALINK_UART_LITE2_BASE | |
+#define RALINK_UART_LITE3_BASE 0x10000E00 | |
+#define RALINK_PCM_BASE 0xB0002000 | |
+#define RALINK_GDMA_BASE 0xB0002800 | |
+#define RALINK_AES_ENGINE_BASE 0xB0004000 | |
+#define RALINK_FRAME_ENGINE_BASE 0xB0100000 | |
+#define RALINK_ETH_SW_BASE 0xB0110000 | |
+#define RALINK_USB_DEV_BASE 0xB0120000 | |
+#define RALINK_MSDC_BASE 0xB0130000 | |
+#define RALINK_PCI_BASE 0xB0140000 | |
+#define RALINK_11N_MAC_BASE 0xB0180000 | |
+#define RALINK_USB_HOST_BASE 0x101C0000 | |
+ | |
+#define RALINK_CPU_CLK_AUTO_CFG 0xB0000444 | |
+#define RALINK_MCNT_CFG 0xB0000500 | |
+#define RALINK_COMPARE 0xB0000504 | |
+#define RALINK_COUNT 0xB0000508 | |
+ | |
+// Interrupt Controller | |
+#define RALINK_INTCTL_SYSCTL (1<<0) | |
+#define RALINK_INTCTL_TIMER0 (1<<1) | |
+#define RALINK_INTCTL_WDTIMER (1<<2) | |
+#define RALINK_INTCTL_ILL_ACCESS (1<<3) | |
+#define RALINK_INTCTL_PCM (1<<4) | |
+#define RALINK_INTCTL_UART (1<<5) | |
+#define RALINK_INTCTL_PIO (1<<6) | |
+#define RALINK_INTCTL_DMA (1<<7) | |
+#define RALINK_INTCTL_PC (1<<9) | |
+#define RALINK_INTCTL_I2S (1<<10) | |
+#define RALINK_INTCTL_SPI (1<<11) | |
+#define RALINK_INTCTL_UARTLITE (1<<12) | |
+#define RALINK_INTCTL_CRYPTO (1<<13) | |
+#define RALINK_INTCTL_SDXC (1<<14) | |
+#define RALINK_INTCTL_ESW (1<<17) | |
+#define RALINK_INTCTL_UHST (1<<18) | |
+#define RALINK_INTCTL_UDEV (1<<19) | |
+#define RALINK_INTCTL_GLOBAL (1<<31) | |
+ | |
+// Reset Control Register | |
+#define RALINK_SYS_RST (1<<0) | |
+#define RALINK_TIMER_RST (1<<8) | |
+#define RALINK_INTC_RST (1<<9) | |
+#define RALINK_MC_RST (1<<10) | |
+#define RALINK_PCM_RST (1<<11) | |
+#define RALINK_UART_RST (1<<12) | |
+#define RALINK_PIO_RST (1<<13) | |
+#define RALINK_DMA_RST (1<<14) | |
+#define RALINK_I2C_RST (1<<16) | |
+#define RALINK_I2S_RST (1<<17) | |
+#define RALINK_SPI_RST (1<<18) | |
+#define RALINK_UARTL_RST (1<<19) | |
+#define RALINK_FE_RST (1<<21) | |
+#define RALINK_UHST_RST (1<<22) | |
+#define RALINK_ESW_RST (1<<23) | |
+#define RALINK_EPHY_RST (1<<24) | |
+#define RALINK_UDEV_RST (1<<25) | |
+#define RALINK_PCIE0_RST (1<<26) | |
+#define RALINK_PCIE1_RST (1<<27) | |
+#define RALINK_MIPS_CNT_RST (1<<28) | |
+#define RALINK_CRYPTO_RST (1<<29) | |
+#define RALINK_SDXC_RST (1<<30) | |
+ | |
+// Clock Conf Register | |
+#define RALINK_PCM_CLK_EN (1<<11) | |
+#define RALINK_I2S_CLK_EN (1<<17) | |
+#define RALINK_UPHY0_CLK_EN (1<<25) | |
+#define RALINK_UPHY1_CLK_EN (1<<22) | |
+#define RALINK_PCIE0_CLK_EN (1<<26) | |
+#define RALINK_PCIE1_CLK_EN (1<<27) | |
+#define RALINK_CRYPTO_CLK_EN (1<<29) | |
+#define RALINK_SDXC_CLK_EN (1<<30) | |
+ | |
+// CPU PLL CFG Register | |
+#define CPLL_SW_CONFIG (0x1UL << 31) | |
+#define CPLL_MULT_RATIO_SHIFT 16 | |
+#define CPLL_MULT_RATIO (0x7UL << CPLL_MULT_RATIO_SHIFT) | |
+#define CPLL_DIV_RATIO_SHIFT 10 | |
+#define CPLL_DIV_RATIO (0x3UL << CPLL_DIV_RATIO_SHIFT) | |
+#define BASE_CLOCK 40 /* Mhz */ | |
+ | |
+// AGPIO | |
+#define MT7628_P0_EPHY_AIO_EN (0x1<<16) | |
+#define MT7628_P1_EPHY_AIO_EN (0x1<<17) | |
+#define MT7628_P2_EPHY_AIO_EN (0x1<<18) | |
+#define MT7628_P3_EPHY_AIO_EN (0x1<<19) | |
+#define MT7628_P4_EPHY_AIO_EN (0x1<<20) | |
+ | |
+#elif defined(CONFIG_ECONET_EN75XX_MP) | |
+ | |
+#define RALINK_SYSCTL_BASE 0xBFB00000 | |
+#define RALINK_TIMER_BASE 0xBFBF0100 | |
+#define RALINK_MEMCTRL_BASE 0xBFB20000 | |
+#define RALINK_PIO_BASE 0xBFBF0200 | |
+#define RALINK_I2C_BASE 0xBFBF8000 | |
+#define RALINK_UART_LITE_BASE 0xBFBF0000 | |
+#define RALINK_UART_LITE2_BASE 0xBFBF0300 | |
+#define RALINK_PCM_BASE 0xBFBD0000 | |
+#define RALINK_GDMA_BASE 0xBFB30000 | |
+#define RALINK_FRAME_ENGINE_BASE 0xBFB50000 | |
+#define RALINK_ETH_SW_BASE 0xBFB58000 | |
+#define RALINK_CRYPTO_ENGINE_BASE 0xBFB70000 | |
+#define RALINK_PCI_BASE 0xBFB80000 | |
+#define RALINK_PCI_PHY0_BASE 0xBFAF2000 | |
+#define RALINK_PCI_PHY1_BASE 0xBFAC0000 | |
+#define RALINK_USB_HOST_BASE 0x1FB90000 | |
+#define RALINK_XHCI_HOST_BASE 0xBFB90000 | |
+#define RALINK_XHCI_UPHY_BASE 0xBFA80000 | |
+#define RALINK_SFC_BASE 0xBFA10000 | |
+#define RALINK_CHIP_SCU_BASE 0xBFA20000 | |
+#define RALINK_11N_MAC_BASE 0xBFB00000 // Unused | |
+ | |
+#if defined(CONFIG_ECONET_EN7528) | |
+#define RALINK_USB_HOST_SIZE 0x00003E00 | |
+#define RALINK_USB_IPPC_BASE 0x1FB93E00 | |
+#else | |
+#define RALINK_USB_HOST_SIZE 0x00004000 | |
+#define RALINK_USB_IPPC_BASE 0x1FA80700 | |
+#endif | |
+ | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+/* GIC */ | |
+#define RALINK_GIC_BASE 0x1F8C0000 | |
+#define RALINK_GIC_ADDRSPACE_SZ 0x20000 | |
+ | |
+/* CPC */ | |
+#define RALINK_CPC_BASE 0x1F8E8000 | |
+#define RALINK_CPC_ADDRSPACE_SZ 0x8000 | |
+ | |
+/* GCMP */ | |
+#define RALINK_GCMP_BASE 0x1F8E0000 | |
+#define RALINK_GCMP_ADDRSPACE_SZ 0x8000 | |
+ | |
+/* CM */ | |
+#define CM_GCR_REG0_BASE_VALUE 0x1C000000 /* CM region 0 base address (Palmbus) */ | |
+#define CM_GCR_REG0_MASK_VALUE 0x0000FC00 /* CM region 0 mask (64M) */ | |
+ | |
+#define CM_GCR_REG1_BASE_VALUE 0x20000000 /* CM region 1 base address (PCIe) */ | |
+#define CM_GCR_REG1_MASK_VALUE 0x0000F000 /* CM region 1 mask (256M) */ | |
+#else | |
+/* Interrupt Controller */ | |
+#define RALINK_INTCL_BASE 0xBFB40000 | |
+#define RALINK_INTCTL_UARTLITE (1<<0) | |
+#define RALINK_INTCTL_PIO (1<<10) | |
+#define RALINK_INTCTL_PCM (1<<11) | |
+#define RALINK_INTCTL_DMA (1<<14) | |
+#define RALINK_INTCTL_GSW (1<<15) | |
+#define RALINK_INTCTL_UHST (1<<17) | |
+#define RALINK_INTCTL_FE (1<<21) | |
+#define RALINK_INTCTL_QDMA (1<<22) | |
+#define RALINK_INTCTL_PCIE0 (1<<23) | |
+#define RALINK_INTCTL_PCIE1 (1<<24) | |
+ | |
+/* Reset Control Register */ | |
+#define RALINK_INTC_RST (1<<9) | |
+#endif | |
+ | |
+/* Reset Control Register */ | |
+#define RALINK_I2S1_RST (1<<0) | |
+#define RALINK_FE_QDMA_LAN_RST (1<<1) | |
+#define RALINK_FE_QDMA_WAN_RST (1<<2) | |
+#define RALINK_PCM2_RST (1<<4) | |
+#define RALINK_PTM_MAC_RST (1<<5) | |
+#define RALINK_CRYPTO_RST (1<<6) | |
+#define RALINK_SAR_RST (1<<7) | |
+#define RALINK_TIMER_RST (1<<8) | |
+#define RALINK_BONDING_RST (1<<10) | |
+#define RALINK_PCM1_RST (1<<11) | |
+#define RALINK_UART_RST (1<<12) | |
+#define RALINK_PIO_RST (1<<13) | |
+#define RALINK_DMA_RST (1<<14) | |
+#define RALINK_I2C_RST (1<<16) | |
+#define RALINK_I2S2_RST (1<<17) | |
+#define RALINK_SPI_RST (1<<18) | |
+#define RALINK_UARTL_RST (1<<19) | |
+#define RALINK_FE_RST (1<<21) | |
+#define RALINK_UHST_RST (1<<22) | |
+#define RALINK_ESW_RST (1<<23) | |
+#define RALINK_SFC2_RST (1<<25) | |
+#define RALINK_PCIE0_RST (1<<26) | |
+#define RALINK_PCIE1_RST (1<<27) | |
+#define RALINK_PCIEHB_RST (1<<29) | |
+ | |
+#else | |
+#error "Ralink chip undefined for MEM map" | |
+#endif | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/rt_serial.h b/arch/mips/include/asm/rt2880/rt_serial.h | |
new file mode 100644 | |
index 000000000000..b4ddc14f913f | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/rt_serial.h | |
@@ -0,0 +1,380 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * serial port definition for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#ifndef __ASM_MACH_MIPS_RT2880_RT_SERIAL_H | |
+#define __ASM_MACH_MIPS_RT2880_RT_SERIAL_H | |
+ | |
+#define RT2880_UART_RBR_OFFSET 0x00 | |
+#define RT2880_UART_TBR_OFFSET 0x00 | |
+#define RT2880_UART_IER_OFFSET 0x04 | |
+#define RT2880_UART_IIR_OFFSET 0x08 | |
+#define RT2880_UART_FCR_OFFSET 0x08 | |
+#define RT2880_UART_LCR_OFFSET 0x0C | |
+#define RT2880_UART_MCR_OFFSET 0x10 | |
+#define RT2880_UART_LSR_OFFSET 0x14 | |
+#define RT2880_UART_DLL_OFFSET 0x00 | |
+#define RT2880_UART_DLM_OFFSET 0x04 | |
+ | |
+#define RBR(x) *(volatile u32 *)((x)+RT2880_UART_RBR_OFFSET) | |
+#define TBR(x) *(volatile u32 *)((x)+RT2880_UART_TBR_OFFSET) | |
+#define IER(x) *(volatile u32 *)((x)+RT2880_UART_IER_OFFSET) | |
+#define IIR(x) *(volatile u32 *)((x)+RT2880_UART_IIR_OFFSET) | |
+#define FCR(x) *(volatile u32 *)((x)+RT2880_UART_FCR_OFFSET) | |
+#define LCR(x) *(volatile u32 *)((x)+RT2880_UART_LCR_OFFSET) | |
+#define MCR(x) *(volatile u32 *)((x)+RT2880_UART_MCR_OFFSET) | |
+#define LSR(x) *(volatile u32 *)((x)+RT2880_UART_LSR_OFFSET) | |
+#define DLL(x) *(volatile u32 *)((x)+RT2880_UART_DLL_OFFSET) | |
+#define DLM(x) *(volatile u32 *)((x)+RT2880_UART_DLM_OFFSET) | |
+ | |
+#define RT2880_UART_RX 0 /* In: Receive buffer */ | |
+#define RT2880_UART_TX 0 /* Out: Transmit buffer */ | |
+#define RT2880_UART_DLL 0 /* Out: Divisor Latch Low */ | |
+#define RT2880_UART_TRG 0 /* FCTR bit 7 selects Rx or Tx | |
+ * In: Fifo count | |
+ * Out: Fifo custom trigger levels */ | |
+ | |
+#define RT2880_UART_DLM 4 /* Out: Divisor Latch High */ | |
+#define RT2880_UART_IER 4 /* Out: Interrupt Enable Register */ | |
+#define RT2880_UART_FCTR 4 /* Feature Control Register */ | |
+ | |
+#define RT2880_UART_IIR 8 /* In: Interrupt ID Register */ | |
+#define RT2880_UART_FCR 8 /* Out: FIFO Control Register */ | |
+#define RT2880_UART_EFR 8 /* I/O: Extended Features Register */ | |
+ | |
+#define RT2880_UART_LCR 12 /* Out: Line Control Register */ | |
+#define RT2880_UART_MCR 16 /* Out: Modem Control Register */ | |
+#define RT2880_UART_LSR 20 /* In: Line Status Register */ | |
+#define RT2880_UART_MSR 24 /* In: Modem Status Register */ | |
+#define RT2880_UART_SCR 28 /* I/O: Scratch Register */ | |
+#define RT2880_UART_EMSR 28 /* Extended Mode Select Register */ | |
+ | |
+/* | |
+ * DLAB=0 | |
+ */ | |
+#define RT2880_UART_IER_MSI 0x08 /* Enable Modem status interrupt */ | |
+#define RT2880_UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ | |
+#define RT2880_UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ | |
+#define RT2880_UART_IER_RDI 0x01 /* Enable receiver data interrupt */ | |
+/* | |
+ * Sleep mode for ST16650 and TI16750. For the ST16650, EFR[4]=1 | |
+ */ | |
+#define RT2880_UART_IERX_SLEEP 0x10 /* Enable sleep mode */ | |
+ | |
+#define RT2880_UART_IIR_NO_INT 0x01 /* No interrupts pending */ | |
+#define RT2880_UART_IIR_ID 0x06 /* Mask for the interrupt ID */ | |
+#define RT2880_UART_IIR_MSI 0x00 /* Modem status interrupt */ | |
+#define RT2880_UART_IIR_THRI 0x02 /* Transmitter holding register empty */ | |
+#define RT2880_UART_IIR_RDI 0x04 /* Receiver data interrupt */ | |
+#define RT2880_UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ | |
+ | |
+#define RT2880_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ | |
+#define RT2880_UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ | |
+#define RT2880_UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ | |
+#define RT2880_UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ | |
+/* | |
+ * Note: The FIFO trigger levels are chip specific: | |
+ * RX:76 = 00 01 10 11 TX:54 = 00 01 10 11 | |
+ * PC16550D: 1 4 8 14 xx xx xx xx | |
+ * TI16C550A: 1 4 8 14 xx xx xx xx | |
+ * TI16C550C: 1 4 8 14 xx xx xx xx | |
+ * ST16C550: 1 4 8 14 xx xx xx xx | |
+ * ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2 | |
+ * NS16C552: 1 4 8 14 xx xx xx xx | |
+ * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 | |
+ * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 | |
+ * TI16C752: 8 16 56 60 8 16 32 56 | |
+ */ | |
+#define RT2880_UART_FCR_R_TRIG_00 0x00 | |
+#define RT2880_UART_FCR_R_TRIG_01 0x40 | |
+#define RT2880_UART_FCR_R_TRIG_10 0x80 | |
+#define RT2880_UART_FCR_R_TRIG_11 0xc0 | |
+#define RT2880_UART_FCR_T_TRIG_00 0x00 | |
+#define RT2880_UART_FCR_T_TRIG_01 0x10 | |
+#define RT2880_UART_FCR_T_TRIG_10 0x20 | |
+#define RT2880_UART_FCR_T_TRIG_11 0x30 | |
+ | |
+#define RT2880_UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ | |
+#define RT2880_UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ | |
+#define RT2880_UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ | |
+#define RT2880_UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ | |
+#define RT2880_UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ | |
+/* 16650 definitions */ | |
+#define RT2880_UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */ | |
+#define RT2880_UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */ | |
+#define RT2880_UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */ | |
+#define RT2880_UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */ | |
+#define RT2880_UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */ | |
+#define RT2880_UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ | |
+#define RT2880_UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ | |
+#define RT2880_UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ | |
+#define RT2880_UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750) */ | |
+ | |
+//#define UART_LCR 3 /* Out: Line Control Register */ | |
+/* | |
+ * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting | |
+ * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. | |
+ */ | |
+#define RT2880_UART_LCR_DLAB 0x80 /* Divisor latch access bit */ | |
+#define RT2880_UART_LCR_SBC 0x40 /* Set break control */ | |
+#define RT2880_UART_LCR_SPAR 0x20 /* Stick parity (?) */ | |
+#define RT2880_UART_LCR_EPAR 0x10 /* Even parity select */ | |
+#define RT2880_UART_LCR_PARITY 0x08 /* Parity Enable */ | |
+#define RT2880_UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */ | |
+#define RT2880_UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ | |
+#define RT2880_UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ | |
+#define RT2880_UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ | |
+#define RT2880_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ | |
+ | |
+//#define RT2880_UART_MCR 4 /* Out: Modem Control Register */ | |
+#define RT2880_UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */ | |
+#define RT2880_UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */ | |
+#define RT2880_UART_MCR_XONANY 0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */ | |
+#define RT2880_UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */ | |
+#define RT2880_UART_MCR_LOOP 0x10 /* Enable loopback test mode */ | |
+#define RT2880_UART_MCR_OUT2 0x08 /* Out2 complement */ | |
+#define RT2880_UART_MCR_OUT1 0x04 /* Out1 complement */ | |
+#define RT2880_UART_MCR_RTS 0x02 /* RTS complement */ | |
+#define RT2880_UART_MCR_DTR 0x01 /* DTR complement */ | |
+ | |
+//#define RT2880_UART_LSR 5 /* In: Line Status Register */ | |
+#define RT2880_UART_LSR_TEMT 0x40 /* Transmitter empty */ | |
+#define RT2880_UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ | |
+#define RT2880_UART_LSR_BI 0x10 /* Break interrupt indicator */ | |
+#define RT2880_UART_LSR_FE 0x08 /* Frame error indicator */ | |
+#define RT2880_UART_LSR_PE 0x04 /* Parity error indicator */ | |
+#define RT2880_UART_LSR_OE 0x02 /* Overrun error indicator */ | |
+#define RT2880_UART_LSR_DR 0x01 /* Receiver data ready */ | |
+ | |
+//#define RT2880_UART_MSR 6 /* In: Modem Status Register */ | |
+#define RT2880_UART_MSR_DCD 0x80 /* Data Carrier Detect */ | |
+#define RT2880_UART_MSR_RI 0x40 /* Ring Indicator */ | |
+#define RT2880_UART_MSR_DSR 0x20 /* Data Set Ready */ | |
+#define RT2880_UART_MSR_CTS 0x10 /* Clear to Send */ | |
+#define RT2880_UART_MSR_DDCD 0x08 /* Delta DCD */ | |
+#define RT2880_UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ | |
+#define RT2880_UART_MSR_DDSR 0x02 /* Delta DSR */ | |
+#define RT2880_UART_MSR_DCTS 0x01 /* Delta CTS */ | |
+#define RT2880_UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ | |
+ | |
+//#define RT2880_UART_SCR 7 /* I/O: Scratch Register */ | |
+ | |
+/* | |
+ * DLAB=1 | |
+ */ | |
+//#define RT2880_UART_DLL 0 /* Out: Divisor Latch Low */ | |
+//#define RT2880_UART_DLM 1 /* Out: Divisor Latch High */ | |
+ | |
+/* | |
+ * LCR=0xBF (or DLAB=1 for 16C660) | |
+ */ | |
+//#define RT2880_UART_EFR 2 /* I/O: Extended Features Register */ | |
+#define RT2880_UART_EFR_CTS 0x80 /* CTS flow control */ | |
+#define RT2880_UART_EFR_RTS 0x40 /* RTS flow control */ | |
+#define RT2880_UART_EFR_SCD 0x20 /* Special character detect */ | |
+#define RT2880_UART_EFR_ECB 0x10 /* Enhanced control bit */ | |
+/* | |
+ * the low four bits control software flow control | |
+ */ | |
+ | |
+/* | |
+ * LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654 | |
+ */ | |
+#define RT2880_UART_XON1 4 /* I/O: Xon character 1 */ | |
+#define RT2880_UART_XON2 5 /* I/O: Xon character 2 */ | |
+#define RT2880_UART_XOFF1 6 /* I/O: Xoff character 1 */ | |
+#define RT2880_UART_XOFF2 7 /* I/O: Xoff character 2 */ | |
+ | |
+/* | |
+ * EFR[4]=1 MCR[6]=1, TI16C752 | |
+ */ | |
+#define RT2880_UART_TI752_TCR 6 /* I/O: transmission control register */ | |
+#define RT2880_UART_TI752_TLR 7 /* I/O: trigger level register */ | |
+ | |
+/* | |
+ * LCR=0xBF, XR16C85x | |
+ */ | |
+//#define RT2880_UART_TRG 0 /* FCTR bit 7 selects Rx or Tx | |
+/* | |
+ * These are the definitions for the Programmable Trigger Register | |
+ */ | |
+#define RT2880_UART_TRG_1 0x01 | |
+#define RT2880_UART_TRG_4 0x04 | |
+#define RT2880_UART_TRG_8 0x08 | |
+#define RT2880_UART_TRG_16 0x10 | |
+#define RT2880_UART_TRG_32 0x20 | |
+#define RT2880_UART_TRG_64 0x40 | |
+#define RT2880_UART_TRG_96 0x60 | |
+#define RT2880_UART_TRG_120 0x78 | |
+#define RT2880_UART_TRG_128 0x80 | |
+ | |
+//#define RT2880_UART_FCTR 1 /* Feature Control Register */ | |
+#define RT2880_UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */ | |
+#define RT2880_UART_FCTR_RTS_4DELAY 0x01 | |
+#define RT2880_UART_FCTR_RTS_6DELAY 0x02 | |
+#define RT2880_UART_FCTR_RTS_8DELAY 0x03 | |
+#define RT2880_UART_FCTR_IRDA 0x04 /* IrDa data encode select */ | |
+#define RT2880_UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */ | |
+#define RT2880_UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */ | |
+#define RT2880_UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */ | |
+#define RT2880_UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */ | |
+#define RT2880_UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */ | |
+#define RT2880_UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */ | |
+#define RT2880_UART_FCTR_RX 0x00 /* Programmable trigger mode select */ | |
+#define RT2880_UART_FCTR_TX 0x80 /* Programmable trigger mode select */ | |
+ | |
+/* | |
+ * LCR=0xBF, FCTR[6]=1 | |
+ */ | |
+//#define RT2880_UART_EMSR 7 /* Extended Mode Select Register */ | |
+#define RT2880_UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */ | |
+#define RT2880_UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */ | |
+ | |
+/* | |
+ * The Intel XScale on-chip UARTs define these bits | |
+ */ | |
+#define RT2880_UART_IER_DMAE 0x80 /* DMA Requests Enable */ | |
+#define RT2880_UART_IER_UUE 0x40 /* UART Unit Enable */ | |
+#define RT2880_UART_IER_NRZE 0x20 /* NRZ coding Enable */ | |
+#define RT2880_UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */ | |
+ | |
+#define RT2880_UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ | |
+ | |
+#define RT2880_UART_FCR_PXAR1 0x00 /* receive FIFO treshold = 1 */ | |
+#define RT2880_UART_FCR_PXAR8 0x40 /* receive FIFO treshold = 8 */ | |
+#define RT2880_UART_FCR_PXAR16 0x80 /* receive FIFO treshold = 16 */ | |
+#define RT2880_UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */ | |
+ | |
+/* | |
+ * These register definitions are for the 16C950 | |
+ */ | |
+#define RT2880_UART_ASR 0x01 /* Additional Status Register */ | |
+#define RT2880_UART_RFL 0x03 /* Receiver FIFO level */ | |
+#define RT2880_UART_TFL 0x04 /* Transmitter FIFO level */ | |
+#define RT2880_UART_ICR 0x05 /* Index Control Register */ | |
+ | |
+/* The 16950 ICR registers */ | |
+#define RT2880_UART_ACR 0x00 /* Additional Control Register */ | |
+#define RT2880_UART_CPR 0x01 /* Clock Prescalar Register */ | |
+#define RT2880_UART_TCR 0x02 /* Times Clock Register */ | |
+#define RT2880_UART_CKS 0x03 /* Clock Select Register */ | |
+#define RT2880_UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */ | |
+#define RT2880_UART_RTL 0x05 /* Receiver Interrupt Trigger Level */ | |
+#define RT2880_UART_FCL 0x06 /* Flow Control Level Lower */ | |
+#define RT2880_UART_FCH 0x07 /* Flow Control Level Higher */ | |
+#define RT2880_UART_ID1 0x08 /* ID #1 */ | |
+#define RT2880_UART_ID2 0x09 /* ID #2 */ | |
+#define RT2880_UART_ID3 0x0A /* ID #3 */ | |
+#define RT2880_UART_REV 0x0B /* Revision */ | |
+#define RT2880_UART_CSR 0x0C /* Channel Software Reset */ | |
+#define RT2880_UART_NMR 0x0D /* Nine-bit Mode Register */ | |
+#define RT2880_UART_CTR 0xFF | |
+ | |
+/* | |
+ * The 16C950 Additional Control Reigster | |
+ */ | |
+#define RT2880_UART_ACR_RXDIS 0x01 /* Receiver disable */ | |
+#define RT2880_UART_ACR_TXDIS 0x02 /* Receiver disable */ | |
+#define RT2880_UART_ACR_DSRFC 0x04 /* DSR Flow Control */ | |
+#define RT2880_UART_ACR_TLENB 0x20 /* 950 trigger levels enable */ | |
+#define RT2880_UART_ACR_ICRRD 0x40 /* ICR Read enable */ | |
+#define RT2880_UART_ACR_ASREN 0x80 /* Additional status enable */ | |
+ | |
+/* | |
+ * These definitions are for the RSA-DV II/S card, from | |
+ * | |
+ * Kiyokazu SUTO <suto@ks-and-ks.ne.jp> | |
+ */ | |
+ | |
+#define RT2880_UART_RSA_BASE (-8) | |
+ | |
+#define RT2880_UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */ | |
+ | |
+#define RT2880_UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */ | |
+#define RT2880_UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */ | |
+#define RT2880_UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */ | |
+#define RT2880_UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */ | |
+ | |
+#define RT2880_UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */ | |
+ | |
+#define RT2880_UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */ | |
+#define RT2880_UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */ | |
+#define RT2880_UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */ | |
+#define RT2880_UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */ | |
+#define RT2880_UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */ | |
+ | |
+#define RT2880_UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */ | |
+ | |
+#define RT2880_UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */ | |
+#define RT2880_UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */ | |
+#define RT2880_UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */ | |
+#define RT2880_UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */ | |
+#define RT2880_UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */ | |
+#define RT2880_UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */ | |
+#define RT2880_UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occurred (1) */ | |
+#define RT2880_UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occurred */ | |
+ | |
+#define RT2880_UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */ | |
+ | |
+#define RT2880_UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */ | |
+ | |
+#define RT2880_UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */ | |
+ | |
+#define RT2880_UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */ | |
+ | |
+/* | |
+ * The RSA DSV/II board has two fixed clock frequencies. One is the | |
+ * standard rate, and the other is 8 times faster. | |
+ */ | |
+#define SERIAL_RSA_BAUD_BASE (921600) | |
+#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) | |
+ | |
+/* | |
+ * Extra serial register definitions for the internal UARTs | |
+ * in TI OMAP processors. | |
+ */ | |
+#define RT2880_UART_OMAP_MDR1 0x08 /* Mode definition register */ | |
+#define RT2880_UART_OMAP_MDR2 0x09 /* Mode definition register 2 */ | |
+#define RT2880_UART_OMAP_SCR 0x10 /* Supplementary control register */ | |
+#define RT2880_UART_OMAP_SSR 0x11 /* Supplementary status register */ | |
+#define RT2880_UART_OMAP_EBLR 0x12 /* BOF length register */ | |
+#define RT2880_UART_OMAP_OSC_12M_SEL 0x13 /* OMAP1510 12MHz osc select */ | |
+#define RT2880_UART_OMAP_MVER 0x14 /* Module version register */ | |
+#define RT2880_UART_OMAP_SYSC 0x15 /* System configuration register */ | |
+#define RT2880_UART_OMAP_SYSS 0x16 /* System status register */ | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/surfboard.h b/arch/mips/include/asm/rt2880/surfboard.h | |
new file mode 100644 | |
index 000000000000..8e0f99a0cf63 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/surfboard.h | |
@@ -0,0 +1,34 @@ | |
+/* | |
+ * Copyright (C) 2001 Palmchip Corporation. All rights reserved. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_SURFBOARD_H | |
+#define __ASM_MACH_MIPS_RT2880_SURFBOARD_H | |
+ | |
+/* | |
+ * Surfboard UART base baud rate = System Clock / 16. | |
+ * Ex. (14.7456 MHZ / 16) = 921600 | |
+ * (32.0000 MHZ / 16) = 2000000 | |
+ */ | |
+#define SURFBOARD_BAUD_DIV (16) | |
+ | |
+extern unsigned int get_surfboard_sysclk(void); | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/surfboardint.h b/arch/mips/include/asm/rt2880/surfboardint.h | |
new file mode 100644 | |
index 000000000000..15c9e8911f8c | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/surfboardint.h | |
@@ -0,0 +1,208 @@ | |
+/* | |
+ * Copyright (C) 2001 Palmchip Corporation. All rights reserved. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * Defines for the Surfboard interrupt controller. | |
+ * | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_SURFBOARDINT_H | |
+#define __ASM_MACH_MIPS_RT2880_SURFBOARDINT_H | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ | |
+#ifdef CONFIG_MIPS_GIC | |
+#include <linux/irqchip/mips-gic.h> | |
+#else | |
+#define GIC_NUM_LOCAL_INTRS 7 | |
+#define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS | |
+#define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) | |
+#endif | |
+ | |
+/* MIPS GIC controller */ | |
+#define GIC_NUM_INTRS 64 | |
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | |
+ | |
+#define SURFBOARDINT_FE (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(3)) /* FE */ | |
+#define SURFBOARDINT_PCIE0 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(4)) /* PCIE0 */ | |
+#define SURFBOARDINT_AUX_TIMER (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(5)) /* AUX timer (systick) */ | |
+#define SURFBOARDINT_SYSCTL (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(6)) /* SYSCTL */ | |
+#define SURFBOARDINT_I2C (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(8)) /* I2C */ | |
+#define SURFBOARDINT_DRAMC (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(9)) /* DRAMC */ | |
+#define SURFBOARDINT_PCM (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(10)) /* PCM */ | |
+#define SURFBOARDINT_HSGDMA (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(11)) /* HSGDMA */ | |
+#define SURFBOARDINT_GPIO (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(12)) /* GPIO */ | |
+#define SURFBOARDINT_DMA (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(13)) /* GDMA */ | |
+#define SURFBOARDINT_NAND (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(14)) /* NAND */ | |
+#define SURFBOARDINT_NAND_ECC (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(15)) /* NFI ECC */ | |
+#define SURFBOARDINT_I2S (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(16)) /* I2S */ | |
+#define SURFBOARDINT_SPI (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(17)) /* SPI */ | |
+#define SURFBOARDINT_SPDIF (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(18)) /* SPDIF */ | |
+#define SURFBOARDINT_CRYPTO (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(19)) /* CryptoEngine */ | |
+#define SURFBOARDINT_SDXC (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(20)) /* SDXC */ | |
+#define SURFBOARDINT_R2P (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(21)) /* Rbus to Pbus */ | |
+#define SURFBOARDINT_USB (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(22)) /* USB */ | |
+#define SURFBOARDINT_ESW (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(23)) /* Switch */ | |
+#define SURFBOARDINT_PCIE1 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(24)) /* PCIE1 */ | |
+#define SURFBOARDINT_PCIE2 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(25)) /* PCIE2 */ | |
+#define SURFBOARDINT_UART_LITE1 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(26)) /* UART Lite */ | |
+#define SURFBOARDINT_UART_LITE2 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(27)) /* UART Lite */ | |
+#define SURFBOARDINT_UART_LITE3 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(28)) /* UART Lite */ | |
+#define SURFBOARDINT_WDG (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(29)) /* WDG timer */ | |
+#define SURFBOARDINT_TIMER0 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(30)) /* Timer0 */ | |
+#define SURFBOARDINT_TIMER1 (MIPS_GIC_IRQ_BASE + GIC_SHARED_TO_HWIRQ(31)) /* Timer1 */ | |
+#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 | |
+#define SURFBOARDINT_UART2 SURFBOARDINT_UART_LITE2 | |
+ | |
+#define SURFBOARDINT_END (MIPS_GIC_IRQ_BASE + GIC_NUM_LOCAL_INTRS + GIC_NUM_INTRS - 1) | |
+ | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ | |
+#define MIPS_INTC_CHAIN_HW0 (MIPS_CPU_IRQ_BASE + 2) /* Chain IP2 */ | |
+#define MIPS_INTC_CHAIN_HW1 (MIPS_CPU_IRQ_BASE + 3) /* Chain IP3 */ | |
+#define SURFBOARDINT_PCIE0 (MIPS_CPU_IRQ_BASE + 4) /* PCIe Slot0 */ | |
+#define SURFBOARDINT_FE (MIPS_CPU_IRQ_BASE + 5) /* Frame Engine */ | |
+#define SURFBOARDINT_WLAN (MIPS_CPU_IRQ_BASE + 6) /* Wireless */ | |
+#define SURFBOARDINT_MIPS_TIMER (MIPS_CPU_IRQ_BASE + 7) /* MIPS Timer */ | |
+ | |
+#define INTC_NUM_INTRS 32 | |
+#define MIPS_INTC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | |
+ | |
+#define SURFBOARDINT_SYSCTL (MIPS_INTC_IRQ_BASE + 0) /* SYSCTL */ | |
+#define SURFBOARDINT_ILL_ACC (MIPS_INTC_IRQ_BASE + 3) /* Illegal access */ | |
+#define SURFBOARDINT_PCM (MIPS_INTC_IRQ_BASE + 4) /* PCM */ | |
+#define SURFBOARDINT_GPIO (MIPS_INTC_IRQ_BASE + 6) /* GPIO */ | |
+#define SURFBOARDINT_DMA (MIPS_INTC_IRQ_BASE + 7) /* DMA */ | |
+#define SURFBOARDINT_NAND (MIPS_INTC_IRQ_BASE + 8) /* NAND */ | |
+#define SURFBOARDINT_PCTRL (MIPS_INTC_IRQ_BASE + 9) /* Performance counter */ | |
+#define SURFBOARDINT_I2S (MIPS_INTC_IRQ_BASE + 10) /* I2S */ | |
+#define SURFBOARDINT_SPI (MIPS_INTC_IRQ_BASE + 11) /* SPI */ | |
+ | |
+#define SURFBOARDINT_SDXC (MIPS_INTC_IRQ_BASE + 14) /* SDXC */ | |
+#define SURFBOARDINT_R2P (MIPS_INTC_IRQ_BASE + 15) /* Rbus to Pbus */ | |
+ | |
+#define SURFBOARDINT_AESENGINE (MIPS_INTC_IRQ_BASE + 13) /* AES Engine */ | |
+#define SURFBOARDINT_UART_LITE1 (MIPS_INTC_IRQ_BASE + 20) /* UART Lite 1 */ | |
+#define SURFBOARDINT_UART_LITE2 (MIPS_INTC_IRQ_BASE + 21) /* UART Lite 2 */ | |
+#define SURFBOARDINT_UART_LITE3 (MIPS_INTC_IRQ_BASE + 22) /* UART Lite 3 */ | |
+#define SURFBOARDINT_WDG (MIPS_INTC_IRQ_BASE + 23) /* WDG timer */ | |
+#define SURFBOARDINT_TIMER0 (MIPS_INTC_IRQ_BASE + 24) /* Timer0 */ | |
+#define SURFBOARDINT_TIMER1 (MIPS_INTC_IRQ_BASE + 25) /* Timer1 */ | |
+#define SURFBOARDINT_PWM (MIPS_INTC_IRQ_BASE + 26) /* PWM */ | |
+#define SURFBOARDINT_WWAKE (MIPS_INTC_IRQ_BASE + 27) /* WLAN Wake */ | |
+#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 | |
+#define SURFBOARDINT_UART2 SURFBOARDINT_UART_LITE2 | |
+ | |
+#define SURFBOARDINT_ESW (MIPS_INTC_IRQ_BASE + 17) /* Embedded Switch */ | |
+#define SURFBOARDINT_UHST (MIPS_INTC_IRQ_BASE + 18) /* USB Host */ | |
+#define SURFBOARDINT_UDEV (MIPS_INTC_IRQ_BASE + 19) /* USB Device */ | |
+ | |
+#define SURFBOARDINT_END (MIPS_INTC_IRQ_BASE + INTC_NUM_INTRS - 1) | |
+ | |
+#elif defined(CONFIG_MIPS_TC3262_1004K) | |
+ | |
+#include <asm/tc3162/tc3262_int_source.h> | |
+ | |
+/* MIPS GIC controller (via EIC) */ | |
+#define GIC_NUM_INTRS 64 | |
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) | |
+ | |
+#define SURFBOARDINT_UART_LITE1 UART_INT /* UART Lite1 */ | |
+#define SURFBOARDINT_TIMER0 TIMER0_INT, /* Timer0 */ | |
+#define SURFBOARDINT_TIMER1 TIMER1_INT /* Timer1 */ | |
+#define SURFBOARDINT_TIMER2 TIMER2_INT /* Timer2 */ | |
+#define SURFBOARDINT_WDG TIMER5_INT /* WDG timer */ | |
+#define SURFBOARDINT_GPIO GPIO_INT /* GPIO */ | |
+#define SURFBOARDINT_PCM PCM1_INT /* PCM */ | |
+#define SURFBOARDINT_ESW MAC1_INT /* ESW */ | |
+#define SURFBOARDINT_UART_LITE2 UART2_INT /* UART Lite2 */ | |
+#define SURFBOARDINT_USB IRQ_RT3XXX_USB /* USB */ | |
+#define SURFBOARDINT_DMT DMT_INT /* xDSL DMT */ | |
+#define SURFBOARDINT_QDMA1 QDMA_LAN0_INTR /* QDMA1, INT0 */ | |
+#define SURFBOARDINT_QDMA2 QDMA_WAN0_INTR /* QDMA2, INT0 */ | |
+#define SURFBOARDINT_PCIE0 PCIE_0_INT /* PCIE0 */ | |
+#define SURFBOARDINT_PCIE1 PCIE_A_INT /* PCIE1 */ | |
+#define SURFBOARDINT_CRYPTO CRYPTO_INT /* CryptoEngine */ | |
+#define SURFBOARDINT_QDMA1_INT1 QDMA_LAN1_INTR /* QDMA1, INT1 */ | |
+#define SURFBOARDINT_QDMA1_INT2 QDMA_LAN2_INTR /* QDMA1, INT2 */ | |
+#define SURFBOARDINT_QDMA1_INT3 QDMA_LAN3_INTR /* QDMA1, INT3 */ | |
+#define SURFBOARDINT_QDMA2_INT1 QDMA_WAN1_INTR /* QDMA2, INT1 */ | |
+#define SURFBOARDINT_QDMA2_INT2 QDMA_WAN2_INTR /* QDMA2, INT2 */ | |
+#define SURFBOARDINT_QDMA2_INT3 QDMA_WAN3_INTR /* QDMA2, INT3 */ | |
+#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 | |
+#define SURFBOARDINT_UART2 SURFBOARDINT_UART_LITE2 | |
+ | |
+#define SURFBOARDINT_END (INTR_SOURCES_NUM - 1) | |
+ | |
+#elif defined(CONFIG_MIPS_TC3262_34K) | |
+ | |
+#include <asm/tc3162/tc3262_int_source.h> | |
+ | |
+#define SURFBOARDINT_UART1 UART_INT /* UART1 */ | |
+#define SURFBOARDINT_GPIO GPIO_INT /* GPIO */ | |
+#define SURFBOARDINT_PCM PCM1_INT /* PCM1 */ | |
+#define SURFBOARDINT_DMA APB_DMA0_INT /* DMA */ | |
+#define SURFBOARDINT_ESW ESW_INT /* ESW */ | |
+#define SURFBOARDINT_USB IRQ_RT3XXX_USB /* USB */ | |
+#define SURFBOARDINT_FE FE_MAC_INT /* Frame Engine */ | |
+#define SURFBOARDINT_QDMA SAR_INT /* QDMA */ | |
+#define SURFBOARDINT_PCIE0 PCIE_0_INT /* PCIe0 */ | |
+#define SURFBOARDINT_PCIE1 PCIE_A_INT /* PCIe1 */ | |
+#define SURFBOARDINT_CRYPTO CRYPTO_INT /* CryptoEngine */ | |
+ | |
+#define SURFBOARDINT_END 40 /* 1 offset + 40 TC */ | |
+ | |
+#else | |
+#error "Ralink chip undefined for INT map" | |
+#endif | |
+ | |
+/* | |
+ * Surfboard registers are memory mapped on 32-bit aligned boundaries and | |
+ * only word access are allowed. | |
+ */ | |
+#ifndef CONFIG_MIPS_TC3262 | |
+#define RALINK_IRQ0STAT (RALINK_INTCL_BASE + 0x9C) //IRQ_STAT | |
+#define RALINK_IRQ1STAT (RALINK_INTCL_BASE + 0xA0) //FIQ_STAT | |
+#define RALINK_INTTYPE (RALINK_INTCL_BASE + 0x6C) //FIQ_SEL | |
+#define RALINK_INTRAW (RALINK_INTCL_BASE + 0xA4) //INT_PURE | |
+#define RALINK_INTENA (RALINK_INTCL_BASE + 0x80) //IRQ_MASK_SET | |
+#define RALINK_FIQENA (RALINK_INTCL_BASE + 0x84) //FIQ_MASK_SET | |
+#define RALINK_INTDIS (RALINK_INTCL_BASE + 0x78) //IRQ_MASK_CLR | |
+#define RALINK_FIQDIS (RALINK_INTCL_BASE + 0x7C) //FIQ_MASK_CLR | |
+#endif | |
+ | |
+/* bobtseng added ++, 2006.3.6. */ | |
+#define read_32bit_cp0_register(source) \ | |
+({ int __res; \ | |
+ __asm__ __volatile__( \ | |
+ ".set\tpush\n\t" \ | |
+ ".set\treorder\n\t" \ | |
+ "mfc0\t%0,"STR(source)"\n\t" \ | |
+ ".set\tpop" \ | |
+ : "=r" (__res)); \ | |
+ __res;}) | |
+ | |
+#define write_32bit_cp0_register(register,value) \ | |
+ __asm__ __volatile__( \ | |
+ "mtc0\t%0,"STR(register)"\n\t" \ | |
+ "nop" \ | |
+ : : "r" (value)); | |
+ | |
+/* bobtseng added --, 2006.3.6. */ | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/rt2880/war.h b/arch/mips/include/asm/rt2880/war.h | |
new file mode 100644 | |
index 000000000000..581de3f8c738 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/rt2880/war.h | |
@@ -0,0 +1,26 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | |
+ * Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com> | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_RT2880_WAR_H | |
+#define __ASM_MACH_MIPS_RT2880_WAR_H | |
+ | |
+#define R4600_V1_INDEX_ICACHEOP_WAR 0 | |
+#define R4600_V1_HIT_CACHEOP_WAR 0 | |
+#define R4600_V2_HIT_CACHEOP_WAR 0 | |
+#define R5432_CP0_INTERRUPT_WAR 0 | |
+#define BCM1250_M3_WAR 0 | |
+#define SIBYTE_1956_WAR 0 | |
+#define MIPS4K_ICACHE_REFILL_WAR 0 | |
+#define MIPS_CACHE_SYNC_WAR 0 | |
+#define TX49XX_ICACHE_INDEX_INV_WAR 0 | |
+#define RM9000_CDEX_SMP_WAR 0 | |
+#define ICACHE_REFILLS_WORKAROUND_WAR 0 | |
+#define R10000_LLSC_WAR 0 | |
+#define MIPS34K_MISSED_ITLB_WAR 0 | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h | |
index db7c322f057f..e5f49dd453c7 100644 | |
--- a/arch/mips/include/asm/smp-ops.h | |
+++ b/arch/mips/include/asm/smp-ops.h | |
@@ -26,7 +26,7 @@ struct plat_smp_ops { | |
void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); | |
void (*init_secondary)(void); | |
void (*smp_finish)(void); | |
- void (*boot_secondary)(int cpu, struct task_struct *idle); | |
+ int (*boot_secondary)(int cpu, struct task_struct *idle); | |
void (*smp_setup)(void); | |
void (*prepare_cpus)(unsigned int max_cpus); | |
#ifdef CONFIG_HOTPLUG_CPU | |
@@ -35,11 +35,11 @@ struct plat_smp_ops { | |
#endif | |
}; | |
-extern void register_smp_ops(struct plat_smp_ops *ops); | |
+extern void register_smp_ops(const struct plat_smp_ops *ops); | |
static inline void plat_smp_setup(void) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
mp_ops->smp_setup(); | |
} | |
@@ -57,7 +57,7 @@ static inline void plat_smp_setup(void) | |
/* UP, nothing to do ... */ | |
} | |
-static inline void register_smp_ops(struct plat_smp_ops *ops) | |
+static inline void register_smp_ops(const struct plat_smp_ops *ops) | |
{ | |
} | |
@@ -66,7 +66,7 @@ static inline void register_smp_ops(struct plat_smp_ops *ops) | |
static inline int register_up_smp_ops(void) | |
{ | |
#ifdef CONFIG_SMP_UP | |
- extern struct plat_smp_ops up_smp_ops; | |
+ extern const struct plat_smp_ops up_smp_ops; | |
register_smp_ops(&up_smp_ops); | |
@@ -79,7 +79,7 @@ static inline int register_up_smp_ops(void) | |
static inline int register_cmp_smp_ops(void) | |
{ | |
#ifdef CONFIG_MIPS_CMP | |
- extern struct plat_smp_ops cmp_smp_ops; | |
+ extern const struct plat_smp_ops cmp_smp_ops; | |
if (!mips_cm_present()) | |
return -ENODEV; | |
@@ -95,7 +95,7 @@ static inline int register_cmp_smp_ops(void) | |
static inline int register_vsmp_smp_ops(void) | |
{ | |
#ifdef CONFIG_MIPS_MT_SMP | |
- extern struct plat_smp_ops vsmp_smp_ops; | |
+ extern const struct plat_smp_ops vsmp_smp_ops; | |
register_smp_ops(&vsmp_smp_ops); | |
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h | |
index 258158c34df1..6d4ac5465864 100644 | |
--- a/arch/mips/include/asm/smp.h | |
+++ b/arch/mips/include/asm/smp.h | |
@@ -52,11 +52,7 @@ extern int __cpu_logical_map[NR_CPUS]; | |
#define SMP_CALL_FUNCTION 0x2 | |
/* Octeon - Tell another core to flush its icache */ | |
#define SMP_ICACHE_FLUSH 0x4 | |
-/* Used by kexec crashdump to save all cpu's state */ | |
-#define SMP_DUMP 0x8 | |
-#define SMP_ASK_C0COUNT 0x10 | |
- | |
-extern cpumask_t cpu_callin_map; | |
+#define SMP_ASK_C0COUNT 0x8 | |
/* Mask of CPUs which are currently definitely operating coherently */ | |
extern cpumask_t cpu_coherent_mask; | |
@@ -72,7 +68,7 @@ extern void calculate_cpu_foreign_map(void); | |
*/ | |
static inline void smp_send_reschedule(int cpu) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF); | |
} | |
@@ -80,14 +76,14 @@ static inline void smp_send_reschedule(int cpu) | |
#ifdef CONFIG_HOTPLUG_CPU | |
static inline int __cpu_disable(void) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
return mp_ops->cpu_disable(); | |
} | |
static inline void __cpu_die(unsigned int cpu) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
mp_ops->cpu_die(cpu); | |
} | |
@@ -111,20 +107,16 @@ int mips_smp_ipi_free(const struct cpumask *mask); | |
static inline void arch_send_call_function_single_ipi(int cpu) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION); | |
} | |
static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) | |
{ | |
- extern struct plat_smp_ops *mp_ops; /* private */ | |
+ extern const struct plat_smp_ops *mp_ops; /* private */ | |
mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION); | |
} | |
-#if defined(CONFIG_KEXEC) | |
-extern void (*dump_ipi_function_ptr)(void *); | |
-void dump_send_ipi(void (*dump_ipi_callback)(void *)); | |
-#endif | |
#endif /* __ASM_SMP_H */ | |
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h | |
index 2f182bdf024f..16f022942274 100644 | |
--- a/arch/mips/include/asm/stackframe.h | |
+++ b/arch/mips/include/asm/stackframe.h | |
@@ -383,14 +383,6 @@ | |
RESTORE_SP | |
.endm | |
- .macro RESTORE_ALL_AND_RET | |
- RESTORE_TEMP | |
- RESTORE_STATIC | |
- RESTORE_AT | |
- RESTORE_SOME | |
- RESTORE_SP_AND_RET | |
- .endm | |
- | |
/* | |
* Move to kernel mode and disable interrupts. | |
* Set cp0 enable bit as sign that we're running on the kernel stack | |
diff --git a/arch/mips/include/asm/string.h b/arch/mips/include/asm/string.h | |
index 29030cb398ee..7b737f9b6d58 100644 | |
--- a/arch/mips/include/asm/string.h | |
+++ b/arch/mips/include/asm/string.h | |
@@ -140,4 +140,42 @@ extern void *memcpy(void *__to, __const__ void *__from, size_t __n); | |
#define __HAVE_ARCH_MEMMOVE | |
extern void *memmove(void *__dest, __const__ void *__src, size_t __n); | |
+#ifndef __ZBOOT__ | |
+#define memset(__s, __c, len) \ | |
+({ \ | |
+ size_t __len = (len); \ | |
+ void *__ret; \ | |
+ if (__builtin_constant_p(len) && __len >= 64) \ | |
+ __ret = memset((__s), (__c), __len); \ | |
+ else \ | |
+ __ret = __builtin_memset((__s), (__c), __len); \ | |
+ __ret; \ | |
+}) | |
+ | |
+#define memcpy(dst, src, len) \ | |
+({ \ | |
+ size_t __len = (len); \ | |
+ void *__ret; \ | |
+ if (__builtin_constant_p(len) && __len >= 64) \ | |
+ __ret = memcpy((dst), (src), __len); \ | |
+ else \ | |
+ __ret = __builtin_memcpy((dst), (src), __len); \ | |
+ __ret; \ | |
+}) | |
+ | |
+#define memmove(dst, src, len) \ | |
+({ \ | |
+ size_t __len = (len); \ | |
+ void *__ret; \ | |
+ if (__builtin_constant_p(len) && __len >= 64) \ | |
+ __ret = memmove((dst), (src), __len); \ | |
+ else \ | |
+ __ret = __builtin_memmove((dst), (src), __len); \ | |
+ __ret; \ | |
+}) | |
+ | |
+#define __HAVE_ARCH_MEMCMP | |
+#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len)) | |
+#endif | |
+ | |
#endif /* _ASM_STRING_H */ | |
diff --git a/arch/mips/include/asm/tc3162/cpu-feature-overrides.h b/arch/mips/include/asm/tc3162/cpu-feature-overrides.h | |
new file mode 100644 | |
index 000000000000..8801b853cac9 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/cpu-feature-overrides.h | |
@@ -0,0 +1,86 @@ | |
+/* | |
+ * Ralink specific CPU feature overrides | |
+ * | |
+ * This file was derived from: include/asm-mips/cpu-features.h | |
+ * Copyright (C) 2003, 2004 Ralf Baechle | |
+ * Copyright (C) 2004 Maciej W. Rozycki | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License version 2 as published | |
+ * by the Free Software Foundation. | |
+ * | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_TC3262_CPU_FEATURE_OVERRIDES_H | |
+#define __ASM_MACH_MIPS_TC3262_CPU_FEATURE_OVERRIDES_H | |
+ | |
+/* EN75xx */ | |
+ | |
+/* CPU options */ | |
+#define cpu_has_tlb 1 | |
+#define cpu_has_4kex 1 | |
+#define cpu_has_3k_cache 0 | |
+#define cpu_has_4k_cache 1 | |
+#define cpu_has_tx39_cache 0 | |
+#define cpu_has_fpu 0 | |
+#define cpu_has_32fpr 0 | |
+#define cpu_has_counter 1 | |
+ | |
+#define cpu_has_watch 1 | |
+#define cpu_has_divec 1 | |
+#define cpu_has_vce 0 | |
+#define cpu_has_cache_cdex_p 0 | |
+#define cpu_has_cache_cdex_s 0 | |
+#define cpu_has_mcheck 1 | |
+#define cpu_has_ejtag 1 | |
+#define cpu_has_nofpuex 0 | |
+ | |
+#define cpu_has_llsc 1 | |
+#define cpu_has_inclusive_pcaches 0 | |
+#define cpu_has_prefetch 1 | |
+#define cpu_has_vint 1 | |
+#define cpu_has_veic 1 | |
+#define cpu_has_userlocal 1 | |
+#define cpu_has_perf_cntr_intr_bit 1 | |
+#define cpu_has_rixi 0 | |
+ | |
+/* CPU ases */ | |
+#define cpu_has_mips16 1 | |
+#define cpu_has_mdmx 0 | |
+#define cpu_has_mips3d 0 | |
+#define cpu_has_smartmips 0 | |
+#define cpu_has_dsp 1 | |
+#define cpu_has_mipsmt 1 | |
+#define cpu_has_dsp2 0 | |
+#define cpu_has_vz 0 | |
+ | |
+/* CPU ISA level */ | |
+#define cpu_has_mips_2 1 | |
+#define cpu_has_mips_3 0 | |
+#define cpu_has_mips_4 0 | |
+#define cpu_has_mips_5 0 | |
+#define cpu_has_mips32r1 1 | |
+#define cpu_has_mips32r2 1 | |
+#define cpu_has_mips64r1 0 | |
+#define cpu_has_mips64r2 0 | |
+ | |
+#define cpu_has_mips32r6 0 | |
+#define cpu_has_mips64r6 0 | |
+ | |
+#define cpu_has_64bits 0 | |
+#define cpu_has_64bit_zero_reg 0 | |
+#define cpu_has_64bit_gp_regs 0 | |
+#define cpu_has_64bit_addresses 0 | |
+ | |
+/* CPU cache info */ | |
+#define cpu_has_vtag_icache 0 | |
+#define cpu_has_ic_fills_f_dc 0 | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+#define cpu_has_dc_aliases 0 | |
+#else | |
+#define cpu_icache_snoops_remote_store 1 | |
+#define cpu_has_dc_aliases 1 | |
+#endif | |
+#define cpu_dcache_line_size() 32 | |
+#define cpu_icache_line_size() 32 | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/irq.h b/arch/mips/include/asm/tc3162/irq.h | |
new file mode 100644 | |
index 000000000000..5e6868b5e432 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/irq.h | |
@@ -0,0 +1,19 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2003 by Ralf Baechle | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_TC3262_IRQ_H | |
+#define __ASM_MACH_MIPS_TC3262_IRQ_H | |
+ | |
+#define MIPS_CPU_IRQ_BASE 0 | |
+ | |
+#include <asm/tc3162/surfboardint.h> | |
+ | |
+#define NR_IRQS (SURFBOARDINT_END + 1) | |
+ | |
+#include_next <irq.h> | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/launch.h b/arch/mips/include/asm/tc3162/launch.h | |
new file mode 100644 | |
index 000000000000..b26c4dbf9bea | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/launch.h | |
@@ -0,0 +1,42 @@ | |
+/* | |
+ * | |
+ */ | |
+ | |
+#ifndef _ASSEMBLER_ | |
+ | |
+struct cpulaunch { | |
+ unsigned long pc; | |
+ unsigned long gp; | |
+ unsigned long sp; | |
+ unsigned long a0; | |
+ unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */ | |
+ unsigned long flags; | |
+}; | |
+ | |
+#else | |
+ | |
+#define LOG2CPULAUNCH 5 | |
+#define LAUNCH_PC 0 | |
+#define LAUNCH_GP 4 | |
+#define LAUNCH_SP 8 | |
+#define LAUNCH_A0 12 | |
+#define LAUNCH_FLAGS 28 | |
+ | |
+#endif | |
+ | |
+#define LAUNCH_FREADY 1 | |
+#define LAUNCH_FGO 2 | |
+#define LAUNCH_FGONE 4 | |
+ | |
+#define CPULAUNCH 0x00000f00 | |
+#define NCPULAUNCH 8 | |
+ | |
+/* Polling period in count cycles for secondary CPU's */ | |
+#define LAUNCHPERIOD 10000 | |
+ | |
+/* use GDMP SRAM for CPU 1,2,3's waiting code and launch flags */ | |
+#define GDMP_SRAM_BASE 0xBFA40000 | |
+#define BUSY_WAIT_ZONE_START 0x040 | |
+#define BUSY_WAIT_ZONE_SIZE 0x100 | |
+#define BUSY_WAIT_ZONE_BASE (GDMP_SRAM_BASE + BUSY_WAIT_ZONE_START) /* 0xbfa40040 */ | |
+#define CPU_LAUNCH_BASE (GDMP_SRAM_BASE + BUSY_WAIT_ZONE_START + BUSY_WAIT_ZONE_SIZE) /* 0xbfa40140 */ | |
diff --git a/arch/mips/include/asm/tc3162/pbus-timer.h b/arch/mips/include/asm/tc3162/pbus-timer.h | |
new file mode 100644 | |
index 000000000000..6d02ebcb2748 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/pbus-timer.h | |
@@ -0,0 +1,139 @@ | |
+#ifndef __ASM_MACH_TC3262_PBUS_TIMER_H | |
+#define __ASM_MACH_TC3262_PBUS_TIMER_H | |
+ | |
+#include <linux/io.h> | |
+#include <linux/kernel.h> | |
+#include <asm/tc3162/tc3162.h> | |
+#include <asm/tc3162/tc3262_int_source.h> | |
+ | |
+#define PBUS_TIMER_0 (0) | |
+#define PBUS_TIMER_1 (1) | |
+#define PBUS_TIMER_2 (2) | |
+#define PBUS_TIMER_3 (5) | |
+ | |
+#define PBUS_TIMER_WATCHDOG (PBUS_TIMER_3) | |
+ | |
+#define PBUS_TIMER_0_IRQ (TIMER0_INT) | |
+#define PBUS_TIMER_1_IRQ (TIMER1_INT) | |
+#define PBUS_TIMER_2_IRQ (TIMER2_INT) | |
+#define PBUS_TIMER_3_IRQ (TIMER5_INT) | |
+ | |
+#define PBUS_TIMER_CTRL (0xbfbf0100) | |
+#define PBUS_TIMER_LVR(n) (0xbfbf0104 + (n) * 8) | |
+#define PBUS_TIMER_CVR(n) (0xbfbf0108 + (n) * 8) | |
+#define PBUS_TIMER_WDOGTHSLD (0xbfbf0134) | |
+#define PBUS_TIMER_RLDWDOG (0xbfbf0138) | |
+ | |
+#define PBUS_TIMER_CTRL_HALT(n) (1U << (26 + (n))) | |
+#define PBUS_TIMER_CTRL_WDG_ENABLE (1U << (25)) | |
+#define PBUS_TIMER_CTRL_INT_ACK(n) (1U << (16 + (n))) | |
+#define PBUS_TIMER_CTRL_PERIODIC(n) (1U << (8 + (n))) | |
+#define PBUS_TIMER_CTRL_ENABLE(n) (1U << (0 + (n))) | |
+ | |
+#define PBUS_TIMER_CTRL_INT_ACK_MASK \ | |
+ (PBUS_TIMER_CTRL_INT_ACK(PBUS_TIMER_0) | \ | |
+ PBUS_TIMER_CTRL_INT_ACK(PBUS_TIMER_1) | \ | |
+ PBUS_TIMER_CTRL_INT_ACK(PBUS_TIMER_2) | \ | |
+ PBUS_TIMER_CTRL_INT_ACK(PBUS_TIMER_3)) | |
+ | |
+#define PBUS_TIMER_TICKS_IN_MSEC ((SYS_HCLK) / 2 * 1000) | |
+ | |
+static inline void | |
+pbus_timer_w32(const u32 reg, const u32 val) | |
+{ | |
+ __raw_writel(val, (void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+static inline u32 | |
+pbus_timer_r32(const u32 reg) | |
+{ | |
+ return __raw_readl((void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+static inline bool | |
+pbus_timer_enable(const unsigned int n, | |
+ const unsigned int interval_ms, | |
+ const enum pbus_timer_mode mode) | |
+{ | |
+ u32 ctrl; | |
+ | |
+ /* an interval is too large */ | |
+ if (U32_MAX / interval_ms < PBUS_TIMER_TICKS_IN_MSEC) | |
+ return false; | |
+ | |
+ ctrl = pbus_timer_r32(PBUS_TIMER_CTRL); | |
+ | |
+ if (mode == PBUS_TIMER_MODE_WATCHDOG) { | |
+ /* enable a watchdog function for a timer | |
+ * that does not support it | |
+ */ | |
+ if (n != PBUS_TIMER_WATCHDOG) | |
+ return false; | |
+ | |
+ ctrl |= PBUS_TIMER_CTRL_WDG_ENABLE; | |
+ pbus_timer_w32(PBUS_TIMER_WDOGTHSLD, U32_MAX); | |
+ } else { | |
+ /* use a watchdog timer as an interval or periodic timer | |
+ */ | |
+ if (n == PBUS_TIMER_WATCHDOG) | |
+ ctrl &= ~PBUS_TIMER_CTRL_WDG_ENABLE; | |
+ } | |
+ | |
+ pbus_timer_w32(PBUS_TIMER_LVR(n), | |
+ interval_ms * PBUS_TIMER_TICKS_IN_MSEC); | |
+ | |
+ ctrl &= ~PBUS_TIMER_CTRL_INT_ACK_MASK; | |
+ ctrl &= ~PBUS_TIMER_CTRL_HALT(n); | |
+ ctrl |= PBUS_TIMER_CTRL_ENABLE(n); | |
+ | |
+ if (mode == PBUS_TIMER_MODE_PERIODIC) | |
+ ctrl |= PBUS_TIMER_CTRL_PERIODIC(n); | |
+ else | |
+ ctrl &= ~PBUS_TIMER_CTRL_PERIODIC(n); | |
+ | |
+ pbus_timer_w32(PBUS_TIMER_CTRL, ctrl); | |
+ | |
+ return true; | |
+} | |
+ | |
+static inline void | |
+pbus_timer_disable(const unsigned int n) | |
+{ | |
+ u32 ctrl = pbus_timer_r32(PBUS_TIMER_CTRL); | |
+ | |
+ ctrl &= ~PBUS_TIMER_CTRL_INT_ACK_MASK; | |
+ ctrl &= ~PBUS_TIMER_CTRL_ENABLE(n); | |
+ pbus_timer_w32(PBUS_TIMER_CTRL, ctrl); | |
+} | |
+ | |
+static inline void | |
+pbus_timer_restart(const unsigned int n) | |
+{ | |
+ u32 ctrl = pbus_timer_r32(PBUS_TIMER_CTRL); | |
+ | |
+ ctrl &= ~PBUS_TIMER_CTRL_INT_ACK_MASK; | |
+ ctrl &= ~PBUS_TIMER_CTRL_ENABLE(n); | |
+ pbus_timer_w32(PBUS_TIMER_CTRL, ctrl); | |
+ | |
+ ctrl |= PBUS_TIMER_CTRL_ENABLE(n); | |
+ pbus_timer_w32(PBUS_TIMER_CTRL, ctrl); | |
+} | |
+ | |
+static inline void | |
+pbus_timer_int_ack(const unsigned int n) | |
+{ | |
+ u32 ctrl = pbus_timer_r32(PBUS_TIMER_CTRL); | |
+ | |
+ ctrl &= ~PBUS_TIMER_CTRL_INT_ACK_MASK; | |
+ ctrl |= PBUS_TIMER_CTRL_INT_ACK(n); | |
+ pbus_timer_w32(PBUS_TIMER_CTRL, ctrl); | |
+} | |
+ | |
+static inline unsigned int | |
+pbus_timer_get(const unsigned int n) | |
+{ | |
+ return pbus_timer_r32(PBUS_TIMER_CVR(n)) / PBUS_TIMER_TICKS_IN_MSEC; | |
+} | |
+ | |
+#endif /* __ASM_MACH_TC3262_PBUS_TIMER_H */ | |
+ | |
diff --git a/arch/mips/include/asm/tc3162/prom.h b/arch/mips/include/asm/tc3162/prom.h | |
new file mode 100644 | |
index 000000000000..89009c93d472 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/prom.h | |
@@ -0,0 +1,35 @@ | |
+/* | |
+ * Carsten Langgaard, carstenl@mips.com | |
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * MIPS boards bootprom interface for the Linux kernel. | |
+ * | |
+ */ | |
+ | |
+#ifndef _MIPS_PROM_H | |
+#define _MIPS_PROM_H | |
+ | |
+extern char *prom_getcmdline(void); | |
+extern char *prom_getenv(char *name); | |
+extern void prom_printf(char *fmt, ...); | |
+extern void prom_init_cmdline(void); | |
+extern void prom_free_prom_memory(void); | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/rt_mmap.h b/arch/mips/include/asm/tc3162/rt_mmap.h | |
new file mode 100644 | |
index 000000000000..5744a1aa00c8 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/rt_mmap.h | |
@@ -0,0 +1,115 @@ | |
+#ifndef __ASM_MACH_MIPS_TC3262_RT_MMAP_H | |
+#define __ASM_MACH_MIPS_TC3262_RT_MMAP_H | |
+ | |
+/* EN7512(3)/EN7516/EN7527/EN7528 */ | |
+ | |
+#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) | |
+#define sysRegRead(phys) (*(volatile unsigned int *)PHYS_TO_K1(phys)) | |
+#define sysRegWrite(phys, val) ((*(volatile unsigned int *)PHYS_TO_K1(phys)) = (val)) | |
+ | |
+#define RALINK_SYSCTL_BASE 0xBFB00000 | |
+#define RALINK_TIMER_BASE 0xBFBF0100 | |
+#define RALINK_MEMCTRL_BASE 0xBFB20000 | |
+#define RALINK_PIO_BASE 0xBFBF0200 | |
+#define RALINK_I2C_BASE 0xBFBF8000 | |
+#define RALINK_UART_LITE_BASE 0xBFBF0000 | |
+#define RALINK_UART_LITE2_BASE 0xBFBF0300 | |
+#define RALINK_PCM_BASE 0xBFBD0000 | |
+#define RALINK_GDMA_BASE 0xBFB30000 | |
+#define RALINK_FRAME_ENGINE_BASE 0xBFB50000 | |
+#define RALINK_ETH_SW_BASE 0xBFB58000 | |
+#define RALINK_CRYPTO_ENGINE_BASE 0xBFB70000 | |
+#define RALINK_PCI_BASE 0xBFB80000 | |
+#define RALINK_PCI_PHY0_BASE 0xBFAF2000 | |
+#define RALINK_PCI_PHY1_BASE 0xBFAC0000 | |
+#define RALINK_USB_HOST_BASE 0x1FB90000 | |
+#define RALINK_XHCI_HOST_BASE 0xBFB90000 | |
+#define RALINK_XHCI_UPHY_BASE 0xBFA80000 | |
+#define RALINK_SFC_BASE 0xBFA10000 | |
+#define RALINK_CHIP_SCU_BASE 0xBFA20000 | |
+#define RALINK_11N_MAC_BASE 0xBFB00000 // Unused | |
+ | |
+#if defined(CONFIG_ECONET_EN7528) | |
+#define RALINK_USB_HOST_SIZE 0x00003E00 | |
+#define RALINK_USB_IPPC_BASE 0x1FB93E00 | |
+#define RALINK_USB_UPHY_P0_BASE (RALINK_XHCI_UPHY_BASE + 0x0300) | |
+#define RALINK_USB_UPHY_P1_BASE (RALINK_XHCI_UPHY_BASE + 0x1300) | |
+#else | |
+#define RALINK_USB_HOST_SIZE 0x00004000 | |
+#define RALINK_USB_IPPC_BASE 0x1FA80700 | |
+#define RALINK_USB_UPHY_P0_BASE (RALINK_XHCI_UPHY_BASE + 0x0800) | |
+#define RALINK_USB_UPHY_P1_BASE (RALINK_XHCI_UPHY_BASE + 0x1000) | |
+#endif | |
+ | |
+#if defined(CONFIG_ECONET_EN7528) | |
+#define RALINK_WOE0_BASE 0x1FA02000 | |
+#define RALINK_WOE1_BASE 0x1FA03000 | |
+ | |
+#define RALINK_WDMA0_BASE 0x1FA06000 | |
+#define RALINK_WDMA1_BASE 0x1FA06400 | |
+#endif | |
+ | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+/* GIC */ | |
+#define RALINK_GIC_BASE 0x1F8C0000 | |
+#define RALINK_GIC_ADDRSPACE_SZ 0x20000 | |
+ | |
+/* CPC */ | |
+#define RALINK_CPC_BASE 0x1F8E8000 | |
+#define RALINK_CPC_ADDRSPACE_SZ 0x8000 | |
+ | |
+/* GCMP */ | |
+#define RALINK_GCMP_BASE 0x1F8E0000 | |
+#define RALINK_GCMP_ADDRSPACE_SZ 0x8000 | |
+ | |
+/* CM */ | |
+#define CM_GCR_REG0_BASE_VALUE 0x1C000000 /* CM region 0 base address (Palmbus) */ | |
+#define CM_GCR_REG0_MASK_VALUE 0x0000FC00 /* CM region 0 mask (64M) */ | |
+ | |
+#define CM_GCR_REG1_BASE_VALUE 0x20000000 /* CM region 1 base address (PCIe) */ | |
+#define CM_GCR_REG1_MASK_VALUE 0x0000F000 /* CM region 1 mask (256M) */ | |
+#else | |
+/* Interrupt Controller */ | |
+#define RALINK_INTCL_BASE 0xBFB40000 | |
+#define RALINK_INTCTL_UARTLITE (1<<0) | |
+#define RALINK_INTCTL_PIO (1<<10) | |
+#define RALINK_INTCTL_PCM (1<<11) | |
+#define RALINK_INTCTL_DMA (1<<14) | |
+#define RALINK_INTCTL_GSW (1<<15) | |
+#define RALINK_INTCTL_UHST (1<<17) | |
+#define RALINK_INTCTL_FE (1<<21) | |
+#define RALINK_INTCTL_QDMA (1<<22) | |
+#define RALINK_INTCTL_PCIE0 (1<<23) | |
+#define RALINK_INTCTL_PCIE1 (1<<24) | |
+ | |
+/* Reset Control Register */ | |
+#define RALINK_INTC_RST (1<<9) | |
+#endif | |
+ | |
+/* Reset Control Register */ | |
+#define RALINK_I2S1_RST (1<<0) | |
+#define RALINK_FE_QDMA_LAN_RST (1<<1) | |
+#define RALINK_FE_QDMA_WAN_RST (1<<2) | |
+#define RALINK_PCM2_RST (1<<4) | |
+#define RALINK_PTM_MAC_RST (1<<5) | |
+#define RALINK_CRYPTO_RST (1<<6) | |
+#define RALINK_SAR_RST (1<<7) | |
+#define RALINK_TIMER_RST (1<<8) | |
+#define RALINK_BONDING_RST (1<<10) | |
+#define RALINK_PCM1_RST (1<<11) | |
+#define RALINK_UART_RST (1<<12) | |
+#define RALINK_PIO_RST (1<<13) | |
+#define RALINK_DMA_RST (1<<14) | |
+#define RALINK_I2C_RST (1<<16) | |
+#define RALINK_I2S2_RST (1<<17) | |
+#define RALINK_SPI_RST (1<<18) | |
+#define RALINK_UARTL_RST (1<<19) | |
+#define RALINK_FE_RST (1<<21) | |
+#define RALINK_UHST_RST (1<<22) | |
+#define RALINK_ESW_RST (1<<23) | |
+#define RALINK_SFC2_RST (1<<25) | |
+#define RALINK_PCIE0_RST (1<<26) | |
+#define RALINK_PCIE1_RST (1<<27) | |
+#define RALINK_PCIEHB_RST (1<<29) | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/spaces.h b/arch/mips/include/asm/tc3162/spaces.h | |
new file mode 100644 | |
index 000000000000..30a39e17b7b9 | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/spaces.h | |
@@ -0,0 +1,25 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle | |
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki | |
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_TC3262_SPACES_H | |
+#define __ASM_MACH_MIPS_TC3262_SPACES_H | |
+ | |
+#define EN75XX_PALMBUS_START 0x1c000000 | |
+ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+#define EN75XX_HIGHMEM_START 0x40000000 | |
+#else | |
+#define EN75XX_HIGHMEM_START 0x9c000000 | |
+#endif | |
+ | |
+#define HIGHMEM_START _AC(EN75XX_HIGHMEM_START, UL) | |
+ | |
+#include <asm/mach-generic/spaces.h> | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/surfboardint.h b/arch/mips/include/asm/tc3162/surfboardint.h | |
new file mode 100644 | |
index 000000000000..5e9ef691d6ec | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/surfboardint.h | |
@@ -0,0 +1,79 @@ | |
+/* | |
+ * Copyright (C) 2001 Palmchip Corporation. All rights reserved. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ * ######################################################################## | |
+ * | |
+ * Defines for the Surfboard interrupt controller. | |
+ * | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_TC3262_SURFBOARDINT_H | |
+#define __ASM_MACH_MIPS_TC3262_SURFBOARDINT_H | |
+ | |
+#include "tc3262_int_source.h" | |
+ | |
+#if defined(CONFIG_MIPS_TC3262_1004K) | |
+ | |
+/* MIPS GIC controller (via EIC) */ | |
+#define GIC_NUM_INTRS 64 | |
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) | |
+ | |
+#define SURFBOARDINT_UART_LITE1 UART_INT /* UART Lite1 */ | |
+#define SURFBOARDINT_TIMER0 TIMER0_INT, /* Timer0 */ | |
+#define SURFBOARDINT_TIMER1 TIMER1_INT /* Timer1 */ | |
+#define SURFBOARDINT_TIMER2 TIMER2_INT /* Timer2 */ | |
+#define SURFBOARDINT_WDG TIMER5_INT /* WDG timer */ | |
+#define SURFBOARDINT_GPIO GPIO_INT /* GPIO */ | |
+#define SURFBOARDINT_PCM PCM1_INT /* PCM */ | |
+#define SURFBOARDINT_ESW MAC1_INT /* ESW */ | |
+#define SURFBOARDINT_UART_LITE2 UART2_INT /* UART Lite2 */ | |
+#define SURFBOARDINT_USB IRQ_RT3XXX_USB /* USB */ | |
+#define SURFBOARDINT_DMT DMT_INT /* xDSL DMT */ | |
+#define SURFBOARDINT_QDMA1 QDMA_LAN0_INTR /* QDMA1, INT0 */ | |
+#define SURFBOARDINT_QDMA2 QDMA_WAN0_INTR /* QDMA2, INT0 */ | |
+#define SURFBOARDINT_PCIE0 PCIE_0_INT /* PCIE0 */ | |
+#define SURFBOARDINT_PCIE1 PCIE_A_INT /* PCIE1 */ | |
+#define SURFBOARDINT_CRYPTO CRYPTO_INT /* CryptoEngine */ | |
+#define SURFBOARDINT_QDMA1_INT1 QDMA_LAN1_INTR /* QDMA1, INT1 */ | |
+#define SURFBOARDINT_QDMA1_INT2 QDMA_LAN2_INTR /* QDMA1, INT2 */ | |
+#define SURFBOARDINT_QDMA1_INT3 QDMA_LAN3_INTR /* QDMA1, INT3 */ | |
+#define SURFBOARDINT_QDMA2_INT1 QDMA_WAN1_INTR /* QDMA2, INT1 */ | |
+#define SURFBOARDINT_QDMA2_INT2 QDMA_WAN2_INTR /* QDMA2, INT2 */ | |
+#define SURFBOARDINT_QDMA2_INT3 QDMA_WAN3_INTR /* QDMA2, INT3 */ | |
+#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 | |
+#define SURFBOARDINT_UART2 SURFBOARDINT_UART_LITE2 | |
+ | |
+#define SURFBOARDINT_END (INTR_SOURCES_NUM - 1) | |
+ | |
+#elif defined(CONFIG_MIPS_TC3262_34K) | |
+ | |
+#define SURFBOARDINT_UART1 UART_INT /* UART1 */ | |
+#define SURFBOARDINT_GPIO GPIO_INT /* GPIO */ | |
+#define SURFBOARDINT_PCM PCM1_INT /* PCM1 */ | |
+#define SURFBOARDINT_DMA APB_DMA0_INT /* DMA */ | |
+#define SURFBOARDINT_ESW ESW_INT /* ESW */ | |
+#define SURFBOARDINT_USB IRQ_RT3XXX_USB /* USB */ | |
+#define SURFBOARDINT_FE FE_MAC_INT /* Frame Engine */ | |
+#define SURFBOARDINT_QDMA SAR_INT /* QDMA */ | |
+#define SURFBOARDINT_PCIE0 PCIE_0_INT /* PCIe0 */ | |
+#define SURFBOARDINT_PCIE1 PCIE_A_INT /* PCIe1 */ | |
+#define SURFBOARDINT_CRYPTO CRYPTO_INT /* CryptoEngine */ | |
+ | |
+#define SURFBOARDINT_END 40 /* 1 offset + 40 TC */ | |
+ | |
+#endif | |
+#endif | |
diff --git a/arch/mips/include/asm/tc3162/tc3162.h b/arch/mips/include/asm/tc3162/tc3162.h | |
new file mode 100644 | |
index 000000000000..d30e49b57c6f | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/tc3162.h | |
@@ -0,0 +1,912 @@ | |
+/* | |
+** $Id: tc3162.h,v 1.7 2011/01/07 06:05:58 pork Exp $ | |
+*/ | |
+/************************************************************************ | |
+ * | |
+ * Copyright (C) 2006 Trendchip Technologies, Corp. | |
+ * All Rights Reserved. | |
+ * | |
+ * Trendchip Confidential; Need to Know only. | |
+ * Protected as an unpublished work. | |
+ * | |
+ * The computer program listings, specifications and documentation | |
+ * herein are the property of Trendchip Technologies, Co. and shall | |
+ * not be reproduced, copied, disclosed, or used in whole or in part | |
+ * for any reason without the prior express written permission of | |
+ * Trendchip Technologeis, Co. | |
+ * | |
+ *************************************************************************/ | |
+/* | |
+** $Log: tc3162.h,v $ | |
+** Revision 1.7 2011/01/07 06:05:58 pork | |
+** add the definition of INT!16,INT32,SINT15,SINT7 | |
+** | |
+** Revision 1.6 2010/09/20 07:08:02 shnwind | |
+** decrease nf_conntrack buffer size | |
+** | |
+** Revision 1.5 2010/09/03 16:43:07 here | |
+** [Ehance] TC3182 GMAC Driver is support TC-Console & WAN2LAN function & update the tc3182 dmt version (3.12.8.83) | |
+** | |
+** Revision 1.4 2010/09/02 07:04:50 here | |
+** [Ehance] Support TC3162U/TC3182 Auto-Bench | |
+** | |
+** Revision 1.3 2010/08/30 07:53:02 lino | |
+** add power saving mode kernel module support | |
+** | |
+** Revision 1.2 2010/06/05 05:40:29 lino | |
+** add tc3182 asic board support | |
+** | |
+** Revision 1.1.1.1 2010/04/09 09:39:21 feiyan | |
+** New TC Linux Make Flow Trunk | |
+** | |
+** Revision 1.4 2010/01/14 10:56:42 shnwind | |
+** recommit | |
+** | |
+** Revision 1.3 2010/01/14 08:00:10 shnwind | |
+** add TC3182 support | |
+** | |
+** Revision 1.2 2010/01/10 15:27:26 here | |
+** [Ehancement]TC3162U MAC EEE is operated at 100M-FD, SAR interface is accroding the SAR_CLK to calculate atm rate. | |
+** | |
+** Revision 1.1.1.1 2009/12/17 01:42:47 josephxu | |
+** 20091217, from Hinchu ,with VoIP | |
+** | |
+** Revision 1.2 2006/07/06 07:24:57 lino | |
+** update copyright year | |
+** | |
+** Revision 1.1.1.1 2005/11/02 05:45:38 lino | |
+** no message | |
+** | |
+** Revision 1.5 2005/09/27 08:01:38 bread.hsu | |
+** adding IMEM support for Tc3162L2 | |
+** | |
+** Revision 1.4 2005/09/14 11:06:20 bread.hsu | |
+** new definition for TC3162L2 | |
+** | |
+** Revision 1.3 2005/06/17 16:26:16 jasonlin | |
+** Remove redundant code to gain extra 100K bytes free memory. | |
+** Add "CODE_REDUCTION" definition to switch | |
+** | |
+** Revision 1.2 2005/06/14 10:02:01 jasonlin | |
+** Merge TC3162L2 source code into new main trunk | |
+** | |
+** Revision 1.1.1.1 2005/03/30 14:04:22 jasonlin | |
+** Import Linos source code | |
+** | |
+** Revision 1.4 2004/11/15 03:43:17 lino | |
+** rename ATM SAR max packet length register | |
+** | |
+** Revision 1.3 2004/09/01 13:15:47 lino | |
+** fixed when pc shutdown, system will reboot | |
+** | |
+** Revision 1.2 2004/08/27 12:16:37 lino | |
+** change SYS_HCLK to 96Mhz | |
+** | |
+** Revision 1.1 2004/07/02 08:03:04 lino | |
+** tc3160 and tc3162 code merge | |
+** | |
+*/ | |
+ | |
+#ifndef _TC3162_H_ | |
+#define _TC3162_H_ | |
+ | |
+#include <asm/setup.h> | |
+ | |
+#include "tc3262_int_source.h" | |
+ | |
+#ifndef INT32 | |
+#define INT32 | |
+typedef signed long int int32; /* 32-bit signed integer */ | |
+#endif | |
+ | |
+#ifndef SINT31 | |
+#define SINT31 | |
+typedef signed long int sint31; /* 32-bit signed integer */ | |
+#endif | |
+ | |
+#ifndef UINT32 | |
+#define UINT32 | |
+typedef unsigned long int uint32; /* 32-bit unsigned integer */ | |
+#endif | |
+ | |
+#ifndef SINT15 | |
+#define SINT15 | |
+typedef signed short sint15; /* 16-bit signed integer */ | |
+#endif | |
+ | |
+#ifndef INT16 | |
+#define INT16 | |
+typedef signed short int int16; /* 16-bit signed integer */ | |
+#endif | |
+ | |
+#ifndef UINT16 | |
+#define UINT16 | |
+typedef unsigned short uint16; /* 16-bit unsigned integer */ | |
+#endif | |
+ | |
+#ifndef SINT7 | |
+#define SINT7 | |
+typedef signed char sint7; /* 8-bit signed integer */ | |
+#endif | |
+ | |
+#ifndef UINT8 | |
+#define UINT8 | |
+typedef unsigned char uint8; /* 8-bit unsigned integer */ | |
+#endif | |
+ | |
+#ifndef VPint | |
+#define VPint *(volatile unsigned long int *) | |
+#endif | |
+#ifndef VPshort | |
+#define VPshort *(volatile unsigned short *) | |
+#endif | |
+#ifndef VPchar | |
+#define VPchar *(volatile unsigned char *) | |
+#endif | |
+ | |
+static inline uint32 regRead32(uint32 reg) | |
+{ | |
+ return VPint(reg); | |
+} | |
+ | |
+static inline void regWrite32(uint32 reg, uint32 val) | |
+{ | |
+ VPint(reg) = val; | |
+} | |
+ | |
+#define isRT63365 (((VPint(0xbfb00064) & 0xffff0000)) == 0x00040000) | |
+#define isMT751020 (((VPint(0xbfb00064) & 0xffff0000)) == 0x00050000) | |
+#define isMT7505 (((VPint(0xbfb00064) & 0xffff0000)) == 0x00060000) | |
+#define isEN7526c (((VPint(0xbfb00064) & 0xffff0000)) == 0x00080000) | |
+#define isEN751221 ((((VPint(0xbfb00064) & 0xffff0000)) == 0x00070000) || isEN7526c) | |
+#define isEN7528 (((VPint(0xbfb00064) & 0xffff0000)) == 0x000B0000) | |
+#ifdef CONFIG_ECONET_EN7528 | |
+#define isEN751627 ((((VPint(0xbfb00064) & 0xffff0000)) == 0x00090000) || isEN7528) | |
+#else | |
+#define isEN751627 (((VPint(0xbfb00064) & 0xffff0000)) == 0x00090000) | |
+#endif | |
+#define isEN7580 (((VPint(0xbfb00064) & 0xffff0000)) == 0x000A0000) | |
+ | |
+/* Support old xDSL chips */ | |
+#define isTC3162L2P2 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)!=0)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3162L3P3 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==7)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3162L4P4 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==8)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3162L5P5E2 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==0xa)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3162L5P5E3 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==0xb)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3162L5P5 (isTC3162L5P5E2 || isTC3162L5P5E3) | |
+#define isTC3162U ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==0x10)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isRT63260 ((((unsigned char)(VPint(0xbfb0008c)>>12)&0xff)==0x20)&&(((VPint(0xbfb00064)&0xffffffff))==0x00000000)?1:0) | |
+#define isTC3169 (((VPint(0xbfb00064)&0xffff0000))==0x00000000) | |
+#define isTC3182 (((VPint(0xbfb00064)&0xffff0000))==0x00010000) | |
+#define isRT65168 (((VPint(0xbfb00064)&0xffff0000))==0x00020000) | |
+#define isRT63165 (((VPint(0xbfb00064)&0xffff0000))==0x00030000) | |
+ | |
+#define PDIDR (VPint(0xBFB0005C)&0xFFFF) | |
+#define isEN751221FPGA ((VPint(0xBFB0008C) & (1 << 29)) ? 0 : 1) //used for 7512/7521 | |
+#define isGenernalFPGA ((VPint(0xBFB0008C) & (1 << 31)) ? 1 : 0) //used for 63365/751020 | |
+#define isGenernalFPGA_2 (((VPint(CR_AHB_SSTR) & 0x1) == 0) ? 1 : 0) //used for EN7526c and later version | |
+#if defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) || \ | |
+ defined(CONFIG_ECONET_EN7528) | |
+#define isFPGA 0 // GET_IS_FPGA | |
+#define SYNC_TYPE4() __asm__ volatile ("sync 0x4") | |
+#else | |
+#define isFPGA 0 //(isEN7526c ? isGenernalFPGA_2 : (isEN751221 ? isEN751221FPGA : isGenernalFPGA)) | |
+#endif | |
+ | |
+#define isEN751627QFP (((VPint(0xbfa20174) & 0x8000) == 0x8000) ? 1 : 0) | |
+ | |
+#define EFUSE_VERIFY_DATA0 (0xBFBF8214) | |
+#define EFUSE_VERIFY_DATA1 (0xBFBF8218) | |
+#define EFUSE_PKG_MASK_7516 (0xC0000) | |
+#define EFUSE_REMARK_BIT_7516 (1 << 0) | |
+#define EFUSE_PKG_REMARK_SHITF_7516 2 | |
+#define EFUSE_PKG_MASK (0x3F) | |
+#define EFUSE_REMARK_BIT (1 << 6) | |
+#define EFUSE_PKG_REMARK_SHITF 7 | |
+ | |
+#define EFUSE_EN7512 (0x4) | |
+#define EFUSE_EN7513 (0x5) | |
+#define EFUSE_EN7513G (0x6) | |
+#define EFUSE_EN7516G (0x80000) | |
+#define EFUSE_EN7561G (0xC0000) | |
+#define EFUSE_EN7527H (0x0) | |
+#define EFUSE_EN7527G (0x0) | |
+ | |
+#define isEN7512 (isEN751221 && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF) & EFUSE_PKG_MASK) == EFUSE_EN7512): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK) == EFUSE_EN7512))) | |
+ | |
+#define isEN7513 (isEN751221 && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF) & EFUSE_PKG_MASK) == EFUSE_EN7513): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK) == EFUSE_EN7513))) | |
+ | |
+#define isEN7513G (isEN751221 && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF) & EFUSE_PKG_MASK) == EFUSE_EN7513G): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK) == EFUSE_EN7513G))) | |
+ | |
+#define isEN7516G (isEN751627 && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT_7516)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF_7516) & EFUSE_PKG_MASK_7516) == EFUSE_EN7516G): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK_7516) == EFUSE_EN7516G))) | |
+ | |
+#define isEN7561G (isEN751627 && !isEN751627QFP && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT_7516)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF_7516) & EFUSE_PKG_MASK_7516) == EFUSE_EN7561G): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK_7516) == EFUSE_EN7516G))) | |
+ | |
+#define isEN7527H (isEN751627 && isEN751627QFP && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT_7516)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF_7516) & EFUSE_PKG_MASK_7516) == EFUSE_EN7527H): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK_7516) == EFUSE_EN7527H))) | |
+ | |
+#define isEN7527G (isEN751627 && !isEN751627QFP && \ | |
+ ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT_7516)? \ | |
+ (((VPint(EFUSE_VERIFY_DATA0) >> EFUSE_PKG_REMARK_SHITF_7516) & EFUSE_PKG_MASK_7516) == EFUSE_EN7527G): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_PKG_MASK_7516) == EFUSE_EN7527G))) | |
+ | |
+#define isEN7528HU (isEN7528 && (GET_PACKAGE_ID == 0x0)) | |
+#define isEN7528DU (isEN7528 && (GET_PACKAGE_ID == 0x1)) | |
+#define isEN7561DU (isEN7528 && (GET_PACKAGE_ID == 0x2)) | |
+#define isEN7526FH_EN7528DU (isEN7528 && (GET_PACKAGE_ID == 0x3)) | |
+#define isEN7521G_EN7528DU (isEN7528 && (GET_PACKAGE_ID == 0x7)) | |
+ | |
+#define EFUSE_DDR3_BIT (1 << 23) | |
+#define EFUSE_DDR3_REMARK_BIT (1 << 24) | |
+#define EFUSE_IS_DDR3 ( (VPint(EFUSE_VERIFY_DATA0) & EFUSE_REMARK_BIT)? \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_DDR3_REMARK_BIT)): \ | |
+ ((VPint(EFUSE_VERIFY_DATA0) & EFUSE_DDR3_BIT))) | |
+ | |
+#define REG_SAVE_INFO 0xBFB00284 | |
+#define GET_REG_SAVE_INFO_POINT ((volatile SYS_GLOBAL_PARM_T *)REG_SAVE_INFO) | |
+ | |
+typedef union { | |
+ struct { | |
+ uint32 packageID : 4; | |
+ uint32 isDDR4 : 1; | |
+ uint32 isSecureHwTrapEn : 1; /* detect secure HW trap */ | |
+ uint32 isSecureModeEn : 1; /* RSA key has been written or not */ | |
+ uint32 isFlashBoot : 1; | |
+ uint32 isCtrlEcc : 1; | |
+ uint32 isFpga : 1; | |
+ uint32 sys_clk : 10; /* bus clock can support up to 1024MHz */ | |
+ uint32 dram_size : 12; /* DRAM size can support up to 2048MB */ | |
+ } raw ; | |
+ uint32 word; | |
+} SYS_GLOBAL_PARM_T ; | |
+ | |
+#define GET_IS_DDR4 (GET_REG_SAVE_INFO_POINT->raw.isDDR4) | |
+#define GET_DRAM_SIZE (GET_REG_SAVE_INFO_POINT->raw.dram_size) | |
+#define GET_SYS_CLK (GET_REG_SAVE_INFO_POINT->raw.sys_clk) | |
+#define GET_IS_FPGA (GET_REG_SAVE_INFO_POINT->raw.isFpga) | |
+#define GET_IS_SPI_ECC (GET_REG_SAVE_INFO_POINT->raw.isCtrlEcc) | |
+#define GET_PACKAGE_ID (GET_REG_SAVE_INFO_POINT->raw.packageID) | |
+#define GET_IS_SECURE_MODE (GET_REG_SAVE_INFO_POINT->raw.isSecureModeEn) | |
+#define GET_IS_SECURE_HWTRAP (GET_REG_SAVE_INFO_POINT->raw.isSecureHwTrapEn) | |
+ | |
+#define SYS_HCLK (GET_SYS_CLK) | |
+#define SAR_CLK ((SYS_HCLK)/(4.0)) //more accurate if 4.0 not 4 | |
+ | |
+/* define CPU timer clock, FPGA is 50Mhz, ASIC is 200Mhz */ | |
+#define CPUTMR_CLK (isFPGA ? (50*1000000) : (200*1000000)) | |
+ | |
+#define isMT7530 (((VPint(0xbfb58000 + 0x7ffc) & 0xffff0000)) == 0x75300000) | |
+ | |
+#define DSPRAM_BASE 0x9c000000 | |
+ | |
+#define ENABLE 1 | |
+#define DISABLE 0 | |
+ | |
+#define WAN2LAN_CH_ID (1<<31) | |
+ | |
+#define tc_inb(offset) (*(volatile unsigned char *)(offset)) | |
+#define tc_inw(offset) (*(volatile unsigned short *)(offset)) | |
+#define tc_inl(offset) (*(volatile unsigned long *)(offset)) | |
+ | |
+#define tc_outb(offset,val) (*(volatile unsigned char *)(offset) = val) | |
+#define tc_outw(offset,val) (*(volatile unsigned short *)(offset) = val) | |
+#define tc_outl(offset,val) (*(volatile unsigned long *)(offset) = val) | |
+ | |
+#define IS_SPIFLASH ((~(VPint(0xBFA10114))) & 0x2) | |
+#define IS_NANDFLASH (VPint(0xBFA10114) & 0x2) | |
+#ifdef TCSUPPORT_SPI_CONTROLLER_ECC | |
+#define isSpiControllerECC (GET_IS_SPI_ECC) | |
+#else | |
+#define isSpiControllerECC (0) | |
+#endif | |
+#define isSpiNandAndCtrlECC (IS_NANDFLASH && isSpiControllerECC) | |
+ | |
+/***************************** | |
+ * RBUS CORE Module Registers * | |
+ *****************************/ | |
+#define ARB_CFG 0xBFA00008 | |
+#define ROUND_ROBIN_ENABLE (1<<30) | |
+#define ROUND_ROBIN_DISABLE ~(1<<30) | |
+ | |
+#if defined(CONFIG_ECONET_EN7528) | |
+#define RBUS_TIMEOUT_STS0 0xBFA000D0 | |
+#define RBUS_TIMEOUT_CFG0 0xBFA000D8 | |
+#define RBUS_TIMEOUT_CFG1 0xBFA000DC | |
+#define RBUS_TIMEOUT_CFG2 0xBFA000E0 | |
+#endif | |
+ | |
+/***************************** | |
+ * DMC Module Registers * | |
+ *****************************/ | |
+ | |
+#define CR_DMC_BASE 0xBFB20000 | |
+#define CR_DMC_SRT (0x00 | CR_DMC_BASE) | |
+#define CR_DMC_STC (0x01 | CR_DMC_BASE) | |
+#define CR_DMC_SAMT (0x02 | CR_DMC_BASE) | |
+#define CR_DMC_SCR (0x03 | CR_DMC_BASE) | |
+ | |
+/* RT63165 specific */ | |
+/* DDR self refresh control register */ | |
+#define CR_DMC_DDR_SR (0x18 | CR_DMC_BASE) | |
+/* DDR self refresh target count */ | |
+#define CR_DMC_DDR_SR_CNT (0x1c | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG0 (0x40 | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG1 (0x44 | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG2 (0x48 | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG3 (0x4c | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG4 (0x50 | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG8 (0x60 | CR_DMC_BASE) | |
+#define CR_DMC_DDR_CFG9 (0x64 | CR_DMC_BASE) | |
+ | |
+#define CR_DMC_CTL0 (0x70 | CR_DMC_BASE) | |
+#define CR_DMC_CTL1 (0x74 | CR_DMC_BASE) | |
+#define CR_DMC_CTL2 (0x78 | CR_DMC_BASE) | |
+#define CR_DMC_CTL3 (0x7c | CR_DMC_BASE) | |
+#define CR_DMC_CTL4 (0x80 | CR_DMC_BASE) | |
+ | |
+#define CR_DMC_DCSR (0xb0 | CR_DMC_BASE) | |
+ | |
+#define CR_DMC_ISPCFGR (0xc0 | CR_DMC_BASE) | |
+#define CR_DMC_DSPCFGR (0xc4 | CR_DMC_BASE) | |
+/***************************** | |
+ * GDMA Module Registers * | |
+ *****************************/ | |
+ | |
+#define CR_GDMA_BASE 0xBFB30000 | |
+#define CR_GDMA_DCSA (0x00 | CR_GDMA_BASE) | |
+#define CR_GDMA_DCDA (0x04 | CR_GDMA_BASE) | |
+#define CR_GDMA_DCBT (0x08 | CR_GDMA_BASE) | |
+#define CR_GDMA_DCBL (0x0a | CR_GDMA_BASE) | |
+#define CR_GDMA_DCC (0x0c | CR_GDMA_BASE) | |
+#define CR_GDMA_DCS (0x0e | CR_GDMA_BASE) | |
+#define CR_GDMA_DCKSUM (0x10 | CR_GDMA_BASE) | |
+ | |
+/***************************** | |
+ * SPI Module Registers * | |
+ *****************************/ | |
+ | |
+#define CR_SPI_BASE 0xBFBC0000 | |
+#define CR_SPI_CTL (0x00 | CR_SPI_BASE) | |
+#define CR_SPI_OPCODE (0x04 | CR_SPI_BASE) | |
+#define CR_SPI_DATA (0x08 | CR_SPI_BASE) | |
+ | |
+/***************************** | |
+ * Ethernet Module Registers * | |
+ *****************************/ | |
+ | |
+#define CR_MAC_BASE 0xBFB50000 | |
+#define CR_MAC_ISR (0x00 | CR_MAC_BASE)// --- Interrupt Status Register --- | |
+#define CR_MAC_IMR (0x04 | CR_MAC_BASE)// --- Interrupt Mask Register --- | |
+#define CR_MAC_MADR (0x08 | CR_MAC_BASE)// --- MAC Address Register [47:32] --- | |
+#define CR_MAC_LADR (0x0c | CR_MAC_BASE)// --- MAC Address Register [31:0] --- | |
+#define CR_MAC_EEE (0x10 | CR_MAC_BASE) | |
+#define CR_MAC_TXPD (0x18 | CR_MAC_BASE)// --- Transmit Poll Demand Register --- | |
+#define CR_MAC_RXPD (0x1c | CR_MAC_BASE)// --- Receive Poll Demand Register --- | |
+#define CR_MAC_TXR_BADR (0x20 | CR_MAC_BASE)// --- Transmit Ring Base Address Register --- | |
+#define CR_MAC_RXR_BADR (0x24 | CR_MAC_BASE)// --- Receive Ring Base Address Register --- | |
+#define CR_MAC_ITC (0x28 | CR_MAC_BASE)// --- Interrupt Timer Control Register --- | |
+#define CR_MAC_TXR_SIZE (0x2c | CR_MAC_BASE)// --- Transmit Ring Size Register --- | |
+#define CR_MAC_RXR_SIZE (0x30 | CR_MAC_BASE)// --- Receive Ring Size Register --- | |
+#define CR_MAC_RXR_SWIDX (0x34 | CR_MAC_BASE)// --- Receive Ring Software Index Register --- | |
+#define CR_MAC_TXDESP_SIZE (0x38 | CR_MAC_BASE)// --- Transmit Descriptor Size Register --- | |
+#define CR_MAC_RXDESP_SIZE (0x3c | CR_MAC_BASE)// --- Receive Descriptor Size Register --- | |
+#define CR_MAC_PRIORITY_CFG (0x50 | CR_MAC_BASE)// --- Priority Configuration Register --- | |
+#define CR_MAC_VLAN_CFG (0x54 | CR_MAC_BASE)// --- VLAN Configuration Register --- | |
+#define CR_MAC_TOS0_CFG (0x58 | CR_MAC_BASE)// --- TOS 0 Configuration Register --- | |
+#define CR_MAC_TOS1_CFG (0x5c | CR_MAC_BASE)// --- TOS 1 Configuration Register --- | |
+#define CR_MAC_TOS2_CFG (0x60 | CR_MAC_BASE)// --- TOS 2 Configuration Register --- | |
+#define CR_MAC_TOS3_CFG (0x64 | CR_MAC_BASE)// --- TOS 3 Configuration Register --- | |
+#define CR_MAC_TCP_CFG (0x68 | CR_MAC_BASE)// --- TCP Configuration Register --- | |
+#define CR_MAC_SWTAG_CFG (0x6c | CR_MAC_BASE)// --- Software Tagging Configuration Register --- | |
+#define CR_MAC_PMBL_CYC_NUM (0x70 | CR_MAC_BASE)// --- Preamble Cycle Number Register --- | |
+#define CR_MAC_FCTL_CYC_NUM (0x74 | CR_MAC_BASE)// --- Flow Control Cycle Number Register --- | |
+#define CR_MAC_JAM_CYC_NUM (0x78 | CR_MAC_BASE)// --- JAM Cycle Number Register --- | |
+#define CR_MAC_DEFER_VAL (0x7c | CR_MAC_BASE)// --- Defer Value Register --- | |
+#define CR_MAC_RANDOM_POLY (0x80 | CR_MAC_BASE)// --- Random Polynomial Register --- | |
+#define CR_MAC_MACCR (0x88 | CR_MAC_BASE)// --- MAC Control Register --- | |
+#define CR_MAC_MACSR (0x8c | CR_MAC_BASE)// --- MAC Status Register --- | |
+#define CR_MAC_PHYCR (0x90 | CR_MAC_BASE)// --- PHY Control Register --- | |
+#define CR_MAC_PHYWDATA (0x94 | CR_MAC_BASE)// --- PHY Write Data Register --- | |
+#define CR_MAC_FCR (0x98 | CR_MAC_BASE)// --- Flow Control Register --- | |
+#define CR_MAC_BPR (0x9c | CR_MAC_BASE)// --- Back Pressure Register --- | |
+#define CR_MAC_DESP_IDX (0xc4 | CR_MAC_BASE)// --- Current Tx/Rx Descriptor Index --- | |
+#define CR_MAC_WOLCR (0xa0 | CR_MAC_BASE)// --- Wake-On-LAN Control Register --- | |
+#define CR_MAC_WOLSR (0xa4 | CR_MAC_BASE)// --- Wake-On-LAN Status Register --- | |
+#define CR_MAC_WFCRC (0xa8 | CR_MAC_BASE)// --- Wake-up Frame CRC Register --- | |
+#define CR_MAC_WFBM1 (0xb0 | CR_MAC_BASE)// --- Wake-up Frame Byte Mask 1st Double Word Register --- | |
+#define CR_MAC_WFBM2 (0xb4 | CR_MAC_BASE)// --- Wake-up Frame Byte Mask 2nd Double Word Register --- | |
+#define CR_MAC_WFBM3 (0xb8 | CR_MAC_BASE)// --- Wake-up Frame Byte Mask 3rd Double Word Register --- | |
+#define CR_MAC_WFBM4 (0xbc | CR_MAC_BASE)// --- Wake-up Frame Byte Mask 4th Double Word Register --- | |
+#define CR_MAC_DMA_FSM (0xc8 | CR_MAC_BASE)// --- DMA State Machine | |
+#define CR_MAC_TM (0xcc | CR_MAC_BASE)// --- Test Mode Register --- | |
+#define CR_MAC_XMPG_CNT (0xdc | CR_MAC_BASE)// --- XM and PG Counter Register --- | |
+#define CR_MAC_RUNT_TLCC_CNT (0xe0 | CR_MAC_BASE)// --- Receive Runt and Transmit Late Collision Packet Counter Register --- | |
+#define CR_MAC_RCRC_RLONG_CNT (0xe4 | CR_MAC_BASE)// --- Receive CRC Error and Long Packet Counter Register --- | |
+#define CR_MAC_RLOSS_RCOL_CNT (0xe8 | CR_MAC_BASE)// --- Receive Packet Loss and Receive Collision Counter Register --- | |
+#define CR_MAC_BROADCAST_CNT (0xec | CR_MAC_BASE)// --- Receive Broadcast Counter Register --- | |
+#define CR_MAC_MULTICAST_CNT (0xf0 | CR_MAC_BASE)// --- Receive Multicast Counter Register --- | |
+#define CR_MAC_RX_CNT (0xf4 | CR_MAC_BASE)// --- Receive Good Packet Counter Register --- | |
+#define CR_MAC_TX_CNT (0xf8 | CR_MAC_BASE)// --- Transmit Good Packet Counter Register --- | |
+ | |
+/************************* | |
+ * UART Module Registers * | |
+ *************************/ | |
+#ifdef __BIG_ENDIAN | |
+#define CR_UART_OFFSET (0x03) | |
+#else | |
+#define CR_UART_OFFSET (0x0) | |
+#endif | |
+ | |
+#define CR_UART_BASE 0xBFBF0000 | |
+#define CR_UART_RBR (0x00+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_THR (0x00+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_IER (0x04+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_IIR (0x08+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_FCR (0x08+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_LCR (0x0c+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_MCR (0x10+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_LSR (0x14+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_MSR (0x18+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_SCR (0x1c+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_BRDL (0x00+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_BRDH (0x04+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_WORDA (0x20+CR_UART_BASE+0x00) | |
+#define CR_UART_HWORDA (0x28+CR_UART_BASE+0x00) | |
+#define CR_UART_MISCC (0x24+CR_UART_BASE+CR_UART_OFFSET) | |
+#define CR_UART_XYD (0x2c+CR_UART_BASE) | |
+ | |
+#define UART_BRD_ACCESS 0x80 | |
+#define UART_XYD_Y 65000 | |
+#define UART_UCLK_115200 0 | |
+#define UART_UCLK_57600 1 | |
+#define UART_UCLK_38400 2 | |
+#define UART_UCLK_28800 3 | |
+#define UART_UCLK_19200 4 | |
+#define UART_UCLK_14400 5 | |
+#define UART_UCLK_9600 6 | |
+#define UART_UCLK_4800 7 | |
+#define UART_UCLK_2400 8 | |
+#define UART_UCLK_1200 9 | |
+#define UART_UCLK_600 10 | |
+#define UART_UCLK_300 11 | |
+#define UART_UCLK_110 12 | |
+#define UART_BRDL 0x03 | |
+#define UART_BRDH 0x00 | |
+#define UART_BRDL_20M 0x01 | |
+#define UART_BRDH_20M 0x00 | |
+#define UART_LCR 0x03 | |
+#define UART_FCR 0x0f | |
+#define UART_WATERMARK (0x0<<6) | |
+#define UART_MCR 0x0 | |
+#define UART_MISCC 0x0 | |
+#define UART_IER 0x01 | |
+ | |
+#define IER_RECEIVED_DATA_INTERRUPT_ENABLE 0x01 | |
+#define IER_THRE_INTERRUPT_ENABLE 0x02 | |
+#define IER_LINE_STATUS_INTERRUPT_ENABLE 0x04 | |
+ | |
+#define IIR_INDICATOR VPchar(CR_UART_IIR) | |
+#define IIR_RECEIVED_LINE_STATUS 0x06 | |
+#define IIR_RECEIVED_DATA_AVAILABLE 0x04 | |
+#define IIR_RECEIVER_IDLE_TRIGGER 0x0C | |
+#define IIR_TRANSMITTED_REGISTER_EMPTY 0x02 | |
+#define LSR_INDICATOR VPchar(CR_UART_LSR) | |
+#define LSR_RECEIVED_DATA_READY 0x01 | |
+#define LSR_OVERRUN 0x02 | |
+#define LSR_PARITY_ERROR 0x04 | |
+#define LSR_FRAME_ERROR 0x08 | |
+#define LSR_BREAK 0x10 | |
+#define LSR_THRE 0x20 | |
+#define LSR_THE 0x40 | |
+#define LSR_RFIFO_FLAG 0x80 | |
+ | |
+#define uartTxIntOn() VPchar(CR_UART_IER) |= IER_THRE_INTERRUPT_ENABLE | |
+#define uartTxIntOff() VPchar(CR_UART_IER) &= ~IER_THRE_INTERRUPT_ENABLE | |
+#define uartRxIntOn() VPchar(CR_UART_IER) |= IER_RECEIVED_DATA_INTERRUPT_ENABLE | |
+#define uartRxIntOff() VPchar(CR_UART_IER) &= ~IER_RECEIVED_DATA_INTERRUPT_ENABLE | |
+ | |
+/************************* | |
+ * UART2 Module Registers * | |
+ *************************/ | |
+#if defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) || \ | |
+ defined(CONFIG_ECONET_EN7528) | |
+#define CR_UART3_BASE 0xBFBE1000 | |
+#endif | |
+#define CR_UART2_BASE 0xBFBF0300 | |
+#define CR_UART2_RBR (0x00+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_THR (0x00+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_IER (0x04+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_IIR (0x08+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_FCR (0x08+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_LCR (0x0c+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_MCR (0x10+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_LSR (0x14+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_MSR (0x18+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_SCR (0x1c+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_BRDL (0x00+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_BRDH (0x04+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_WORDA (0x20+CR_UART2_BASE+0x00) | |
+#define CR_UART2_HWORDA (0x28+CR_UART2_BASE+0x00) | |
+#define CR_UART2_MISCC (0x24+CR_UART2_BASE+CR_UART_OFFSET) | |
+#define CR_UART2_XYD (0x2c+CR_UART2_BASE) | |
+ | |
+#define IIR_INDICATOR2 VPchar(CR_UART2_IIR) | |
+#define LSR_INDICATOR2 VPchar(CR_UART2_LSR) | |
+ | |
+/************************* | |
+ * HSUART Module Registers * | |
+ *************************/ | |
+#define CR_HSUART_BASE 0xBFBF0300 | |
+#define CR_HSUART_RBR (0x00+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_THR (0x00+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_IER (0x04+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_IIR (0x08+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_FCR (0x08+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_LCR (0x0c+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_MCR (0x10+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_LSR (0x14+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_MSR (0x18+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_SCR (0x1c+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_BRDL (0x00+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_BRDH (0x04+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_WORDA (0x20+CR_HSUART_BASE+0x00) | |
+#define CR_HSUART_HWORDA (0x28+CR_HSUART_BASE+0x00) | |
+#define CR_HSUART_MISCC (0x24+CR_HSUART_BASE+CR_UART_OFFSET) | |
+#define CR_HSUART_XYD (0x2c+CR_HSUART_BASE) | |
+ | |
+/********************************** | |
+ * Interrupt Controller Registers * | |
+ **********************************/ | |
+#define CR_INTC_BASE 0xBFB40000 | |
+ // --- Interrupt Type Register --- | |
+#define CR_INTC_ITR (CR_INTC_BASE+0x0000) | |
+ // --- Interrupt Mask Register --- | |
+#define CR_INTC_IMR (CR_INTC_BASE+0x0004) | |
+ // --- Interrupt Pending Register --- | |
+#define CR_INTC_IPR (CR_INTC_BASE+0x0008) | |
+ // --- Interrupt Set Register --- | |
+#define CR_INTC_ISR (CR_INTC_BASE+0x000c) | |
+ // --- Interrupt Priority Register 0 --- | |
+#define CR_INTC_IPR0 (CR_INTC_BASE+0x0010) | |
+ // --- Interrupt Priority Register 1 --- | |
+#define CR_INTC_IPR1 (CR_INTC_BASE+0x0014) | |
+ // --- Interrupt Priority Register 2 --- | |
+#define CR_INTC_IPR2 (CR_INTC_BASE+0x0018) | |
+ // --- Interrupt Priority Register 3 --- | |
+#define CR_INTC_IPR3 (CR_INTC_BASE+0x001c) | |
+ // --- Interrupt Priority Register 4 --- | |
+#define CR_INTC_IPR4 (CR_INTC_BASE+0x0020) | |
+ // --- Interrupt Priority Register 5 --- | |
+#define CR_INTC_IPR5 (CR_INTC_BASE+0x0024) | |
+ // --- Interrupt Priority Register 6 --- | |
+#define CR_INTC_IPR6 (CR_INTC_BASE+0x0028) | |
+ // --- Interrupt Priority Register 7 --- | |
+#define CR_INTC_IPR7 (CR_INTC_BASE+0x002c) | |
+ // --- Interrupt Vector egister --- | |
+ | |
+ // --- Interrupt VPE and SRS Register 0 --- | |
+#define CR_INTC_IVSR0 (CR_INTC_BASE+0x0030) | |
+ // --- Interrupt VPE and SRS Register 1 --- | |
+#define CR_INTC_IVSR1 (CR_INTC_BASE+0x0034) | |
+ // --- Interrupt VPE and SRS Register 2 --- | |
+#define CR_INTC_IVSR2 (CR_INTC_BASE+0x0038) | |
+ // --- Interrupt VPE and SRS Register 3 --- | |
+#define CR_INTC_IVSR3 (CR_INTC_BASE+0x003c) | |
+ // --- Interrupt VPE and SRS Register 4 --- | |
+#define CR_INTC_IVSR4 (CR_INTC_BASE+0x0040) | |
+ // --- Interrupt VPE and SRS Register 5 --- | |
+#define CR_INTC_IVSR5 (CR_INTC_BASE+0x0044) | |
+ // --- Interrupt VPE and SRS Register 6 --- | |
+#define CR_INTC_IVSR6 (CR_INTC_BASE+0x0048) | |
+ // --- Interrupt VPE and SRS Register 7 --- | |
+#define CR_INTC_IVSR7 (CR_INTC_BASE+0x004c) | |
+ // --- Interrupt Vector egister --- | |
+#define CR_INTC_IVR (CR_INTC_BASE+0x0050) | |
+ | |
+/* RT63165 */ | |
+ // --- Interrupt Mask Register --- | |
+#define CR_INTC_IMR_1 (CR_INTC_BASE+0x0050) | |
+ // --- Interrupt Pending Register --- | |
+#define CR_INTC_IPR_1 (CR_INTC_BASE+0x0054) | |
+ // --- Interrupt Priority Register 8 --- | |
+#define CR_INTC_IPSR8 (CR_INTC_BASE+0x0058) | |
+ // --- Interrupt Priority Register 9 --- | |
+#define CR_INTC_IPSR9 (CR_INTC_BASE+0x005c) | |
+ // --- Interrupt VPE and SRS Register 8 --- | |
+#define CR_INTC_IVSR8 (CR_INTC_BASE+0x0060) | |
+ // --- Interrupt VPE and SRS Register 9 --- | |
+#define CR_INTC_IVSR9 (CR_INTC_BASE+0x0064) | |
+ | |
+enum | |
+interrupt_priority | |
+{ | |
+ IPL0, IPL1, IPL2, IPL3, IPL4, | |
+ IPL5, IPL6, IPL7, IPL8, IPL9, | |
+ IPL10, IPL11, IPL12, IPL13, IPL14, | |
+ IPL15, IPL16, IPL17, IPL18, IPL19, | |
+ IPL20, IPL21, IPL22, IPL23, IPL24, | |
+ IPL25, IPL26, IPL27, IPL28, IPL29, | |
+ IPL30, IPL31 | |
+}; | |
+ | |
+/************************** | |
+ * Timer Module Registers * | |
+ **************************/ | |
+#define CR_CPUTMR_BASE 0xBFBF0400 | |
+#define CR_CPUTMR_CTL (CR_CPUTMR_BASE + 0x00) | |
+#define CR_CPUTMR_CMR0 (CR_CPUTMR_BASE + 0x04) | |
+#define CR_CPUTMR_CNT0 (CR_CPUTMR_BASE + 0x08) | |
+#define CR_CPUTMR_CMR1 (CR_CPUTMR_BASE + 0x0c) | |
+#define CR_CPUTMR_CNT1 (CR_CPUTMR_BASE + 0x10) | |
+ | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+#define CR_CPUTMR_23_BASE 0xBFBE0000 | |
+#define CR_CPUTMR_23_CTL (CR_CPUTMR_23_BASE + 0x00) | |
+#define CR_CPUTMR_CMR2 (CR_CPUTMR_23_BASE + 0x04) | |
+#define CR_CPUTMR_CNT2 (CR_CPUTMR_23_BASE + 0x08) | |
+#define CR_CPUTMR_CMR3 (CR_CPUTMR_23_BASE + 0x0c) | |
+#define CR_CPUTMR_CNT3 (CR_CPUTMR_23_BASE + 0x10) | |
+#endif | |
+ | |
+/************************* | |
+ * GPIO Module Registers * | |
+ *************************/ | |
+#define CR_GPIO_BASE 0xBFBF0200 | |
+#define CR_GPIO_CTRL (CR_GPIO_BASE + 0x00) | |
+#define CR_GPIO_DATA (CR_GPIO_BASE + 0x04) | |
+#define CR_GPIO_INTS (CR_GPIO_BASE + 0x08) | |
+#define CR_GPIO_EDET (CR_GPIO_BASE + 0x0C) | |
+#define CR_GPIO_LDET (CR_GPIO_BASE + 0x10) | |
+#define CR_GPIO_ODRAIN (CR_GPIO_BASE + 0x14) | |
+#define CR_GPIO_CTRL1 (CR_GPIO_BASE + 0x20) | |
+ | |
+#define GPIO_IN 0x0 | |
+#define GPIO_OUT 0x1 | |
+#define GPIO_ALT_IN 0x2 | |
+#define GPIO_ALT_OUT 0x3 | |
+ | |
+#define GPIO_E_DIS 0x0 | |
+#define GPIO_E_RISE 0x1 | |
+#define GPIO_E_FALL 0x2 | |
+#define GPIO_E_BOTH 0x3 | |
+ | |
+#define GPIO_L_DIS 0x0 | |
+#define GPIO_L_HIGH 0x1 | |
+#define GPIO_L_LOW 0x2 | |
+#define GPIO_L_BOTH 0x3 | |
+ | |
+/***************************** | |
+ * Arbiter/Decoder Registers * | |
+ *****************************/ | |
+#define CR_AHB_BASE 0xBFB00000 | |
+#define CR_AHB_AACS (CR_AHB_BASE + 0x00) | |
+#define CR_AHB_ABEM (CR_AHB_BASE + 0x08) | |
+#define CR_AHB_ABEA (CR_AHB_BASE + 0x0C) | |
+#define CR_AHB_DMB0 (CR_AHB_BASE + 0x10) | |
+#define CR_AHB_DMB1 (CR_AHB_BASE + 0x14) | |
+#define CR_AHB_DMB2 (CR_AHB_BASE + 0x18) | |
+#define CR_AHB_DMB3 (CR_AHB_BASE + 0x1C) | |
+#define CR_AHB_SMB0 (CR_AHB_BASE + 0x20) | |
+#define CR_AHB_SMB1 (CR_AHB_BASE + 0x24) | |
+#define CR_AHB_SMB2 (CR_AHB_BASE + 0x28) | |
+#define CR_AHB_SMB3 (CR_AHB_BASE + 0x2C) | |
+#define CR_AHB_SMB4 (CR_AHB_BASE + 0x30) | |
+#define CR_AHB_SMB5 (CR_AHB_BASE + 0x34) | |
+ | |
+/* RT63165 */ | |
+#define CR_ERR_ADDR (CR_AHB_BASE + 0x3c) | |
+#define CR_PRATIR (CR_AHB_BASE + 0x58) | |
+#define CR_MON_TMR (CR_AHB_BASE + 0x60) | |
+ | |
+#define CR_AHB_RSTCR (CR_AHB_BASE + 0x40) | |
+ | |
+#define CR_AHB_PMCR (CR_AHB_BASE + 0x80) | |
+#define CR_AHB_DMTCR (CR_AHB_BASE + 0x84) | |
+#define CR_AHB_PCIC (CR_AHB_BASE + 0x88) | |
+ | |
+#if defined(CONFIG_ECONET_EN7528) | |
+#define BOOT_TRAP_CONF (0xBFB000B8) | |
+#endif | |
+ | |
+#if defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) || \ | |
+ defined(CONFIG_ECONET_EN7528) | |
+#define CR_AHB_HWCONF (0xBFA20174) | |
+#else | |
+#define CR_AHB_HWCONF (CR_AHB_BASE + 0x8C) | |
+#endif | |
+#define CR_AHB_SSR (CR_AHB_BASE + 0x90) | |
+#define CR_AHB_SSTR (CR_AHB_BASE + 0x9C) | |
+#define CR_IMEM (CR_AHB_BASE + 0x9C) | |
+#define CR_DMEM (CR_AHB_BASE + 0xA0) | |
+ | |
+/* RT63365 */ | |
+#define CR_CRCC_REG (CR_AHB_BASE + 0xA0) | |
+#define CR_AHB_UHCR (CR_AHB_BASE + 0xA8) | |
+#define CR_AHB_ABMR (CR_AHB_BASE + 0xB8) | |
+#define CR_CKGEN_CONF (CR_AHB_BASE + 0xC0) | |
+#define CR_PSMCR (CR_AHB_BASE + 0xCC) | |
+#define CR_PSMDR (CR_AHB_BASE + 0xD0) | |
+#define CR_PSMMR (CR_AHB_BASE + 0xD0) | |
+ | |
+/* RT63165 */ | |
+#define CR_SRAM (CR_AHB_BASE + 0xF4) | |
+ | |
+/* RT63365 */ | |
+#define CR_AHB_CLK (CR_AHB_BASE + 0x1c0) | |
+#define CR_CLK_CFG (CR_AHB_BASE + 0x82c) | |
+#define CR_RSTCTRL2 (CR_AHB_BASE + 0x834) | |
+#define CR_GPIO_SHR (CR_AHB_BASE + 0x860) | |
+ | |
+#define CR_BUSTIMEOUT_SWITCH (CR_AHB_BASE + 0x92c) | |
+ | |
+/************************************************* | |
+ * SRAM/FLASH/ROM Controller Operation Registers * | |
+ *************************************************/ | |
+#define CR_SMC_BASE 0xBFB10000 | |
+#define CR_SMC_BCR0 (CR_SMC_BASE + 0x00) | |
+#define CR_SMC_BCR1 (CR_SMC_BASE + 0x04) | |
+#define CR_SMC_BCR2 (CR_SMC_BASE + 0x08) | |
+#define CR_SMC_BCR3 (CR_SMC_BASE + 0x0C) | |
+#define CR_SMC_BCR4 (CR_SMC_BASE + 0x10) | |
+#define CR_SMC_BCR5 (CR_SMC_BASE + 0x14) | |
+ | |
+/***************************** | |
+ * Clock Generator Registers * | |
+ *****************************/ | |
+ | |
+/**************************** | |
+ * USB Module Registers * | |
+ ****************************/ | |
+ | |
+/************************* | |
+ * HOST BRIDGE Registers * | |
+ * ***********************/ | |
+#define HOST_BRIDGE_BASE 0xBFB80000 | |
+#define CR_CFG_ADDR_REG (HOST_BRIDGE_BASE+0x0020) | |
+#define CR_CFG_DATA_REG (HOST_BRIDGE_BASE+0x0024) | |
+/**************************** | |
+ * ATM SAR Module Registers * | |
+ ****************************/ | |
+#define TSCONTROL_BASE 0xBFB00000 | |
+#define TSARM_REGISTER_BASE (TSCONTROL_BASE + 0x00060000) | |
+ | |
+/* ----- General configuration registers ----- */ | |
+ | |
+/* ----- Reset And Identify register ----- */ | |
+#define TSARM_RAI VPint(TSARM_REGISTER_BASE + 0x0000) | |
+/* ----- General Configuration register ----- */ | |
+#define TSARM_GFR VPint(TSARM_REGISTER_BASE + 0x0004) | |
+/* ----- Traffic Scheduler Timer Base Counter register ----- */ | |
+#define TSARM_TSTBR VPint(TSARM_REGISTER_BASE + 0x0008) | |
+/* ----- Receive Maximum Packet Length register ----- */ | |
+#define TSARM_RMPLR VPint(TSARM_REGISTER_BASE + 0x000c) | |
+/* ----- Transmit Priority 0/1 Data Buffer Control and Status Register ----- */ | |
+#define TSARM_TXDBCSR_P01 VPint(TSARM_REGISTER_BASE + 0x0010) | |
+/* ----- TX OAM Buffer Control and Status register ----- */ | |
+#define TSARM_TXMBCSR VPint(TSARM_REGISTER_BASE + 0x0014) | |
+/* ----- RX Data Buffer Control and Status register ----- */ | |
+#define TSARM_RXDBCSR VPint(TSARM_REGISTER_BASE + 0x0018) | |
+/* ----- RX OAM Buffer Control and Status register ----- */ | |
+#define TSARM_RXMBCSR VPint(TSARM_REGISTER_BASE + 0x001c) | |
+/* ----- Last IRQ Status register ----- */ | |
+#define TSARM_LIRQ VPint(TSARM_REGISTER_BASE + 0x0020) | |
+/* ----- IRQ Queue Base Address register ----- */ | |
+#define TSARM_IRQBA VPint(TSARM_REGISTER_BASE + 0x0024) | |
+/* ----- IRQ Queue Entry Length register ----- */ | |
+#define TSARM_IRQLEN VPint(TSARM_REGISTER_BASE + 0x0028) | |
+/* ----- IRQ Head Indication register ----- */ | |
+#define TSARM_IRQH VPint(TSARM_REGISTER_BASE + 0x002c) | |
+/* ----- Clear IRQ Entry register ----- */ | |
+#define TSARM_IRQC VPint(TSARM_REGISTER_BASE + 0x0030) | |
+//Traffic Scheduler Line Rate Counter Register | |
+#define TSARM_TXSLRC VPint(TSARM_REGISTER_BASE + 0x0034) | |
+//Transmit Priority 2/3 Data Buffer Control and Status Register | |
+#define TSARM_TXDBCSR_P23 VPint(TSARM_REGISTER_BASE + 0x0038) | |
+ | |
+/* ----- VC IRQ Mask register ----- */ | |
+#define TSARM_IRQM_BASE (TSARM_REGISTER_BASE + 0x0040) | |
+#define TSARM_IRQM(vc) VPint(TSARM_IRQM_BASE + (vc * 4)) | |
+#define TSARM_IRQMCC VPint(TSARM_IRQM_BASE + 0x0040) | |
+#define TSARM_IRQ_QUE_THRE VPint(TSARM_REGISTER_BASE + 0x0084) //IRQ Queue Threshold Register | |
+#define TSARM_IRQ_TIMEOUT_CTRL VPint(TSARM_REGISTER_BASE + 0x0088) //IRQ Timeout Control Register | |
+ | |
+/* ----- VC Configuration register ----- */ | |
+#define TSARM_VCCR_BASE (TSARM_REGISTER_BASE + 0x0100) | |
+#define TSARM_VCCR(vc) VPint(TSARM_VCCR_BASE + (vc * 4)) | |
+#define TSARM_CCCR VPint(TSARM_VCCR_BASE + 0x0040) | |
+ | |
+/* ----- DMA WRR Configuration Register (DMA_WRR_WEIT) (for TC3162L4) ----- */ | |
+#define TSARM_DMAWRRCR VPint(TSARM_REGISTER_BASE + 0x0150) | |
+ | |
+/* ----- Transmit Buffer Descriptor register ----- */ | |
+#define TSARM_TXDCBDA_BASE (TSARM_REGISTER_BASE + 0x0200) | |
+#define TSARM_TXDCBDA(vc) VPint(TSARM_TXDCBDA_BASE + (vc * 4)) | |
+#define TSARM_TXMCBDA_BASE (TSARM_REGISTER_BASE + 0x0240) | |
+#define TSARM_TXMCBDA(vc) VPint(TSARM_TXMCBDA_BASE + (vc * 4)) | |
+ | |
+#define TSARM_CC_TX_BD_BASE VPint(TSARM_REGISTER_BASE + 0x0228) //Control Channel Transmit BD Base Address 0x228 | |
+#define TSARM_CC_TX_BD_MNG_BASE VPint(TSARM_REGISTER_BASE + 0x0268) //Control Channel Transmit BD Management Base | |
+#define TSARM_VC_TX_BD_PRIORITY01_BASE (TSARM_REGISTER_BASE + 0x0280) | |
+#define TSARM_VC_TX_BD_PRIORITY01(vc) VPint(TSARM_VC_TX_BD_PRIORITY01_BASE + vc * 4) //VC0 Transmit BD Data Priority 0/1 Base 280 | |
+#define TSARM_VC_TX_BD_PRIORITY23_BASE (TSARM_REGISTER_BASE + 0x02c0) | |
+#define TSARM_VC_TX_BD_PRIORITY23(vc) VPint(TSARM_VC_TX_BD_PRIORITY23_BASE + vc * 4) //VC0 Transmit BD Data Priority 0/1 Base 280 | |
+ | |
+/* ----- Receive Buffer Descriptor register ----- */ | |
+#define TSARM_RXDCBDA_BASE (TSARM_REGISTER_BASE + 0x0300) | |
+#define TSARM_RXDCBDA(vc) VPint(TSARM_RXDCBDA_BASE + (vc * 4)) | |
+#define TSARM_RXMCBDA_BASE (TSARM_REGISTER_BASE + 0x0340) | |
+#define TSARM_RXMCBDA(vc) VPint(TSARM_RXMCBDA_BASE + (vc * 4)) | |
+ | |
+#define TSARM_CC_RX_BD_BASE VPint(TSARM_REGISTER_BASE + 0x328) //Control Channel Receive BD Base Address 0x328 | |
+#define TSARM_CC_RX_BD_MNG_BASE VPint(TSARM_REGISTER_BASE + 0x368) //Control Channel Receive BD Management Base 0x368 | |
+#define TSARM_VC_RX_DATA_BASE (TSARM_REGISTER_BASE + 0x380) | |
+#define TSARM_VC_RX_DATA(vc) VPint(TSARM_VC_RX_DATA_BASE + vc * 4) //VC0 Receive BD Data Base 0x380 | |
+ | |
+/* ----- Traffic Scheduler register ----- */ | |
+#define TSARM_PCR_BASE (TSARM_REGISTER_BASE + 0x0400) | |
+#define TSARM_PCR(vc) VPint(TSARM_PCR_BASE + (vc * 4)) | |
+#define TSARM_SCR_BASE (TSARM_REGISTER_BASE + 0x0440) | |
+#define TSARM_SCR(vc) VPint(TSARM_SCR_BASE + (vc * 4)) | |
+#define TSARM_MBSTP_BASE (TSARM_REGISTER_BASE + 0x0480) | |
+#define TSARM_MBSTP(vc) VPint(TSARM_MBSTP_BASE + (vc * 4)) | |
+ | |
+#define TSARM_MAX_FRAME_SIZE_BASE (TSARM_REGISTER_BASE + 0x04c0) | |
+#define TSARM_MAX_FRAME_SIZE(vc) VPint(TSARM_MAX_FRAME_SIZE_BASE + (vc * 4)) | |
+/* define for TC3162L4 */ | |
+#define TSARM_TRAFFIC_SHAPER_WEIGHT_BASE (TSARM_REGISTER_BASE + 0x0500) | |
+#define TSARM_TRAFFIC_SHAPER_WEIGHT(vc) VPint(TSARM_TRAFFIC_SHAPER_WEIGHT_BASE + (vc * 4)) | |
+ | |
+/* ----- TX Statistic Counter register ----- */ | |
+#define TSARM_TDCNT_BASE (TSARM_REGISTER_BASE + 0x0600) | |
+#define TSARM_TDCNT(vc) VPint(TSARM_TDCNT_BASE + (vc * 4)) | |
+#define TSARM_TDCNTCC VPint(TSARM_TDCNT_BASE + 0x0040) | |
+ | |
+/* ----- RX Statistic Counter register ----- */ | |
+#define TSARM_RDCNT_BASE (TSARM_REGISTER_BASE + 0x0700) | |
+#define TSARM_RDCNT(vc) VPint(TSARM_RDCNT_BASE + (vc * 4)) | |
+#define TSARM_RDCNTCC VPint(TSARM_RDCNT_BASE + 0x0040) | |
+#define TSARM_MISCNT VPint(TSARM_RDCNT_BASE + 0x0044) | |
+ | |
+#define TSARM_MPOA_GCR VPint(TSARM_REGISTER_BASE + 0x0800) //MPOA global control register | |
+#define TSARM_VC_MPOA_CTRL_BASE (TSARM_REGISTER_BASE + 0x0810) //VC0 ~9 MPOA Control register | |
+#define TSARM_VC_MPOA_CTRL(vc) VPint(TSARM_VC_MPOA_CTRL_BASE + vc * 4) | |
+#define TSARM_MPOA_HFIV11 VPint(TSARM_REGISTER_BASE + 0x0850) //MPOA header Field1 Insertion Value1 | |
+#define TSARM_MPOA_HFIV12 VPint(TSARM_REGISTER_BASE + 0x0854) //MPOA header Field1 Insertion Value2 | |
+#define TSARM_MPOA_HFIV13 VPint(TSARM_REGISTER_BASE + 0x0858) //MPOA header Field2 Insertion Value1 | |
+#define TSARM_MPOA_HFIV21 VPint(TSARM_REGISTER_BASE + 0x0860) //MPOA header Field2 Insertion Value2 | |
+#define TSARM_MPOA_HFIV22 VPint(TSARM_REGISTER_BASE + 0x0864) //MPOA header Field2 Insertion Value2 | |
+#define TSARM_MPOA_HFIV23 VPint(TSARM_REGISTER_BASE + 0x0868) //MPOA header Field2 Insertion Value2 | |
+#define TSARM_MPOA_HFIV31 VPint(TSARM_REGISTER_BASE + 0x0870) //MPOA header Field3 Insertion Value1 | |
+#define TSARM_MPOA_HFIV32 VPint(TSARM_REGISTER_BASE + 0x0874) //MPOA header Field3 Insertion Value2 | |
+#define TSARM_MPOA_HFIV33 VPint(TSARM_REGISTER_BASE + 0x0878) //MPOA header Field3 Insertion Value3 | |
+#define TSARM_MPOA_HFIV41 VPint(TSARM_REGISTER_BASE + 0x0880) //MPOA header Field4 Insertion Value1 | |
+#define TSARM_MPOA_HFIV42 VPint(TSARM_REGISTER_BASE + 0x0884) //MPOA header Field4 Insertion Value2 | |
+#define TSARM_MPOA_HFIV43 VPint(TSARM_REGISTER_BASE + 0x0888) //MPOA header Field4 Insertion Value2 | |
+ | |
+/************************** | |
+ * USB Module Registers * | |
+ **************************/ | |
+ | |
+#define LA_DEBUG_TRIGGER(addr,val) VPint(0xbfc00000+addr) = val | |
+ | |
+#endif /* _TC3162_H_ */ | |
diff --git a/arch/mips/include/asm/tc3162/tc3262_int_source.h b/arch/mips/include/asm/tc3162/tc3262_int_source.h | |
new file mode 100644 | |
index 000000000000..a953a39f9e6b | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/tc3262_int_source.h | |
@@ -0,0 +1,135 @@ | |
+/************************************************************************ | |
+ * | |
+ * Copyright (C) 2006 Trendchip Technologies, Corp. | |
+ * All Rights Reserved. | |
+ * | |
+ * Trendchip Confidential; Need to Know only. | |
+ * Protected as an unpublished work. | |
+ * | |
+ * The computer program listings, specifications and documentation | |
+ * herein are the property of Trendchip Technologies, Co. and shall | |
+ * not be reproduced, copied, disclosed, or used in whole or in part | |
+ * for any reason without the prior express written permission of | |
+ * Trendchip Technologeis, Co. | |
+ * | |
+ *************************************************************************/ | |
+ | |
+#ifndef _TC3262_INT_SOURCE_H_ | |
+#define _TC3262_INT_SOURCE_H_ | |
+ | |
+enum interrupt_source | |
+{ | |
+#if defined(CONFIG_MIPS_TC3262_1004K) | |
+ /* intrName irqNum Source fullName */ | |
+ DUMMY=0, /* n/a n/a dummy */ | |
+ UART5_INT, /* 1 46 UART5 */ | |
+ UART4_INT, /* 2 45 UART4 */ | |
+ UART3_INT, /* 3 38 UART3 */ | |
+ UART2_INT, /* 4 16 UART2 */ | |
+ UART_INT, /* 5 2 UART */ | |
+ GPIO_INT, /* 6 10 GPIO */ | |
+ GDMA_INTR, /* 7 14 GDMA */ | |
+ CRYPTO_INT, /* 8 28 Crypto engine */ | |
+ USB_HOST_2, /* 9 48 USB host 2 (port1) */ | |
+ IRQ_RT3XXX_USB, /* 10 17 USB host (port0)*/ | |
+ HSDMA_INTR, /* 11 47 High Speed DMA */ | |
+ WDMA1_WOE_INTR, /* 12 58 WIFI DMA 1 for WOE */ | |
+ WDMA1_P1_INTR, /* 13 57 WIFI DMA 1 port 1 */ | |
+ WDMA1_P0_INTR, /* 14 56 WIFI DMA 1 port 0 */ | |
+ WDMA0_WOE_INTR, /* 15 55 WIFI DMA 1 for WOE */ | |
+ WDMA0_P1_INTR, /* 16 54 WIFI DMA 1 port 1 */ | |
+ WDMA0_P0_INTR, /* 17 53 WIFI DMA 1 port 0 */ | |
+ WOE1_INTR, /* 18 52 WIFI Offload Engine 1 */ | |
+ WOE0_INTR, /* 19 51 WIFI Offload Engine 0 */ | |
+ PCIE_A_INT, /* 20 24 PCIE port 1 */ | |
+ PCIE_0_INT, /* 21 23 PCIE port 0 */ | |
+ MAC1_INT, /* 22 15 Giga Switch */ | |
+ XSI_PHY_INTR, /* 23 50 XFI/HGSMII PHY interface */ | |
+ XSI_MAC_INTR, /* 24 49 XFI/HGSMII MAC interface */ | |
+ QDMA_LAN3_INTR, /* 25 41 QDMA LAN 3 */ | |
+ QDMA_LAN2_INTR, /* 26 40 QDMA LAN 2 */ | |
+ QDMA_LAN1_INTR, /* 27 39 QDMA LAN 1 */ | |
+ QDMA_LAN0_INTR, /* 28 21 QDMA LAN 0 */ | |
+ QDMA_WAN3_INTR, /* 29 44 QDMA WAN 3 */ | |
+ QDMA_WAN2_INTR, /* 30 43 QDMA WAN 2 */ | |
+ QDMA_WAN1_INTR, /* 31 42 QDMA WAN 1 */ | |
+ QDMA_WAN0_INTR, /* 32 22 QDMA WAN 0 */ | |
+ TIMER2_INT, /* 33 6 timer 2 */ | |
+ TIMER1_INT, /* 34 5 timer 1 */ | |
+ TIMER0_INT, /* 35 4 timer 0 */ | |
+ PCM2_INT, /* 36 32 PCM 2 */ | |
+ PCM1_INT, /* 37 11 PCM 1 */ | |
+ XPON_PHY_INTR, /* 38 27 XPON PHY */ | |
+ XPON_MAC_INTR, /* 39 26 XPON MAC */ | |
+ DMT_INT, /* 40 19 xDSL DMT */ | |
+ DYINGGASP_INT, /* 41 18 Dying gasp */ | |
+ CPU_CM_PCINT, /* 42 1 CPU CM Perf Cnt overflow */ | |
+ CPU_CM_ERR, /* 43 0 CPU Coherence Manager Error */ | |
+ FE_ERR_INTR, /* 44 33 Frame Engine Error */ | |
+ EFUSE_ERR1_INTR, /* 45 60 efuse error for prev action not finished */ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+ RBUS_TOUT_INTR, /* 46 59 rbus timeout interrupt */ | |
+#else | |
+ EFUSE_ERR0_INTR, /* 46 59 efuse error for not setting key */ | |
+#endif | |
+ AUTO_MANUAL_INT, /* 47 35 SPI Controller Error */ | |
+ PCIE_SERR_INT, /* 48 25 PCIE error */ | |
+ DRAM_PROTECTION, /* 49 3 dram illegal access*/ | |
+ BUS_TOUT_INT, /* 50 31 Pbus timeout */ | |
+ TIMER5_INT, /* 51 9 timer 3 (watchdog) */ | |
+ SI_TIMER_INT, /* 52 30/29/37/36 external CPU timers 0/1/2/3 */ | |
+ GIC_EDGE_NMI, /* 53 20 send NMI to CPU by gic edge register */ | |
+ RESVINT1, /* 54 n/a n/a */ | |
+ RESVINT2, /* 55 n/a n/a */ | |
+ IPI_RESCHED_INT0, /* 56 7 ipi resched 0 */ | |
+ IPI_RESCHED_INT1, /* 57 8 ipi resched 1 */ | |
+ IPI_RESCHED_INT2, /* 58 12 ipi resched 2 */ | |
+ IPI_RESCHED_INT3, /* 59 13 ipi resched 3 */ | |
+ IPI_CALL_INT0, /* 60 34 ipi call 0 */ | |
+ IPI_CALL_INT1, /* 61 61 ipi call 0 */ | |
+ IPI_CALL_INT2, /* 62 62 ipi call 0 */ | |
+ IPI_CALL_INT3, /* 63 63 ipi call 0 */ | |
+#elif defined(CONFIG_MIPS_TC3262_34K) | |
+ DUMMY_INT, | |
+ UART_INT, //0 IPL10 | |
+ PTM_B0_INT, //1 | |
+ SI_SWINT1_INT0, //2 | |
+ SI_SWINT1_INT1, //3 | |
+ TIMER0_INT, //4 IPL1 | |
+ TIMER1_INT, //5 IPL5 | |
+ TIMER2_INT, //6 IPL6 | |
+ SI_SWINT_INT0, //7 | |
+ SI_SWINT_INT1, //8 | |
+ TIMER5_INT, //9 IPL9 | |
+ GPIO_INT, //10 IPL11 | |
+ PCM1_INT, //11 IPL20 | |
+ SI_PC1_INT, //12 | |
+ SI_PC_INT, //13 | |
+ APB_DMA0_INT, //14 IPL12 | |
+ ESW_INT, //15 IPL13 | |
+ HSUART_INT, //16 IPL23 | |
+ IRQ_RT3XXX_USB, //17 IPL24 | |
+ DYINGGASP_INT, //18 IPL25 | |
+ DMT_INT, //19 IPL26 | |
+ UNUSED0_INT, //20 | |
+ FE_MAC_INT, //21 IPL3 | |
+ SAR_INT, //22 IPL2 | |
+ PCIE_0_INT, //23 | |
+ PCIE_A_INT, //24 | |
+ PCIE_SERR_INT, //25 | |
+ PTM_B1_INT, //26 IPL15 | |
+ SPI_MC_INT, //27 IPL16 | |
+ CRYPTO_INT, //28 IPL17 | |
+ SI_TIMER1_INT, //29 | |
+ SI_TIMER_INT, //30 | |
+ SWR_INT, //31 IPL4 | |
+ BUS_TOUT_INT, //32 | |
+ PCM2_INT, //33 | |
+ RESERVE_B_INT, //34 | |
+ RESERVE_C_INT, //35 | |
+ AUTO_MANUAL_INT, //36 | |
+#endif | |
+ INTR_SOURCES_NUM | |
+}; | |
+ | |
+#endif /* _TC3262_INT_SOURCE_H_ */ | |
diff --git a/arch/mips/include/asm/tc3162/war.h b/arch/mips/include/asm/tc3162/war.h | |
new file mode 100644 | |
index 000000000000..85912cd1055b | |
--- /dev/null | |
+++ b/arch/mips/include/asm/tc3162/war.h | |
@@ -0,0 +1,26 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | |
+ * Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com> | |
+ */ | |
+#ifndef __ASM_MACH_MIPS_TC3262_WAR_H | |
+#define __ASM_MACH_MIPS_TC3262_WAR_H | |
+ | |
+#define R4600_V1_INDEX_ICACHEOP_WAR 0 | |
+#define R4600_V1_HIT_CACHEOP_WAR 0 | |
+#define R4600_V2_HIT_CACHEOP_WAR 0 | |
+#define R5432_CP0_INTERRUPT_WAR 0 | |
+#define BCM1250_M3_WAR 0 | |
+#define SIBYTE_1956_WAR 0 | |
+#define MIPS4K_ICACHE_REFILL_WAR 0 | |
+#define MIPS_CACHE_SYNC_WAR 0 | |
+#define TX49XX_ICACHE_INDEX_INV_WAR 0 | |
+#define RM9000_CDEX_SMP_WAR 0 | |
+#define ICACHE_REFILLS_WORKAROUND_WAR 0 | |
+#define R10000_LLSC_WAR 0 | |
+#define MIPS34K_MISSED_ITLB_WAR 0 | |
+ | |
+#endif | |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h | |
index da1cb0499d6c..0f81f3a48ba4 100644 | |
--- a/arch/mips/include/asm/thread_info.h | |
+++ b/arch/mips/include/asm/thread_info.h | |
@@ -81,6 +81,9 @@ static inline struct thread_info *current_thread_info(void) | |
#endif /* !__ASSEMBLY__ */ | |
/* thread information allocation */ | |
+#if defined(CONFIG_THREAD_STACK_SIZE_ADJUSTMENT) | |
+#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER) | |
+#else | |
#if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) | |
#define THREAD_SIZE_ORDER (1) | |
#endif | |
@@ -99,6 +102,7 @@ static inline struct thread_info *current_thread_info(void) | |
#ifdef CONFIG_PAGE_SIZE_64KB | |
#define THREAD_SIZE_ORDER (0) | |
#endif | |
+#endif | |
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | |
#define THREAD_MASK (THREAD_SIZE - 1UL) | |
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h | |
index 2f106d0357f4..82efef2ded20 100644 | |
--- a/arch/mips/include/uapi/asm/socket.h | |
+++ b/arch/mips/include/uapi/asm/socket.h | |
@@ -110,4 +110,6 @@ | |
#define SO_COOKIE 57 | |
+#define SO_NDMMARK 127 | |
+ | |
#endif /* _UAPI_ASM_SOCKET_H */ | |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile | |
index 4a603a3ea657..71d1a43193e5 100644 | |
--- a/arch/mips/kernel/Makefile | |
+++ b/arch/mips/kernel/Makefile | |
@@ -65,6 +65,7 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o | |
obj-$(CONFIG_MIPS_MSC) += irq-msc01.o | |
obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o | |
obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o | |
+obj-$(CONFIG_IRQ_GIC) += irq-gic.o | |
obj-$(CONFIG_KPROBES) += kprobes.o | |
obj-$(CONFIG_32BIT) += scall32-o32.o | |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c | |
index dd6a18bc10ab..53bc5f1697bc 100644 | |
--- a/arch/mips/kernel/cevt-r4k.c | |
+++ b/arch/mips/kernel/cevt-r4k.c | |
@@ -250,7 +250,7 @@ unsigned int __weak get_c0_compare_int(void) | |
return MIPS_CPU_IRQ_BASE + cp0_compare_irq; | |
} | |
-int r4k_clockevent_init(void) | |
+int __weak r4k_clockevent_init(void) | |
{ | |
unsigned int cpu = smp_processor_id(); | |
struct clock_event_device *cd; | |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c | |
index 921211bcd2ba..4edfd9540b64 100644 | |
--- a/arch/mips/kernel/cpu-probe.c | |
+++ b/arch/mips/kernel/cpu-probe.c | |
@@ -32,6 +32,12 @@ | |
#include <asm/spram.h> | |
#include <asm/uaccess.h> | |
+#if defined(CONFIG_RALINK_MT7621) || \ | |
+ defined(CONFIG_RALINK_MT7628) || \ | |
+ defined(CONFIG_MIPS_TC3262) | |
+#define PROBE_ONLY_ARCH_MIPS | |
+#endif | |
+ | |
/* Hardware capabilities */ | |
unsigned int elf_hwcap __read_mostly; | |
@@ -1152,6 +1158,7 @@ static inline void cpu_probe_vz(struct cpuinfo_mips *c) | |
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ | |
| MIPS_CPU_COUNTER) | |
+#ifndef PROBE_ONLY_ARCH_MIPS | |
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |
{ | |
switch (c->processor_id & PRID_IMP_MASK) { | |
@@ -1510,6 +1517,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |
break; | |
} | |
} | |
+#endif /* !PROBE_ONLY_ARCH_MIPS */ | |
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |
{ | |
@@ -1640,6 +1648,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |
spram_config(); | |
} | |
+#ifndef PROBE_ONLY_ARCH_MIPS | |
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu) | |
{ | |
decode_configs(c); | |
@@ -1931,6 +1940,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) | |
} | |
c->kscratch_mask = 0xf; | |
} | |
+#endif /* !PROBE_ONLY_ARCH_MIPS */ | |
#ifdef CONFIG_64BIT | |
/* For use by uaccess.h */ | |
@@ -1956,12 +1966,15 @@ void cpu_probe(void) | |
c->processor_id = read_c0_prid(); | |
switch (c->processor_id & PRID_COMP_MASK) { | |
+#ifndef PROBE_ONLY_ARCH_MIPS | |
case PRID_COMP_LEGACY: | |
cpu_probe_legacy(c, cpu); | |
break; | |
+#endif /* !PROBE_ONLY_ARCH_MIPS */ | |
case PRID_COMP_MIPS: | |
cpu_probe_mips(c, cpu); | |
break; | |
+#ifndef PROBE_ONLY_ARCH_MIPS | |
case PRID_COMP_ALCHEMY: | |
cpu_probe_alchemy(c, cpu); | |
break; | |
@@ -1991,6 +2004,7 @@ void cpu_probe(void) | |
case PRID_COMP_NETLOGIC: | |
cpu_probe_netlogic(c, cpu); | |
break; | |
+#endif /* !PROBE_ONLY_ARCH_MIPS */ | |
} | |
BUG_ON(!__cpu_name[cpu]); | |
diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c | |
index e757f36cea6f..6a8b094129c9 100644 | |
--- a/arch/mips/kernel/crash.c | |
+++ b/arch/mips/kernel/crash.c | |
@@ -59,7 +59,7 @@ static void crash_kexec_prepare_cpus(void) | |
ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ | |
- dump_send_ipi(crash_shutdown_secondary); | |
+ smp_call_function(crash_shutdown_secondary, NULL, 0); | |
smp_wmb(); | |
/* | |
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c | |
index d76275da54cb..1372d2526ab8 100644 | |
--- a/arch/mips/kernel/csrc-r4k.c | |
+++ b/arch/mips/kernel/csrc-r4k.c | |
@@ -65,7 +65,7 @@ static bool rdhwr_count_usable(void) | |
return false; | |
} | |
-int __init init_r4k_clocksource(void) | |
+int __init __weak init_r4k_clocksource(void) | |
{ | |
if (!cpu_has_counter || !mips_hpt_frequency) | |
return -ENXIO; | |
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S | |
index d1bb506adc10..cdabe6c899e7 100644 | |
--- a/arch/mips/kernel/head.S | |
+++ b/arch/mips/kernel/head.S | |
@@ -23,6 +23,7 @@ | |
#include <asm/regdef.h> | |
#include <asm/mipsregs.h> | |
#include <asm/stackframe.h> | |
+#include <asm/cacheops.h> | |
#include <kernel-entry-init.h> | |
@@ -87,6 +88,48 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |
setup_c0_status_pri | |
+#ifdef CONFIG_MIPS_L2_CACHE_ER35 | |
+ /* Set L2 CCA Override to WT on lowest 256MB */ | |
+ | |
+ /* Jump to KSEG1 so that we can perform cache related operations */ | |
+ PTR_LA t0, 0f | |
+ li t1, 5 | |
+ ins t0, t1, 29, 3 | |
+ jr t0 | |
+ nop | |
+0: | |
+ | |
+ /* Flush L2 Cache before setting CCA overrides */ | |
+ /* Define L2 Cache Line Size 32 */ | |
+#define L2_LINE_SIZE 32 | |
+ /* Define L2 Size 256K */ | |
+#define L2_SIZE (256 << 10) | |
+ li t0, L2_SIZE | |
+ move t1, zero | |
+ | |
+1: | |
+ cache Index_Writeback_Inv_SD, 0(t1) | |
+ addiu t1, t1, L2_LINE_SIZE /* Increase Index */ | |
+ bne t1, t0, 1b | |
+ nop | |
+ | |
+ sync | |
+ | |
+ /* Override bottom half of DDR to uncached (DMA zone) */ | |
+ PTR_LI t0, 0xbfbf8000 | |
+ | |
+ lui t1, (~((CONFIG_ZONE_DMA_SIZE - 1) >> 16)) & 0xffff | |
+ ori t1, t1, 0x0051 | |
+ sw t1, 0xb8(t0) | |
+ | |
+ /* Base */ | |
+ sw zero, 0xb0(t0) | |
+ | |
+ /* Set default override to WT */ | |
+ PTR_LI t1, 0x1fbf8010 | |
+ sw t1, 0x08(t0) | |
+#endif | |
+ | |
/* We might not get launched at the address the kernel is linked to, | |
so we jump there. */ | |
PTR_LA t0, 0f | |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c | |
new file mode 100644 | |
index 000000000000..26f8969651a5 | |
--- /dev/null | |
+++ b/arch/mips/kernel/irq-gic.c | |
@@ -0,0 +1,574 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org) | |
+ * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | |
+ */ | |
+#include <linux/bitmap.h> | |
+#include <linux/init.h> | |
+#include <linux/smp.h> | |
+#include <linux/interrupt.h> | |
+#include <linux/irq.h> | |
+ | |
+#include <asm/io.h> | |
+#include <asm/gic.h> | |
+#include <asm/setup.h> | |
+ | |
+#include <asm/traps.h> | |
+#include <asm/mips-cpc.h> | |
+#include <asm/smp-ops.h> | |
+ | |
+#include <linux/ioport.h> | |
+#include <linux/hardirq.h> | |
+#include <linux/sched.h> | |
+#include <asm-generic/bitops/find.h> | |
+ | |
+unsigned int gic_present; | |
+unsigned int gic_irq_base; | |
+unsigned long _gic_base; | |
+ | |
+static unsigned long __gic_base_addr; | |
+static unsigned int gic_irq_flags[GIC_NUM_INTRS]; | |
+ | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+#define EIC_NUM_VECTORS (64 + GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET) | |
+ | |
+/* The index into this array is the vector # of the interrupt. */ | |
+static struct gic_shared_intr_map gic_shared_intr_map[EIC_NUM_VECTORS]; | |
+#else | |
+struct gic_pcpu_mask { | |
+ DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | |
+}; | |
+ | |
+static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | |
+#endif | |
+ | |
+int gic_get_usm_range(struct resource *gic_usm_res) | |
+{ | |
+ if (!gic_present) | |
+ return -1; | |
+ | |
+ gic_usm_res->start = __gic_base_addr + USM_VISIBLE_SECTION_OFS; | |
+ gic_usm_res->end = gic_usm_res->start + (USM_VISIBLE_SECTION_SIZE - 1); | |
+ | |
+ return 0; | |
+} | |
+ | |
+unsigned gic_read_local_vp_id(void) | |
+{ | |
+ unsigned int ident; | |
+ | |
+ GICREAD(GIC_REG(VPE_LOCAL, GIC_VP_IDENT), ident); | |
+ return ident & GIC_VP_IDENT_VCNUM_MSK; | |
+} | |
+ | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+static void gic_bind_eic_interrupt(int irq, int regset) | |
+{ | |
+ /* Convert irq vector # to hw int # */ | |
+ irq -= GIC_PIN_TO_VEC_OFFSET; | |
+ | |
+ /* Set irq to use shadow set */ | |
+ GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), regset); | |
+} | |
+ | |
+static void gic_eic_irq_dispatch(void) | |
+{ | |
+ unsigned int cause = read_c0_cause(); | |
+ int irq; | |
+ | |
+ irq = (cause & ST0_IM) >> STATUSB_IP2; | |
+ if (irq == 0) | |
+ irq = -1; | |
+ | |
+ if (irq >= 0) | |
+ do_IRQ(gic_irq_base + irq); | |
+ else | |
+ spurious_interrupt(); | |
+} | |
+#else | |
+void gic_irq_dispatch(void) | |
+{ | |
+ unsigned int i, intr; | |
+ unsigned long *pcpu_mask; | |
+ unsigned long *pending_abs, *intrmask_abs; | |
+ DECLARE_BITMAP(pending, GIC_NUM_INTRS); | |
+ DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | |
+ | |
+ /* Get per-cpu bitmaps */ | |
+ pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; | |
+ | |
+ pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | |
+ GIC_SH_PEND_31_0_OFS); | |
+ intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | |
+ GIC_SH_MASK_31_0_OFS); | |
+ | |
+ for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { | |
+ GICREAD(*pending_abs, pending[i]); | |
+ GICREAD(*intrmask_abs, intrmask[i]); | |
+ pending_abs++; | |
+ intrmask_abs++; | |
+ } | |
+ | |
+ bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); | |
+ bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); | |
+ | |
+ intr = find_first_bit(pending, GIC_NUM_INTRS); | |
+ while (intr < GIC_NUM_INTRS) { | |
+ do_IRQ(gic_irq_base + intr); | |
+ | |
+ /* go to next pending bit */ | |
+ bitmap_clear(pending, intr, 1); | |
+ intr = find_first_bit(pending, GIC_NUM_INTRS); | |
+ } | |
+} | |
+#endif | |
+ | |
+static inline void gic_send_ipi(unsigned int intr) | |
+{ | |
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(intr)); | |
+} | |
+ | |
+static void __init vpe_local_setup(unsigned int numvpes) | |
+{ | |
+ unsigned int timer_intr = GIC_INT_TMR; | |
+ unsigned int perf_intr = GIC_INT_PERFCTR; | |
+ unsigned int vpe_ctl; | |
+ int i; | |
+ | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ if (cpu_has_veic) { | |
+ /* | |
+ * GIC timer interrupt -> CPU HW Int X (vector X+2) -> | |
+ * map to pin X+2-1 (since GIC adds 1) | |
+ */ | |
+ timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | |
+ /* | |
+ * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) -> | |
+ * map to pin X+2-1 (since GIC adds 1) | |
+ */ | |
+ perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | |
+ } | |
+#endif | |
+ | |
+ /* | |
+ * Setup the default performance counter timer interrupts | |
+ * for all VPEs | |
+ */ | |
+ for (i = 0; i < numvpes; i++) { | |
+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | |
+ | |
+ /* Are Interrupts locally routable? */ | |
+ GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); | |
+ if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) | |
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), | |
+ GIC_MAP_TO_PIN_MSK | timer_intr); | |
+ | |
+ if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) | |
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), | |
+ GIC_MAP_TO_PIN_MSK | perf_intr); | |
+ } | |
+ | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ if (cpu_has_veic) { | |
+ int veic; | |
+ | |
+ veic = timer_intr + GIC_PIN_TO_VEC_OFFSET; | |
+ set_vi_handler(veic, gic_eic_irq_dispatch); | |
+ gic_shared_intr_map[veic].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK; | |
+ | |
+ veic = perf_intr + GIC_PIN_TO_VEC_OFFSET; | |
+ set_vi_handler(veic, gic_eic_irq_dispatch); | |
+ gic_shared_intr_map[veic].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK; | |
+ } | |
+#endif | |
+} | |
+ | |
+static void gic_mask_irq(struct irq_data *d) | |
+{ | |
+ int intr = (d->irq - gic_irq_base); | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ if (map_ptr->shared_intr_flags & GIC_FLAG_PERCPU) | |
+ intr = map_ptr->shared_intr_list[smp_processor_id()]; | |
+ else | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ /* disable interrupt */ | |
+ GIC_CLR_INTR_MASK(intr); | |
+} | |
+ | |
+static void gic_unmask_irq(struct irq_data *d) | |
+{ | |
+ int intr = (d->irq - gic_irq_base); | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ if (map_ptr->shared_intr_flags & GIC_FLAG_PERCPU) | |
+ intr = map_ptr->shared_intr_list[smp_processor_id()]; | |
+ else | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ /* enable interrupt */ | |
+ GIC_SET_INTR_MASK(intr); | |
+} | |
+ | |
+static void gic_mask_ack_irq(struct irq_data *d) | |
+{ | |
+ int intr = (d->irq - gic_irq_base); | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ if (map_ptr->shared_intr_flags & GIC_FLAG_PERCPU) | |
+ intr = map_ptr->shared_intr_list[smp_processor_id()]; | |
+ else | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ /* disable interrupt */ | |
+ GIC_CLR_INTR_MASK(intr); | |
+ | |
+ /* clear edge detector */ | |
+ if (gic_irq_flags[intr] & GIC_TRIG_EDGE) | |
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(intr)); | |
+} | |
+ | |
+static void gic_ack_irq(struct irq_data *d) | |
+{ | |
+ int intr = (d->irq - gic_irq_base); | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ if (map_ptr->shared_intr_flags & GIC_FLAG_PERCPU) | |
+ intr = map_ptr->shared_intr_list[smp_processor_id()]; | |
+ else | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ /* clear edge detector */ | |
+ if (gic_irq_flags[intr] & GIC_TRIG_EDGE) | |
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(intr)); | |
+} | |
+ | |
+#ifdef CONFIG_SMP | |
+static DEFINE_SPINLOCK(gic_lock); | |
+ | |
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | |
+ bool force) | |
+{ | |
+ int intr = (d->irq - gic_irq_base); | |
+ cpumask_t tmp = CPU_MASK_NONE; | |
+ unsigned long flags; | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ if (map_ptr->shared_intr_flags & GIC_FLAG_PERCPU) | |
+ return -EINVAL; | |
+ | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#else | |
+ int i; | |
+#endif | |
+ | |
+ cpumask_and(&tmp, cpumask, cpu_online_mask); | |
+ if (cpumask_empty(&tmp)) | |
+ return -EINVAL; | |
+ | |
+ /* Assumption : cpumask refers to a single CPU */ | |
+ spin_lock_irqsave(&gic_lock, flags); | |
+ | |
+ /* Re-route this IRQ */ | |
+ GIC_SH_MAP_TO_VPE_SMASK(intr, cpumask_first(&tmp)); | |
+ | |
+#ifndef CONFIG_IRQ_GIC_EIC | |
+ /* Update the pcpu_masks */ | |
+ for (i = 0; i < NR_CPUS; i++) | |
+ clear_bit(intr, pcpu_masks[i].pcpu_mask); | |
+ set_bit(intr, pcpu_masks[cpumask_first(&tmp)].pcpu_mask); | |
+#endif | |
+ cpumask_copy(d->common->affinity, cpumask); | |
+ | |
+ spin_unlock_irqrestore(&gic_lock, flags); | |
+ | |
+ return IRQ_SET_MASK_OK_NOCOPY; | |
+} | |
+#endif | |
+ | |
+static struct irq_chip gic_irq_controller = { | |
+ .name = "MIPS GIC", | |
+ .irq_ack = gic_ack_irq, | |
+ .irq_mask = gic_mask_irq, | |
+ .irq_mask_ack = gic_mask_ack_irq, | |
+ .irq_unmask = gic_unmask_irq, | |
+ .irq_eoi = gic_unmask_irq, | |
+ .irq_disable = gic_mask_irq, | |
+ .irq_enable = gic_unmask_irq, | |
+#ifdef CONFIG_SMP | |
+ .irq_set_affinity = gic_set_affinity, | |
+#endif | |
+}; | |
+ | |
+static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | |
+ unsigned int pin, unsigned int polarity, unsigned int trigtype, | |
+ unsigned int flags) | |
+{ | |
+ /* Setup Intr to Pin mapping */ | |
+ if (pin & GIC_MAP_TO_NMI_MSK) { | |
+ int i; | |
+ | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); | |
+ /* FIXME: hack to route NMI to all cpu's */ | |
+ for (i = 0; i < NR_CPUS; i += 32) { | |
+ GICWRITE(GIC_REG_ADDR(SHARED, | |
+ GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), | |
+ 0xffffffff); | |
+ } | |
+ } else { | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), | |
+ GIC_MAP_TO_PIN_MSK | pin); | |
+ /* Setup Intr to CPU mapping */ | |
+ GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ if (cpu_has_veic) { | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET, | |
+ gic_eic_irq_dispatch); | |
+ map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET]; | |
+ map_ptr->shared_intr_flags = flags; | |
+ if (flags & GIC_FLAG_PERCPU) { | |
+ if (cpu < NR_CPUS) | |
+ map_ptr->shared_intr_list[cpu] = intr; | |
+ } else | |
+ map_ptr->shared_intr_list[0] = intr; | |
+ } | |
+#endif | |
+ } | |
+ | |
+ /* Setup Intr Polarity */ | |
+ GIC_SET_POLARITY(intr, polarity); | |
+ | |
+ /* Setup Intr Trigger Type */ | |
+ GIC_SET_TRIGGER(intr, trigtype); | |
+ | |
+ /* Init Intr Masks */ | |
+ GIC_CLR_INTR_MASK(intr); | |
+ | |
+#ifndef CONFIG_IRQ_GIC_EIC | |
+ /* Initialise per-cpu Interrupt software masks */ | |
+ set_bit(intr, pcpu_masks[cpu].pcpu_mask); | |
+#endif | |
+ if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) | |
+ GIC_SET_INTR_MASK(intr); | |
+ if (trigtype == GIC_TRIG_EDGE) | |
+ gic_irq_flags[intr] |= GIC_TRIG_EDGE; | |
+} | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+static int gic_resched_int_base; | |
+static int gic_call_int_base; | |
+ | |
+static inline unsigned int plat_ipi_resched_int_xlate(int cpu) | |
+{ | |
+ unsigned int intr = gic_resched_int_base + cpu; | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ return intr; | |
+} | |
+ | |
+static inline unsigned int plat_ipi_call_int_xlate(int cpu) | |
+{ | |
+ unsigned int intr = gic_call_int_base + cpu; | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ struct gic_shared_intr_map *map_ptr; | |
+ | |
+ map_ptr = &gic_shared_intr_map[intr]; | |
+ intr = map_ptr->shared_intr_list[0]; | |
+#endif | |
+ return intr; | |
+} | |
+ | |
+void mips_smp_send_ipi_single(int cpu, unsigned int action) | |
+{ | |
+ unsigned long flags; | |
+ unsigned int intr; | |
+ unsigned int core = cpu_data[cpu].core; | |
+ | |
+ local_irq_save(flags); | |
+ | |
+ switch (action) { | |
+ case SMP_CALL_FUNCTION: | |
+ intr = plat_ipi_call_int_xlate(cpu); | |
+ break; | |
+ | |
+ case SMP_RESCHEDULE_YOURSELF: | |
+ intr = plat_ipi_resched_int_xlate(cpu); | |
+ break; | |
+ | |
+ default: | |
+ BUG(); | |
+ } | |
+ | |
+ gic_send_ipi(intr); | |
+ | |
+ if (mips_cpc_present() && (core != current_cpu_data.core)) { | |
+ while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { | |
+ mips_cm_lock_other(core, 0); | |
+ mips_cpc_lock_other(core); | |
+ write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); | |
+ mips_cpc_unlock_other(); | |
+ mips_cm_unlock_other(); | |
+ } | |
+ } | |
+ | |
+ local_irq_restore(flags); | |
+} | |
+ | |
+void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |
+{ | |
+ unsigned int i; | |
+ | |
+ for_each_cpu(i, mask) | |
+ mips_smp_send_ipi_single(i, action); | |
+} | |
+ | |
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | |
+{ | |
+ scheduler_ipi(); | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | |
+{ | |
+ generic_smp_call_function_interrupt(); | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static struct irqaction irq_resched = { | |
+ .handler = ipi_resched_interrupt, | |
+ .flags = IRQF_PERCPU, | |
+ .name = "IPI_resched" | |
+}; | |
+ | |
+static struct irqaction irq_call = { | |
+ .handler = ipi_call_interrupt, | |
+ .flags = IRQF_PERCPU, | |
+ .name = "IPI_call" | |
+}; | |
+ | |
+static __init void gic_ipi_init_one(unsigned int irq, struct irqaction *action) | |
+{ | |
+ irq_set_handler(gic_irq_base + irq, handle_percpu_irq); | |
+ setup_irq(gic_irq_base + irq, action); | |
+} | |
+ | |
+static inline void gic_ipi_init(int intnumintrs, int numvpes) | |
+{ | |
+ int cpu; | |
+ | |
+ gic_call_int_base = intnumintrs - numvpes; | |
+ gic_resched_int_base = gic_call_int_base - numvpes; | |
+ | |
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) { | |
+ gic_ipi_init_one(gic_resched_int_base + cpu, &irq_resched); | |
+ gic_ipi_init_one(gic_call_int_base + cpu, &irq_call); | |
+ } | |
+} | |
+#else | |
+static inline void gic_ipi_init(int intnumintrs, int numvpes) | |
+{ | |
+} | |
+#endif | |
+ | |
+static void __init gic_basic_init(int numintrs, | |
+ int numvpes, | |
+ const struct gic_intr_map *intrmap, | |
+ unsigned int mapsize) | |
+{ | |
+ unsigned int i, cpu; | |
+ unsigned int pin_offset = 0; | |
+ | |
+ /* Setup defaults */ | |
+ for (i = 0; i < numintrs; i++) { | |
+ GIC_SET_POLARITY(i, GIC_POL_POS); | |
+ GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); | |
+ GIC_CLR_INTR_MASK(i); | |
+ if (i < GIC_NUM_INTRS) | |
+ gic_irq_flags[i] = 0; | |
+ } | |
+ | |
+#ifdef CONFIG_IRQ_GIC_EIC | |
+ board_bind_eic_interrupt = gic_bind_eic_interrupt; | |
+ | |
+ for (i = 0; i < EIC_NUM_VECTORS; i++) { | |
+ gic_shared_intr_map[i].shared_intr_flags = 0; | |
+ gic_shared_intr_map[i].local_intr_mask = 0; | |
+ } | |
+ | |
+ /* | |
+ * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract | |
+ * one because the GIC will add one (since 0=no intr). | |
+ */ | |
+ if (cpu_has_veic) | |
+ pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | |
+#endif | |
+ | |
+ /* Setup specifics */ | |
+ for (i = 0; i < mapsize; i++) { | |
+ cpu = intrmap[i].cpunum; | |
+ if (cpu == GIC_UNUSED) | |
+ continue; | |
+ gic_setup_intr(i, | |
+ intrmap[i].cpunum, | |
+ intrmap[i].pin + pin_offset, | |
+ intrmap[i].polarity, | |
+ intrmap[i].trigtype, | |
+ intrmap[i].flags); | |
+ } | |
+ | |
+ vpe_local_setup(numvpes); | |
+} | |
+ | |
+void __init gic_init(unsigned long gic_base_addr, | |
+ unsigned long gic_addrspace_size, | |
+ const struct gic_intr_map *intr_map, | |
+ unsigned int intr_map_size, | |
+ unsigned int irqbase) | |
+{ | |
+ unsigned int gicconfig, gicrev; | |
+ int numvpes, numintrs; | |
+ | |
+ __gic_base_addr = gic_base_addr; | |
+ | |
+ _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | |
+ gic_addrspace_size); | |
+ gic_irq_base = irqbase; | |
+ | |
+ GICREAD(GIC_REG(SHARED, GIC_SH_REVISIONID), gicrev); | |
+ pr_info("MIPS GIC RevID: %d.%d\n", (gicrev >> 8) & 0xff, gicrev & 0xff); | |
+ | |
+ GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | |
+ numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | |
+ GIC_SH_CONFIG_NUMINTRS_SHF; | |
+ numintrs = ((numintrs + 1) * 8); | |
+ | |
+ numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> | |
+ GIC_SH_CONFIG_NUMVPES_SHF; | |
+ numvpes = numvpes + 1; | |
+ | |
+ gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); | |
+ | |
+ gic_platform_init(numintrs, &gic_irq_controller); | |
+ | |
+ gic_ipi_init(numintrs, numvpes); | |
+} | |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c | |
index 50fb62544df7..6fa6cdfa6e22 100644 | |
--- a/arch/mips/kernel/linux32.c | |
+++ b/arch/mips/kernel/linux32.c | |
@@ -64,15 +64,10 @@ SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, | |
unsigned long, prot, unsigned long, flags, unsigned long, fd, | |
unsigned long, pgoff) | |
{ | |
- unsigned long error; | |
- | |
- error = -EINVAL; | |
if (pgoff & (~PAGE_MASK >> 12)) | |
- goto out; | |
- error = sys_mmap_pgoff(addr, len, prot, flags, fd, | |
- pgoff >> (PAGE_SHIFT-12)); | |
-out: | |
- return error; | |
+ return -EINVAL; | |
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, | |
+ pgoff >> (PAGE_SHIFT-12)); | |
} | |
#define RLIM_INFINITY32 0x7fffffff | |
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c | |
index df65516778a2..31e645d62794 100644 | |
--- a/arch/mips/kernel/mips-cm.c | |
+++ b/arch/mips/kernel/mips-cm.c | |
@@ -232,6 +232,7 @@ int mips_cm_probe(void) | |
return -ENODEV; | |
} | |
+#if !defined(CONFIG_MIPS_L2_CACHE_ER35) | |
/* set default target to memory */ | |
base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK; | |
base_reg |= CM_GCR_BASE_CMDEFTGT_MEM; | |
@@ -246,6 +247,7 @@ int mips_cm_probe(void) | |
write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); | |
write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK); | |
write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); | |
+#endif | |
/* probe for an L2-only sync region */ | |
mips_cm_probe_l2sync(); | |
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c | |
index 789d7bf4fef3..ddde22787287 100644 | |
--- a/arch/mips/kernel/mips-mt-fpaff.c | |
+++ b/arch/mips/kernel/mips-mt-fpaff.c | |
@@ -99,9 +99,10 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, | |
retval = -ENOMEM; | |
goto out_free_new_mask; | |
} | |
- retval = -EPERM; | |
- if (!check_same_owner(p) && !capable(CAP_SYS_NICE)) | |
+ if (!check_same_owner(p) && !capable(CAP_SYS_NICE)) { | |
+ retval = -EPERM; | |
goto out_unlock; | |
+ } | |
retval = security_task_setscheduler(p); | |
if (retval) | |
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c | |
index 88b1ef5f868a..13d90f59d669 100644 | |
--- a/arch/mips/kernel/mips-mt.c | |
+++ b/arch/mips/kernel/mips-mt.c | |
@@ -118,18 +118,20 @@ void mips_mt_regdump(unsigned long mvpctl) | |
local_irq_restore(flags); | |
} | |
-static int mt_opt_norps; | |
static int mt_opt_rpsctl = -1; | |
static int mt_opt_nblsu = -1; | |
static int mt_opt_forceconfig7; | |
static int mt_opt_config7 = -1; | |
+#ifdef CONFIG_MIPS_TC3262_34K | |
+static int mt_opt_es; | |
-static int __init rps_disable(char *s) | |
+static int __init es_set(char *str) | |
{ | |
- mt_opt_norps = 1; | |
+ get_option(&str, &mt_opt_es); | |
return 1; | |
} | |
-__setup("norps", rps_disable); | |
+__setup("es=", es_set); | |
+#endif | |
static int __init rpsctl_set(char *str) | |
{ | |
@@ -153,40 +155,6 @@ static int __init config7_set(char *str) | |
} | |
__setup("config7=", config7_set); | |
-/* Experimental cache flush control parameters that should go away some day */ | |
-int mt_protiflush; | |
-int mt_protdflush; | |
-int mt_n_iflushes = 1; | |
-int mt_n_dflushes = 1; | |
- | |
-static int __init set_protiflush(char *s) | |
-{ | |
- mt_protiflush = 1; | |
- return 1; | |
-} | |
-__setup("protiflush", set_protiflush); | |
- | |
-static int __init set_protdflush(char *s) | |
-{ | |
- mt_protdflush = 1; | |
- return 1; | |
-} | |
-__setup("protdflush", set_protdflush); | |
- | |
-static int __init niflush(char *s) | |
-{ | |
- get_option(&s, &mt_n_iflushes); | |
- return 1; | |
-} | |
-__setup("niflush=", niflush); | |
- | |
-static int __init ndflush(char *s) | |
-{ | |
- get_option(&s, &mt_n_dflushes); | |
- return 1; | |
-} | |
-__setup("ndflush=", ndflush); | |
- | |
static unsigned int itc_base; | |
static int __init set_itc_base(char *str) | |
@@ -202,9 +170,15 @@ void mips_mt_set_cpuoptions(void) | |
unsigned int oconfig7 = read_c0_config7(); | |
unsigned int nconfig7 = oconfig7; | |
- if (mt_opt_norps) { | |
- printk("\"norps\" option deprecated: use \"rpsctl=\"\n"); | |
+#ifdef CONFIG_MIPS_TC3262_34K | |
+ if (mt_opt_es >= 0) { | |
+ if (mt_opt_es) | |
+ nconfig7 |= (1 << 8); | |
+ else | |
+ nconfig7 &= ~(1 << 8); | |
} | |
+#endif | |
+ | |
if (mt_opt_rpsctl >= 0) { | |
printk("34K return prediction stack override set to %d.\n", | |
mt_opt_rpsctl); | |
@@ -231,16 +205,6 @@ void mips_mt_set_cpuoptions(void) | |
printk("Config7: 0x%08x\n", read_c0_config7()); | |
} | |
- /* Report Cache management debug options */ | |
- if (mt_protiflush) | |
- printk("I-cache flushes single-threaded\n"); | |
- if (mt_protdflush) | |
- printk("D-cache flushes single-threaded\n"); | |
- if (mt_n_iflushes != 1) | |
- printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes); | |
- if (mt_n_dflushes != 1) | |
- printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); | |
- | |
if (itc_base != 0) { | |
/* | |
* Configure ITC mapping. This code is very | |
@@ -282,21 +246,6 @@ void mips_mt_set_cpuoptions(void) | |
} | |
} | |
-/* | |
- * Function to protect cache flushes from concurrent execution | |
- * depends on MP software model chosen. | |
- */ | |
- | |
-void mt_cflush_lockdown(void) | |
-{ | |
- /* FILL IN VSMP and AP/SP VERSIONS HERE */ | |
-} | |
- | |
-void mt_cflush_release(void) | |
-{ | |
- /* FILL IN VSMP and AP/SP VERSIONS HERE */ | |
-} | |
- | |
struct class *mt_class; | |
static int __init mt_init(void) | |
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c | |
index 94627a3a6a0d..947981a9aa72 100644 | |
--- a/arch/mips/kernel/module.c | |
+++ b/arch/mips/kernel/module.c | |
@@ -44,14 +44,221 @@ struct mips_hi16 { | |
static LIST_HEAD(dbe_list); | |
static DEFINE_SPINLOCK(dbe_lock); | |
-#ifdef MODULE_START | |
+/* | |
+ * Get the potential max trampolines size required of the init and | |
+ * non-init sections. Only used if we cannot find enough contiguous | |
+ * physically mapped memory to put the module into. | |
+ */ | |
+static unsigned int | |
+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | |
+ const char *secstrings, unsigned int symindex, bool is_init) | |
+{ | |
+ unsigned long ret = 0; | |
+ unsigned int i, j; | |
+ Elf_Sym *syms; | |
+ | |
+ /* Everything marked ALLOC (this includes the exported symbols) */ | |
+ for (i = 1; i < hdr->e_shnum; ++i) { | |
+ unsigned int info = sechdrs[i].sh_info; | |
+ | |
+ if (sechdrs[i].sh_type != SHT_REL | |
+ && sechdrs[i].sh_type != SHT_RELA) | |
+ continue; | |
+ | |
+ /* Not a valid relocation section? */ | |
+ if (info >= hdr->e_shnum) | |
+ continue; | |
+ | |
+ /* Don't bother with non-allocated sections */ | |
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) | |
+ continue; | |
+ | |
+ /* If it's called *.init*, and we're not init, we're | |
+ not interested */ | |
+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) | |
+ != is_init) | |
+ continue; | |
+ | |
+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; | |
+ if (sechdrs[i].sh_type == SHT_REL) { | |
+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; | |
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); | |
+ | |
+ for (j = 0; j < size; ++j) { | |
+ Elf_Sym *sym; | |
+ | |
+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) | |
+ continue; | |
+ | |
+ sym = syms + ELF_MIPS_R_SYM(rel[j]); | |
+ if (!is_init && sym->st_shndx != SHN_UNDEF) | |
+ continue; | |
+ | |
+ ret += 4 * sizeof(int); | |
+ } | |
+ } else { | |
+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; | |
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); | |
+ | |
+ for (j = 0; j < size; ++j) { | |
+ Elf_Sym *sym; | |
+ | |
+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) | |
+ continue; | |
+ | |
+ sym = syms + ELF_MIPS_R_SYM(rela[j]); | |
+ if (!is_init && sym->st_shndx != SHN_UNDEF) | |
+ continue; | |
+ | |
+ ret += 4 * sizeof(int); | |
+ } | |
+ } | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+#ifndef MODULE_START | |
+static void *alloc_phys(unsigned long size) | |
+{ | |
+ unsigned order; | |
+ struct page *page; | |
+ struct page *p; | |
+ | |
+ size = PAGE_ALIGN(size); | |
+ order = get_order(size); | |
+ | |
+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | | |
+ __GFP_THISNODE, order); | |
+ if (!page) | |
+ return NULL; | |
+ | |
+ split_page(page, order); | |
+ | |
+ /* mark all pages except for the last one */ | |
+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) | |
+ set_bit(PG_owner_priv_1, &p->flags); | |
+ | |
+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) | |
+ __free_page(p); | |
+ | |
+ return page_address(page); | |
+} | |
+#endif | |
+ | |
+static void free_phys(void *ptr) | |
+{ | |
+ struct page *page; | |
+ bool free; | |
+ | |
+ page = virt_to_page(ptr); | |
+ do { | |
+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); | |
+ __free_page(page); | |
+ page++; | |
+ } while (free); | |
+} | |
+ | |
+ | |
void *module_alloc(unsigned long size) | |
{ | |
+#ifdef MODULE_START | |
return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, | |
GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, | |
__builtin_return_address(0)); | |
+#else | |
+ void *ptr; | |
+ | |
+ if (size == 0) | |
+ return NULL; | |
+ | |
+ ptr = alloc_phys(size); | |
+ | |
+ /* If we failed to allocate physically contiguous memory, | |
+ * fall back to regular vmalloc. The module loader code will | |
+ * create jump tables to handle long jumps */ | |
+ if (!ptr) | |
+ return vmalloc(size); | |
+ | |
+ return ptr; | |
+#endif | |
} | |
+ | |
+static inline bool is_phys_addr(void *ptr) | |
+{ | |
+#ifdef CONFIG_64BIT | |
+ return (KSEGX((unsigned long)ptr) == CKSEG0); | |
+#else | |
+ return (KSEGX(ptr) == KSEG0); | |
#endif | |
+} | |
+ | |
+/* Free memory returned from module_alloc */ | |
+void module_memfree(void *module_region) | |
+{ | |
+ if (is_phys_addr(module_region)) | |
+ free_phys(module_region); | |
+ else | |
+ vfree(module_region); | |
+} | |
+ | |
+static void *__module_alloc(int size, bool phys) | |
+{ | |
+ void *ptr; | |
+ | |
+ if (phys) | |
+ ptr = kmalloc(size, GFP_KERNEL); | |
+ else | |
+ ptr = vmalloc(size); | |
+ return ptr; | |
+} | |
+ | |
+static void __module_free(void *ptr) | |
+{ | |
+ if (is_phys_addr(ptr)) | |
+ kfree(ptr); | |
+ else | |
+ vfree(ptr); | |
+} | |
+ | |
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | |
+ char *secstrings, struct module *mod) | |
+{ | |
+ unsigned int symindex = 0; | |
+ unsigned int core_size, init_size; | |
+ int i; | |
+ | |
+ mod->arch.phys_plt_offset = 0; | |
+ mod->arch.virt_plt_offset = 0; | |
+ mod->arch.phys_plt_tbl = NULL; | |
+ mod->arch.virt_plt_tbl = NULL; | |
+ | |
+ if (IS_ENABLED(CONFIG_64BIT)) | |
+ return 0; | |
+ | |
+ for (i = 1; i < hdr->e_shnum; i++) | |
+ if (sechdrs[i].sh_type == SHT_SYMTAB) | |
+ symindex = i; | |
+ | |
+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); | |
+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); | |
+ | |
+ if ((core_size + init_size) == 0) | |
+ return 0; | |
+ | |
+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); | |
+ if (!mod->arch.phys_plt_tbl) | |
+ return -ENOMEM; | |
+ | |
+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); | |
+ if (!mod->arch.virt_plt_tbl) { | |
+ __module_free(mod->arch.phys_plt_tbl); | |
+ mod->arch.phys_plt_tbl = NULL; | |
+ return -ENOMEM; | |
+ } | |
+ | |
+ return 0; | |
+} | |
int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) | |
{ | |
@@ -65,8 +272,39 @@ static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v) | |
return 0; | |
} | |
+static Elf_Addr add_plt_entry_to(unsigned *plt_offset, | |
+ void *start, Elf_Addr v) | |
+{ | |
+ unsigned *tramp = start + *plt_offset; | |
+ *plt_offset += 4 * sizeof(int); | |
+ | |
+ /* adjust carry for addiu */ | |
+ if (v & 0x00008000) | |
+ v += 0x10000; | |
+ | |
+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ | |
+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ | |
+ tramp[2] = 0x03200008; /* jr t9 */ | |
+ tramp[3] = 0x00000000; /* nop */ | |
+ | |
+ return (Elf_Addr) tramp; | |
+} | |
+ | |
+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) | |
+{ | |
+ if (is_phys_addr(location)) | |
+ return add_plt_entry_to(&me->arch.phys_plt_offset, | |
+ me->arch.phys_plt_tbl, v); | |
+ else | |
+ return add_plt_entry_to(&me->arch.virt_plt_offset, | |
+ me->arch.virt_plt_tbl, v); | |
+ | |
+} | |
+ | |
static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) | |
{ | |
+ u32 ofs = *location & 0x03ffffff; | |
+ | |
if (v % 4) { | |
pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", | |
me->name); | |
@@ -74,13 +312,17 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) | |
} | |
if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { | |
- pr_err("module %s: relocation overflow\n", | |
- me->name); | |
- return -ENOEXEC; | |
+ v = add_plt_entry(me, location, v + (ofs << 2)); | |
+ if (!v) { | |
+ pr_err("module %s: relocation overflow\n", | |
+ me->name); | |
+ return -ENOEXEC; | |
+ } | |
+ ofs = 0; | |
} | |
*location = (*location & ~0x03ffffff) | | |
- ((*location + (v >> 2)) & 0x03ffffff); | |
+ ((ofs + (v >> 2)) & 0x03ffffff); | |
return 0; | |
} | |
@@ -349,9 +591,36 @@ int module_finalize(const Elf_Ehdr *hdr, | |
list_add(&me->arch.dbe_list, &dbe_list); | |
spin_unlock_irq(&dbe_lock); | |
} | |
+ | |
+ /* Get rid of the fixup trampoline if we're running the module | |
+ * from physically mapped address space */ | |
+ if (me->arch.phys_plt_offset == 0) { | |
+ __module_free(me->arch.phys_plt_tbl); | |
+ me->arch.phys_plt_tbl = NULL; | |
+ } | |
+ if (me->arch.virt_plt_offset == 0) { | |
+ __module_free(me->arch.virt_plt_tbl); | |
+ me->arch.virt_plt_tbl = NULL; | |
+ } | |
+ | |
return 0; | |
} | |
+void module_arch_freeing_init(struct module *mod) | |
+{ | |
+ if (mod->state == MODULE_STATE_LIVE) | |
+ return; | |
+ | |
+ if (mod->arch.phys_plt_tbl) { | |
+ __module_free(mod->arch.phys_plt_tbl); | |
+ mod->arch.phys_plt_tbl = NULL; | |
+ } | |
+ if (mod->arch.virt_plt_tbl) { | |
+ __module_free(mod->arch.virt_plt_tbl); | |
+ mod->arch.virt_plt_tbl = NULL; | |
+ } | |
+} | |
+ | |
void module_arch_cleanup(struct module *mod) | |
{ | |
spin_lock_irq(&dbe_lock); | |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c | |
index 2c3b89a65317..576c44752203 100644 | |
--- a/arch/mips/kernel/setup.c | |
+++ b/arch/mips/kernel/setup.c | |
@@ -375,6 +375,9 @@ static void __init bootmem_init(void) | |
unsigned long bootmap_size; | |
bool bootmap_valid = false; | |
int i; | |
+#if defined(CONFIG_MIPS_L2_CACHE_ER35) | |
+ unsigned long kernel_load_paddr; | |
+#endif | |
/* | |
* Sanity check any INITRD first. We don't take it into account | |
@@ -609,6 +612,14 @@ static void __init bootmem_init(void) | |
} | |
#endif | |
+#if defined(CONFIG_MIPS_L2_CACHE_ER35) | |
+ /* Free memory up to start of kernel image */ | |
+ kernel_load_paddr = CPHYSADDR((unsigned long) &_text); | |
+ if (kernel_load_paddr > CONFIG_ZONE_DMA_SIZE) | |
+ free_bootmem(kernel_load_paddr - CONFIG_ZONE_DMA_SIZE, | |
+ CONFIG_ZONE_DMA_SIZE); | |
+#endif | |
+ | |
/* | |
* Reserve initrd memory if needed. | |
*/ | |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c | |
index 6e3671752775..b0c80dcbed30 100644 | |
--- a/arch/mips/kernel/smp-bmips.c | |
+++ b/arch/mips/kernel/smp-bmips.c | |
@@ -177,7 +177,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus) | |
/* | |
* Tell the hardware to boot CPUx - runs on CPU0 | |
*/ | |
-static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |
+static int bmips_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
bmips_smp_boot_sp = __KSTK_TOS(idle); | |
bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); | |
@@ -229,6 +229,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |
} | |
cpumask_set_cpu(cpu, &bmips_booted_mask); | |
} | |
+ | |
+ return 0; | |
} | |
/* | |
@@ -366,7 +368,6 @@ static int bmips_cpu_disable(void) | |
set_cpu_online(cpu, false); | |
calculate_cpu_foreign_map(); | |
- cpumask_clear_cpu(cpu, &cpu_callin_map); | |
clear_c0_status(IE_IRQ5); | |
local_flush_tlb_all(); | |
@@ -409,7 +410,7 @@ void __ref play_dead(void) | |
#endif /* CONFIG_HOTPLUG_CPU */ | |
-struct plat_smp_ops bmips43xx_smp_ops = { | |
+const struct plat_smp_ops bmips43xx_smp_ops = { | |
.smp_setup = bmips_smp_setup, | |
.prepare_cpus = bmips_prepare_cpus, | |
.boot_secondary = bmips_boot_secondary, | |
@@ -423,7 +424,7 @@ struct plat_smp_ops bmips43xx_smp_ops = { | |
#endif | |
}; | |
-struct plat_smp_ops bmips5000_smp_ops = { | |
+const struct plat_smp_ops bmips5000_smp_ops = { | |
.smp_setup = bmips_smp_setup, | |
.prepare_cpus = bmips_prepare_cpus, | |
.boot_secondary = bmips_boot_secondary, | |
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c | |
index 76923349b4fe..e751e4b90799 100644 | |
--- a/arch/mips/kernel/smp-cmp.c | |
+++ b/arch/mips/kernel/smp-cmp.c | |
@@ -24,7 +24,9 @@ | |
#include <linux/cpumask.h> | |
#include <linux/interrupt.h> | |
#include <linux/compiler.h> | |
+#ifndef CONFIG_IRQ_GIC | |
#include <linux/irqchip/mips-gic.h> | |
+#endif | |
#include <linux/atomic.h> | |
#include <asm/cacheflush.h> | |
@@ -38,14 +40,21 @@ | |
#include <asm/mipsmtregs.h> | |
#include <asm/mips_mt.h> | |
#include <asm/amon.h> | |
+#ifdef CONFIG_IRQ_GIC | |
+#include <asm/gic.h> | |
+#endif | |
static void cmp_init_secondary(void) | |
{ | |
struct cpuinfo_mips *c __maybe_unused = ¤t_cpu_data; | |
/* Assume GIC is present */ | |
- change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | | |
- STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); | |
+ if (cpu_has_veic) | |
+ clear_c0_status(ST0_IM); | |
+ else | |
+ change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | | |
+ STATUSF_IP4 | STATUSF_IP5 | | |
+ STATUSF_IP6 | STATUSF_IP7); | |
/* Enable per-cpu interrupts: platform specific */ | |
@@ -78,7 +87,7 @@ static void cmp_smp_finish(void) | |
* __KSTK_TOS(idle) is apparently the stack pointer | |
* (unsigned long)idle->thread_info the gp | |
*/ | |
-static void cmp_boot_secondary(int cpu, struct task_struct *idle) | |
+static int cmp_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
struct thread_info *gp = task_thread_info(idle); | |
unsigned long sp = __KSTK_TOS(idle); | |
@@ -95,6 +104,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) | |
#endif | |
amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); | |
+ return 0; | |
} | |
/* | |
@@ -148,7 +158,7 @@ void __init cmp_prepare_cpus(unsigned int max_cpus) | |
} | |
-struct plat_smp_ops cmp_smp_ops = { | |
+const struct plat_smp_ops cmp_smp_ops = { | |
.send_ipi_single = mips_smp_send_ipi_single, | |
.send_ipi_mask = mips_smp_send_ipi_mask, | |
.init_secondary = cmp_init_secondary, | |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c | |
index 6183ad84cc73..91907a4a1b2e 100644 | |
--- a/arch/mips/kernel/smp-cps.c | |
+++ b/arch/mips/kernel/smp-cps.c | |
@@ -10,7 +10,9 @@ | |
#include <linux/delay.h> | |
#include <linux/io.h> | |
+#ifndef CONFIG_IRQ_GIC | |
#include <linux/irqchip/mips-gic.h> | |
+#endif | |
#include <linux/sched.h> | |
#include <linux/slab.h> | |
#include <linux/smp.h> | |
@@ -26,6 +28,9 @@ | |
#include <asm/smp-cps.h> | |
#include <asm/time.h> | |
#include <asm/uasm.h> | |
+#ifdef CONFIG_IRQ_GIC | |
+#include <asm/gic.h> | |
+#endif | |
static bool threads_disabled; | |
static DECLARE_BITMAP(core_power, NR_CPUS); | |
@@ -56,6 +61,11 @@ static unsigned core_vpe_count(unsigned core) | |
return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; | |
} | |
+bool __weak plat_cpu_core_present(int core) | |
+{ | |
+ return true; | |
+} | |
+ | |
static void __init cps_smp_setup(void) | |
{ | |
unsigned int ncores, nvpes, core_vpes; | |
@@ -66,6 +76,8 @@ static void __init cps_smp_setup(void) | |
ncores = mips_cm_numcores(); | |
pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE"); | |
for (c = nvpes = 0; c < ncores; c++) { | |
+ if (!plat_cpu_core_present(c)) | |
+ continue; | |
core_vpes = core_vpe_count(c); | |
pr_cont("%c%u", c ? ',' : '{', core_vpes); | |
@@ -287,7 +299,7 @@ static void remote_vpe_boot(void *dummy) | |
mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); | |
} | |
-static void cps_boot_secondary(int cpu, struct task_struct *idle) | |
+static int cps_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
unsigned core = cpu_data[cpu].core; | |
unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); | |
@@ -326,7 +338,11 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) | |
if (cpu_online(remote)) | |
break; | |
} | |
- BUG_ON(remote >= NR_CPUS); | |
+ if (remote >= NR_CPUS) { | |
+ pr_crit("No online CPU in core %u to start CPU%d\n", | |
+ core, cpu); | |
+ goto out; | |
+ } | |
err = smp_call_function_single(remote, remote_vpe_boot, | |
NULL, 1); | |
@@ -341,6 +357,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) | |
mips_cps_boot_vpes(core_cfg, vpe_id); | |
out: | |
preempt_enable(); | |
+ return 0; | |
} | |
static void cps_init_secondary(void) | |
@@ -399,7 +416,6 @@ static int cps_cpu_disable(void) | |
smp_mb__after_atomic(); | |
set_cpu_online(cpu, false); | |
calculate_cpu_foreign_map(); | |
- cpumask_clear_cpu(cpu, &cpu_callin_map); | |
return 0; | |
} | |
@@ -418,13 +434,12 @@ void play_dead(void) | |
local_irq_disable(); | |
idle_task_exit(); | |
cpu = smp_processor_id(); | |
+ core = cpu_data[cpu].core; | |
cpu_death = CPU_DEATH_POWER; | |
pr_debug("CPU%d going offline\n", cpu); | |
if (cpu_has_mipsmt || cpu_has_vp) { | |
- core = cpu_data[cpu].core; | |
- | |
/* Look for another online VPE within the core */ | |
for_each_online_cpu(cpu_death_sibling) { | |
if (cpu_data[cpu_death_sibling].core != core) | |
@@ -546,7 +561,7 @@ static void cps_cpu_die(unsigned int cpu) | |
#endif /* CONFIG_HOTPLUG_CPU */ | |
-static struct plat_smp_ops cps_smp_ops = { | |
+static const struct plat_smp_ops cps_smp_ops = { | |
.smp_setup = cps_smp_setup, | |
.prepare_cpus = cps_prepare_cpus, | |
.boot_secondary = cps_boot_secondary, | |
@@ -562,7 +577,7 @@ static struct plat_smp_ops cps_smp_ops = { | |
bool mips_cps_smp_in_use(void) | |
{ | |
- extern struct plat_smp_ops *mp_ops; | |
+ extern const struct plat_smp_ops *mp_ops; | |
return mp_ops == &cps_smp_ops; | |
} | |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c | |
index e077ea3e11fb..705248e3955f 100644 | |
--- a/arch/mips/kernel/smp-mt.c | |
+++ b/arch/mips/kernel/smp-mt.c | |
@@ -21,7 +21,9 @@ | |
#include <linux/sched.h> | |
#include <linux/cpumask.h> | |
#include <linux/interrupt.h> | |
+#ifndef CONFIG_IRQ_GIC | |
#include <linux/irqchip/mips-gic.h> | |
+#endif | |
#include <linux/compiler.h> | |
#include <linux/smp.h> | |
@@ -35,6 +37,9 @@ | |
#include <asm/mipsregs.h> | |
#include <asm/mipsmtregs.h> | |
#include <asm/mips_mt.h> | |
+#ifdef CONFIG_IRQ_GIC | |
+#include <asm/gic.h> | |
+#endif | |
static void __init smvp_copy_vpe_config(void) | |
{ | |
@@ -119,7 +124,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) | |
unsigned long flags; | |
int vpflags; | |
-#ifdef CONFIG_MIPS_GIC | |
+#if defined(CONFIG_MIPS_GIC) || defined(CONFIG_IRQ_GIC) | |
if (gic_present) { | |
mips_smp_send_ipi_single(cpu, action); | |
return; | |
@@ -158,7 +163,11 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |
static void vsmp_init_secondary(void) | |
{ | |
-#ifdef CONFIG_MIPS_GIC | |
+#ifdef CONFIG_MIPS_TC3262_34K | |
+ write_c0_status((read_c0_status() & ~ST0_IM ) | | |
+ (STATUSF_IP0 | STATUSF_IP1)); | |
+#else | |
+#if defined(CONFIG_MIPS_GIC) || defined(CONFIG_IRQ_GIC) | |
/* This is Malta specific: IPI,performance and timer interrupts */ | |
if (gic_present) | |
change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | | |
@@ -168,6 +177,7 @@ static void vsmp_init_secondary(void) | |
#endif | |
change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | | |
STATUSF_IP6 | STATUSF_IP7); | |
+#endif | |
} | |
static void vsmp_smp_finish(void) | |
@@ -192,7 +202,7 @@ static void vsmp_smp_finish(void) | |
* (unsigned long)idle->thread_info the gp | |
* assumes a 1:1 mapping of TC => VPE | |
*/ | |
-static void vsmp_boot_secondary(int cpu, struct task_struct *idle) | |
+static int vsmp_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
struct thread_info *gp = task_thread_info(idle); | |
dvpe(); | |
@@ -224,6 +234,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle) | |
clear_c0_mvpcontrol(MVPCONTROL_VPC); | |
evpe(EVPE_ENABLE); | |
+ | |
+ return 0; | |
} | |
/* | |
@@ -279,7 +291,7 @@ static void __init vsmp_prepare_cpus(unsigned int max_cpus) | |
mips_mt_set_cpuoptions(); | |
} | |
-struct plat_smp_ops vsmp_smp_ops = { | |
+const struct plat_smp_ops vsmp_smp_ops = { | |
.send_ipi_single = vsmp_send_ipi_single, | |
.send_ipi_mask = vsmp_send_ipi_mask, | |
.init_secondary = vsmp_init_secondary, | |
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c | |
index 17878d71ef2b..525d3196f793 100644 | |
--- a/arch/mips/kernel/smp-up.c | |
+++ b/arch/mips/kernel/smp-up.c | |
@@ -39,8 +39,9 @@ static void up_smp_finish(void) | |
/* | |
* Firmware CPU startup hook | |
*/ | |
-static void up_boot_secondary(int cpu, struct task_struct *idle) | |
+static int up_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
+ return 0; | |
} | |
static void __init up_smp_setup(void) | |
@@ -63,7 +64,7 @@ static void up_cpu_die(unsigned int cpu) | |
} | |
#endif | |
-struct plat_smp_ops up_smp_ops = { | |
+const struct plat_smp_ops up_smp_ops = { | |
.send_ipi_single = up_send_ipi_single, | |
.send_ipi_mask = up_send_ipi_mask, | |
.init_secondary = up_init_secondary, | |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c | |
index 01aa8d6da4b9..9177472b2570 100644 | |
--- a/arch/mips/kernel/smp.c | |
+++ b/arch/mips/kernel/smp.c | |
@@ -48,8 +48,6 @@ | |
#include <asm/setup.h> | |
#include <asm/maar.h> | |
-cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ | |
- | |
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ | |
EXPORT_SYMBOL(__cpu_number_map); | |
@@ -149,10 +147,10 @@ void calculate_cpu_foreign_map(void) | |
&temp_foreign_map, &cpu_sibling_map[i]); | |
} | |
-struct plat_smp_ops *mp_ops; | |
+const struct plat_smp_ops *mp_ops; | |
EXPORT_SYMBOL(mp_ops); | |
-void register_smp_ops(struct plat_smp_ops *ops) | |
+void register_smp_ops(const struct plat_smp_ops *ops) | |
{ | |
if (mp_ops) | |
printk(KERN_WARNING "Overriding previously set SMP ops\n"); | |
@@ -357,7 +355,9 @@ asmlinkage void start_secondary(void) | |
mips_clockevent_init(); | |
mp_ops->init_secondary(); | |
cpu_report(); | |
+#if defined(CONFIG_CPU_MIPS32_R5_FEATURES) | |
maar_init(); | |
+#endif | |
/* | |
* XXX parity protection should be folded in here when it's converted | |
@@ -446,7 +446,11 @@ void smp_prepare_boot_cpu(void) | |
int __cpu_up(unsigned int cpu, struct task_struct *tidle) | |
{ | |
- mp_ops->boot_secondary(cpu, tidle); | |
+ int err; | |
+ | |
+ err = mp_ops->boot_secondary(cpu, tidle); | |
+ if (err) | |
+ return err; | |
/* Wait for CPU to start and be ready to sync counters */ | |
if (!wait_for_completion_timeout(&cpu_starting, | |
@@ -650,23 +654,6 @@ void flush_tlb_one(unsigned long vaddr) | |
EXPORT_SYMBOL(flush_tlb_page); | |
EXPORT_SYMBOL(flush_tlb_one); | |
-#if defined(CONFIG_KEXEC) | |
-void (*dump_ipi_function_ptr)(void *) = NULL; | |
-void dump_send_ipi(void (*dump_ipi_callback)(void *)) | |
-{ | |
- int i; | |
- int cpu = smp_processor_id(); | |
- | |
- dump_ipi_function_ptr = dump_ipi_callback; | |
- smp_mb(); | |
- for_each_online_cpu(i) | |
- if (i != cpu) | |
- mp_ops->send_ipi_single(i, SMP_DUMP); | |
- | |
-} | |
-EXPORT_SYMBOL(dump_send_ipi); | |
-#endif | |
- | |
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST | |
static DEFINE_PER_CPU(atomic_t, tick_broadcast_count); | |
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c | |
index d6e6cf75114d..bdc7e9bba1d9 100644 | |
--- a/arch/mips/kernel/spram.c | |
+++ b/arch/mips/kernel/spram.c | |
@@ -17,6 +17,13 @@ | |
#include <asm/r4kcache.h> | |
#include <asm/hazards.h> | |
+#ifdef CONFIG_TC3262_IMEM | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#define MIPS34K_Index_Store_Data_I 0x0c | |
+extern int __imem; | |
+#endif | |
+ | |
/* | |
* These definitions are correct for the 24K/34K/74K SPRAM sample | |
* implementation. The 4KS interpreted the tags differently... | |
@@ -81,6 +88,7 @@ static unsigned int ispram_load_tag(unsigned int offset) | |
return data; | |
} | |
+#ifndef CONFIG_TC3262_IMEM | |
static void dspram_store_tag(unsigned int offset, unsigned int data) | |
{ | |
unsigned int errctl; | |
@@ -113,6 +121,7 @@ static unsigned int dspram_load_tag(unsigned int offset) | |
return data; | |
} | |
+#endif | |
static void probe_spram(char *type, | |
unsigned int base, | |
@@ -195,6 +204,61 @@ static void probe_spram(char *type, | |
offset += 2 * SPRAM_TAG_STRIDE; | |
} | |
} | |
+ | |
+#ifdef CONFIG_TC3262_IMEM | |
+static void | |
+ispram_store_data(unsigned int offset, unsigned int datalo, unsigned int datahi) | |
+{ | |
+ unsigned int errctl; | |
+ | |
+ /* enable SPRAM tag access */ | |
+ errctl = bis_c0_errctl(ERRCTL_SPRAM); | |
+ ehb(); | |
+ | |
+#ifdef __BIG_ENDIAN | |
+ write_c0_idatalo(datahi); | |
+ ehb(); | |
+ | |
+ write_c0_idatahi(datalo); | |
+ ehb(); | |
+#else | |
+ write_c0_idatalo(datalo); | |
+ ehb(); | |
+ | |
+ write_c0_idatahi(datahi); | |
+ ehb(); | |
+#endif | |
+ | |
+ cache_op(MIPS34K_Index_Store_Data_I, CKSEG0|offset); | |
+ ehb(); | |
+ | |
+ write_c0_errctl(errctl); | |
+ ehb(); | |
+} | |
+ | |
+static void ispram_fill(void) | |
+{ | |
+ unsigned int pa, size, tag0, tag1; | |
+ unsigned int offset; | |
+ unsigned int datalo, datahi; | |
+ | |
+ tag0 = ispram_load_tag(0); | |
+ tag1 = ispram_load_tag(0 + SPRAM_TAG_STRIDE); | |
+ | |
+ pa = tag0 & SPRAM_TAG0_PA_MASK; | |
+ size = tag1 & SPRAM_TAG1_SIZE_MASK; | |
+ | |
+ if (size == 0) | |
+ return; | |
+ | |
+ for (offset = 0; offset < size; offset += 8) { | |
+ datalo = *(unsigned int *) ((unsigned int)PHYS_TO_K0(pa + offset)); | |
+ datahi = *(unsigned int *) ((unsigned int)PHYS_TO_K0(pa + offset + 4)); | |
+ ispram_store_data(offset, datalo, datahi); | |
+ } | |
+} | |
+#endif | |
+ | |
void spram_config(void) | |
{ | |
unsigned int config0; | |
@@ -212,6 +276,13 @@ void spram_config(void) | |
case CPU_I6400: | |
case CPU_P6600: | |
config0 = read_c0_config(); | |
+#ifdef CONFIG_TC3262_IMEM | |
+ if (config0 & (1<<24)) { | |
+ probe_spram("ISPRAM", CPHYSADDR(&__imem), | |
+ &ispram_load_tag, &ispram_store_tag); | |
+ ispram_fill(); | |
+ } | |
+#else | |
/* FIXME: addresses are Malta specific */ | |
if (config0 & (1<<24)) { | |
probe_spram("ISPRAM", 0x1c000000, | |
@@ -220,5 +291,6 @@ void spram_config(void) | |
if (config0 & (1<<23)) | |
probe_spram("DSPRAM", 0x1c100000, | |
&dspram_load_tag, &dspram_store_tag); | |
+#endif | |
} | |
} | |
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c | |
index 4472a7f98577..1992c79af721 100644 | |
--- a/arch/mips/kernel/sync-r4k.c | |
+++ b/arch/mips/kernel/sync-r4k.c | |
@@ -29,7 +29,7 @@ void synchronise_count_master(int cpu) | |
int i; | |
unsigned long flags; | |
- printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu); | |
+ pr_info("Synchronize counters for CPU %u: ", cpu); | |
local_irq_save(flags); | |
@@ -83,12 +83,15 @@ void synchronise_count_master(int cpu) | |
* count registers were almost certainly out of sync | |
* so no point in alarming people | |
*/ | |
- printk("done.\n"); | |
+ pr_cont("done.\n"); | |
} | |
void synchronise_count_slave(int cpu) | |
{ | |
int i; | |
+ unsigned long flags; | |
+ | |
+ local_irq_save(flags); | |
/* | |
* Not every cpu is online at the time this gets called, | |
@@ -112,5 +115,7 @@ void synchronise_count_slave(int cpu) | |
} | |
/* Arrange for an interrupt in a short while */ | |
write_c0_compare(read_c0_count() + COUNTON); | |
+ | |
+ local_irq_restore(flags); | |
} | |
#undef NR_LOOPS | |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c | |
index 67d3cba60c9f..0c5b9af24aea 100644 | |
--- a/arch/mips/kernel/syscall.c | |
+++ b/arch/mips/kernel/syscall.c | |
@@ -61,16 +61,9 @@ SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, | |
unsigned long, prot, unsigned long, flags, unsigned long, | |
fd, off_t, offset) | |
{ | |
- unsigned long result; | |
- | |
- result = -EINVAL; | |
if (offset & ~PAGE_MASK) | |
- goto out; | |
- | |
- result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | |
- | |
-out: | |
- return result; | |
+ return -EINVAL; | |
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | |
} | |
SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, | |
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c | |
index c6297a03d945..62689a604314 100644 | |
--- a/arch/mips/kernel/vdso.c | |
+++ b/arch/mips/kernel/vdso.c | |
@@ -13,7 +13,9 @@ | |
#include <linux/err.h> | |
#include <linux/init.h> | |
#include <linux/ioport.h> | |
+#ifndef CONFIG_IRQ_GIC | |
#include <linux/irqchip/mips-gic.h> | |
+#endif | |
#include <linux/kernel.h> | |
#include <linux/mm.h> | |
#include <linux/sched.h> | |
@@ -23,6 +25,9 @@ | |
#include <asm/abi.h> | |
#include <asm/page.h> | |
#include <asm/vdso.h> | |
+#ifdef CONFIG_IRQ_GIC | |
+#include <asm/gic.h> | |
+#endif | |
/* Kernel-provided data used by the VDSO. */ | |
static union mips_vdso_data vdso_data __page_aligned_data; | |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S | |
index 23c5509f3b51..b334e6fbff05 100644 | |
--- a/arch/mips/kernel/vmlinux.lds.S | |
+++ b/arch/mips/kernel/vmlinux.lds.S | |
@@ -11,6 +11,10 @@ | |
#include <asm-generic/vmlinux.lds.h> | |
+#ifdef CONFIG_TC3262_IMEM | |
+#define TC3262_IMEM_SIZE 65536 | |
+#endif | |
+ | |
#undef mips | |
#define mips mips | |
OUTPUT_ARCH(mips) | |
@@ -53,25 +57,40 @@ SECTIONS | |
/* read-only */ | |
_text = .; /* Text and read-only data */ | |
.text : { | |
+#ifdef CONFIG_RALINK_MT7628 | |
+ . = . + 0x8000; | |
+#endif | |
TEXT_TEXT | |
SCHED_TEXT | |
CPUIDLE_TEXT | |
LOCK_TEXT | |
KPROBES_TEXT | |
+#ifndef CONFIG_TC3262_IMEM | |
IRQENTRY_TEXT | |
SOFTIRQENTRY_TEXT | |
+#endif | |
*(.text.*) | |
*(.fixup) | |
*(.gnu.warning) | |
} :text = 0 | |
+ | |
+#ifdef CONFIG_TC3262_IMEM | |
+ . = ALIGN(32768); | |
+ __imem = . ; | |
+ .imem_text : { *(.imem_text) } | |
+ _imem_end = .; | |
+ _etext = (__imem + TC3262_IMEM_SIZE) > . ? (__imem + TC3262_IMEM_SIZE) : .; | |
+ . = _etext; | |
+#else | |
_etext = .; /* End of text section */ | |
+#endif | |
EXCEPTION_TABLE(16) | |
/* Exception table for data bus errors */ | |
__dbe_table : { | |
__start___dbe_table = .; | |
- *(__dbe_table) | |
+ KEEP(*(__dbe_table)) | |
__stop___dbe_table = .; | |
} | |
@@ -122,7 +141,7 @@ SECTIONS | |
. = ALIGN(4); | |
.mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) { | |
__mips_machines_start = .; | |
- *(.mips.machines.init) | |
+ KEEP(*(.mips.machines.init)) | |
__mips_machines_end = .; | |
} | |
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile | |
index fba4ca56e46a..3053677fb236 100644 | |
--- a/arch/mips/lib/Makefile | |
+++ b/arch/mips/lib/Makefile | |
@@ -4,7 +4,7 @@ | |
lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ | |
mips-atomic.o strlen_user.o strncpy_user.o \ | |
- strnlen_user.o uncached.o | |
+ strnlen_user.o uncached.o memcmp.o | |
obj-y += iomap.o | |
obj-$(CONFIG_PCI) += iomap-pci.o | |
diff --git a/arch/mips/lib/memcmp.c b/arch/mips/lib/memcmp.c | |
new file mode 100644 | |
index 000000000000..35ef1646286e | |
--- /dev/null | |
+++ b/arch/mips/lib/memcmp.c | |
@@ -0,0 +1,22 @@ | |
+/* | |
+ * copied from linux/lib/string.c | |
+ * | |
+ * Copyright (C) 1991, 1992 Linus Torvalds | |
+ */ | |
+ | |
+#include <linux/module.h> | |
+#include <linux/string.h> | |
+ | |
+#undef memcmp | |
+int memcmp(const void *cs, const void *ct, size_t count) | |
+{ | |
+ const unsigned char *su1, *su2; | |
+ int res = 0; | |
+ | |
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) | |
+ if ((res = *su1 - *su2) != 0) | |
+ break; | |
+ return res; | |
+} | |
+EXPORT_SYMBOL(memcmp); | |
+ | |
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c | |
index 99aab9f85904..8bffc04581e7 100644 | |
--- a/arch/mips/loongson64/loongson-3/smp.c | |
+++ b/arch/mips/loongson64/loongson-3/smp.c | |
@@ -381,7 +381,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus) | |
/* | |
* Setup the PC, SP, and GP of a secondary processor and start it runing! | |
*/ | |
-static void loongson3_boot_secondary(int cpu, struct task_struct *idle) | |
+static int loongson3_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
unsigned long startargs[4]; | |
@@ -404,6 +404,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) | |
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); | |
loongson3_ipi_write64(startargs[0], | |
(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); | |
+ return 0; | |
} | |
#ifdef CONFIG_HOTPLUG_CPU | |
@@ -418,7 +419,6 @@ static int loongson3_cpu_disable(void) | |
set_cpu_online(cpu, false); | |
calculate_cpu_foreign_map(); | |
- cpumask_clear_cpu(cpu, &cpu_callin_map); | |
local_irq_save(flags); | |
fixup_irqs(); | |
local_irq_restore(flags); | |
@@ -716,7 +716,7 @@ early_initcall(register_loongson3_notifier); | |
#endif | |
-struct plat_smp_ops loongson3_smp_ops = { | |
+const struct plat_smp_ops loongson3_smp_ops = { | |
.send_ipi_single = loongson3_send_ipi_single, | |
.send_ipi_mask = loongson3_send_ipi_mask, | |
.init_secondary = loongson3_init_secondary, | |
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c | |
index 0e45b061e514..8064821e9805 100644 | |
--- a/arch/mips/mm/c-octeon.c | |
+++ b/arch/mips/mm/c-octeon.c | |
@@ -127,23 +127,6 @@ static void octeon_flush_icache_range(unsigned long start, unsigned long end) | |
} | |
-/** | |
- * Flush the icache for a trampoline. These are used for interrupt | |
- * and exception hooking. | |
- * | |
- * @addr: Address to flush | |
- */ | |
-static void octeon_flush_cache_sigtramp(unsigned long addr) | |
-{ | |
- struct vm_area_struct *vma; | |
- | |
- down_read(¤t->mm->mmap_sem); | |
- vma = find_vma(current->mm, addr); | |
- octeon_flush_icache_all_cores(vma); | |
- up_read(¤t->mm->mmap_sem); | |
-} | |
- | |
- | |
/** | |
* Flush a range out of a vma | |
* | |
@@ -289,7 +272,6 @@ void octeon_cache_init(void) | |
flush_cache_mm = octeon_flush_cache_mm; | |
flush_cache_page = octeon_flush_cache_page; | |
flush_cache_range = octeon_flush_cache_range; | |
- flush_cache_sigtramp = octeon_flush_cache_sigtramp; | |
flush_icache_all = octeon_flush_icache_all; | |
flush_data_cache_page = octeon_flush_data_cache_page; | |
flush_icache_range = octeon_flush_icache_range; | |
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c | |
index 21e4e662c1fa..432b8c8a588c 100644 | |
--- a/arch/mips/mm/c-r3k.c | |
+++ b/arch/mips/mm/c-r3k.c | |
@@ -273,30 +273,6 @@ static void r3k_flush_data_cache_page(unsigned long addr) | |
{ | |
} | |
-static void r3k_flush_cache_sigtramp(unsigned long addr) | |
-{ | |
- unsigned long flags; | |
- | |
- pr_debug("csigtramp[%08lx]\n", addr); | |
- | |
- flags = read_c0_status(); | |
- | |
- write_c0_status(flags&~ST0_IEC); | |
- | |
- /* Fill the TLB to avoid an exception with caches isolated. */ | |
- asm( "lw\t$0, 0x000(%0)\n\t" | |
- "lw\t$0, 0x004(%0)\n\t" | |
- : : "r" (addr) ); | |
- | |
- write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); | |
- | |
- asm( "sb\t$0, 0x000(%0)\n\t" | |
- "sb\t$0, 0x004(%0)\n\t" | |
- : : "r" (addr) ); | |
- | |
- write_c0_status(flags); | |
-} | |
- | |
static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size) | |
{ | |
BUG(); | |
@@ -330,7 +306,6 @@ void r3k_cache_init(void) | |
__flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; | |
- flush_cache_sigtramp = r3k_flush_cache_sigtramp; | |
local_flush_data_cache_page = local_r3k_flush_data_cache_page; | |
flush_data_cache_page = r3k_flush_data_cache_page; | |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c | |
index b9dea4ce290c..741569afd9f6 100644 | |
--- a/arch/mips/mm/c-r4k.c | |
+++ b/arch/mips/mm/c-r4k.c | |
@@ -109,7 +109,9 @@ static inline void r4k_on_each_cpu(unsigned int type, | |
*/ | |
static unsigned long icache_size __read_mostly; | |
static unsigned long dcache_size __read_mostly; | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
static unsigned long vcache_size __read_mostly; | |
+#endif | |
static unsigned long scache_size __read_mostly; | |
/* | |
@@ -320,8 +322,10 @@ static void r4k_blast_icache_page_setup(void) | |
r4k_blast_icache_page = (void *)cache_noop; | |
else if (ic_lsize == 16) | |
r4k_blast_icache_page = blast_icache16_page; | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
else if (ic_lsize == 32 && current_cpu_type() == CPU_LOONGSON2) | |
r4k_blast_icache_page = loongson2_blast_icache32_page; | |
+#endif | |
else if (ic_lsize == 32) | |
r4k_blast_icache_page = blast_icache32_page; | |
else if (ic_lsize == 64) | |
@@ -369,9 +373,11 @@ static void r4k_blast_icache_page_indexed_setup(void) | |
else if (TX49XX_ICACHE_INDEX_INV_WAR) | |
r4k_blast_icache_page_indexed = | |
tx49_blast_icache32_page_indexed; | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
else if (current_cpu_type() == CPU_LOONGSON2) | |
r4k_blast_icache_page_indexed = | |
loongson2_blast_icache32_page_indexed; | |
+#endif | |
else | |
r4k_blast_icache_page_indexed = | |
blast_icache32_page_indexed; | |
@@ -395,8 +401,10 @@ static void r4k_blast_icache_setup(void) | |
r4k_blast_icache = blast_r4600_v1_icache32; | |
else if (TX49XX_ICACHE_INDEX_INV_WAR) | |
r4k_blast_icache = tx49_blast_icache32; | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
else if (current_cpu_type() == CPU_LOONGSON2) | |
r4k_blast_icache = loongson2_blast_icache32; | |
+#endif | |
else | |
r4k_blast_icache = blast_icache32; | |
} else if (ic_lsize == 64) | |
@@ -462,6 +470,10 @@ static void r4k_blast_scache_setup(void) | |
static inline void local_r4k___flush_cache_all(void * args) | |
{ | |
switch (current_cpu_type()) { | |
+#if defined(CONFIG_CPU_LOONGSON3) || \ | |
+ defined(CONFIG_CPU_LOONGSON2) || \ | |
+ defined(CONFIG_CPU_R4X00) || \ | |
+ defined(CONFIG_CPU_R10000) | |
case CPU_LOONGSON2: | |
case CPU_LOONGSON3: | |
case CPU_R4000SC: | |
@@ -479,11 +491,14 @@ static inline void local_r4k___flush_cache_all(void * args) | |
*/ | |
r4k_blast_scache(); | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_BMIPS5000) | |
case CPU_BMIPS5000: | |
r4k_blast_scache(); | |
__sync(); | |
break; | |
+#endif | |
default: | |
r4k_blast_dcache(); | |
@@ -584,6 +599,7 @@ static inline void local_r4k_flush_cache_mm(void * args) | |
if (!has_valid_asid(mm, R4K_INDEX)) | |
return; | |
+#if defined(CONFIG_CPU_R4X00) | |
/* | |
* Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we | |
* only flush the primary caches but R1x000 behave sane ... | |
@@ -597,6 +613,7 @@ static inline void local_r4k_flush_cache_mm(void * args) | |
r4k_blast_scache(); | |
return; | |
} | |
+#endif | |
r4k_blast_dcache(); | |
} | |
@@ -748,9 +765,11 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, | |
r4k_blast_icache(); | |
else { | |
switch (boot_cpu_type()) { | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
case CPU_LOONGSON2: | |
protected_loongson2_blast_icache_range(start, end); | |
break; | |
+#endif | |
default: | |
if (user) | |
@@ -832,6 +851,7 @@ static void r4k_flush_icache_user_range(unsigned long start, unsigned long end) | |
#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) | |
+__IMEM | |
static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |
{ | |
/* Catch bad driver code */ | |
@@ -869,6 +889,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |
__sync(); | |
} | |
+__IMEM | |
static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |
{ | |
/* Catch bad driver code */ | |
@@ -908,119 +929,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |
} | |
#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */ | |
-struct flush_cache_sigtramp_args { | |
- struct mm_struct *mm; | |
- struct page *page; | |
- unsigned long addr; | |
-}; | |
- | |
-/* | |
- * While we're protected against bad userland addresses we don't care | |
- * very much about what happens in that case. Usually a segmentation | |
- * fault will dump the process later on anyway ... | |
- */ | |
-static void local_r4k_flush_cache_sigtramp(void *args) | |
-{ | |
- struct flush_cache_sigtramp_args *fcs_args = args; | |
- unsigned long addr = fcs_args->addr; | |
- struct page *page = fcs_args->page; | |
- struct mm_struct *mm = fcs_args->mm; | |
- int map_coherent = 0; | |
- void *vaddr; | |
- | |
- unsigned long ic_lsize = cpu_icache_line_size(); | |
- unsigned long dc_lsize = cpu_dcache_line_size(); | |
- unsigned long sc_lsize = cpu_scache_line_size(); | |
- | |
- /* | |
- * If owns no valid ASID yet, cannot possibly have gotten | |
- * this page into the cache. | |
- */ | |
- if (!has_valid_asid(mm, R4K_HIT)) | |
- return; | |
- | |
- if (mm == current->active_mm) { | |
- vaddr = NULL; | |
- } else { | |
- /* | |
- * Use kmap_coherent or kmap_atomic to do flushes for | |
- * another ASID than the current one. | |
- */ | |
- map_coherent = (cpu_has_dc_aliases && | |
- page_mapcount(page) && | |
- !Page_dcache_dirty(page)); | |
- if (map_coherent) | |
- vaddr = kmap_coherent(page, addr); | |
- else | |
- vaddr = kmap_atomic(page); | |
- addr = (unsigned long)vaddr + (addr & ~PAGE_MASK); | |
- } | |
- | |
- R4600_HIT_CACHEOP_WAR_IMPL; | |
- if (!cpu_has_ic_fills_f_dc) { | |
- if (dc_lsize) | |
- vaddr ? flush_dcache_line(addr & ~(dc_lsize - 1)) | |
- : protected_writeback_dcache_line( | |
- addr & ~(dc_lsize - 1)); | |
- if (!cpu_icache_snoops_remote_store && scache_size) | |
- vaddr ? flush_scache_line(addr & ~(sc_lsize - 1)) | |
- : protected_writeback_scache_line( | |
- addr & ~(sc_lsize - 1)); | |
- } | |
- if (ic_lsize) | |
- vaddr ? flush_icache_line(addr & ~(ic_lsize - 1)) | |
- : protected_flush_icache_line(addr & ~(ic_lsize - 1)); | |
- | |
- if (vaddr) { | |
- if (map_coherent) | |
- kunmap_coherent(); | |
- else | |
- kunmap_atomic(vaddr); | |
- } | |
- | |
- if (MIPS4K_ICACHE_REFILL_WAR) { | |
- __asm__ __volatile__ ( | |
- ".set push\n\t" | |
- ".set noat\n\t" | |
- ".set "MIPS_ISA_LEVEL"\n\t" | |
-#ifdef CONFIG_32BIT | |
- "la $at,1f\n\t" | |
-#endif | |
-#ifdef CONFIG_64BIT | |
- "dla $at,1f\n\t" | |
-#endif | |
- "cache %0,($at)\n\t" | |
- "nop; nop; nop\n" | |
- "1:\n\t" | |
- ".set pop" | |
- : | |
- : "i" (Hit_Invalidate_I)); | |
- } | |
- if (MIPS_CACHE_SYNC_WAR) | |
- __asm__ __volatile__ ("sync"); | |
-} | |
- | |
-static void r4k_flush_cache_sigtramp(unsigned long addr) | |
-{ | |
- struct flush_cache_sigtramp_args args; | |
- int npages; | |
- | |
- down_read(¤t->mm->mmap_sem); | |
- | |
- npages = get_user_pages_fast(addr, 1, 0, &args.page); | |
- if (npages < 1) | |
- goto out; | |
- | |
- args.mm = current->mm; | |
- args.addr = addr; | |
- | |
- r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args); | |
- | |
- put_page(args.page); | |
-out: | |
- up_read(¤t->mm->mmap_sem); | |
-} | |
- | |
static void r4k_flush_icache_all(void) | |
{ | |
if (cpu_has_vtag_icache) | |
@@ -1137,6 +1045,7 @@ static inline int alias_74k_erratum(struct cpuinfo_mips *c) | |
return present; | |
} | |
+#if defined(CONFIG_CPU_BMIPS5000) | |
static void b5k_instruction_hazard(void) | |
{ | |
__sync(); | |
@@ -1148,6 +1057,7 @@ static void b5k_instruction_hazard(void) | |
" nop; nop; nop; nop; nop; nop; nop; nop\n" | |
: : : "memory"); | |
} | |
+#endif | |
static char *way_string[] = { NULL, "direct mapped", "2-way", | |
"3-way", "4-way", "5-way", "6-way", "7-way", "8-way", | |
@@ -1197,6 +1107,7 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH; | |
break; | |
+#if defined(CONFIG_CPU_TX49XX) | |
case CPU_TX49XX: | |
icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | |
c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | |
@@ -1211,7 +1122,10 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_CACHE_CDEX_P; | |
c->options |= MIPS_CPU_PREFETCH; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_R4X00) || \ | |
+ defined(CONFIG_CPU_R4300) | |
case CPU_R4000PC: | |
case CPU_R4000SC: | |
case CPU_R4000MC: | |
@@ -1231,7 +1145,9 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_CACHE_CDEX_P; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_R10000) | |
case CPU_R10000: | |
case CPU_R12000: | |
case CPU_R14000: | |
@@ -1248,7 +1164,9 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_PREFETCH; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_VR41XX) | |
case CPU_VR4133: | |
write_c0_config(config & ~VR41_CONF_P4K); | |
case CPU_VR4131: | |
@@ -1291,7 +1209,9 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_CACHE_CDEX_P; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_RM7000) | |
case CPU_RM7000: | |
rm7k_erratum31(); | |
@@ -1308,7 +1228,9 @@ static void probe_pcache(void) | |
c->options |= MIPS_CPU_CACHE_CDEX_P; | |
c->options |= MIPS_CPU_PREFETCH; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
case CPU_LOONGSON2: | |
icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | |
c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | |
@@ -1326,7 +1248,9 @@ static void probe_pcache(void) | |
c->dcache.ways = 2; | |
c->dcache.waybit = 0; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
case CPU_LOONGSON3: | |
config1 = read_c0_config1(); | |
lsize = (config1 >> 19) & 7; | |
@@ -1355,7 +1279,9 @@ static void probe_pcache(void) | |
if ((prid & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R2) | |
c->options |= MIPS_CPU_PREFETCH; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_CAVIUM_OCTEON) | |
case CPU_CAVIUM_OCTEON3: | |
/* For now lie about the number of ways. */ | |
c->icache.linesz = 128; | |
@@ -1370,6 +1296,7 @@ static void probe_pcache(void) | |
dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz; | |
c->options |= MIPS_CPU_PREFETCH; | |
break; | |
+#endif | |
default: | |
if (!(config & MIPS_CONF_M)) | |
@@ -1502,6 +1429,18 @@ static void probe_pcache(void) | |
c->dcache.flags |= MIPS_CACHE_ALIASES; | |
} | |
+ /* Physically indexed caches don't suffer from virtual aliasing */ | |
+ if (c->dcache.flags & MIPS_CACHE_PINDEX) | |
+ c->dcache.flags &= ~MIPS_CACHE_ALIASES; | |
+ | |
+ /* | |
+ * In systems with CM the icache fills from L2 or closer caches, and | |
+ * thus sees remote stores without needing to write them back any | |
+ * further than that. | |
+ */ | |
+ if (mips_cm_present()) | |
+ c->icache.flags |= MIPS_IC_SNOOPS_REMOTE; | |
+ | |
switch (current_cpu_type()) { | |
case CPU_20KC: | |
/* | |
@@ -1530,19 +1469,20 @@ static void probe_pcache(void) | |
c->icache.ways = 1; | |
} | |
- printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", | |
- icache_size >> 10, | |
- c->icache.flags & MIPS_CACHE_VTAG ? "VIVT" : "VIPT", | |
- way_string[c->icache.ways], c->icache.linesz); | |
+ pr_info("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", | |
+ icache_size >> 10, | |
+ c->icache.flags & MIPS_CACHE_VTAG ? "VIVT" : "VIPT", | |
+ way_string[c->icache.ways], c->icache.linesz); | |
- printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n", | |
- dcache_size >> 10, way_string[c->dcache.ways], | |
- (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT", | |
- (c->dcache.flags & MIPS_CACHE_ALIASES) ? | |
+ pr_info("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n", | |
+ dcache_size >> 10, way_string[c->dcache.ways], | |
+ (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT", | |
+ (c->dcache.flags & MIPS_CACHE_ALIASES) ? | |
"cache aliases" : "no aliases", | |
- c->dcache.linesz); | |
+ c->dcache.linesz); | |
} | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
static void probe_vcache(void) | |
{ | |
struct cpuinfo_mips *c = ¤t_cpu_data; | |
@@ -1568,7 +1508,11 @@ static void probe_vcache(void) | |
pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", | |
vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); | |
} | |
+#else | |
+static inline void probe_vcache(void) {} | |
+#endif | |
+#if defined(CONFIG_CPU_R4X00) | |
/* | |
* If you even _breathe_ on this function, look at the gcc output and make sure | |
* it does not pop things on and off the stack for the cache sizing loop that | |
@@ -1629,7 +1573,9 @@ static int probe_scache(void) | |
return 1; | |
} | |
+#endif | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
static void loongson2_sc_init(void) | |
{ | |
struct cpuinfo_mips *c = ¤t_cpu_data; | |
@@ -1641,11 +1587,13 @@ static void loongson2_sc_init(void) | |
c->scache.waysize = scache_size / (c->scache.ways); | |
c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); | |
pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", | |
- scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
c->options |= MIPS_CPU_INCLUSIVE_CACHES; | |
} | |
+#endif | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
static void __init loongson3_sc_init(void) | |
{ | |
struct cpuinfo_mips *c = ¤t_cpu_data; | |
@@ -1668,11 +1616,12 @@ static void __init loongson3_sc_init(void) | |
c->scache.waybit = 0; | |
c->scache.waysize = scache_size / c->scache.ways; | |
pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", | |
- scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
if (scache_size) | |
c->options |= MIPS_CPU_INCLUSIVE_CACHES; | |
return; | |
} | |
+#endif | |
extern int r5k_sc_init(void); | |
extern int rm7k_sc_init(void); | |
@@ -1681,7 +1630,9 @@ extern int mips_sc_init(void); | |
static void setup_scache(void) | |
{ | |
struct cpuinfo_mips *c = ¤t_cpu_data; | |
+#if defined(CONFIG_CPU_R10000) | |
unsigned int config = read_c0_config(); | |
+#endif | |
int sc_present = 0; | |
/* | |
@@ -1690,6 +1641,7 @@ static void setup_scache(void) | |
* Linux memory management. | |
*/ | |
switch (current_cpu_type()) { | |
+#if defined(CONFIG_CPU_R4X00) | |
case CPU_R4000SC: | |
case CPU_R4000MC: | |
case CPU_R4400SC: | |
@@ -1698,7 +1650,9 @@ static void setup_scache(void) | |
if (sc_present) | |
c->options |= MIPS_CPU_CACHE_CDEX_S; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_R10000) | |
case CPU_R10000: | |
case CPU_R12000: | |
case CPU_R14000: | |
@@ -1709,6 +1663,7 @@ static void setup_scache(void) | |
c->scache.waybit= 0; | |
sc_present = 1; | |
break; | |
+#endif | |
case CPU_R5000: | |
case CPU_NEVADA: | |
@@ -1724,11 +1679,15 @@ static void setup_scache(void) | |
return; | |
case CPU_LOONGSON2: | |
+#if defined(CONFIG_CPU_LOONGSON2) | |
loongson2_sc_init(); | |
+#endif | |
return; | |
case CPU_LOONGSON3: | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
loongson3_sc_init(); | |
+#endif | |
return; | |
case CPU_CAVIUM_OCTEON3: | |
@@ -1743,9 +1702,9 @@ static void setup_scache(void) | |
#ifdef CONFIG_MIPS_CPU_SCACHE | |
if (mips_sc_init ()) { | |
scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; | |
- printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n", | |
- scache_size >> 10, | |
- way_string[c->scache.ways], c->scache.linesz); | |
+ pr_info("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n", | |
+ scache_size >> 10, | |
+ way_string[c->scache.ways], c->scache.linesz); | |
if (current_cpu_type() == CPU_BMIPS5000) | |
c->options |= MIPS_CPU_INCLUSIVE_CACHES; | |
@@ -1768,8 +1727,8 @@ static void setup_scache(void) | |
c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); | |
- printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", | |
- scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
+ pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", | |
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); | |
c->options |= MIPS_CPU_INCLUSIVE_CACHES; | |
} | |
@@ -1849,6 +1808,7 @@ static void coherency_setup(void) | |
* silly idea of putting something else there ... | |
*/ | |
switch (current_cpu_type()) { | |
+#if defined(CONFIG_CPU_R4X00) | |
case CPU_R4000PC: | |
case CPU_R4000SC: | |
case CPU_R4000MC: | |
@@ -1857,6 +1817,7 @@ static void coherency_setup(void) | |
case CPU_R4400MC: | |
clear_c0_config(CONF_CU); | |
break; | |
+#endif | |
/* | |
* We need to catch the early Alchemy SOCs with | |
* the write-only co_config.od bit and set it back to one on: | |
@@ -1936,7 +1897,6 @@ void r4k_cache_init(void) | |
__flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; | |
- flush_cache_sigtramp = r4k_flush_cache_sigtramp; | |
flush_icache_all = r4k_flush_icache_all; | |
local_flush_data_cache_page = local_r4k_flush_data_cache_page; | |
flush_data_cache_page = r4k_flush_data_cache_page; | |
@@ -1984,6 +1944,7 @@ void r4k_cache_init(void) | |
/* No IPI is needed because all CPUs share the same D$ */ | |
flush_data_cache_page = r4k_blast_dcache_page; | |
break; | |
+#if defined(CONFIG_CPU_BMIPS5000) | |
case CPU_BMIPS5000: | |
/* We lose our superpowers if L2 is disabled */ | |
if (c->scache.flags & MIPS_CACHE_NOT_PRESENT) | |
@@ -1992,7 +1953,6 @@ void r4k_cache_init(void) | |
/* I$ fills from D$ just by emptying the write buffers */ | |
flush_cache_page = (void *)b5k_instruction_hazard; | |
flush_cache_range = (void *)b5k_instruction_hazard; | |
- flush_cache_sigtramp = (void *)b5k_instruction_hazard; | |
local_flush_data_cache_page = (void *)b5k_instruction_hazard; | |
flush_data_cache_page = (void *)b5k_instruction_hazard; | |
flush_icache_range = (void *)b5k_instruction_hazard; | |
@@ -2002,6 +1962,8 @@ void r4k_cache_init(void) | |
/* Optimization: an L2 flush implicitly flushes the L1 */ | |
current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; | |
break; | |
+#endif | |
+#if defined(CONFIG_CPU_LOONGSON3) | |
case CPU_LOONGSON3: | |
/* Loongson-3 maintains cache coherency by hardware */ | |
__flush_cache_all = cache_noop; | |
@@ -2011,11 +1973,11 @@ void r4k_cache_init(void) | |
flush_cache_mm = (void *)cache_noop; | |
flush_cache_page = (void *)cache_noop; | |
flush_cache_range = (void *)cache_noop; | |
- flush_cache_sigtramp = (void *)cache_noop; | |
flush_icache_all = (void *)cache_noop; | |
flush_data_cache_page = (void *)cache_noop; | |
local_flush_data_cache_page = (void *)cache_noop; | |
break; | |
+#endif | |
} | |
} | |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c | |
index 5c282583edf1..f9c7e2a0cc51 100644 | |
--- a/arch/mips/mm/c-tx39.c | |
+++ b/arch/mips/mm/c-tx39.c | |
@@ -289,25 +289,6 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) | |
} | |
} | |
-static void tx39_flush_cache_sigtramp(unsigned long addr) | |
-{ | |
- unsigned long ic_lsize = current_cpu_data.icache.linesz; | |
- unsigned long dc_lsize = current_cpu_data.dcache.linesz; | |
- unsigned long config; | |
- unsigned long flags; | |
- | |
- protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); | |
- | |
- /* disable icache (set ICE#) */ | |
- local_irq_save(flags); | |
- config = read_c0_conf(); | |
- write_c0_conf(config & ~TX39_CONF_ICE); | |
- TX39_STOP_STREAMING(); | |
- protected_flush_icache_line(addr & ~(ic_lsize - 1)); | |
- write_c0_conf(config); | |
- local_irq_restore(flags); | |
-} | |
- | |
static __init void tx39_probe_cache(void) | |
{ | |
unsigned long config; | |
@@ -367,7 +348,6 @@ void tx39_cache_init(void) | |
flush_icache_range = (void *) tx39h_flush_icache_all; | |
local_flush_icache_range = (void *) tx39h_flush_icache_all; | |
- flush_cache_sigtramp = (void *) tx39h_flush_icache_all; | |
local_flush_data_cache_page = (void *) tx39h_flush_icache_all; | |
flush_data_cache_page = (void *) tx39h_flush_icache_all; | |
@@ -396,7 +376,6 @@ void tx39_cache_init(void) | |
__flush_kernel_vmap_range = tx39_flush_kernel_vmap_range; | |
- flush_cache_sigtramp = tx39_flush_cache_sigtramp; | |
local_flush_data_cache_page = local_tx39_flush_data_cache_page; | |
flush_data_cache_page = tx39_flush_data_cache_page; | |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c | |
index 6db341347202..f913394478dc 100644 | |
--- a/arch/mips/mm/cache.c | |
+++ b/arch/mips/mm/cache.c | |
@@ -43,10 +43,8 @@ void (*__flush_cache_vunmap)(void); | |
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); | |
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); | |
-void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); | |
/* MIPS specific cache operations */ | |
-void (*flush_cache_sigtramp)(unsigned long addr); | |
void (*local_flush_data_cache_page)(void * addr); | |
void (*flush_data_cache_page)(unsigned long addr); | |
void (*flush_icache_all)(void); | |
@@ -63,6 +61,9 @@ void (*_dma_cache_wback)(unsigned long start, unsigned long size); | |
void (*_dma_cache_inv)(unsigned long start, unsigned long size); | |
EXPORT_SYMBOL(_dma_cache_wback_inv); | |
+#ifdef CONFIG_MIPS_TC3262 | |
+EXPORT_SYMBOL(_dma_cache_inv); | |
+#endif | |
#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */ | |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c | |
index 46d5696c4f27..cca82ad8d223 100644 | |
--- a/arch/mips/mm/dma-default.c | |
+++ b/arch/mips/mm/dma-default.c | |
@@ -106,7 +106,11 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) | |
dma_flag = __GFP_DMA; | |
else | |
#endif | |
+#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_MIPS_L2_CACHE_ER35) | |
+ dma_flag = __GFP_DMA; | |
+#else | |
dma_flag = 0; | |
+#endif | |
/* Don't invoke OOM killer */ | |
gfp |= __GFP_NORETRY; | |
@@ -270,13 +274,8 @@ static inline void __dma_sync(struct page *page, | |
if (PageHighMem(page)) { | |
void *addr; | |
- if (offset + len > PAGE_SIZE) { | |
- if (offset >= PAGE_SIZE) { | |
- page += offset >> PAGE_SHIFT; | |
- offset &= ~PAGE_MASK; | |
- } | |
+ if (offset + len > PAGE_SIZE) | |
len = PAGE_SIZE - offset; | |
- } | |
addr = kmap_atomic(page); | |
__dma_sync_virtual(addr + offset, len, direction); | |
@@ -290,8 +289,9 @@ static inline void __dma_sync(struct page *page, | |
} while (left); | |
} | |
-static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, | |
- size_t size, enum dma_data_direction direction, unsigned long attrs) | |
+static void __maybe_unused | |
+mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, | |
+ enum dma_data_direction direction, unsigned long attrs) | |
{ | |
if (cpu_needs_post_dma_flush(dev)) | |
__dma_sync(dma_addr_to_page(dev, dma_addr), | |
@@ -346,8 +346,9 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | |
} | |
} | |
-static void mips_dma_sync_single_for_cpu(struct device *dev, | |
- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) | |
+static void __maybe_unused | |
+mips_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | |
+ size_t size, enum dma_data_direction direction) | |
{ | |
if (cpu_needs_post_dma_flush(dev)) | |
__dma_sync(dma_addr_to_page(dev, dma_handle), | |
@@ -363,9 +364,9 @@ static void mips_dma_sync_single_for_device(struct device *dev, | |
dma_handle & ~PAGE_MASK, size, direction); | |
} | |
-static void mips_dma_sync_sg_for_cpu(struct device *dev, | |
- struct scatterlist *sglist, int nelems, | |
- enum dma_data_direction direction) | |
+static void __maybe_unused | |
+mips_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, | |
+ int nelems, enum dma_data_direction direction) | |
{ | |
int i; | |
struct scatterlist *sg; | |
@@ -394,11 +395,6 @@ static void mips_dma_sync_sg_for_device(struct device *dev, | |
} | |
} | |
-int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |
-{ | |
- return 0; | |
-} | |
- | |
int mips_dma_supported(struct device *dev, u64 mask) | |
{ | |
return plat_dma_supported(dev, mask); | |
@@ -420,14 +416,15 @@ static struct dma_map_ops mips_default_dma_map_ops = { | |
.free = mips_dma_free_coherent, | |
.mmap = mips_dma_mmap, | |
.map_page = mips_dma_map_page, | |
- .unmap_page = mips_dma_unmap_page, | |
.map_sg = mips_dma_map_sg, | |
.unmap_sg = mips_dma_unmap_sg, | |
+#ifdef CONFIG_DMA_UNMAP_POST_FLUSH | |
+ .unmap_page = mips_dma_unmap_page, | |
.sync_single_for_cpu = mips_dma_sync_single_for_cpu, | |
- .sync_single_for_device = mips_dma_sync_single_for_device, | |
.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, | |
+#endif | |
+ .sync_single_for_device = mips_dma_sync_single_for_device, | |
.sync_sg_for_device = mips_dma_sync_sg_for_device, | |
- .mapping_error = mips_dma_mapping_error, | |
.dma_supported = mips_dma_supported | |
}; | |
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c | |
index 3bef306cdfdb..03c2ca7a0e69 100644 | |
--- a/arch/mips/mm/fault.c | |
+++ b/arch/mips/mm/fault.c | |
@@ -209,15 +209,15 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, | |
if (show_unhandled_signals && | |
unhandled_signal(tsk, SIGSEGV) && | |
__ratelimit(&ratelimit_state)) { | |
- pr_info("do_page_fault(): sending SIGSEGV to %s for invalid %s %0*lx\n", | |
+ pr_warn("do_page_fault(): sending SIGSEGV to %s for invalid %s %0*lx\n", | |
tsk->comm, | |
write ? "write access to" : "read access from", | |
field, address); | |
- pr_info("epc = %0*lx in", field, | |
+ pr_warn("epc = %0*lx in", field, | |
(unsigned long) regs->cp0_epc); | |
print_vma_addr(KERN_CONT " ", regs->cp0_epc); | |
pr_cont("\n"); | |
- pr_info("ra = %0*lx in", field, | |
+ pr_warn("ra = %0*lx in", field, | |
(unsigned long) regs->regs[31]); | |
print_vma_addr(KERN_CONT " ", regs->regs[31]); | |
pr_cont("\n"); | |
@@ -267,20 +267,27 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, | |
/* Kernel mode? Handle exceptions or die */ | |
if (!user_mode(regs)) | |
goto no_context; | |
- else | |
+ | |
/* | |
* Send a sigbus, regardless of whether we were in kernel | |
* or user mode. | |
*/ | |
-#if 0 | |
- printk("do_page_fault() #3: sending SIGBUS to %s for " | |
- "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n", | |
- tsk->comm, | |
- write ? "write access to" : "read access from", | |
- field, address, | |
- field, (unsigned long) regs->cp0_epc, | |
- field, (unsigned long) regs->regs[31]); | |
-#endif | |
+ if (show_unhandled_signals && | |
+ unhandled_signal(tsk, SIGBUS) && | |
+ __ratelimit(&ratelimit_state)) { | |
+ pr_warn("do_page_fault(): sending SIGBUS to %s for invalid %s %0*lx\n", | |
+ tsk->comm, | |
+ write ? "write access to" : "read access from", | |
+ field, address); | |
+ pr_warn("epc = %0*lx in", field, | |
+ (unsigned long) regs->cp0_epc); | |
+ print_vma_addr(KERN_CONT " ", regs->cp0_epc); | |
+ pr_cont("\n"); | |
+ pr_warn("ra = %0*lx in", field, | |
+ (unsigned long) regs->regs[31]); | |
+ print_vma_addr(KERN_CONT " ", regs->regs[31]); | |
+ pr_cont("\n"); | |
+ } | |
current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f; | |
tsk->thread.cp0_badvaddr = address; | |
info.si_signo = SIGBUS; | |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c | |
index e86ebcf5c071..367d506bfe68 100644 | |
--- a/arch/mips/mm/init.c | |
+++ b/arch/mips/mm/init.c | |
@@ -257,6 +257,7 @@ void __init fixrange_init(unsigned long start, unsigned long end, | |
#endif | |
} | |
+#if defined(CONFIG_CPU_MIPS32_R5_FEATURES) | |
unsigned __weak platform_maar_init(unsigned num_pairs) | |
{ | |
struct maar_config cfg[BOOT_MEM_MAP_MAX]; | |
@@ -368,6 +369,7 @@ void maar_init(void) | |
} | |
} | |
} | |
+#endif | |
#ifndef CONFIG_NEED_MULTIPLE_NODES | |
int page_is_ram(unsigned long pagenr) | |
@@ -466,7 +468,9 @@ void __init mem_init(void) | |
#endif | |
high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | |
+#if defined(CONFIG_CPU_MIPS32_R5_FEATURES) | |
maar_init(); | |
+#endif | |
free_all_bootmem(); | |
setup_zero_pages(); /* Setup zeroed pages. */ | |
mem_init_free_highmem(); | |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c | |
index f625fd20b21e..6a64998017ca 100644 | |
--- a/arch/mips/mm/tlbex.c | |
+++ b/arch/mips/mm/tlbex.c | |
@@ -406,6 +406,7 @@ static void build_restore_work_registers(u32 **p) | |
*/ | |
extern unsigned long pgd_current[]; | |
+#ifndef CONFIG_CPU_MIPS32_R2 | |
/* | |
* The R3000 TLB handler is simple. | |
*/ | |
@@ -446,6 +447,7 @@ static void build_r3000_tlb_refill_handler(void) | |
dump_handler("r3000_tlb_refill", (u32 *)ebase, 32); | |
} | |
+#endif /* !CONFIG_CPU_MIPS32_R2 */ | |
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ | |
/* | |
@@ -839,9 +841,11 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, | |
if (pgd_reg != -1) { | |
/* pgd is in pgd_reg */ | |
+#ifdef CONFIG_CPU_LOONGSON3 | |
if (cpu_has_ldpte) | |
UASM_i_MFC0(p, ptr, C0_PWBASE); | |
else | |
+#endif | |
UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg); | |
} else { | |
#if defined(CONFIG_MIPS_PGD_C0_CONTEXT) | |
@@ -1461,6 +1465,7 @@ static void build_r4000_tlb_refill_handler(void) | |
dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); | |
} | |
+#ifdef CONFIG_CPU_LOONGSON3 | |
static void setup_pw(void) | |
{ | |
unsigned long pgd_i, pgd_w; | |
@@ -1562,6 +1567,7 @@ static void build_loongson3_tlb_refill_handler(void) | |
local_flush_icache_range(ebase + 0x80, ebase + 0x100); | |
dump_handler("loongson3_tlb_refill", (u32 *)(ebase + 0x80), 32); | |
} | |
+#endif | |
extern u32 handle_tlbl[], handle_tlbl_end[]; | |
extern u32 handle_tlbs[], handle_tlbs_end[]; | |
@@ -1610,9 +1616,11 @@ static void build_setup_pgd(void) | |
uasm_i_ehb(&p); | |
} else { | |
/* PGD in c0_KScratch */ | |
+#ifdef CONFIG_CPU_LOONGSON3 | |
if (cpu_has_ldpte) | |
UASM_i_MTC0(&p, a0, C0_PWBASE); | |
else | |
+#endif | |
UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg); | |
uasm_i_jr(&p, 31); | |
uasm_i_ehb(&p); | |
@@ -1850,7 +1858,7 @@ build_pte_modifiable(u32 **p, struct uasm_reloc **r, | |
} | |
} | |
-#ifndef CONFIG_MIPS_PGD_C0_CONTEXT | |
+#if !defined(CONFIG_MIPS_PGD_C0_CONTEXT) && !defined(CONFIG_CPU_MIPS32_R2) | |
/* | |
@@ -2007,7 +2015,7 @@ static void build_r3000_tlb_modify_handler(void) | |
dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size); | |
} | |
-#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ | |
+#endif /* !CONFIG_MIPS_PGD_C0_CONTEXT && !CONFIG_CPU_MIPS32_R2 */ | |
/* | |
* R4000 style TLB load/store/modify handlers. | |
@@ -2076,7 +2084,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, | |
static void build_r4000_tlb_load_handler(void) | |
{ | |
- u32 *p = handle_tlbl; | |
+ u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbl); | |
const int handle_tlbl_size = handle_tlbl_end - handle_tlbl; | |
struct uasm_label *l = labels; | |
struct uasm_reloc *r = relocs; | |
@@ -2259,7 +2267,7 @@ static void build_r4000_tlb_load_handler(void) | |
static void build_r4000_tlb_store_handler(void) | |
{ | |
- u32 *p = handle_tlbs; | |
+ u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbs); | |
const int handle_tlbs_size = handle_tlbs_end - handle_tlbs; | |
struct uasm_label *l = labels; | |
struct uasm_reloc *r = relocs; | |
@@ -2314,7 +2322,7 @@ static void build_r4000_tlb_store_handler(void) | |
static void build_r4000_tlb_modify_handler(void) | |
{ | |
- u32 *p = handle_tlbm; | |
+ u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbm); | |
const int handle_tlbm_size = handle_tlbm_end - handle_tlbm; | |
struct uasm_label *l = labels; | |
struct uasm_reloc *r = relocs; | |
@@ -2491,9 +2499,9 @@ static void config_htw_params(void) | |
print_htw_config(); | |
} | |
+#ifdef CONFIG_XPA | |
static void config_xpa_params(void) | |
{ | |
-#ifdef CONFIG_XPA | |
unsigned int pagegrain; | |
if (mips_xpa_disabled) { | |
@@ -2510,8 +2518,8 @@ static void config_xpa_params(void) | |
pr_info("Extended Physical Addressing (XPA) enabled\n"); | |
else | |
panic("Extended Physical Addressing (XPA) disabled"); | |
-#endif | |
} | |
+#endif | |
static void check_pabits(void) | |
{ | |
@@ -2568,6 +2576,7 @@ void build_tlb_refill_handler(void) | |
#endif | |
switch (current_cpu_type()) { | |
+#ifndef CONFIG_CPU_MIPS32_R2 | |
case CPU_R2000: | |
case CPU_R3000: | |
case CPU_R3000A: | |
@@ -2576,12 +2585,9 @@ void build_tlb_refill_handler(void) | |
case CPU_TX3922: | |
case CPU_TX3927: | |
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT | |
- if (cpu_has_local_ebase) | |
- build_r3000_tlb_refill_handler(); | |
if (!run_once) { | |
- if (!cpu_has_local_ebase) | |
- build_r3000_tlb_refill_handler(); | |
build_setup_pgd(); | |
+ build_r3000_tlb_refill_handler(); | |
build_r3000_tlb_load_handler(); | |
build_r3000_tlb_store_handler(); | |
build_r3000_tlb_modify_handler(); | |
@@ -2602,9 +2608,12 @@ void build_tlb_refill_handler(void) | |
panic("No R8000 TLB refill handler yet"); | |
break; | |
+#endif /* !CONFIG_CPU_MIPS32_R2 */ | |
default: | |
+#ifdef CONFIG_CPU_LOONGSON3 | |
if (cpu_has_ldpte) | |
setup_pw(); | |
+#endif | |
if (!run_once) { | |
scratch_reg = allocate_kscratch(); | |
@@ -2612,17 +2621,19 @@ void build_tlb_refill_handler(void) | |
build_r4000_tlb_load_handler(); | |
build_r4000_tlb_store_handler(); | |
build_r4000_tlb_modify_handler(); | |
+#ifdef CONFIG_CPU_LOONGSON3 | |
if (cpu_has_ldpte) | |
build_loongson3_tlb_refill_handler(); | |
- else if (!cpu_has_local_ebase) | |
+ else | |
+#endif | |
build_r4000_tlb_refill_handler(); | |
flush_tlb_handlers(); | |
run_once++; | |
} | |
- if (cpu_has_local_ebase) | |
- build_r4000_tlb_refill_handler(); | |
+#ifdef CONFIG_XPA | |
if (cpu_has_xpa) | |
config_xpa_params(); | |
+#endif | |
if (cpu_has_htw) | |
config_htw_params(); | |
} | |
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c | |
index 10d86d54880a..70a703c42014 100644 | |
--- a/arch/mips/netlogic/common/smp.c | |
+++ b/arch/mips/netlogic/common/smp.c | |
@@ -146,7 +146,7 @@ unsigned long nlm_next_gp; | |
unsigned long nlm_next_sp; | |
static cpumask_t phys_cpu_present_mask; | |
-void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | |
+int nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | |
{ | |
uint64_t picbase; | |
int hwtid; | |
@@ -160,6 +160,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | |
/* barrier for sp/gp store above */ | |
__sync(); | |
nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ | |
+ | |
+ return 0; | |
} | |
void __init nlm_smp_setup(void) | |
@@ -271,7 +273,7 @@ int nlm_wakeup_secondary_cpus(void) | |
return 0; | |
} | |
-struct plat_smp_ops nlm_smp_ops = { | |
+const struct plat_smp_ops nlm_smp_ops = { | |
.send_ipi_single = nlm_send_ipi_single, | |
.send_ipi_mask = nlm_send_ipi_mask, | |
.init_secondary = nlm_init_secondary, | |
diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c | |
index f8d3e081b2eb..324630445ad9 100644 | |
--- a/arch/mips/paravirt/paravirt-smp.c | |
+++ b/arch/mips/paravirt/paravirt-smp.c | |
@@ -99,11 +99,12 @@ static void paravirt_smp_finish(void) | |
local_irq_enable(); | |
} | |
-static void paravirt_boot_secondary(int cpu, struct task_struct *idle) | |
+static int paravirt_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); | |
smp_wmb(); | |
paravirt_smp_sp[cpu] = __KSTK_TOS(idle); | |
+ return 0; | |
} | |
static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) | |
@@ -132,7 +133,7 @@ static void paravirt_prepare_cpus(unsigned int max_cpus) | |
} | |
} | |
-struct plat_smp_ops paravirt_smp_ops = { | |
+const struct plat_smp_ops paravirt_smp_ops = { | |
.send_ipi_single = paravirt_send_ipi_single, | |
.send_ipi_mask = paravirt_send_ipi_mask, | |
.init_secondary = paravirt_init_secondary, | |
diff --git a/arch/mips/paravirt/setup.c b/arch/mips/paravirt/setup.c | |
index cb8448b373a7..d2ffec1409a7 100644 | |
--- a/arch/mips/paravirt/setup.c | |
+++ b/arch/mips/paravirt/setup.c | |
@@ -14,7 +14,7 @@ | |
#include <asm/smp-ops.h> | |
#include <asm/time.h> | |
-extern struct plat_smp_ops paravirt_smp_ops; | |
+extern const struct plat_smp_ops paravirt_smp_ops; | |
const char *get_system_type(void) | |
{ | |
diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c | |
index 1c02f5737367..b4c263f16b15 100644 | |
--- a/arch/mips/pci/fixup-capcella.c | |
+++ b/arch/mips/pci/fixup-capcella.c | |
@@ -32,13 +32,13 @@ | |
#define INTC PC104PLUS_INTC_IRQ | |
#define INTD PC104PLUS_INTD_IRQ | |
-static char irq_tab_capcella[][5] __initdata = { | |
+static char irq_tab_capcella[][5] = { | |
[11] = { -1, INT1, INT1, INT1, INT1 }, | |
[12] = { -1, INT2, INT2, INT2, INT2 }, | |
[14] = { -1, INTA, INTB, INTC, INTD } | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return irq_tab_capcella[slot][pin]; | |
} | |
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c | |
index b3ab59318d91..44be65c3e6bb 100644 | |
--- a/arch/mips/pci/fixup-cobalt.c | |
+++ b/arch/mips/pci/fixup-cobalt.c | |
@@ -147,7 +147,7 @@ static void qube_raq_via_board_id_fixup(struct pci_dev *dev) | |
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, | |
qube_raq_via_board_id_fixup); | |
-static char irq_tab_qube1[] __initdata = { | |
+static char irq_tab_qube1[] = { | |
[COBALT_PCICONF_CPU] = 0, | |
[COBALT_PCICONF_ETH0] = QUBE1_ETH0_IRQ, | |
[COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, | |
@@ -156,7 +156,7 @@ static char irq_tab_qube1[] __initdata = { | |
[COBALT_PCICONF_ETH1] = 0 | |
}; | |
-static char irq_tab_cobalt[] __initdata = { | |
+static char irq_tab_cobalt[] = { | |
[COBALT_PCICONF_CPU] = 0, | |
[COBALT_PCICONF_ETH0] = ETH0_IRQ, | |
[COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, | |
@@ -165,7 +165,7 @@ static char irq_tab_cobalt[] __initdata = { | |
[COBALT_PCICONF_ETH1] = ETH1_IRQ | |
}; | |
-static char irq_tab_raq2[] __initdata = { | |
+static char irq_tab_raq2[] = { | |
[COBALT_PCICONF_CPU] = 0, | |
[COBALT_PCICONF_ETH0] = ETH0_IRQ, | |
[COBALT_PCICONF_RAQSCSI] = RAQ2_SCSI_IRQ, | |
@@ -174,7 +174,7 @@ static char irq_tab_raq2[] __initdata = { | |
[COBALT_PCICONF_ETH1] = ETH1_IRQ | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) | |
return irq_tab_qube1[slot]; | |
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c | |
index 19caf775c206..c31cb6af1cd0 100644 | |
--- a/arch/mips/pci/fixup-emma2rh.c | |
+++ b/arch/mips/pci/fixup-emma2rh.c | |
@@ -43,7 +43,7 @@ | |
*/ | |
#define MAX_SLOT_NUM 10 | |
-static unsigned char irq_map[][5] __initdata = { | |
+static unsigned char irq_map[][5] = { | |
[3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC, | |
MARKEINS_PCI_IRQ_INTD, 0,}, | |
[4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,}, | |
@@ -85,7 +85,7 @@ static void emma2rh_pci_host_fixup(struct pci_dev *dev) | |
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, | |
emma2rh_pci_host_fixup); | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return irq_map[slot][pin]; | |
} | |
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c | |
index 50da773faede..b47c2771dc99 100644 | |
--- a/arch/mips/pci/fixup-fuloong2e.c | |
+++ b/arch/mips/pci/fixup-fuloong2e.c | |
@@ -19,7 +19,7 @@ | |
/* South bridge slot number is set by the pci probe process */ | |
static u8 sb_slot = 5; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int irq = 0; | |
diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c | |
index 133685e215ee..c6ec18a07e63 100644 | |
--- a/arch/mips/pci/fixup-ip32.c | |
+++ b/arch/mips/pci/fixup-ip32.c | |
@@ -21,7 +21,7 @@ | |
#define INTB MACEPCI_SHARED0_IRQ | |
#define INTC MACEPCI_SHARED1_IRQ | |
#define INTD MACEPCI_SHARED2_IRQ | |
-static char irq_tab_mace[][5] __initdata = { | |
+static char irq_tab_mace[][5] = { | |
/* Dummy INT#A INT#B INT#C INT#D */ | |
{0, 0, 0, 0, 0}, /* This is placeholder row - never used */ | |
{0, SCSI0, SCSI0, SCSI0, SCSI0}, | |
@@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = { | |
* irqs. I suppose a device without a pin A will thank us for doing it | |
* right if there exists such a broken piece of crap. | |
*/ | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return irq_tab_mace[slot][pin]; | |
} | |
diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c | |
index 0f1069527cba..d3102eeea898 100644 | |
--- a/arch/mips/pci/fixup-jmr3927.c | |
+++ b/arch/mips/pci/fixup-jmr3927.c | |
@@ -31,7 +31,7 @@ | |
#include <asm/txx9/pci.h> | |
#include <asm/txx9/jmr3927.h> | |
-int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
unsigned char irq = pin; | |
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c | |
index 2b5427d3f35c..81530a13b349 100644 | |
--- a/arch/mips/pci/fixup-lantiq.c | |
+++ b/arch/mips/pci/fixup-lantiq.c | |
@@ -23,7 +23,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |
return 0; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return of_irq_parse_and_map_pci(dev, slot, pin); | |
} | |
diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c | |
index 95ab9a1bd010..20cdfdc08938 100644 | |
--- a/arch/mips/pci/fixup-lemote2f.c | |
+++ b/arch/mips/pci/fixup-lemote2f.c | |
@@ -30,7 +30,7 @@ | |
#define PCID 7 | |
/* all the pci device has the PCIA pin, check the datasheet. */ | |
-static char irq_tab[][5] __initdata = { | |
+static char irq_tab[][5] = { | |
/* INTA INTB INTC INTD */ | |
{0, 0, 0, 0, 0}, /* 11: Unused */ | |
{0, 0, 0, 0, 0}, /* 12: Unused */ | |
@@ -51,7 +51,7 @@ static char irq_tab[][5] __initdata = { | |
{0, 0, 0, 0, 0}, /* 27: Unused */ | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int virq; | |
diff --git a/arch/mips/pci/fixup-loongson3.c b/arch/mips/pci/fixup-loongson3.c | |
index 2b6d5e196f99..8a741c2c6685 100644 | |
--- a/arch/mips/pci/fixup-loongson3.c | |
+++ b/arch/mips/pci/fixup-loongson3.c | |
@@ -32,7 +32,7 @@ static void print_fixup_info(const struct pci_dev *pdev) | |
pdev->vendor, pdev->device, pdev->irq); | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
print_fixup_info(dev); | |
return dev->irq; | |
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c | |
index 40e920c653cc..3ec85331795e 100644 | |
--- a/arch/mips/pci/fixup-malta.c | |
+++ b/arch/mips/pci/fixup-malta.c | |
@@ -12,7 +12,7 @@ | |
static char pci_irq[5] = { | |
}; | |
-static char irq_tab[][5] __initdata = { | |
+static char irq_tab[][5] = { | |
/* INTA INTB INTC INTD */ | |
{0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */ | |
{0, 0, 0, 0, 0 }, /* 1: Unused */ | |
@@ -38,7 +38,7 @@ static char irq_tab[][5] __initdata = { | |
{0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int virq; | |
virq = irq_tab[slot][pin]; | |
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c | |
index 8e4f8288eca2..66eaf456bc89 100644 | |
--- a/arch/mips/pci/fixup-mpc30x.c | |
+++ b/arch/mips/pci/fixup-mpc30x.c | |
@@ -22,19 +22,19 @@ | |
#include <asm/vr41xx/mpc30x.h> | |
-static const int internal_func_irqs[] __initconst = { | |
+static const int internal_func_irqs[] = { | |
VRC4173_CASCADE_IRQ, | |
VRC4173_AC97_IRQ, | |
VRC4173_USB_IRQ, | |
}; | |
-static const int irq_tab_mpc30x[] __initconst = { | |
+static const int irq_tab_mpc30x[] = { | |
[12] = VRC4173_PCMCIA1_IRQ, | |
[13] = VRC4173_PCMCIA2_IRQ, | |
[29] = MQ200_IRQ, | |
}; | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
if (slot == 30) | |
return internal_func_irqs[PCI_FUNC(dev->devfn)]; | |
diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c | |
index fab405c21c2f..4ad2ef02087b 100644 | |
--- a/arch/mips/pci/fixup-pmcmsp.c | |
+++ b/arch/mips/pci/fixup-pmcmsp.c | |
@@ -47,7 +47,7 @@ | |
#if defined(CONFIG_PMC_MSP7120_GW) | |
/* Garibaldi Board IRQ wiring to PCI slots */ | |
-static char irq_tab[][5] __initdata = { | |
+static char irq_tab[][5] = { | |
/* INTA INTB INTC INTD */ | |
{0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ | |
{0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ | |
@@ -86,7 +86,7 @@ static char irq_tab[][5] __initdata = { | |
#elif defined(CONFIG_PMC_MSP7120_EVAL) | |
/* MSP7120 Eval Board IRQ wiring to PCI slots */ | |
-static char irq_tab[][5] __initdata = { | |
+static char irq_tab[][5] = { | |
/* INTA INTB INTC INTD */ | |
{0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ | |
{0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ | |
@@ -125,7 +125,7 @@ static char irq_tab[][5] __initdata = { | |
#else | |
/* Unknown board -- don't assign any IRQs */ | |
-static char irq_tab[][5] __initdata = { | |
+static char irq_tab[][5] = { | |
/* INTA INTB INTC INTD */ | |
{0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ | |
{0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ | |
@@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |
* RETURNS: IRQ number | |
* | |
****************************************************************************/ | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) | |
printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); | |
diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c | |
index 321db265829c..d6aaed1d6be9 100644 | |
--- a/arch/mips/pci/fixup-rbtx4927.c | |
+++ b/arch/mips/pci/fixup-rbtx4927.c | |
@@ -36,7 +36,7 @@ | |
#include <asm/txx9/pci.h> | |
#include <asm/txx9/rbtx4927.h> | |
-int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
unsigned char irq = pin; | |
diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c | |
index a80579af609b..ff22a22db73e 100644 | |
--- a/arch/mips/pci/fixup-rbtx4938.c | |
+++ b/arch/mips/pci/fixup-rbtx4938.c | |
@@ -13,7 +13,7 @@ | |
#include <asm/txx9/pci.h> | |
#include <asm/txx9/rbtx4938.h> | |
-int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int irq = tx4938_pcic1_map_irq(dev, slot); | |
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c | |
index f67ebeeb4200..adb9a58641e8 100644 | |
--- a/arch/mips/pci/fixup-sni.c | |
+++ b/arch/mips/pci/fixup-sni.c | |
@@ -40,7 +40,7 @@ | |
* seem to be a documentation error. At least on my RM200C the Cirrus | |
* Logic CL-GD5434 VGA is device 3. | |
*/ | |
-static char irq_tab_rm200[8][5] __initdata = { | |
+static char irq_tab_rm200[8][5] = { | |
/* INTA INTB INTC INTD */ | |
{ 0, 0, 0, 0, 0 }, /* EISA bridge */ | |
{ SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ | |
@@ -57,7 +57,7 @@ static char irq_tab_rm200[8][5] __initdata = { | |
* | |
* The VGA card is optional for RM300 systems. | |
*/ | |
-static char irq_tab_rm300d[8][5] __initdata = { | |
+static char irq_tab_rm300d[8][5] = { | |
/* INTA INTB INTC INTD */ | |
{ 0, 0, 0, 0, 0 }, /* EISA bridge */ | |
{ SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ | |
@@ -69,7 +69,7 @@ static char irq_tab_rm300d[8][5] __initdata = { | |
{ 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ | |
}; | |
-static char irq_tab_rm300e[5][5] __initdata = { | |
+static char irq_tab_rm300e[5][5] = { | |
/* INTA INTB INTC INTD */ | |
{ 0, 0, 0, 0, 0 }, /* HOST bridge */ | |
{ SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ | |
@@ -96,7 +96,7 @@ static char irq_tab_rm300e[5][5] __initdata = { | |
#define INTC PCIT_IRQ_INTC | |
#define INTD PCIT_IRQ_INTD | |
-static char irq_tab_pcit[13][5] __initdata = { | |
+static char irq_tab_pcit[13][5] = { | |
/* INTA INTB INTC INTD */ | |
{ 0, 0, 0, 0, 0 }, /* HOST bridge */ | |
{ SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */ | |
@@ -113,7 +113,7 @@ static char irq_tab_pcit[13][5] __initdata = { | |
{ 0, INTA, INTB, INTC, INTD }, /* Slot 5 */ | |
}; | |
-static char irq_tab_pcit_cplus[13][5] __initdata = { | |
+static char irq_tab_pcit_cplus[13][5] = { | |
/* INTA INTB INTC INTD */ | |
{ 0, 0, 0, 0, 0 }, /* HOST bridge */ | |
{ 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */ | |
@@ -130,7 +130,7 @@ static inline int is_rm300_revd(void) | |
return (csmsr & 0xa0) == 0x20; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
switch (sni_brd_type) { | |
case SNI_BRD_PCI_TOWER_CPLUS: | |
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c | |
index d0b0083fbd27..cc581535f257 100644 | |
--- a/arch/mips/pci/fixup-tb0219.c | |
+++ b/arch/mips/pci/fixup-tb0219.c | |
@@ -23,7 +23,7 @@ | |
#include <asm/vr41xx/tb0219.h> | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int irq = -1; | |
diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c | |
index 4196ccf3ea3d..b827b5cad5fd 100644 | |
--- a/arch/mips/pci/fixup-tb0226.c | |
+++ b/arch/mips/pci/fixup-tb0226.c | |
@@ -23,7 +23,7 @@ | |
#include <asm/vr41xx/giu.h> | |
#include <asm/vr41xx/tb0226.h> | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int irq = -1; | |
diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c | |
index 8c5039ed75d7..98f26285f2e3 100644 | |
--- a/arch/mips/pci/fixup-tb0287.c | |
+++ b/arch/mips/pci/fixup-tb0287.c | |
@@ -22,7 +22,7 @@ | |
#include <asm/vr41xx/tb0287.h> | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
unsigned char bus; | |
int irq = -1; | |
diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c | |
index e99ca7702d8a..f15ec98de2de 100644 | |
--- a/arch/mips/pci/pci-alchemy.c | |
+++ b/arch/mips/pci/pci-alchemy.c | |
@@ -522,7 +522,7 @@ static int __init alchemy_pci_init(void) | |
arch_initcall(alchemy_pci_init); | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
struct alchemy_pci_context *ctx = dev->sysdata; | |
if (ctx && ctx->board_map_irq) | |
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c | |
index 76f16eaed0ad..230d7dd273e2 100644 | |
--- a/arch/mips/pci/pci-bcm47xx.c | |
+++ b/arch/mips/pci/pci-bcm47xx.c | |
@@ -28,7 +28,7 @@ | |
#include <linux/bcma/bcma.h> | |
#include <bcm47xx.h> | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return 0; | |
} | |
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c | |
index 40d2797d2bc4..47f4ee6bbb3b 100644 | |
--- a/arch/mips/pci/pci-lasat.c | |
+++ b/arch/mips/pci/pci-lasat.c | |
@@ -61,7 +61,7 @@ arch_initcall(lasat_pci_setup); | |
#define LASAT_IRQ_PCIC (LASAT_IRQ_BASE + 7) | |
#define LASAT_IRQ_PCID (LASAT_IRQ_BASE + 8) | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
switch (slot) { | |
case 1: | |
diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c | |
index 009b840ee5ef..5db63d9836ed 100644 | |
--- a/arch/mips/pci/pci-legacy.c | |
+++ b/arch/mips/pci/pci-legacy.c | |
@@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) | |
static int need_domain_info; | |
LIST_HEAD(resources); | |
struct pci_bus *bus; | |
+ struct pci_host_bridge *bridge; | |
+ int ret; | |
+ | |
+ bridge = pci_alloc_host_bridge(0); | |
+ if (!bridge) | |
+ return; | |
if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) | |
next_busno = (*hose->get_busno)(); | |
@@ -86,20 +92,25 @@ static void pcibios_scanbus(struct pci_controller *hose) | |
hose->mem_resource, hose->mem_offset); | |
pci_add_resource_offset(&resources, | |
hose->io_resource, hose->io_offset); | |
- pci_add_resource_offset(&resources, | |
- hose->busn_resource, hose->busn_offset); | |
- bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | |
- &resources); | |
- hose->bus = bus; | |
+ pci_add_resource(&resources, hose->busn_resource); | |
+ list_splice_init(&resources, &bridge->windows); | |
+ bridge->dev.parent = NULL; | |
+ bridge->sysdata = hose; | |
+ bridge->busnr = next_busno; | |
+ bridge->ops = hose->pci_ops; | |
+ bridge->swizzle_irq = pci_common_swizzle; | |
+ bridge->map_irq = pcibios_map_irq; | |
+ ret = pci_scan_root_bus_bridge(bridge); | |
+ if (ret) { | |
+ pci_free_host_bridge(bridge); | |
+ return; | |
+ } | |
+ | |
+ hose->bus = bus = bridge->bus; | |
need_domain_info = need_domain_info || pci_domain_nr(bus); | |
set_pci_need_domain_info(hose, need_domain_info); | |
- if (!bus) { | |
- pci_free_resource_list(&resources); | |
- return; | |
- } | |
- | |
next_busno = bus->busn_res.end + 1; | |
/* Don't allow 8-bit bus number overflow inside the hose - | |
reserve some space for bridges. */ | |
@@ -199,7 +210,7 @@ void register_pci_controller(struct pci_controller *hose) | |
} | |
INIT_LIST_HEAD(&hose->list); | |
- list_add(&hose->list, &controllers); | |
+ list_add_tail(&hose->list, &controllers); | |
/* | |
* Do not panic here but later - this might happen before console init. | |
@@ -234,8 +245,6 @@ static int __init pcibios_init(void) | |
list_for_each_entry(hose, &controllers, list) | |
pcibios_scanbus(hose); | |
- pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); | |
- | |
pci_initialized = 1; | |
return 0; | |
@@ -274,7 +283,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) | |
cmd |= PCI_COMMAND_MEMORY; | |
} | |
if (cmd != old_cmd) { | |
- printk("PCI: Enabling device %s (%04x -> %04x)\n", | |
+ printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", | |
pci_name(dev), old_cmd, cmd); | |
pci_write_config_word(dev, PCI_COMMAND, cmd); | |
} | |
diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c | |
index a7962f79c4fe..cc3ddf434efe 100644 | |
--- a/arch/mips/pci/pci-mt7620.c | |
+++ b/arch/mips/pci/pci-mt7620.c | |
@@ -361,7 +361,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) | |
return 0; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
u16 cmd; | |
u32 val; | |
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c | |
index 7c512834a8f1..5f8107116334 100644 | |
--- a/arch/mips/pci/pci-octeon.c | |
+++ b/arch/mips/pci/pci-octeon.c | |
@@ -59,8 +59,7 @@ union octeon_pci_address { | |
} s; | |
}; | |
-int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev, | |
- u8 slot, u8 pin); | |
+int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); | |
enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; | |
/** | |
@@ -74,7 +73,7 @@ enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; | |
* as it goes through each bridge. | |
* Returns Interrupt number for the device | |
*/ | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
if (octeon_pcibios_map_irq) | |
return octeon_pcibios_map_irq(dev, slot, pin); | |
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c | |
index d6360fe73d05..711cdccdf65b 100644 | |
--- a/arch/mips/pci/pci-rt2880.c | |
+++ b/arch/mips/pci/pci-rt2880.c | |
@@ -181,7 +181,7 @@ static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) | |
spin_unlock_irqrestore(&rt2880_pci_lock, flags); | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
u16 cmd; | |
int irq = -1; | |
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c | |
index 3520e9b414e7..e8597d39cd5b 100644 | |
--- a/arch/mips/pci/pci-rt3883.c | |
+++ b/arch/mips/pci/pci-rt3883.c | |
@@ -565,7 +565,7 @@ static int rt3883_pci_probe(struct platform_device *pdev) | |
return err; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return of_irq_parse_and_map_pci(dev, slot, pin); | |
} | |
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c | |
index 141bba562488..d0aceb4d81fe 100644 | |
--- a/arch/mips/pci/pci-tx4938.c | |
+++ b/arch/mips/pci/pci-tx4938.c | |
@@ -112,7 +112,7 @@ int __init tx4938_pciclk66_setup(void) | |
return pciclk; | |
} | |
-int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
+int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
{ | |
if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { | |
switch (slot) { | |
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c | |
index cd8ed09c4f53..8801571ddc73 100644 | |
--- a/arch/mips/pci/pci-tx4939.c | |
+++ b/arch/mips/pci/pci-tx4939.c | |
@@ -48,7 +48,7 @@ void __init tx4939_report_pci1clk(void) | |
((pciclk + 50000) / 100000) % 10); | |
} | |
-int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
+int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
{ | |
if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { | |
switch (slot) { | |
@@ -68,7 +68,7 @@ int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) | |
return -1; | |
} | |
-int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
int irq = tx4939_pcic1_map_irq(dev, slot); | |
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c | |
index 7babf01600cb..9eff9137f78e 100644 | |
--- a/arch/mips/pci/pci-xlp.c | |
+++ b/arch/mips/pci/pci-xlp.c | |
@@ -205,7 +205,7 @@ int xlp_socdev_to_node(const struct pci_dev *lnkdev) | |
return PCI_SLOT(lnkdev->devfn) / 8; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
struct pci_dev *lnkdev; | |
int lnkfunc, node; | |
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c | |
index 26d2dabef281..2a1c81a129ba 100644 | |
--- a/arch/mips/pci/pci-xlr.c | |
+++ b/arch/mips/pci/pci-xlr.c | |
@@ -315,7 +315,7 @@ static void xls_pcie_ack_b(struct irq_data *d) | |
} | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
return get_irq_vector(dev); | |
} | |
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c | |
index 9f672ceb089b..aebef6e33000 100644 | |
--- a/arch/mips/pci/pcie-octeon.c | |
+++ b/arch/mips/pci/pcie-octeon.c | |
@@ -1464,8 +1464,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) | |
* as it goes through each bridge. | |
* Returns Interrupt number for the device | |
*/ | |
-int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, | |
- u8 slot, u8 pin) | |
+int octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
/* | |
* The EBH5600 board with the PCI to PCIe bridge mistakenly | |
diff --git a/arch/mips/rt2880/Kconfig b/arch/mips/rt2880/Kconfig | |
new file mode 100644 | |
index 000000000000..94d6dffe777b | |
--- /dev/null | |
+++ b/arch/mips/rt2880/Kconfig | |
@@ -0,0 +1,110 @@ | |
+ | |
+if RALINK_MT7621 | |
+ | |
+choice | |
+ prompt "Soc Hardware Type" | |
+ default MT7621_ASIC | |
+ | |
+config MT7621_ASIC | |
+ bool "MT7621-ASIC" | |
+endchoice | |
+ | |
+config PCIE_PORT0 | |
+ bool "PCIe Port0 support" | |
+ default y | |
+ | |
+config PCIE_PORT1 | |
+ bool "PCIe Port1 support" | |
+ default n | |
+ | |
+config PCIE_PORT2 | |
+ bool "PCIe Port2 support" | |
+ default n | |
+ | |
+config PCIE_PERST_ONLY | |
+ bool "Use single PERST_N pin (GPIO19) to reset PCIe peripherals" | |
+ default y | |
+endif | |
+ | |
+#-------------------------- | |
+ | |
+if RALINK_MT7628 | |
+ | |
+choice | |
+ prompt "Soc Hardware Type" | |
+ default MT7628_ASIC | |
+ | |
+config MT7628_ASIC | |
+ bool "MT7628/MT7688-ASIC" | |
+endchoice | |
+ | |
+endif | |
+ | |
+#-------------------------- | |
+ | |
+config CLKSRC_MIPS_GIC | |
+ bool "Use MIPS GIC Counter (64 bit)" | |
+ depends on MIPS_GIC | |
+ default n | |
+ | |
+#-------------------------- | |
+ | |
+choice | |
+ prompt "DRAM Size" | |
+ default RT2880_DRAM_64M | |
+ | |
+config RT2880_DRAM_16M | |
+ bool "16M" | |
+ | |
+config RT2880_DRAM_32M | |
+ bool "32M" | |
+ | |
+config RT2880_DRAM_64M | |
+ bool "64M" | |
+ | |
+config RT2880_DRAM_128M | |
+ bool "128M" | |
+ | |
+config RT2880_DRAM_256M | |
+ bool "256M" | |
+ | |
+config RT2880_DRAM_512M | |
+ bool "512M (448M + 64M Highmem)" | |
+ depends on (RALINK_MT7621 || MIPS_TC3262_1004K) | |
+ select LONG_CALLS | |
+ | |
+endchoice | |
+ | |
+config RALINK_RAM_SIZE | |
+ int | |
+ default 16 if RT2880_DRAM_16M | |
+ default 32 if RT2880_DRAM_32M | |
+ default 64 if RT2880_DRAM_64M | |
+ default 128 if RT2880_DRAM_128M | |
+ default 256 if RT2880_DRAM_256M | |
+ default 512 if RT2880_DRAM_512M | |
+ | |
+#-------------------------- | |
+ | |
+if MTD | |
+source "drivers/mtd/ralink/Kconfig" | |
+endif | |
+ | |
+#-------------------------- | |
+ | |
+choice | |
+ prompt "UART Baud Rate" | |
+ default RT2880_UART_57600 | |
+ | |
+config RT2880_UART_57600 | |
+ bool "57600" | |
+ | |
+config RT2880_UART_115200 | |
+ bool "115200" | |
+ | |
+endchoice | |
+ | |
+config RALINK_UART_BRATE | |
+ int | |
+ default 57600 if RT2880_UART_57600 | |
+ default 115200 if RT2880_UART_115200 | |
diff --git a/arch/mips/rt2880/Makefile b/arch/mips/rt2880/Makefile | |
new file mode 100644 | |
index 000000000000..e5e8d37c5113 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/Makefile | |
@@ -0,0 +1,43 @@ | |
+############################################################################### | |
+# Jan 2007 Bruce Chang | |
+# | |
+# Initial Release | |
+# | |
+# | |
+# | |
+############################################################################### | |
+ | |
+.S.s: | |
+ $(CPP) $(CFLAGS) $< -o $*.s | |
+.S.o: | |
+ $(CC) $(CFLAGS) -c $< -o $*.o | |
+ | |
+obj-y := reset.o init.o memory.o printf.o cmdline.o setup.o time.o | |
+ | |
+ifdef CONFIG_MIPS_GIC | |
+obj-y += irqchip-gic.o | |
+else | |
+ifdef CONFIG_IRQ_GIC | |
+obj-y += irq-gic.o | |
+else | |
+obj-y += irq.o | |
+endif | |
+endif | |
+ | |
+obj-$(CONFIG_MIPS_CMP) += malta-amon.o | |
+ | |
+obj-$(CONFIG_PCI) += pci.o | |
+obj-$(CONFIG_MTD_NAND_MT7621) += dev-nand.o | |
+ | |
+ifdef CONFIG_USB_EHCI_HCD_PLATFORM | |
+obj-y += dev-ehci_ohci.o uphy.o | |
+endif | |
+ | |
+ifdef CONFIG_USB_XHCI_MTK | |
+obj-y += dev-xhci.o uphy.o | |
+endif | |
+ | |
+ifdef CONFIG_MTK_MMC | |
+obj-y += dev-mmc.o | |
+endif | |
+ | |
diff --git a/arch/mips/rt2880/Platform b/arch/mips/rt2880/Platform | |
new file mode 100644 | |
index 000000000000..ba7da7174641 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/Platform | |
@@ -0,0 +1,15 @@ | |
+# | |
+## Ralink MT7621 board | |
+# | |
+platform-$(CONFIG_RALINK_MT7621)+= rt2880/ | |
+cflags-$(CONFIG_RALINK_MT7621) += -mtune=1004kc | |
+cflags-$(CONFIG_RALINK_MT7621) += -I$(srctree)/arch/mips/include/asm/rt2880 | |
+load-$(CONFIG_RALINK_MT7621) += 0xffffffff80001000+$(CONFIG_ZONE_DMA_SIZE) | |
+ | |
+# | |
+## Ralink MT7628 board | |
+# | |
+platform-$(CONFIG_RALINK_MT7628)+= rt2880/ | |
+cflags-$(CONFIG_RALINK_MT7628) += -mtune=24kec | |
+cflags-$(CONFIG_RALINK_MT7628) += -I$(srctree)/arch/mips/include/asm/rt2880 | |
+load-$(CONFIG_RALINK_MT7628) += 0xffffffff80000000 | |
diff --git a/arch/mips/rt2880/cmdline.c b/arch/mips/rt2880/cmdline.c | |
new file mode 100644 | |
index 000000000000..d54744f65d72 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/cmdline.c | |
@@ -0,0 +1,102 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * cmdline parsing for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+ | |
+#include <asm/bootinfo.h> | |
+ | |
+#if defined(CONFIG_RT2880_UART_115200) | |
+#define TTY_UART_CONSOLE "console=ttyS0,115200n8" | |
+#else | |
+#define TTY_UART_CONSOLE "console=ttyS0,57600n8" | |
+#endif | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+extern int prom_argc; | |
+extern int *_prom_argv; | |
+ | |
+/* | |
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | |
+ * This macro take care of sign extension. | |
+ */ | |
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) | |
+#endif | |
+ | |
+extern char arcs_cmdline[COMMAND_LINE_SIZE]; | |
+ | |
+char * __init prom_getcmdline(void) | |
+{ | |
+ return &(arcs_cmdline[0]); | |
+} | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+void __init uboot_cmdline(char *s, size_t size) | |
+{ | |
+ int i; | |
+ | |
+ for (i = 1; i < prom_argc; i++) { /* Skip argv[0] */ | |
+ strlcat(s, prom_argv(i), size); | |
+ | |
+ /* Prevent last space */ | |
+ if (i != prom_argc - 1) | |
+ strlcat(s, " ", size); | |
+ } | |
+} | |
+#else | |
+static inline void uboot_cmdline(char *s, size_t size) {} | |
+#endif | |
+ | |
+static inline void fixup_cmdline(char *s, size_t size) | |
+{ | |
+ const char *p = TTY_UART_CONSOLE; | |
+ | |
+ if (strstr(s, "console=")) | |
+ return; | |
+ | |
+ /* Add space if there are symbols in buffer */ | |
+ if (*s) | |
+ strlcat(s, " ", size); | |
+ strlcat(s, p, size); | |
+} | |
+ | |
+void __init prom_init_cmdline(void) | |
+{ | |
+ uboot_cmdline(arcs_cmdline, sizeof(arcs_cmdline)); | |
+ fixup_cmdline(arcs_cmdline, sizeof(arcs_cmdline)); | |
+} | |
diff --git a/arch/mips/rt2880/dev-ehci_ohci.c b/arch/mips/rt2880/dev-ehci_ohci.c | |
new file mode 100644 | |
index 000000000000..f0144c3b8648 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/dev-ehci_ohci.c | |
@@ -0,0 +1,212 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * EHCI/OHCI init for Ralink RT3xxx | |
+ * | |
+ * Copyright 2009 Ralink Inc. (yyhuang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * March 2009 YYHuang Initial Release | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/delay.h> | |
+#include <linux/err.h> | |
+#include <linux/dma-mapping.h> | |
+#include <linux/platform_device.h> | |
+#if IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) | |
+#include <linux/usb/ehci_pdriver.h> | |
+#endif | |
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) | |
+#include <linux/usb/ohci_pdriver.h> | |
+#endif | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#define RT3XXX_EHCI_MEM_START (RALINK_USB_HOST_BASE) | |
+#define RT3XXX_OHCI_MEM_START (RALINK_USB_HOST_BASE + 0x1000) | |
+ | |
+static struct resource rt3xxx_ehci_resources[] = { | |
+ [0] = { | |
+ .start = RT3XXX_EHCI_MEM_START, | |
+ .end = RT3XXX_EHCI_MEM_START + 0xfff, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ [1] = { | |
+ .start = SURFBOARDINT_UHST, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static struct resource rt3xxx_ohci_resources[] = { | |
+ [0] = { | |
+ .start = RT3XXX_OHCI_MEM_START, | |
+ .end = RT3XXX_OHCI_MEM_START + 0xfff, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ [1] = { | |
+ .start = SURFBOARDINT_UHST, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static u64 rt3xxx_ehci_dmamask = DMA_BIT_MASK(32); | |
+static u64 rt3xxx_ohci_dmamask = DMA_BIT_MASK(32); | |
+ | |
+#if IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) || IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) | |
+static atomic_t rt3xxx_power_instance = ATOMIC_INIT(0); | |
+ | |
+extern void uphy_init(void); | |
+ | |
+#define SYSCFG1_REG (RALINK_SYSCTL_BASE + 0x14) | |
+#define RALINK_UHST_MODE (1UL<<10) | |
+ | |
+#define CLKCFG1_REG (RALINK_SYSCTL_BASE + 0x30) | |
+#define RSTCTRL_REG (RALINK_SYSCTL_BASE + 0x34) | |
+ | |
+static void rt_usb_wake_up(void) | |
+{ | |
+ u32 val; | |
+ | |
+ /* enable PHY0/1 clock */ | |
+ val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG)); | |
+ val |= (RALINK_UPHY0_CLK_EN | RALINK_UPHY1_CLK_EN); | |
+ *(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(10); | |
+ | |
+ /* set HOST mode */ | |
+ val = le32_to_cpu(*(volatile u32 *)(SYSCFG1_REG)); | |
+ val |= (RALINK_UHST_MODE); | |
+ *(volatile u32 *)(SYSCFG1_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(1); | |
+ | |
+ /* release reset */ | |
+ val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG)); | |
+ val &= ~(RALINK_UHST_RST | RALINK_UDEV_RST); | |
+ *(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(100); | |
+ | |
+ uphy_init(); | |
+} | |
+ | |
+static void rt_usb_sleep(void) | |
+{ | |
+ u32 val; | |
+ | |
+ /* raise reset */ | |
+ val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG)); | |
+ val |= (RALINK_UHST_RST | RALINK_UDEV_RST); | |
+ *(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(10); | |
+ | |
+ /* disable PHY0/1 clock */ | |
+ val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG)); | |
+ val &= ~(RALINK_UPHY0_CLK_EN | RALINK_UPHY1_CLK_EN); | |
+ *(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val); | |
+ | |
+ udelay(10); | |
+} | |
+ | |
+static int rt3xxx_power_on(struct platform_device *pdev) | |
+{ | |
+ if (atomic_inc_return(&rt3xxx_power_instance) == 1) | |
+ rt_usb_wake_up(); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void rt3xxx_power_off(struct platform_device *pdev) | |
+{ | |
+ if (atomic_dec_return(&rt3xxx_power_instance) == 0) | |
+ rt_usb_sleep(); | |
+} | |
+ | |
+static struct usb_ehci_pdata rt3xxx_ehci_pdata = { | |
+ .caps_offset = 0, | |
+ .has_synopsys_hc_bug = 1, | |
+ .power_on = rt3xxx_power_on, | |
+ .power_off = rt3xxx_power_off, | |
+}; | |
+ | |
+static struct usb_ohci_pdata rt3xxx_ohci_pdata = { | |
+ .power_on = rt3xxx_power_on, | |
+ .power_off = rt3xxx_power_off, | |
+}; | |
+#endif | |
+ | |
+static struct platform_device rt3xxx_ehci_device = { | |
+ .name = "ehci-platform", | |
+ .id = -1, | |
+ .dev = { | |
+#if IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) | |
+ .platform_data = &rt3xxx_ehci_pdata, | |
+#endif | |
+ .dma_mask = &rt3xxx_ehci_dmamask, | |
+ .coherent_dma_mask = DMA_BIT_MASK(32), | |
+ }, | |
+ .num_resources = ARRAY_SIZE(rt3xxx_ehci_resources), | |
+ .resource = rt3xxx_ehci_resources, | |
+}; | |
+ | |
+static struct platform_device rt3xxx_ohci_device = { | |
+ .name = "ohci-platform", | |
+ .id = -1, | |
+ .dev = { | |
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) | |
+ .platform_data = &rt3xxx_ohci_pdata, | |
+#endif | |
+ .dma_mask = &rt3xxx_ohci_dmamask, | |
+ .coherent_dma_mask = DMA_BIT_MASK(32), | |
+ }, | |
+ .num_resources = ARRAY_SIZE(rt3xxx_ohci_resources), | |
+ .resource = rt3xxx_ohci_resources, | |
+}; | |
+ | |
+static struct platform_device *rt3xxx_devices[] __initdata = { | |
+ &rt3xxx_ehci_device, | |
+ &rt3xxx_ohci_device, | |
+}; | |
+ | |
+int __init init_rt3xxx_ehci_ohci(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_add_devices(rt3xxx_devices, ARRAY_SIZE(rt3xxx_devices)); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "EHCI/OHCI"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+device_initcall(init_rt3xxx_ehci_ohci); | |
diff --git a/arch/mips/rt2880/dev-mmc.c b/arch/mips/rt2880/dev-mmc.c | |
new file mode 100644 | |
index 000000000000..319ec992fd25 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/dev-mmc.c | |
@@ -0,0 +1,108 @@ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/delay.h> | |
+#include <linux/err.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#include <ralink/mtk_mmc_dev.h> | |
+ | |
+#define MTK_SDXC_MEM_START RALINK_MSDC_BASE | |
+ | |
+static struct resource mtk_mmc_resources[] = { | |
+ [0] = { | |
+ .start = MTK_SDXC_MEM_START, | |
+ .end = MTK_SDXC_MEM_START + 0x3fff, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ [1] = { | |
+ .start = SURFBOARDINT_SDXC, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+#define CLKCFG1_REG (RALINK_SYSCTL_BASE + 0x30) | |
+#define RSTCTRL_REG (RALINK_SYSCTL_BASE + 0x34) | |
+ | |
+static void mtk_mmc_power_on(void) | |
+{ | |
+ u32 val; | |
+ | |
+ /* enable SDXC clock */ | |
+ val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG)); | |
+ val |= (RALINK_SDXC_CLK_EN); | |
+ *(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(1); | |
+ | |
+ /* release SDXC reset */ | |
+ val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG)); | |
+ val &= ~(RALINK_SDXC_RST); | |
+ *(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val); | |
+ | |
+ mdelay(10); | |
+} | |
+ | |
+static void mtk_mmc_power_off(void) | |
+{ | |
+ u32 val; | |
+ | |
+ /* raise SDXC reset */ | |
+ val = le32_to_cpu(*(volatile u32 *)(RSTCTRL_REG)); | |
+ val |= (RALINK_SDXC_RST); | |
+ *(volatile u32 *)(RSTCTRL_REG) = cpu_to_le32(val); | |
+ | |
+ udelay(100); | |
+ | |
+ /* disable SDXC clock */ | |
+ val = le32_to_cpu(*(volatile u32 *)(CLKCFG1_REG)); | |
+ val &= ~(RALINK_SDXC_CLK_EN); | |
+ *(volatile u32 *)(CLKCFG1_REG) = cpu_to_le32(val); | |
+} | |
+ | |
+static struct msdc_hw mtk_mmc_hw = { | |
+ .clk_src = 0, | |
+ .cmd_edge = MSDC_SMPL_FALLING, | |
+ .data_edge = MSDC_SMPL_FALLING, | |
+ .crc_edge = MSDC_SMPL_FALLING, | |
+ .clk_drv = 4, | |
+ .cmd_drv = 4, | |
+ .dat_drv = 4, | |
+#if defined(CONFIG_MTK_MMC_EMMC_8BIT) | |
+ .data_pins = 8, | |
+#else | |
+ .data_pins = 4, | |
+#endif | |
+ .flags = MSDC_SYS_SUSPEND | MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE | MSDC_HIGHSPEED, | |
+ .ext_power_on = mtk_mmc_power_on, | |
+ .ext_power_off = mtk_mmc_power_off, | |
+}; | |
+ | |
+static struct platform_device mtk_mmc_device = { | |
+ .name = MMC_DRV_NAME, | |
+ .id = 0, | |
+ .dev = { | |
+ .platform_data = &mtk_mmc_hw, | |
+ }, | |
+ .num_resources = ARRAY_SIZE(mtk_mmc_resources), | |
+ .resource = mtk_mmc_resources, | |
+}; | |
+ | |
+int __init init_mtk_mmc(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_device_register(&mtk_mmc_device); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "MMC"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+device_initcall(init_mtk_mmc); | |
diff --git a/arch/mips/rt2880/dev-nand.c b/arch/mips/rt2880/dev-nand.c | |
new file mode 100644 | |
index 000000000000..48c9b28e1d6e | |
--- /dev/null | |
+++ b/arch/mips/rt2880/dev-nand.c | |
@@ -0,0 +1,57 @@ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/err.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#include <soc/ralink/dev_nand.h> | |
+ | |
+#define NFI_BASE RALINK_NAND_CTRL_BASE | |
+#define NFIECC_BASE RALINK_NANDECC_CTRL_BASE | |
+ | |
+static struct resource mt7621_nand_resource[] = { | |
+ { | |
+ .start = NFI_BASE, | |
+ .end = NFI_BASE + 0x1A0, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ { | |
+ .start = NFIECC_BASE, | |
+ .end = NFIECC_BASE + 0x150, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ { | |
+ .start = SURFBOARDINT_NAND, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+ { | |
+ .start = SURFBOARDINT_NAND_ECC, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static struct platform_device mt7621_nand_device = { | |
+ .name = MTK_NAND_DRV_NAME, | |
+ .id = 0, | |
+ .num_resources = ARRAY_SIZE(mt7621_nand_resource), | |
+ .resource = mt7621_nand_resource, | |
+}; | |
+ | |
+int __init mtk_nand_register(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_device_register(&mt7621_nand_device); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "NAND"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+arch_initcall(mtk_nand_register); | |
diff --git a/arch/mips/rt2880/dev-xhci.c b/arch/mips/rt2880/dev-xhci.c | |
new file mode 100644 | |
index 000000000000..87cabfe229ac | |
--- /dev/null | |
+++ b/arch/mips/rt2880/dev-xhci.c | |
@@ -0,0 +1,67 @@ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/err.h> | |
+#include <linux/dma-mapping.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#include <soc/ralink/dev_xhci.h> | |
+ | |
+static struct resource mt7621_xhci_resources[] = { | |
+ [0] = { | |
+ .start = RALINK_USB_HOST_BASE, | |
+ .end = RALINK_USB_HOST_BASE + RALINK_USB_HOST_SIZE - 1, | |
+ .flags = IORESOURCE_MEM, | |
+ .name = "mac", | |
+ }, | |
+ [1] = { | |
+ .start = RALINK_USB_IPPC_BASE, | |
+ .end = RALINK_USB_IPPC_BASE + 0xff, | |
+ .flags = IORESOURCE_MEM, | |
+ .name = "ippc", | |
+ }, | |
+ [2] = { | |
+ .start = SURFBOARDINT_USB, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static u64 mt7621_xhci_dmamask = DMA_BIT_MASK(32); | |
+ | |
+extern void uphy_init(void); | |
+ | |
+static struct xhci_mtk_pdata mt7621_xhci_pdata = { | |
+ .uphy_init = uphy_init, | |
+ .usb3_lpm_capable = true, | |
+}; | |
+ | |
+static struct platform_device mt7621_xhci_device = { | |
+ .name = XHCI_MTK_DRV_NAME, | |
+ .id = -1, | |
+ .dev = { | |
+ .platform_data = &mt7621_xhci_pdata, | |
+ .dma_mask = &mt7621_xhci_dmamask, | |
+ .coherent_dma_mask = DMA_BIT_MASK(32), | |
+ }, | |
+ .num_resources = ARRAY_SIZE(mt7621_xhci_resources), | |
+ .resource = mt7621_xhci_resources, | |
+}; | |
+ | |
+int __init init_mt7621_xhci(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_device_register(&mt7621_xhci_device); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "xHCI"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+device_initcall(init_mt7621_xhci); | |
diff --git a/arch/mips/rt2880/init.c b/arch/mips/rt2880/init.c | |
new file mode 100644 | |
index 000000000000..253f372f0e1f | |
--- /dev/null | |
+++ b/arch/mips/rt2880/init.c | |
@@ -0,0 +1,590 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * init setup for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+#include <linux/kernel.h> | |
+#include <linux/serial_8250.h> | |
+#include <linux/delay.h> | |
+#include <asm/bootinfo.h> | |
+#include <asm/io.h> | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#include <asm/smp-ops.h> | |
+#include <asm/mips-cm.h> | |
+#include <asm/mips-cpc.h> | |
+#include <asm/mips-boards/launch.h> | |
+#endif | |
+ | |
+#include <asm/rt2880/prom.h> | |
+#include <asm/rt2880/generic.h> | |
+#include <asm/rt2880/surfboard.h> | |
+#include <asm/rt2880/surfboardint.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+#include <asm/rt2880/rt_serial.h> | |
+#include <asm/rt2880/eureka_ep430.h> | |
+ | |
+#define UART_BAUDRATE CONFIG_RALINK_UART_BRATE | |
+ | |
+#define RALINK_CLKCFG1 *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x30) | |
+#define RALINK_RSTCTRL *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x34) | |
+#define RALINK_RSTSTAT *(volatile u32 *)(RALINK_SYSCTL_BASE + 0x38) | |
+ | |
+u32 mips_cpu_feq; | |
+u32 surfboard_sysclk; | |
+u32 ralink_asic_rev_id; | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+/* Environment variable */ | |
+typedef struct { | |
+ char *name; | |
+ char *val; | |
+} t_env_var; | |
+ | |
+int prom_argc; | |
+int *_prom_argv, *_prom_envp; | |
+ | |
+/* | |
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | |
+ * This macro take care of sign extension, if running in 64-bit mode. | |
+ */ | |
+#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)])) | |
+#endif | |
+ | |
+char *prom_getenv(char *envname) | |
+{ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+ /* | |
+ * Return a pointer to the given environment variable. | |
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers | |
+ * in the PROM structures are only 32-bit, so we need some | |
+ * workarounds, if we are running in 64-bit mode. | |
+ */ | |
+ int i, index=0; | |
+ char *p, *q; | |
+ | |
+ i = strlen(envname); | |
+ while (prom_envp(index)) { | |
+ p = (char*) KSEG0ADDR(prom_envp(index)); | |
+ if(!strncmp(envname, p, i)) { | |
+ q = strchr(p, '='); | |
+ if (q) | |
+ q++; | |
+ return q; | |
+ } | |
+ index++; | |
+ } | |
+#endif | |
+ return NULL; | |
+} | |
+ | |
+static inline void prom_show_pstat(void) | |
+{ | |
+ unsigned long status; | |
+ const char *const s = prom_getenv("pstat"); | |
+ | |
+ if (!s) | |
+ return; | |
+ | |
+ status = simple_strtoul(s, NULL, 0); | |
+ | |
+ switch (status) { | |
+ default: | |
+ pr_err("SoC power status: unknown (%08lx)\n", status); | |
+ break; | |
+ case 3: | |
+ pr_warn("SoC power status: hardware watchdog reset\n"); | |
+ break; | |
+ case 2: | |
+ pr_info("SoC power status: software reset\n"); | |
+ break; | |
+ case 1: | |
+ pr_info("SoC power status: power-on reset\n"); | |
+ break; | |
+ } | |
+} | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ | |
+phys_addr_t mips_cpc_default_phys_base(void) | |
+{ | |
+ return RALINK_CPC_BASE; | |
+} | |
+ | |
+static inline void prom_init_cm(void) | |
+{ | |
+ /* early detection of CMP support */ | |
+ mips_cm_probe(); | |
+ mips_cpc_probe(); | |
+ | |
+ if (mips_cm_numiocu()) { | |
+ /* Palmbus CM region */ | |
+ write_gcr_reg0_base(CM_GCR_REG0_BASE_VALUE); | |
+ write_gcr_reg0_mask((CM_GCR_REG0_MASK_VALUE << 16) | CM_GCR_REGn_MASK_CMTGT_IOCU0); | |
+#ifdef CONFIG_PCI | |
+ /* PCIe CM region */ | |
+ write_gcr_reg1_base(CM_GCR_REG1_BASE_VALUE); | |
+ write_gcr_reg1_mask((CM_GCR_REG1_MASK_VALUE << 16) | CM_GCR_REGn_MASK_CMTGT_IOCU0); | |
+#endif | |
+ __sync(); | |
+ } | |
+ | |
+ if (register_cps_smp_ops() == 0) | |
+ return; | |
+ if (register_cmp_smp_ops() == 0) | |
+ return; | |
+ if (register_vsmp_smp_ops() == 0) | |
+ return; | |
+} | |
+ | |
+bool plat_cpu_core_present(int core) | |
+{ | |
+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); | |
+ | |
+ if (!core) | |
+ return true; | |
+ | |
+ launch += core * 2; /* 2 VPEs per core */ | |
+ if (!(launch->flags & LAUNCH_FREADY)) | |
+ return false; | |
+ | |
+ if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE)) | |
+ return false; | |
+ | |
+ return true; | |
+} | |
+#endif | |
+ | |
+static inline void prom_init_pcie(void) | |
+{ | |
+#if defined(CONFIG_RALINK_MT7628) | |
+ /* assert PCIe RC RST */ | |
+ RALINK_RSTCTRL |= RALINK_PCIE0_RST; | |
+ | |
+ /* disable PCIe clock */ | |
+ RALINK_CLKCFG1 &= ~RALINK_PCIE0_CLK_EN; | |
+ | |
+#if !defined(CONFIG_PCI) | |
+ /* set PCIe PHY to 1.3mA for power saving */ | |
+ (*((volatile u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET))) = 0x10; | |
+#endif | |
+#elif defined(CONFIG_RALINK_MT7621) | |
+ u32 val = 0; | |
+#if !defined(CONFIG_PCI) || !defined(CONFIG_PCIE_PORT0) | |
+ val |= RALINK_PCIE0_RST; | |
+#endif | |
+#if !defined(CONFIG_PCI) || !defined(CONFIG_PCIE_PORT1) | |
+ val |= RALINK_PCIE1_RST; | |
+#endif | |
+#if !defined(CONFIG_PCI) || !defined(CONFIG_PCIE_PORT2) | |
+ val |= RALINK_PCIE2_RST; | |
+#endif | |
+ if (val) { | |
+ /* deassert PCIe RC RST for disabled ports */ | |
+ if ((ralink_asic_rev_id & 0xFFFF) == 0x0101) | |
+ RALINK_RSTCTRL &= ~(val); | |
+ else | |
+ RALINK_RSTCTRL |= (val); | |
+ udelay(100); | |
+ } | |
+#if !defined(CONFIG_PCI) || !(defined(CONFIG_PCIE_PORT0) || defined(CONFIG_PCIE_PORT1)) | |
+ /* set PCIe PHY P0P1 to 1.3mA for power saving */ | |
+ (*((volatile u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET))) = 0x10; | |
+#endif | |
+#if !defined(CONFIG_PCI) || !defined(CONFIG_PCIE_PORT2) | |
+ /* set PCIe PHY P2 to 1.3mA for power saving */ | |
+ (*((volatile u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET))) = 0x10; | |
+#endif | |
+#if !defined(CONFIG_PCI) | |
+ /* assert PCIe RC RST for disabled ports */ | |
+ if ((ralink_asic_rev_id & 0xFFFF) == 0x0101) | |
+ RALINK_RSTCTRL |= (val); | |
+ else | |
+ RALINK_RSTCTRL &= ~(val); | |
+ /* disable PCIe clock for disabled ports */ | |
+ RALINK_CLKCFG1 &= ~val; | |
+#endif | |
+#endif | |
+} | |
+ | |
+static inline void prom_init_usb(void) | |
+{ | |
+#if defined(CONFIG_RALINK_MT7628) | |
+ u32 reg; | |
+ | |
+ /* raise USB reset */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34)); | |
+ reg |= (RALINK_UDEV_RST | RALINK_UHST_RST); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34))= reg; | |
+ | |
+ /* disable PHY0/1 clock */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)); | |
+ reg &= ~(RALINK_UPHY0_CLK_EN | RALINK_UPHY1_CLK_EN); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)) = reg; | |
+#endif | |
+} | |
+ | |
+static inline void prom_init_sdxc(void) | |
+{ | |
+#if defined(CONFIG_RALINK_MT7621) || defined(CONFIG_RALINK_MT7628) | |
+ u32 reg; | |
+ | |
+ /* raise SDXC reset */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34)); | |
+ reg |= (RALINK_SDXC_RST); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34))= reg; | |
+ | |
+ /* disable SDXC clock */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)); | |
+ reg &= ~(RALINK_SDXC_CLK_EN); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)) = reg; | |
+#endif | |
+} | |
+ | |
+static inline void prom_init_nand(void) | |
+{ | |
+#if !defined(CONFIG_MTD_NAND_MT7621) | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ u32 reg; | |
+ | |
+ /* raise NAND reset */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34)); | |
+ reg |= (RALINK_NAND_RST); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34))= reg; | |
+ | |
+ /* disable NAND clock */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)); | |
+ reg &= ~(RALINK_NAND_CLK_EN); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)) = reg; | |
+#endif | |
+#endif | |
+} | |
+ | |
+static inline void prom_init_spdif(void) | |
+{ | |
+#if !defined(CONFIG_RALINK_SPDIF) | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ u32 reg; | |
+ | |
+ /* raise SPDIF reset */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34)); | |
+ reg |= (RALINK_SPDIF_RST); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x34))= reg; | |
+ | |
+ /* disable SPDIF clock */ | |
+ reg = *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)); | |
+ reg &= ~(RALINK_SPDIF_CLK_EN); | |
+ *(volatile u32 *)KSEG1ADDR((RALINK_SYSCTL_BASE + 0x30)) = reg; | |
+#endif | |
+#endif | |
+} | |
+ | |
+static void prom_init_sysclk(void) | |
+{ | |
+ const char *vendor_name, *ram_type = "DDR2"; | |
+ char asic_id[8]; | |
+ int xtal = 40; | |
+ u32 reg, ocp_freq; | |
+ u8 clk_sel; | |
+#if defined(CONFIG_MT7621_ASIC) || defined(CONFIG_MT7628_ASIC) | |
+ u8 clk_sel2; | |
+#endif | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ u32 cpu_fdiv = 0; | |
+ u32 cpu_ffrac = 0; | |
+ u32 fbdiv = 0; | |
+#endif | |
+ | |
+ reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x00)); | |
+ memcpy(asic_id, ®, 4); | |
+ reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x04)); | |
+ memcpy(asic_id+4, ®, 4); | |
+ asic_id[6] = '\0'; | |
+ asic_id[7] = '\0'; | |
+ | |
+ ralink_asic_rev_id = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x0c)); | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ /* CORE_NUM [17:17], 0: Single Core (S), 1: Dual Core (A) */ | |
+ if (ralink_asic_rev_id & (1UL<<17)) | |
+ asic_id[6] = 'A'; | |
+ else | |
+ asic_id[6] = 'S'; | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ /* Detect MT7688 via FUSE EE_CFG bit 20 */ | |
+ reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x08)); | |
+ if (reg & (1UL<<20)) | |
+ asic_id[4] = '8'; | |
+ | |
+ /* PKG_ID [16:16], 0: DRQFN-120 (KN), 1: DRQFN-156 (AN) */ | |
+ if (ralink_asic_rev_id & (1UL<<16)) | |
+ asic_id[6] = 'A'; | |
+ else | |
+ asic_id[6] = 'K'; | |
+#endif | |
+ | |
+ reg = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x10))); | |
+ | |
+#if defined(CONFIG_MT7621_ASIC) | |
+ clk_sel = 0; /* GPLL (500MHz) */ | |
+ clk_sel2 = (reg>>4) & 0x03; | |
+ reg = (reg >> 6) & 0x7; | |
+ if (reg >= 6) | |
+ xtal = 25; | |
+ else if (reg <= 2) | |
+ xtal = 20; | |
+ reg = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x2C))); | |
+ if (reg & (0x1UL << 30)) | |
+ clk_sel = 1; /* CPU PLL */ | |
+#elif defined(CONFIG_MT7628_ASIC) | |
+ clk_sel = 0; /* CPU PLL (580/575MHz) */ | |
+ clk_sel2 = reg & 0x01; | |
+ if (!(reg & (1UL<<6))) | |
+ xtal = 25; | |
+ reg = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x2C))); | |
+ if (reg & (0x1UL << 1)) | |
+ clk_sel = 1; /* BBP PLL (480MHz) */ | |
+#else | |
+#error Please Choice System Type | |
+#endif | |
+ | |
+ switch(clk_sel) { | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ case 0: /* GPLL (500MHz) */ | |
+ reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x44)); | |
+ cpu_fdiv = ((reg >> 8) & 0x1F); | |
+ cpu_ffrac = (reg & 0x1F); | |
+ mips_cpu_feq = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000; | |
+ break; | |
+ case 1: /* CPU PLL */ | |
+ reg = (*(volatile u32 *)(RALINK_MEMCTRL_BASE + 0x648)); | |
+ fbdiv = ((reg >> 4) & 0x7F) + 1; | |
+ if (xtal == 25) | |
+ mips_cpu_feq = 25 * fbdiv * 1000 * 1000; /* 25Mhz Xtal */ | |
+ else | |
+ mips_cpu_feq = 20 * fbdiv * 1000 * 1000; /* 20/40Mhz Xtal */ | |
+ break; | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ case 0: | |
+ if (xtal == 25) | |
+ mips_cpu_feq = 575 * 1000 * 1000; /* 25MHZ Xtal */ | |
+ else | |
+ mips_cpu_feq = 580 * 1000 * 1000; /* 40MHz Xtal */ | |
+ break; | |
+ case 1: | |
+ mips_cpu_feq = (480*1000*1000); | |
+ break; | |
+#else | |
+#error Please Choice Chip Type | |
+#endif | |
+ } | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ if (clk_sel2 & 0x01) | |
+ ram_type = "DDR2"; | |
+ else | |
+ ram_type = "DDR3"; | |
+ if (clk_sel2 & 0x02) | |
+ ocp_freq = mips_cpu_feq/4; /* OCP_RATIO 1:4 */ | |
+ else | |
+ ocp_freq = mips_cpu_feq/3; /* OCP_RATIO 1:3 */ | |
+ surfboard_sysclk = mips_cpu_feq/4; | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ surfboard_sysclk = mips_cpu_feq/3; | |
+ if (clk_sel2) | |
+ ram_type = "DDR1"; | |
+ else | |
+ ram_type = "DDR2"; | |
+ /* set CPU ratio for sleep mode (USB OCP must be >= 30MHz) */ | |
+ reg = (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x440))); | |
+ reg &= ~0x0f0f; | |
+ reg |= 0x0606; /* CPU ratio 1/6 for sleep mode (OCP: 575/6/3 = 31 MHz) */ | |
+ (*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x440))) = reg; | |
+ udelay(10); | |
+ | |
+ /* disable request preemption */ | |
+ reg = (*((volatile u32 *)(RALINK_RBUS_MATRIXCTL_BASE + 0x0))); | |
+ reg &= ~0x04000000; | |
+ (*((volatile u32 *)(RALINK_RBUS_MATRIXCTL_BASE + 0x0))) = reg; | |
+ | |
+ /* MIPS reset apply to Andes */ | |
+ RALINK_RSTSTAT |= (1U << 9); | |
+#else | |
+ surfboard_sysclk = mips_cpu_feq/3; | |
+#endif | |
+ | |
+#if !defined(CONFIG_RALINK_MT7621) | |
+ ocp_freq = surfboard_sysclk; | |
+#endif | |
+ | |
+ vendor_name = "MediaTek"; | |
+ | |
+ printk(KERN_INFO "%s SoC: %s, RevID: %04X, RAM: %s, XTAL: %dMHz\n", | |
+ vendor_name, | |
+ asic_id, | |
+ ralink_asic_rev_id & 0xffff, | |
+ ram_type, | |
+ xtal | |
+ ); | |
+ | |
+ printk(KERN_INFO "CPU/OCP/SYS frequency: %d/%d/%d MHz\n", | |
+ mips_cpu_feq / 1000 / 1000, | |
+ ocp_freq / 1000 / 1000, | |
+ surfboard_sysclk / 1000 / 1000 | |
+ ); | |
+} | |
+ | |
+/* | |
+** This function sets up the local prom_rs_table used only for the fake console | |
+** console (mainly prom_printf for debug display and no input processing) | |
+** and also sets up the global rs_table used for the actual serial console. | |
+** To get the correct baud_base value, prom_init_sysclk() must be called before | |
+** this function is called. | |
+*/ | |
+ | |
+static void __init prom_init_serial_port(void) | |
+{ | |
+ unsigned int uartclk; | |
+ unsigned int clock_divisor; | |
+ struct uart_port serial_req[2]; | |
+ | |
+ /* | |
+ * baud rate = system clock freq / (CLKDIV * 16) | |
+ * CLKDIV=system clock freq/16/baud rate | |
+ */ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ uartclk = 50000000; | |
+#else | |
+ uartclk = 40000000; | |
+#endif | |
+ clock_divisor = (uartclk / SURFBOARD_BAUD_DIV / UART_BAUDRATE); | |
+ | |
+ memset(serial_req, 0, sizeof(serial_req)); | |
+ | |
+ // fixed 8n1 | |
+ IER(RALINK_SYSCTL_BASE + 0xC00) = 0; | |
+ LCR(RALINK_SYSCTL_BASE + 0xC00) = RT2880_UART_LCR_WLEN8; | |
+ DLL(RALINK_SYSCTL_BASE + 0xC00) = (clock_divisor & 0xFF); | |
+ DLM(RALINK_SYSCTL_BASE + 0xC00) = (clock_divisor >> 8) & 0xFF; | |
+ FCR(RALINK_SYSCTL_BASE + 0xC00) = 7; /* reset TX and RX */ | |
+ | |
+ // fixed 8n1 | |
+ IER(RALINK_SYSCTL_BASE + 0xD00) = 0; | |
+ LCR(RALINK_SYSCTL_BASE + 0xD00) = RT2880_UART_LCR_WLEN8; | |
+ DLL(RALINK_SYSCTL_BASE + 0xD00) = (clock_divisor & 0xFF); | |
+ DLM(RALINK_SYSCTL_BASE + 0xD00) = (clock_divisor >> 8) & 0xFF; | |
+ FCR(RALINK_SYSCTL_BASE + 0xD00) = 7; /* reset TX and RX */ | |
+ | |
+ serial_req[0].line = 0; | |
+ serial_req[0].type = PORT_16550A; | |
+ serial_req[0].iotype = UPIO_MEM32; | |
+ serial_req[0].irq = SURFBOARDINT_UART1; | |
+ serial_req[0].flags = UPF_FIXED_TYPE | UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | |
+ serial_req[0].uartclk = uartclk; | |
+ serial_req[0].regshift = 2; | |
+ serial_req[0].mapbase = RALINK_UART_LITE_BASE; | |
+ serial_req[0].membase = ioremap_nocache(serial_req[0].mapbase, 0x0100); | |
+ serial_req[0].mapsize = 0x0100; | |
+ early_serial_setup(&serial_req[0]); | |
+ | |
+#if !defined(CONFIG_RALINK_GPIOMODE_UARTF) && (CONFIG_SERIAL_8250_NR_UARTS > 1) | |
+ serial_req[1].line = 1; | |
+ serial_req[1].type = PORT_16550A; | |
+ serial_req[1].iotype = UPIO_MEM32; | |
+ serial_req[1].irq = SURFBOARDINT_UART2; | |
+ serial_req[1].flags = UPF_FIXED_TYPE | UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | |
+ serial_req[1].uartclk = uartclk; | |
+ serial_req[1].regshift = 2; | |
+ serial_req[1].mapbase = RALINK_UART_BASE; | |
+ serial_req[1].membase = ioremap_nocache(serial_req[1].mapbase, 0x0100); | |
+ serial_req[1].mapsize = 0x0100; | |
+ early_serial_setup(&serial_req[1]); | |
+#endif | |
+} | |
+ | |
+int __init prom_get_ttysnum(void) | |
+{ | |
+ char *argptr; | |
+ int ttys_num = 0; /* default UART Lite */ | |
+ | |
+ /* get ttys_num to use with the fake console/prom_printf */ | |
+ argptr = prom_getcmdline(); | |
+ | |
+ if ((argptr = strstr(argptr, "console=ttyS")) != NULL) { | |
+ argptr += strlen("console=ttyS"); | |
+ if (argptr[0] == '0') /* ttyS0 */ | |
+ ttys_num = 0; /* happens to be rs_table[0] */ | |
+ else if (argptr[0] == '1') /* ttyS1 */ | |
+ ttys_num = 1; /* happens to be rs_table[1] */ | |
+ } | |
+ | |
+ return (ttys_num); | |
+} | |
+ | |
+void __init prom_init(void) | |
+{ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+ prom_argc = fw_arg0; | |
+ _prom_argv = (int*) fw_arg1; | |
+ _prom_envp = (int*) fw_arg2; | |
+#endif | |
+ | |
+ set_io_port_base(KSEG1); | |
+ | |
+ /* remove all wired TLB entries */ | |
+ write_c0_wired(0); | |
+ | |
+ prom_init_cmdline(); | |
+ prom_init_printf(prom_get_ttysnum()); | |
+ prom_init_sysclk(); | |
+ prom_init_serial_port(); /* Needed for Serial Console */ | |
+ prom_init_usb(); /* USB power saving */ | |
+ prom_init_pcie(); /* PCIe power saving */ | |
+ prom_init_sdxc(); /* SDXC power saving */ | |
+ prom_init_nand(); /* NAND power saving */ | |
+ prom_init_spdif(); /* SPDIF power saving */ | |
+ prom_meminit(); | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ prom_init_cm(); | |
+#endif | |
+ | |
+ prom_show_pstat(); | |
+ | |
+ prom_printf("Linux kernel started.\n"); | |
+} | |
+ | |
diff --git a/arch/mips/rt2880/irq-gic.c b/arch/mips/rt2880/irq-gic.c | |
new file mode 100644 | |
index 000000000000..44ab12669dc5 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/irq-gic.c | |
@@ -0,0 +1,217 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * Interrupt routines for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * Initial Release | |
+ * | |
+ * May 2009 Bruce Chang | |
+ * support RT3883 PCIe | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/slab.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/setup.h> | |
+#include <asm/mips-cm.h> | |
+#include <asm/irq_cpu.h> | |
+#include <asm/gic.h> | |
+ | |
+#include <asm/rt2880/rt_mmap.h> | |
+#include <asm/rt2880/surfboardint.h> | |
+ | |
+#define X GIC_UNUSED | |
+static const struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 00: CPU Coherence Manager Error | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 01: CPU CM Perf Cnt overflow | |
+ { X, X, X, X, 0 }, // 02: N/A | |
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 03: FE | |
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 04: PCIe0 | |
+ { X, X, X, X, 0 }, // 05: AUX_STCK | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 06: SYSCTL | |
+ { X, X, X, X, 0 }, // 07: N/A | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 08: I2C | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 09: DRAMC | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 10: PCM | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 11: HS GDMA | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 12: GPIO | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 13: GDMA | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 14: NFI NAND | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 15: NFI ECC | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 16: I2S | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 17: SPI | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 18: SPDIF | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 19: CryptoEngine | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 20: SDXC | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 21: Rbus to Pbus | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 22: USB XHCI | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 23: ESW MT7530 | |
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 24: PCIe1 | |
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 25: PCIe2 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 26: UART 1 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 27: UART 2 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 28: UART 3 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 29: Timer WDG | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 30: Timer0 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, // 31: Timer1 | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 32: PCIE_P0_LINT_DOWN_RST | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 33: PCIE_P1_LINT_DOWN_RST | |
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 34: PCIE_P2_LINT_DOWN_RST | |
+ { X, X, X, X, 0 }, // 35: N/A | |
+ { X, X, X, X, 0 }, // 36: N/A | |
+ { X, X, X, X, 0 }, // 37: N/A | |
+ { X, X, X, X, 0 }, // 38: N/A | |
+ { X, X, X, X, 0 }, // 39: N/A | |
+ { X, X, X, X, 0 }, // 40: N/A | |
+ { X, X, X, X, 0 }, // 41: N/A | |
+ { X, X, X, X, 0 }, // 42: N/A | |
+ { X, X, X, X, 0 }, // 43: N/A | |
+ { X, X, X, X, 0 }, // 44: N/A | |
+ { X, X, X, X, 0 }, // 45: N/A | |
+ { X, X, X, X, 0 }, // 46: N/A | |
+ { X, X, X, X, 0 }, // 47: N/A | |
+ { X, X, X, X, 0 }, // 48: N/A | |
+ { X, X, X, X, 0 }, // 49: N/A | |
+ { X, X, X, X, 0 }, // 50: N/A | |
+ { X, X, X, X, 0 }, // 51: N/A | |
+ { X, X, X, X, 0 }, // 52: N/A | |
+ { X, X, X, X, 0 }, // 53: N/A | |
+ { X, X, X, X, 0 }, // 54: N/A | |
+ { X, X, X, X, 0 }, // 55: N/A | |
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 56: IPI resched 0 | |
+ { 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 57: IPI resched 1 | |
+ { 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 58: IPI resched 2 | |
+ { 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 59: IPI resched 3 | |
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 60: IPI call 0 | |
+ { 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 61: IPI call 1 | |
+ { 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, // 62: IPI call 2 | |
+ { 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 0 } // 63: IPI call 3 | |
+}; | |
+#undef X | |
+ | |
+static int mips_cpu_timer_irq = CP0_LEGACY_COMPARE_IRQ; | |
+ | |
+static void mips_timer_dispatch(void) | |
+{ | |
+ do_IRQ(mips_cpu_timer_irq); | |
+} | |
+ | |
+unsigned int get_c0_compare_int(void) | |
+{ | |
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | |
+ | |
+ return mips_cpu_timer_irq; | |
+} | |
+ | |
+void mtk_disable_irq_all(void) | |
+{ | |
+ unsigned long flags; | |
+ | |
+ if (!gic_present) | |
+ return; | |
+ | |
+ local_irq_save(flags); | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 0x00), 0xffffffff); | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 0x04), 0xffffffff); | |
+ local_irq_restore(flags); | |
+} | |
+ | |
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | |
+{ | |
+ int i; | |
+ | |
+ for (i = 0; i < irqs; i++) | |
+ irq_set_chip(gic_irq_base + i, irq_controller); | |
+ | |
+ for (i = 0; i < (GIC_NUM_INTRS - 8); i++) { | |
+ if (gic_intr_map[i].cpunum == GIC_UNUSED) | |
+ continue; | |
+ | |
+ if (gic_intr_map[i].trigtype == GIC_TRIG_EDGE) | |
+ irq_set_handler(gic_irq_base + i, handle_edge_irq); | |
+ else | |
+ irq_set_handler(gic_irq_base + i, handle_level_irq); | |
+ } | |
+} | |
+ | |
+void __init arch_init_irq(void) | |
+{ | |
+ phys_addr_t gic_base = RALINK_GIC_BASE; | |
+ | |
+ mips_cpu_irq_init(); | |
+ | |
+ if (mips_cm_present()) { | |
+ gic_base = read_gcr_gic_base() & ~CM_GCR_GIC_BASE_GICEN_MSK; | |
+ | |
+ write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); | |
+ __sync(); | |
+ } | |
+ | |
+ gic_present = true; | |
+ | |
+ gic_init(gic_base, RALINK_GIC_ADDRSPACE_SZ, gic_intr_map, | |
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE + GIC_SHARED_HWIRQ_BASE); | |
+ | |
+ if (cpu_has_vint) { | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT0, gic_irq_dispatch); // Other | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT1, gic_irq_dispatch); // IPI resched | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT2, gic_irq_dispatch); // IPI call | |
+#endif | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT3, gic_irq_dispatch); // FE | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT4, gic_irq_dispatch); // PCIe | |
+ set_vi_handler(GIC_CPU_PIN_OFFSET + GIC_CPU_INT5, mips_timer_dispatch); | |
+ } | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ set_c0_status(STATUSF_IP7 | STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP2 | | |
+ STATUSF_IP4 | STATUSF_IP3); | |
+#else | |
+ set_c0_status(STATUSF_IP7 | STATUSF_IP6 | STATUSF_IP5 | STATUSF_IP2); | |
+#endif | |
+} | |
+ | |
+asmlinkage void plat_irq_dispatch(void) | |
+{ | |
+ unsigned int pending; | |
+ | |
+ pending = read_c0_status() & read_c0_cause() & ST0_IM; | |
+ if (unlikely(!pending)) { | |
+ spurious_interrupt(); | |
+ return; | |
+ } | |
+ | |
+ if (pending & CAUSEF_IP7) | |
+ mips_timer_dispatch(); | |
+ | |
+ if (pending & (CAUSEF_IP6 | CAUSEF_IP5 | CAUSEF_IP4 | CAUSEF_IP3 | CAUSEF_IP2)) | |
+ gic_irq_dispatch(); | |
+} | |
diff --git a/arch/mips/rt2880/irq.c b/arch/mips/rt2880/irq.c | |
new file mode 100644 | |
index 000000000000..9f563c48d7f3 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/irq.c | |
@@ -0,0 +1,236 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * Interrupt routines for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * Initial Release | |
+ * | |
+ * May 2009 Bruce Chang | |
+ * support RT3883 PCIe | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/slab.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/setup.h> | |
+#include <asm/irq_cpu.h> | |
+ | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+static unsigned int fiq_mask; | |
+ | |
+unsigned int get_c0_compare_int(void) | |
+{ | |
+ return SURFBOARDINT_MIPS_TIMER; | |
+} | |
+ | |
+#if IS_ENABLED(CONFIG_HW_PERF_EVENTS) || IS_ENABLED(CONFIG_OPROFILE) | |
+int get_c0_perfcount_int(void) | |
+{ | |
+ return SURFBOARDINT_PCTRL; | |
+} | |
+EXPORT_SYMBOL_GPL(get_c0_perfcount_int); | |
+#endif | |
+ | |
+static void mask_ralink_irq(struct irq_data *id) | |
+{ | |
+ unsigned int irq_mask = BIT(id->hwirq); | |
+ | |
+ if (irq_mask & fiq_mask) | |
+ *(volatile u32 *)(RALINK_FIQDIS) = irq_mask; | |
+ else | |
+ *(volatile u32 *)(RALINK_INTDIS) = irq_mask; | |
+} | |
+ | |
+static void unmask_ralink_irq(struct irq_data *id) | |
+{ | |
+ unsigned int irq_mask = BIT(id->hwirq); | |
+ | |
+ if (irq_mask & fiq_mask) | |
+ *(volatile u32 *)(RALINK_FIQENA) = irq_mask; | |
+ else | |
+ *(volatile u32 *)(RALINK_INTENA) = irq_mask; | |
+} | |
+ | |
+static struct irq_chip ralink_irq_chip = { | |
+ .name = "INTC", | |
+ .irq_mask = mask_ralink_irq, | |
+ .irq_mask_ack = mask_ralink_irq, | |
+ .irq_unmask = unmask_ralink_irq, | |
+ .irq_disable = mask_ralink_irq, | |
+ .irq_enable = unmask_ralink_irq, | |
+}; | |
+ | |
+static int ralink_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | |
+{ | |
+ irq_set_chip_and_handler(irq, &ralink_irq_chip, handle_level_irq); | |
+ return 0; | |
+} | |
+ | |
+static const struct irq_domain_ops ralink_intc_domain_ops = { | |
+ .xlate = irq_domain_xlate_onecell, | |
+ .map = ralink_intc_map, | |
+}; | |
+ | |
+static void ralink_intc_irq_handler(struct irq_desc *desc) | |
+{ | |
+ struct irq_domain *domain = irq_desc_get_handler_data(desc); | |
+ u32 pending; | |
+ | |
+ if (irq_desc_get_irq(desc) == MIPS_INTC_CHAIN_HW1) | |
+ pending = *(volatile u32 *)(RALINK_IRQ1STAT); | |
+ else | |
+ pending = *(volatile u32 *)(RALINK_IRQ0STAT); | |
+ | |
+ if (unlikely(!pending)) { | |
+ spurious_interrupt(); | |
+ return; | |
+ } | |
+ | |
+ generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); | |
+} | |
+ | |
+static void dispatch_mips_line_timer(void) | |
+{ | |
+ do_IRQ(SURFBOARDINT_MIPS_TIMER); | |
+} | |
+ | |
+static void dispatch_mips_line_wlan(void) | |
+{ | |
+ do_IRQ(SURFBOARDINT_WLAN); | |
+} | |
+ | |
+static void dispatch_mips_line_fe(void) | |
+{ | |
+ do_IRQ(SURFBOARDINT_FE); | |
+} | |
+ | |
+static void dispatch_mips_line_pci(void) | |
+{ | |
+ do_IRQ(SURFBOARDINT_PCIE0); | |
+} | |
+ | |
+static void dispatch_mips_chain_hw1(void) | |
+{ | |
+ do_IRQ(MIPS_INTC_CHAIN_HW1); | |
+} | |
+ | |
+static void dispatch_mips_chain_hw0(void) | |
+{ | |
+ do_IRQ(MIPS_INTC_CHAIN_HW0); | |
+} | |
+ | |
+void mtk_disable_irq_all(void) | |
+{ | |
+ unsigned long flags; | |
+ | |
+ local_irq_save(flags); | |
+ *(volatile u32 *)(RALINK_FIQDIS) = ~0u; | |
+ *(volatile u32 *)(RALINK_INTDIS) = ~0u; | |
+ local_irq_restore(flags); | |
+} | |
+ | |
+void __init arch_init_irq(void) | |
+{ | |
+ struct irq_domain *domain; | |
+ unsigned int int_type = 0; | |
+ | |
+ mips_cpu_irq_init(); | |
+ | |
+ /* disable all interrupts */ | |
+ *(volatile u32 *)(RALINK_FIQDIS) = ~0u; | |
+ *(volatile u32 *)(RALINK_INTDIS) = ~0u; | |
+ | |
+ /* route some INTC interrupts to MIPS HW1 interrupt (high priority) */ | |
+#ifdef RALINK_INTCTL_UHST | |
+ int_type |= RALINK_INTCTL_UHST; | |
+#endif | |
+#ifdef RALINK_INTCTL_SDXC | |
+ int_type |= RALINK_INTCTL_SDXC; | |
+#endif | |
+#ifdef RALINK_INTCTL_CRYPTO | |
+ int_type |= RALINK_INTCTL_CRYPTO; | |
+#endif | |
+ int_type |= RALINK_INTCTL_DMA; | |
+ *(volatile u32 *)(RALINK_INTTYPE) = int_type; | |
+ | |
+ if (cpu_has_vint) { | |
+ pr_info("Setting up vectored interrupts\n"); | |
+ set_vi_handler(SURFBOARDINT_MIPS_TIMER, dispatch_mips_line_timer); | |
+ set_vi_handler(SURFBOARDINT_WLAN, dispatch_mips_line_wlan); | |
+ set_vi_handler(SURFBOARDINT_FE, dispatch_mips_line_fe); | |
+ set_vi_handler(SURFBOARDINT_PCIE0, dispatch_mips_line_pci); | |
+ set_vi_handler(MIPS_INTC_CHAIN_HW1, dispatch_mips_chain_hw1); | |
+ set_vi_handler(MIPS_INTC_CHAIN_HW0, dispatch_mips_chain_hw0); | |
+ } | |
+ | |
+ domain = irq_domain_add_legacy(NULL, INTC_NUM_INTRS, MIPS_INTC_IRQ_BASE, 0, &ralink_intc_domain_ops, NULL); | |
+ if (!domain) | |
+ panic("Failed to add irqdomain"); | |
+ | |
+ irq_set_chained_handler_and_data(MIPS_INTC_CHAIN_HW0, ralink_intc_irq_handler, domain); | |
+ irq_set_chained_handler_and_data(MIPS_INTC_CHAIN_HW1, ralink_intc_irq_handler, domain); | |
+ | |
+ /* enable global interrupt bit */ | |
+ fiq_mask = int_type; | |
+ *(volatile u32 *)(RALINK_FIQENA) = BIT(31); | |
+ *(volatile u32 *)(RALINK_INTENA) = BIT(31); | |
+} | |
+ | |
+asmlinkage void plat_irq_dispatch(void) | |
+{ | |
+ unsigned int pending; | |
+ | |
+ pending = read_c0_status() & read_c0_cause() & ST0_IM; | |
+ if (unlikely(!pending)) { | |
+ spurious_interrupt(); | |
+ return; | |
+ } | |
+ | |
+ if (pending & CAUSEF_IP7) | |
+ do_IRQ(SURFBOARDINT_MIPS_TIMER); | |
+ | |
+ if (pending & CAUSEF_IP5) | |
+ do_IRQ(SURFBOARDINT_FE); | |
+ | |
+ if (pending & CAUSEF_IP6) | |
+ do_IRQ(SURFBOARDINT_WLAN); | |
+ | |
+ if (pending & CAUSEF_IP4) | |
+ do_IRQ(SURFBOARDINT_PCIE0); | |
+ | |
+ if (pending & CAUSEF_IP3) | |
+ do_IRQ(MIPS_INTC_CHAIN_HW1); | |
+ | |
+ if (pending & CAUSEF_IP2) | |
+ do_IRQ(MIPS_INTC_CHAIN_HW0); | |
+} | |
+ | |
diff --git a/arch/mips/rt2880/irqchip-gic.c b/arch/mips/rt2880/irqchip-gic.c | |
new file mode 100644 | |
index 000000000000..62961cbcdc90 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/irqchip-gic.c | |
@@ -0,0 +1,63 @@ | |
+#include <linux/init.h> | |
+#include <linux/slab.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/setup.h> | |
+#include <asm/irq_cpu.h> | |
+ | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#ifndef CONFIG_CLKSRC_MIPS_GIC | |
+unsigned int get_c0_compare_int(void) | |
+{ | |
+ return gic_get_c0_compare_int(); | |
+} | |
+#endif | |
+ | |
+#if IS_ENABLED(CONFIG_HW_PERF_EVENTS) || IS_ENABLED(CONFIG_OPROFILE) | |
+int get_c0_perfcount_int(void) | |
+{ | |
+ /* | |
+ * Performance counter events are routed through GIC. | |
+ * Prevent them from firing on CPU IRQ7 as well | |
+ */ | |
+ clear_c0_status(IE_SW0 << 7); | |
+ | |
+ return gic_get_c0_perfcount_int(); | |
+} | |
+EXPORT_SYMBOL_GPL(get_c0_perfcount_int); | |
+#endif | |
+ | |
+#ifdef CONFIG_MIPS_EJTAG_FDC_TTY | |
+int get_c0_fdc_int(void) | |
+{ | |
+ return gic_get_c0_fdc_int(); | |
+} | |
+#endif | |
+ | |
+void mtk_disable_irq_all(void) | |
+{ | |
+} | |
+ | |
+void __init arch_init_irq(void) | |
+{ | |
+ phys_addr_t gic_base = RALINK_GIC_BASE; | |
+ size_t gic_len = RALINK_GIC_ADDRSPACE_SZ; | |
+ | |
+ mips_cpu_irq_init(); | |
+ | |
+ if (mips_cm_present()) { | |
+ gic_base = read_gcr_gic_base() & ~CM_GCR_GIC_BASE_GICEN_MSK; | |
+ | |
+ write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); | |
+ __sync(); | |
+ } | |
+ | |
+ gic_present = true; | |
+ | |
+ gic_init(gic_base, gic_len, GIC_CPU_PIN_OFFSET, 0); | |
+ | |
+ /* set EDGE type int for MT7530 MCM (prevent race) */ | |
+ irq_set_irq_type(SURFBOARDINT_ESW, IRQ_TYPE_EDGE_RISING); | |
+} | |
+ | |
diff --git a/arch/mips/rt2880/malta-amon.c b/arch/mips/rt2880/malta-amon.c | |
new file mode 100644 | |
index 000000000000..84ac523b0ce0 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/malta-amon.c | |
@@ -0,0 +1,88 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2007 MIPS Technologies, Inc. All rights reserved. | |
+ * Copyright (C) 2013 Imagination Technologies Ltd. | |
+ * | |
+ * Arbitrary Monitor Interface | |
+ */ | |
+#include <linux/kernel.h> | |
+#include <linux/smp.h> | |
+ | |
+#include <asm/addrspace.h> | |
+#include <asm/mipsmtregs.h> | |
+#include <asm/mips-boards/launch.h> | |
+#include <asm/vpe.h> | |
+ | |
+int amon_cpu_avail(int cpu) | |
+{ | |
+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); | |
+ | |
+ if (cpu < 0 || cpu >= NCPULAUNCH) { | |
+ pr_debug("avail: cpu%d is out of range\n", cpu); | |
+ return 0; | |
+ } | |
+ | |
+ launch += cpu; | |
+ if (!(launch->flags & LAUNCH_FREADY)) { | |
+ pr_debug("avail: cpu%d is not ready\n", cpu); | |
+ return 0; | |
+ } | |
+ if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) { | |
+ pr_debug("avail: too late.. cpu%d is already gone\n", cpu); | |
+ return 0; | |
+ } | |
+ | |
+ return 1; | |
+} | |
+ | |
+int amon_cpu_start(int cpu, | |
+ unsigned long pc, unsigned long sp, | |
+ unsigned long gp, unsigned long a0) | |
+{ | |
+ volatile struct cpulaunch *launch = | |
+ (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); | |
+ | |
+ if (!amon_cpu_avail(cpu)) | |
+ return -1; | |
+ if (cpu == smp_processor_id()) { | |
+ pr_debug("launch: I am cpu%d!\n", cpu); | |
+ return -1; | |
+ } | |
+ launch += cpu; | |
+ | |
+ pr_debug("launch: starting cpu%d\n", cpu); | |
+ | |
+ launch->pc = pc; | |
+ launch->gp = gp; | |
+ launch->sp = sp; | |
+ launch->a0 = a0; | |
+ | |
+ smp_wmb(); /* Target must see parameters before go */ | |
+ launch->flags |= LAUNCH_FGO; | |
+ smp_wmb(); /* Target must see go before we poll */ | |
+ | |
+ while ((launch->flags & LAUNCH_FGONE) == 0) | |
+ ; | |
+ smp_rmb(); /* Target will be updating flags soon */ | |
+ pr_debug("launch: cpu%d gone!\n", cpu); | |
+ | |
+ return 0; | |
+} | |
+ | |
+#ifdef CONFIG_MIPS_VPE_LOADER_CMP | |
+int vpe_run(struct vpe *v) | |
+{ | |
+ struct vpe_notifications *n; | |
+ | |
+ if (amon_cpu_start(aprp_cpu_index(), v->__start, 0, 0, 0) < 0) | |
+ return -1; | |
+ | |
+ list_for_each_entry(n, &v->notify, list) | |
+ n->start(VPE_MODULE_MINOR); | |
+ | |
+ return 0; | |
+} | |
+#endif | |
diff --git a/arch/mips/rt2880/memory.c b/arch/mips/rt2880/memory.c | |
new file mode 100644 | |
index 000000000000..3f1c92bb8bc4 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/memory.c | |
@@ -0,0 +1,122 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * memory setup for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/mm.h> | |
+#include <linux/bootmem.h> | |
+#include <linux/ioport.h> | |
+#include <asm/bootinfo.h> | |
+#include <asm/page.h> | |
+ | |
+#include <asm/rt2880/prom.h> | |
+ | |
+//#define DEBUG | |
+ | |
+#define RAM_BASE 0x00000000 | |
+#define RAM_SIZE (CONFIG_RALINK_RAM_SIZE*1024*1024) | |
+#define RAM_SIZE_MIN (8*1024*1024) | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#define RAM_SIZE_MAX (512*1024*1024) | |
+#else | |
+#define RAM_SIZE_MAX (256*1024*1024) | |
+#endif | |
+ | |
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+static unsigned int __init prom_get_ramsize(void) | |
+{ | |
+ char *argptr; | |
+ unsigned int ramsize = 0; | |
+ | |
+ argptr = prom_getcmdline(); | |
+ | |
+ if ((argptr = strstr(argptr, "ramsize=")) != NULL) { | |
+ argptr += strlen("ramsize="); | |
+ ramsize = simple_strtoul(&argptr[0], NULL, 0); | |
+ } | |
+ | |
+ return ramsize; | |
+} | |
+#endif | |
+ | |
+void __init prom_meminit(void) | |
+{ | |
+ phys_addr_t ramsize = 0; | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+ ramsize = (phys_addr_t)prom_get_ramsize(); | |
+#endif | |
+ if (ramsize < RAM_SIZE_MIN || ramsize > RAM_SIZE_MAX) | |
+ ramsize = RAM_SIZE; | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ if (ramsize > 0x1c000000) { | |
+ /* 1. Normal region 0..448MB */ | |
+ add_memory_region(RAM_BASE, 0x1c000000, BOOT_MEM_RAM); | |
+ | |
+#ifdef CONFIG_HIGHMEM | |
+ /* 2. Highmem region */ | |
+ add_memory_region(0x20000000, (ramsize - 0x1c000000), BOOT_MEM_RAM); | |
+#endif | |
+ } else | |
+#endif | |
+ add_memory_region(RAM_BASE, ramsize, BOOT_MEM_RAM); | |
+} | |
+ | |
+void __init prom_free_prom_memory(void) | |
+{ | |
+#ifdef DEBUG | |
+ /* Nothing to do! Need only for DEBUG. */ | |
+ /* This is may be corrupt working memory. */ | |
+ | |
+ unsigned long addr; | |
+ int i; | |
+ | |
+ for (i = 0; i < boot_mem_map.nr_map; i++) { | |
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | |
+ continue; | |
+ | |
+ addr = boot_mem_map.map[i].addr; | |
+ free_init_pages("prom memory", addr, addr + boot_mem_map.map[i].size); | |
+ } | |
+#endif | |
+} | |
+ | |
diff --git a/arch/mips/rt2880/pci.c b/arch/mips/rt2880/pci.c | |
new file mode 100644 | |
index 000000000000..bc4b8cf54736 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/pci.c | |
@@ -0,0 +1,808 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * PCI init for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * Initial Release | |
+ * | |
+ * May 2009 Bruce Chang | |
+ * support RT2880/RT3883 PCIe | |
+ * | |
+ * May 2011 Bruce Chang | |
+ * support RT6855/MT7620 PCIe | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/types.h> | |
+#include <linux/pci.h> | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/mod_devicetable.h> | |
+#include <linux/slab.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/pci.h> | |
+#include <asm/io.h> | |
+#include <asm/irq.h> | |
+ | |
+#include <asm/rt2880/eureka_ep430.h> | |
+ | |
+#ifdef CONFIG_PCI | |
+ | |
+//#define RAPCI_DEBUG | |
+ | |
+#if defined(CONFIG_RT2880_DRAM_512M) | |
+#define BAR0_MASK 0x1FFF0000 | |
+#elif defined(CONFIG_RT2880_DRAM_256M) | |
+#define BAR0_MASK 0x0FFF0000 | |
+#elif defined(CONFIG_RT2880_DRAM_128M) | |
+#define BAR0_MASK 0x07FF0000 | |
+#elif defined(CONFIG_RT2880_DRAM_64M) | |
+#define BAR0_MASK 0x03FF0000 | |
+#elif defined(CONFIG_RT2880_DRAM_32M) | |
+#define BAR0_MASK 0x01FF0000 | |
+#else | |
+#define BAR0_MASK 0x7FFF0000 /* 2G */ | |
+#endif | |
+ | |
+/* | |
+ * These functions and structures provide the BIOS scan and mapping of the PCI | |
+ * devices. | |
+ */ | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#define RALINK_SYSTEM_CONTROL_BASE 0xbe000000 | |
+#define RALINK_PCI_MM_MAP_BASE 0x60000000 | |
+#define RALINK_PCI_IO_MAP_BASE 0x1e160000 | |
+#else | |
+#define RALINK_SYSTEM_CONTROL_BASE 0xb0000000 | |
+#define RALINK_PCI_MM_MAP_BASE 0x20000000 | |
+#define RALINK_PCI_IO_MAP_BASE 0x10160000 | |
+#endif | |
+ | |
+#define BAR0_MEMORY_BASE 0x0 | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+extern u32 ralink_asic_rev_id; | |
+static int pcie_link_status = 0; | |
+ | |
+/* use GPIO control instead of PERST_N (pulse from driver) */ | |
+#define GPIO_PERST | |
+ | |
+/* uncomment this to enable PCIe ports Spread Spectrum (MT7603E Ch14 Rx De-sense issue) */ | |
+//#define PCIE_PHY_SSC | |
+ | |
+#define PCIE_SHARE_PIN_SW 10 // PERST_N GPIO Mode | |
+#if defined(GPIO_PERST) | |
+#define GPIO_PCIE_PORT0 19 // PERST_N | |
+#if defined(CONFIG_RALINK_I2S) || defined(CONFIG_RALINK_I2S_MODULE) || defined(CONFIG_PCIE_PERST_ONLY) | |
+#define UARTL3_SHARE_PIN_SW PCIE_SHARE_PIN_SW | |
+#define GPIO_PCIE_PORT1 GPIO_PCIE_PORT0 | |
+#define GPIO_PCIE_PORT2 GPIO_PCIE_PORT0 | |
+#else | |
+#define UARTL3_SHARE_PIN_SW 3 // UART3 GPIO Mode | |
+#define GPIO_PCIE_PORT1 8 // RXD3 (I2S_SDI) | |
+#define GPIO_PCIE_PORT2 7 // TXD3 (I2S_WS) | |
+#endif | |
+#define RALINK_GPIO_CTRL0 *(volatile u32 *)(RALINK_PIO_BASE + 0x00) | |
+#define RALINK_GPIO_DATA0 *(volatile u32 *)(RALINK_PIO_BASE + 0x20) | |
+#endif | |
+ | |
+#define ASSERT_SYSRST_PCIE(val) do { \ | |
+ if ((ralink_asic_rev_id & 0xFFFF) == 0x0101) \ | |
+ RALINK_RSTCTRL |= val; \ | |
+ else \ | |
+ RALINK_RSTCTRL &= ~val; \ | |
+ } while(0) | |
+#define DEASSERT_SYSRST_PCIE(val) do { \ | |
+ if ((ralink_asic_rev_id & 0xFFFF) == 0x0101) \ | |
+ RALINK_RSTCTRL &= ~val; \ | |
+ else \ | |
+ RALINK_RSTCTRL |= val; \ | |
+ } while(0) | |
+#endif | |
+ | |
+#define RALINK_SYSCFG1 *(volatile u32 *)(RALINK_SYSTEM_CONTROL_BASE + 0x14) | |
+#define RALINK_CLKCFG1 *(volatile u32 *)(RALINK_SYSTEM_CONTROL_BASE + 0x30) | |
+#define RALINK_RSTCTRL *(volatile u32 *)(RALINK_SYSTEM_CONTROL_BASE + 0x34) | |
+#define RALINK_GPIOMODE *(volatile u32 *)(RALINK_SYSTEM_CONTROL_BASE + 0x60) | |
+ | |
+#define PCI_ACCESS_READ_1 0 | |
+#define PCI_ACCESS_READ_2 1 | |
+#define PCI_ACCESS_READ_4 2 | |
+#define PCI_ACCESS_WRITE_1 3 | |
+#define PCI_ACCESS_WRITE_2 4 | |
+#define PCI_ACCESS_WRITE_4 5 | |
+ | |
+static DEFINE_SPINLOCK(asic_pcr_lock); | |
+ | |
+static int config_access(int access_type, u32 busn, u32 slot, u32 func, u32 where, u32 *data) | |
+{ | |
+ unsigned int address, shift, tmp; | |
+ unsigned long flags; | |
+ | |
+ /* setup PCR address */ | |
+ address = (1u << 31) | (((where & 0xf00) >> 8) << 24) | (busn << 16) | (slot << 11) | (func << 8) | (where & 0xfc); | |
+ | |
+ shift = (where & 0x3) << 3; | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ | |
+ /* start the configuration cycle */ | |
+ RALINK_PCI_PCR_ADDR = address; | |
+ | |
+ switch (access_type) { | |
+ case PCI_ACCESS_WRITE_1: | |
+ tmp = RALINK_PCI_PCR_DATA; | |
+ tmp &= ~(0xff << shift); | |
+ tmp |= ((*data & 0xff) << shift); | |
+ RALINK_PCI_PCR_DATA = tmp; | |
+ break; | |
+ case PCI_ACCESS_WRITE_2: | |
+ tmp = RALINK_PCI_PCR_DATA; | |
+ if (shift > 16) | |
+ shift = 16; | |
+ tmp &= ~(0xffff << shift); | |
+ tmp |= ((*data & 0xffff) << shift); | |
+ RALINK_PCI_PCR_DATA = tmp; | |
+ break; | |
+ case PCI_ACCESS_WRITE_4: | |
+ RALINK_PCI_PCR_DATA = *data; | |
+ break; | |
+ case PCI_ACCESS_READ_1: | |
+ tmp = RALINK_PCI_PCR_DATA; | |
+ *data = (tmp >> shift) & 0xff; | |
+ break; | |
+ case PCI_ACCESS_READ_2: | |
+ tmp = RALINK_PCI_PCR_DATA; | |
+ if (shift > 16) | |
+ shift = 16; | |
+ *data = (tmp >> shift) & 0xffff; | |
+ break; | |
+ case PCI_ACCESS_READ_4: | |
+ *data = RALINK_PCI_PCR_DATA; | |
+ break; | |
+ } | |
+ | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+ | |
+ return PCIBIOS_SUCCESSFUL; | |
+} | |
+ | |
+static int ralink_pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) | |
+{ | |
+ u32 busn = bus->number; | |
+ u32 slot = PCI_SLOT(devfn); | |
+ u32 func = PCI_FUNC(devfn); | |
+ int access_type = PCI_ACCESS_READ_4; | |
+ | |
+ switch (size) { | |
+ case 1: | |
+ access_type = PCI_ACCESS_READ_1; | |
+ break; | |
+ case 2: | |
+ access_type = PCI_ACCESS_READ_2; | |
+ break; | |
+ } | |
+ | |
+ return config_access(access_type, busn, slot, func, (u32)where, val); | |
+} | |
+ | |
+static int ralink_pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) | |
+{ | |
+ u32 busn = bus->number; | |
+ u32 slot = PCI_SLOT(devfn); | |
+ u32 func = PCI_FUNC(devfn); | |
+ int access_type = PCI_ACCESS_WRITE_4; | |
+ | |
+ switch (size) { | |
+ case 1: | |
+ access_type = PCI_ACCESS_WRITE_1; | |
+ break; | |
+ case 2: | |
+ access_type = PCI_ACCESS_WRITE_2; | |
+ break; | |
+ } | |
+ | |
+ return config_access(access_type, busn, slot, func, (u32)where, &val); | |
+} | |
+ | |
+/* | |
+ * General-purpose PCI functions. | |
+ */ | |
+ | |
+struct pci_ops ralink_pci_ops = { | |
+ .read = ralink_pci_config_read, | |
+ .write = ralink_pci_config_write, | |
+}; | |
+ | |
+static struct resource ralink_res_pci_mem1 = { | |
+ .name = "PCI MEM1", | |
+ .start = RALINK_PCI_MM_MAP_BASE, | |
+ .end = (RALINK_PCI_MM_MAP_BASE + 0x0fffffff), | |
+ .flags = IORESOURCE_MEM, | |
+}; | |
+ | |
+static struct resource ralink_res_pci_io1 = { | |
+ .name = "PCI I/O1", | |
+ .start = RALINK_PCI_IO_MAP_BASE, | |
+ .end = (RALINK_PCI_IO_MAP_BASE + 0x0ffff), | |
+ .flags = IORESOURCE_IO, | |
+}; | |
+ | |
+struct pci_controller ralink_pci_controller = { | |
+ .pci_ops = &ralink_pci_ops, | |
+ .mem_resource = &ralink_res_pci_mem1, | |
+ .io_resource = &ralink_res_pci_io1, | |
+ .mem_offset = 0x00000000UL, | |
+ .io_offset = 0x00000000UL, | |
+}; | |
+ | |
+int pcibios_plat_dev_init(struct pci_dev *dev) | |
+{ | |
+ u32 __maybe_unused val; | |
+#ifdef RAPCI_DEBUG | |
+ int i; | |
+ struct resource *res; | |
+ | |
+ printk("%s: ** bus: %d, slot: 0x%x\n", __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn)); | |
+ | |
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &val); | |
+ printk(" PCI_BASE_ADDRESS_0: 0x%08X\n", val); | |
+ | |
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &val); | |
+ printk(" PCI_BASE_ADDRESS_1: 0x%08X\n", val); | |
+ | |
+ pci_read_config_dword(dev, PCI_IO_BASE, &val); | |
+ printk(" PCI_IO_BASE: 0x%08X\n", val); | |
+ | |
+ for (i = 0; i < 2; i++) { | |
+ res = (struct resource*)&dev->resource[i]; | |
+ printk(" res[%d]->start = %x\n", i, res->start); | |
+ printk(" res[%d]->end = %x\n", i, res->end); | |
+ } | |
+#endif | |
+ | |
+ /* P2P bridge */ | |
+ if (dev->bus->number == 0) { | |
+ /* set N_FTS 0x28 -> 0x50 */ | |
+ val = 0; | |
+ pci_read_config_dword(dev, 0x70c, &val); | |
+ val &= ~(0xff<<8); | |
+ val |= (0x50<<8); | |
+ pci_write_config_dword(dev, 0x70c, val); | |
+ | |
+ /* set CLS */ | |
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES >> 2)); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+{ | |
+ int pci_irq = 0; | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ if ((dev->bus->number == 1) && (slot == 0x0)) { | |
+ switch (pcie_link_status) { | |
+ case 0x2: | |
+ case 0x6: | |
+ pci_irq = SURFBOARDINT_PCIE1; | |
+ break; | |
+ case 0x4: | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ break; | |
+ default: | |
+ pci_irq = SURFBOARDINT_PCIE0; | |
+ } | |
+ } else if ((dev->bus->number == 2) && (slot == 0x0)) { | |
+ switch (pcie_link_status) { | |
+ case 0x5: | |
+ case 0x6: | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ break; | |
+ default: | |
+ pci_irq = SURFBOARDINT_PCIE1; | |
+ } | |
+ } else if ((dev->bus->number == 2) && (slot == 0x1)) { | |
+ switch (pcie_link_status) { | |
+ case 0x5: | |
+ case 0x6: | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ break; | |
+ default: | |
+ pci_irq = SURFBOARDINT_PCIE1; | |
+ } | |
+ } else if ((dev->bus->number == 3) && (slot == 0x0)) { | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ } else if ((dev->bus->number == 3) && (slot == 0x1)) { | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ } else if ((dev->bus->number == 3) && (slot == 0x2)) { | |
+ pci_irq = SURFBOARDINT_PCIE2; | |
+ } | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ if ((dev->bus->number == 1) && (slot == 0x0)) { | |
+ pci_irq = SURFBOARDINT_PCIE0; | |
+ } | |
+#endif | |
+ | |
+#ifdef RAPCI_DEBUG | |
+ printk("%s: ** bus: %d, slot: 0x%x -> irq: %d\n", __FUNCTION__, dev->bus->number, slot, pci_irq); | |
+#endif | |
+ | |
+ return pci_irq; | |
+} | |
+ | |
+static void set_pcie_phy(u32 *addr, int start_b, int bits, int val) | |
+{ | |
+ *(volatile u32 *)(addr) &= ~(((1<<bits) - 1)<<start_b); | |
+ *(volatile u32 *)(addr) |= val << start_b; | |
+} | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+static void bypass_pipe_rst(void) | |
+{ | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ /* PCIe Port 0 */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ /* PCIe Port 1 */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ /* PCIe Port 2 */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4] | |
+#endif | |
+} | |
+ | |
+static void set_phy_for_ssc(void) | |
+{ | |
+ u32 reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)); | |
+ | |
+ reg = (reg >> 6) & 0x7; | |
+#if defined(CONFIG_PCIE_PORT0) || defined(CONFIG_PCIE_PORT1) | |
+ /* Set PCIe Port0 & Port1 PHY to disable SSC */ | |
+ /* Debug Xtal Type */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 1 enable control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x00); // rg_pe1_phy_en //Port 1 disable | |
+ if (reg <= 5 && reg >= 3) { | |
+ /* 40MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x1a); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x1a); // RG_LC_DDS_SSC_DELTA1 | |
+ } else { | |
+ /* 25MHz or 20MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) | |
+ if (reg >= 6) { | |
+ /* 25MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x11); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x11); // RG_LC_DDS_SSC_DELTA1 | |
+ } else { | |
+ /* 20MHz Xtal */ | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x1a); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x1a); // RG_LC_DDS_SSC_DELTA1 | |
+ } | |
+ } | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN | |
+ if (reg <= 5 && reg >= 3) { | |
+ /* 40MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv | |
+ } | |
+#ifdef PCIE_PHY_SSC | |
+ /* Enable Port0&Port1 SSC */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 28, 2, 0x1); // rg_pe1_frc_lcdds_ssc_en //value of da_pe1_mstckdiv when force mode enable | |
+#else | |
+ /* Disable Port0&Port1 SSC */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 28, 2, 0x0); // rg_pe1_frc_lcdds_ssc_en //value of da_pe1_mstckdiv when force mode enable | |
+#endif | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x040), 17, 4, 0x07); // rg_pe1_crtmsel //value of da[x]_pe1_crtmsel when force mode enable for Port 0 | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x040), 16, 1, 0x01); // rg_pe1_frc_crtmsel //force mode enable of da[x]_pe1_crtmsel for Port 0 | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x140), 17, 4, 0x07); // rg_pe1_crtmsel //value of da[x]_pe1_crtmsel when force mode enable for Port 1 | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x140), 16, 1, 0x01); // rg_pe1_frc_crtmsel //force mode enable of da[x]_pe1_crtmsel for Port 1 | |
+ /* Enable PHY and disable force mode */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en //Port 1 enable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 1 disable control | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ /* Set PCIe Port2 PHY to disable SSC */ | |
+ /* Debug Xtal Type */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable | |
+ if (reg <= 5 && reg >= 3) { | |
+ /* 40MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x1a); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x1a); // RG_LC_DDS_SSC_DELTA1 | |
+ } else { | |
+ /* 25MHz or 20MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode) | |
+ if (reg >= 6) { | |
+ /* 25MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode) | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x11); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x11); // RG_LC_DDS_SSC_DELTA1 | |
+ } else { | |
+ /* 20MHz Xtal */ | |
+ | |
+ /* SSC option tune from -5000ppm to -1000ppm */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x1a); // RG_LC_DDS_SSC_DELTA | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x1a); // RG_LC_DDS_SSC_DELTA1 | |
+ } | |
+ } | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN | |
+ if (reg <= 5 && reg >= 3) { | |
+ /* 40MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv | |
+ } | |
+#ifdef PCIE_PHY_SSC | |
+ /* Enable Port2 SSC */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 28, 2, 0x1); // rg_pe1_frc_lcdds_ssc_en //value of da_pe1_mstckdiv when force mode enable | |
+#else | |
+ /* Disable Port2 SSC */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 28, 2, 0x0); // rg_pe1_frc_lcdds_ssc_en //value of da_pe1_mstckdiv when force mode enable | |
+#endif | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x040), 17, 4, 0x07); // rg_pe1_crtmsel //value of da[x]_pe1_crtmsel when force mode enable for Port 0 | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x040), 16, 1, 0x01); // rg_pe1_frc_crtmsel //force mode enable of da[x]_pe1_crtmsel for Port 0 | |
+ /* Enable PHY and disable force mode */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control | |
+#endif | |
+} | |
+#endif | |
+ | |
+#if defined(CONFIG_MT7628_ASIC) | |
+void pcie_phy_config(void) | |
+{ | |
+ u32 reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10)); | |
+ | |
+ reg = (reg >> 6) & 0x1; | |
+ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x400), 8, 1, 0x01); // [rg_pe1_frc_h_xtal_type]: Enable Crystal type force mode | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x400), 9, 2, 0x00); // [rg_pe1_h_xtal_type]: Force Crystal type = 20MHz | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x000), 4, 1, 0x01); // [rg_pe1_frc_phy_en]: Enable Port 0 force mode | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x000), 5, 1, 0x00); // [rg_pe1_phy_en]: Port 0 disable | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4AC),16, 3, 0x03); // [RG_PE1_H_PLL_BR] | |
+ if (reg == 1) { | |
+ /* 40MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4BC),24, 8, 0x7D); // [RG_PE1_H_PLL_FBKDIV] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x490),12, 4, 0x08); // [RG_PE1_H_PLL_IR] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x490), 6, 2, 0x01); // [RG_PE1_H_PLL_PREDIV]: Pre-divider ratio (for host mode) | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4C0), 0,32, 0x1F400000); // [RG_PE1_H_LCDDS_PCW_NCPO]: For 40MHz crystal input | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A4), 0,16, 0x013D); // [RG_PE1_H_LCDDS_SSC_PRD] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A8),16,16, 0x74); // [RG_PE1_H_LCDDS_SSC_DELTA1]: For SSC=4500ppm | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A8), 0,16, 0x74); // [RG_PE1_H_LCDDS_SSC_DELTA]: For SSC=4500ppm | |
+ } else { | |
+ /* 25MHz Xtal */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4BC),24, 8, 0x64); // [RG_PE1_H_PLL_FBKDIV] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x490),12, 4, 0x0A); // [RG_PE1_H_PLL_IR] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x490), 6, 2, 0x00); // [RG_PE1_H_PLL_PREDIV]: Pre-divider ratio (for host mode) | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4C0), 0,32, 0x19000000); // [RG_PE1_H_LCDDS_PCW_NCPO]: For 25MHz crystal input | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A4), 0,16, 0x018D); // [RG_PE1_H_LCDDS_SSC_PRD] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A8),16,16, 0x4A); // [RG_PE1_H_LCDDS_SSC_DELTA1]: For SSC=4500ppm | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x4A8), 0,16, 0x4A); // [RG_PE1_H_LCDDS_SSC_DELTA]: For SSC=4500ppm | |
+ } | |
+ /* MT7628 PCIe PHY LDO setting: 0x1 -> 0x5 (1.0V -> 1.2V) */ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x498), 0, 8, 0x05); | |
+ | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x000), 5, 1, 0x01); // Port 0 enable [rg_pe1_phy_en] | |
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0_CTL_OFFSET + 0x000), 4, 1, 0x00); // Disable Port 0 force mode [rg_pe1_frc_phy_en] | |
+} | |
+#endif | |
+ | |
+int __init init_ralink_pci(void) | |
+{ | |
+ u32 __maybe_unused val; | |
+ | |
+ PCIBIOS_MIN_IO = 0; | |
+ PCIBIOS_MIN_MEM = 0; | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ pcie_link_status = 0; | |
+ val = RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST; | |
+ ASSERT_SYSRST_PCIE(val); // raise reset all PCIe ports | |
+ udelay(100); | |
+#if defined(GPIO_PERST) | |
+ val = RALINK_GPIOMODE; | |
+ val &= ~((0x3<<PCIE_SHARE_PIN_SW) | (0x3<<UARTL3_SHARE_PIN_SW)); | |
+ val |= ((0x1<<PCIE_SHARE_PIN_SW) | (0x1<<UARTL3_SHARE_PIN_SW)); | |
+ if (RALINK_GPIOMODE != val) { | |
+ RALINK_GPIOMODE = val; | |
+ mdelay(100); | |
+ } | |
+ val = 0; | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ val |= (0x1<<GPIO_PCIE_PORT0); | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ val |= (0x1<<GPIO_PCIE_PORT1); | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ val |= (0x1<<GPIO_PCIE_PORT2); | |
+#endif | |
+ RALINK_GPIO_CTRL0 |= val; // switch PERST_N pin to output mode | |
+ mdelay(100); | |
+ RALINK_GPIO_DATA0 &= ~(val); // fall PERST_N pin (reset peripherals) | |
+#else /* !defined(GPIO_PERST) */ | |
+ RALINK_GPIOMODE &= ~(0x3<<PCIE_SHARE_PIN_SW); // fall PERST_N pin (reset peripherals) | |
+#endif | |
+ mdelay(100); // wait 100 ms pulse | |
+ | |
+ val = 0; | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ val |= RALINK_PCIE0_RST; | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ val |= RALINK_PCIE1_RST; | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ val |= RALINK_PCIE2_RST; | |
+#endif | |
+ DEASSERT_SYSRST_PCIE(val); // release reset for needed PCIe ports | |
+ | |
+ val = RALINK_CLKCFG1; | |
+ val &= ~(RALINK_PCIE0_CLK_EN | RALINK_PCIE1_CLK_EN | RALINK_PCIE2_CLK_EN); | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ val |= RALINK_PCIE0_CLK_EN; | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ val |= RALINK_PCIE1_CLK_EN; | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ val |= RALINK_PCIE2_CLK_EN; | |
+#endif | |
+ RALINK_CLKCFG1 = val; // enable clock for needed PCIe ports | |
+ | |
+ mdelay(10); | |
+ | |
+ if ((ralink_asic_rev_id & 0xFFFF) == 0x0101) // MT7621 E2 | |
+ bypass_pipe_rst(); | |
+ | |
+ set_phy_for_ssc(); | |
+ | |
+ mdelay(100); | |
+ | |
+#if defined(GPIO_PERST) | |
+ val = 0; | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ val |= (0x1<<GPIO_PCIE_PORT0); | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ val |= (0x1<<GPIO_PCIE_PORT1); | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ val |= (0x1<<GPIO_PCIE_PORT2); | |
+#endif | |
+ RALINK_GPIO_DATA0 |= val; // rise PERST_N pin (complete reset peripherals) | |
+#else /* !defined(GPIO_PERST) */ | |
+ RALINK_PCI_PCICFG_ADDR &= ~(1<<1); // release PCIRST | |
+#endif | |
+ | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ RALINK_GPIOMODE &= ~(0x01<<16); // PERST_GPIO_MODE = 1'b0 | |
+ | |
+ RALINK_RSTCTRL &= ~RALINK_PCIE0_RST; | |
+ RALINK_CLKCFG1 |= RALINK_PCIE0_CLK_EN; | |
+ | |
+ mdelay(100); | |
+ | |
+ pcie_phy_config(); | |
+ | |
+ mdelay(10); | |
+ | |
+ RALINK_PCI_PCICFG_ADDR &= ~(1<<1); // release PCIRST | |
+#endif | |
+ | |
+ /* wait before detect card in slots */ | |
+ mdelay(500); | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ if ((RALINK_PCI0_STATUS & 0x1) == 0) { | |
+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST); | |
+ RALINK_CLKCFG1 &= ~RALINK_PCIE0_CLK_EN; | |
+ printk("%s: no card, disable it (RST&CLK)\n", "PCIe0"); | |
+ } else { | |
+ pcie_link_status |= (1<<0); | |
+ } | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ if ((RALINK_PCI1_STATUS & 0x1) == 0) { | |
+ ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST); | |
+ RALINK_CLKCFG1 &= ~RALINK_PCIE1_CLK_EN; | |
+ printk("%s: no card, disable it (RST&CLK)\n", "PCIe1"); | |
+ } else { | |
+ pcie_link_status |= (1<<1); | |
+ } | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ if ((RALINK_PCI2_STATUS & 0x1) == 0) { | |
+ ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST); | |
+ RALINK_CLKCFG1 &= ~RALINK_PCIE2_CLK_EN; | |
+ printk("%s: no card, disable it (RST&CLK)\n", "PCIe2"); | |
+ } else { | |
+ pcie_link_status |= (1<<2); | |
+ } | |
+#endif | |
+ | |
+ /* No cards, exit */ | |
+ if (pcie_link_status == 0) | |
+ return 0; | |
+ | |
+/* | |
+ pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num | |
+ 3'b000 x x x | |
+ 3'b001 x x 0 | |
+ 3'b010 x 0 x | |
+ 3'b011 x 1 0 | |
+ 3'b100 0 x x | |
+ 3'b101 1 x 0 | |
+ 3'b110 1 0 x | |
+ 3'b111 2 1 0 | |
+*/ | |
+ switch (pcie_link_status) { | |
+ case 0x2: | |
+ /* PCIe1 only */ | |
+ RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000; | |
+ RALINK_PCI_PCICFG_ADDR |= (0x1 << 16); // PCIe0 -> port1 | |
+ RALINK_PCI_PCICFG_ADDR |= (0x0 << 20); // PCIe1 -> port0 (*) | |
+ break; | |
+ case 0x4: | |
+ /* PCIe2 only */ | |
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; | |
+ RALINK_PCI_PCICFG_ADDR |= (0x1 << 16); // PCIe0 -> port1 | |
+ RALINK_PCI_PCICFG_ADDR |= (0x2 << 20); // PCIe1 -> port2 | |
+ RALINK_PCI_PCICFG_ADDR |= (0x0 << 24); // PCIe2 -> port0 (*) | |
+ break; | |
+ case 0x5: | |
+ /* PCIe0 + PCIe2 */ | |
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; | |
+ RALINK_PCI_PCICFG_ADDR |= (0x0 << 16); // PCIe0 -> port0 (*) | |
+ RALINK_PCI_PCICFG_ADDR |= (0x2 << 20); // PCIe1 -> port2 | |
+ RALINK_PCI_PCICFG_ADDR |= (0x1 << 24); // PCIe2 -> port1 (*) | |
+ break; | |
+ case 0x6: | |
+ /* PCIe1 + PCIe2 */ | |
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000; | |
+ RALINK_PCI_PCICFG_ADDR |= (0x2 << 16); // PCIe0 -> port2 | |
+ RALINK_PCI_PCICFG_ADDR |= (0x0 << 20); // PCIe1 -> port0 (*) | |
+ RALINK_PCI_PCICFG_ADDR |= (0x1 << 24); // PCIe2 -> port1 (*) | |
+ break; | |
+ } | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ if ((RALINK_PCI0_STATUS & 0x1) == 0) { | |
+ RALINK_RSTCTRL |= RALINK_PCIE0_RST; | |
+ RALINK_CLKCFG1 &= ~RALINK_PCIE0_CLK_EN; | |
+ printk("%s: no card, disable it (RST&CLK)\n", "PCIe0"); | |
+ return 0; | |
+ } | |
+#endif | |
+ | |
+ RALINK_PCI_MEMBASE = 0xffffffff; // valid for PCI host mode only | |
+ RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE; // valid for PCI host mode only | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+#if defined(CONFIG_PCIE_PORT0) | |
+ // PCIe0 | |
+ if ((pcie_link_status & 0x1) != 0) { | |
+ RALINK_PCI0_BAR0SETUP_ADDR = 0x7fff0001; // open BAR0 (2GB) | |
+ RALINK_PCI0_BAR1SETUP_ADDR = 0x00000000; // disable BAR1 (used in EP mode) | |
+ RALINK_PCI0_IMBASEBAR0_ADDR = BAR0_MEMORY_BASE; // make BAR0 | |
+ RALINK_PCI0_CLASS = 0x06040001; | |
+ RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable PCIe0 interrupt | |
+ } | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT1) | |
+ // PCIe1 | |
+ if ((pcie_link_status & 0x2) != 0) { | |
+ RALINK_PCI1_BAR0SETUP_ADDR = 0x7fff0001; // open BAR0 (2GB) | |
+ RALINK_PCI1_BAR1SETUP_ADDR = 0x00000000; // disable BAR1 (used in EP mode) | |
+ RALINK_PCI1_IMBASEBAR0_ADDR = BAR0_MEMORY_BASE; // make BAR0 | |
+ RALINK_PCI1_CLASS = 0x06040001; | |
+ RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable PCIe1 interrupt | |
+ } | |
+#endif | |
+#if defined(CONFIG_PCIE_PORT2) | |
+ // PCIe2 | |
+ if ((pcie_link_status & 0x4) != 0) { | |
+ RALINK_PCI2_BAR0SETUP_ADDR = 0x7fff0001; // open BAR0 (2GB) | |
+ RALINK_PCI2_BAR1SETUP_ADDR = 0x00000000; // disable BAR1 (used in EP mode) | |
+ RALINK_PCI2_IMBASEBAR0_ADDR = BAR0_MEMORY_BASE; // make BAR0 | |
+ RALINK_PCI2_CLASS = 0x06040001; | |
+ RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable PCIe2 interrupt | |
+ } | |
+#endif | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ //PCIe0 | |
+ RALINK_PCI0_BAR0SETUP_ADDR = 0x7fff0001; // open BAR0 (2GB) | |
+ RALINK_PCI0_BAR1SETUP_ADDR = 0x00000000; // disable BAR1 (used in EP mode) | |
+ RALINK_PCI0_IMBASEBAR0_ADDR = BAR0_MEMORY_BASE; // make BAR0 | |
+ RALINK_PCI0_CLASS = 0x06040001; | |
+ RALINK_PCI_PCIMSK_ADDR = (1<<20); // enable PCIe0 interrupt | |
+#endif | |
+ | |
+ ralink_pci_controller.io_map_base = mips_io_port_base; | |
+ | |
+ register_pci_controller(&ralink_pci_controller); | |
+ | |
+ return 0; | |
+} | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) || defined(CONFIG_RALINK_MT7628) | |
+arch_initcall(init_ralink_pci); | |
+#else | |
+#error Please disable CONFIG_PCI for unsupported SoC! | |
+#endif | |
+ | |
+#endif /* CONFIG_PCI */ | |
diff --git a/arch/mips/rt2880/printf.c b/arch/mips/rt2880/printf.c | |
new file mode 100644 | |
index 000000000000..26acd164d1b5 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/printf.c | |
@@ -0,0 +1,118 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * prom_printf for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/kernel.h> | |
+#include <linux/spinlock.h> | |
+#include <asm/io.h> | |
+ | |
+#include <asm/rt2880/rt_mmap.h> | |
+#include <asm/rt2880/rt_serial.h> | |
+ | |
+static DEFINE_SPINLOCK(con_lock); | |
+static char buf[256]; | |
+static unsigned int uart_base; | |
+ | |
+static inline unsigned int serial_in(int offset) | |
+{ | |
+ return inl(uart_base + offset); | |
+} | |
+ | |
+static inline void serial_out(int offset, int value) | |
+{ | |
+ outl(value, uart_base + offset); | |
+} | |
+ | |
+#ifdef CONFIG_EARLY_PRINTK | |
+void prom_putchar(unsigned char c) | |
+{ | |
+ while ((serial_in(RT2880_UART_LSR) & RT2880_UART_LSR_THRE) == 0) | |
+ ; | |
+ | |
+ serial_out(RT2880_UART_TX, c); | |
+} | |
+#endif | |
+ | |
+int putPromChar(char c) | |
+{ | |
+ while ((serial_in(RT2880_UART_LSR) & RT2880_UART_LSR_THRE) == 0) | |
+ ; | |
+ | |
+ serial_out(RT2880_UART_TX, c); | |
+ | |
+ return 1; | |
+} | |
+ | |
+char getPromChar(void) | |
+{ | |
+ while (!(serial_in(RT2880_UART_LSR) & 1)) | |
+ ; | |
+ | |
+ return serial_in(RT2880_UART_RX); | |
+} | |
+ | |
+void __init prom_init_printf(int tty_no) | |
+{ | |
+#if !defined(CONFIG_RALINK_GPIOMODE_UARTF) && (CONFIG_SERIAL_8250_NR_UARTS > 1) | |
+ if (tty_no == 1) | |
+ uart_base = RALINK_UART_BASE; | |
+ else | |
+#endif | |
+ uart_base = RALINK_UART_LITE_BASE; | |
+} | |
+ | |
+void __init prom_printf(char *fmt, ...) | |
+{ | |
+ va_list args; | |
+ int l; | |
+ char *p, *buf_end; | |
+ unsigned long flags; | |
+ | |
+ spin_lock_irqsave(&con_lock, flags); | |
+ va_start(args, fmt); | |
+ l = vsnprintf(buf, sizeof(buf), fmt, args); | |
+ va_end(args); | |
+ buf_end = buf + l; | |
+ for (p = buf; p < buf_end; p++) { | |
+ /* Crude cr/nl handling is better than none */ | |
+ if (*p == '\n') | |
+ putPromChar('\r'); | |
+ putPromChar(*p); | |
+ } | |
+ spin_unlock_irqrestore(&con_lock, flags); | |
+} | |
diff --git a/arch/mips/rt2880/reset.c b/arch/mips/rt2880/reset.c | |
new file mode 100644 | |
index 000000000000..65a8511d6976 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/reset.c | |
@@ -0,0 +1,124 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * reboot/reset setting for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+#include <linux/ioport.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/time.h> | |
+#include <asm/reboot.h> | |
+#include <asm/pbus-timer.h> | |
+ | |
+#include <asm/rt2880/generic.h> | |
+ | |
+extern void mtk_disable_irq_all(void); | |
+ | |
+static void hw_uninit(bool do_reboot) | |
+{ | |
+ mtk_disable_irq_all(); | |
+ | |
+ /* stop all APB module timers except an active watchdog */ | |
+ pbus_timer_disable(PBUS_TIMER_0); | |
+ pbus_timer_disable(PBUS_TIMER_2); | |
+ | |
+ /* timer 3 is in a non-watchdog mode */ | |
+ if (!(pbus_timer_r32(RSTSTAT) & RSTSTAT_WDT_EN)) | |
+ pbus_timer_disable(PBUS_TIMER_1); | |
+ | |
+#if defined(CONFIG_RALINK_MT7628) | |
+ /* reset PCIe */ | |
+ *(volatile u32 *)(SOFTRES_REG) = RALINK_PCIE0_RST; | |
+ | |
+ if (do_reboot) | |
+ mdelay(10); | |
+#endif | |
+ | |
+ if (do_reboot) { | |
+ /* system software reset */ | |
+ *(volatile u32 *)(SOFTRES_REG) = GORESET; | |
+ *(volatile u32 *)(SOFTRES_REG) = 0; | |
+ } | |
+} | |
+ | |
+static void mips_machine_restart(char *command) | |
+{ | |
+ printk(KERN_WARNING "Machine restart ... \n"); | |
+ | |
+ hw_uninit(true); | |
+} | |
+ | |
+static void mips_machine_halt(void) | |
+{ | |
+ printk(KERN_WARNING "Machine halted ... \n"); | |
+ | |
+ hw_uninit(false); | |
+} | |
+ | |
+static void mips_machine_power_off(void) | |
+{ | |
+ printk(KERN_WARNING "Machine poweroff ... \n"); | |
+ | |
+ *(volatile u32*)(POWER_DIR_REG) = POWER_DIR_OUTPUT; | |
+ *(volatile u32*)(POWER_POL_REG) = 0; | |
+ *(volatile u32*)(POWEROFF_REG) = POWEROFF; | |
+} | |
+ | |
+static int mtk_panic_event(struct notifier_block *nb, | |
+ unsigned long action, void *data) | |
+{ | |
+ if (action == PANIC_ACTION_RESTART) | |
+ mips_machine_restart(NULL); | |
+ else | |
+ mips_machine_halt(); | |
+ | |
+ return NOTIFY_DONE; | |
+} | |
+ | |
+static struct notifier_block mtk_panic_block = { | |
+ .notifier_call = mtk_panic_event, | |
+}; | |
+ | |
+void mips_reboot_setup(void) | |
+{ | |
+ _machine_restart = mips_machine_restart; | |
+ _machine_halt = mips_machine_halt; | |
+ pm_power_off = mips_machine_power_off; | |
+ | |
+ atomic_notifier_chain_register(&panic_notifier_list, &mtk_panic_block); | |
+} | |
diff --git a/arch/mips/rt2880/setup.c b/arch/mips/rt2880/setup.c | |
new file mode 100644 | |
index 000000000000..3d71e8b995eb | |
--- /dev/null | |
+++ b/arch/mips/rt2880/setup.c | |
@@ -0,0 +1,115 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * board setup for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+#include <linux/ioport.h> | |
+#include <asm/cpu.h> | |
+#include <asm/cpu-info.h> | |
+#include <asm/bootinfo.h> | |
+#ifdef CONFIG_DMA_MAYBE_COHERENT | |
+#include <asm/mips-cm.h> | |
+#include <asm/dma-coherence.h> | |
+#endif | |
+ | |
+#include <asm/rt2880/prom.h> | |
+ | |
+extern void mips_reboot_setup(void); | |
+ | |
+const char *get_system_type(void) | |
+{ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ return "MediaTek MT7621 SoC"; | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ return "MediaTek MT7628 SoC"; | |
+#else | |
+ return "MediaTek SoC"; | |
+#endif | |
+} | |
+ | |
+#ifdef CONFIG_DMA_MAYBE_COHERENT | |
+static inline int plat_enable_iocoherency(void) | |
+{ | |
+ int supported = 0; | |
+ | |
+ if (mips_cm_numiocu()) { | |
+ pr_info("GCMP IOCU detected\n"); | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ /* MT7621 GCMP reported about IOCU=1, but IOCU switch disabled by default */ | |
+// supported = 1; | |
+#endif | |
+ } | |
+ | |
+ return supported; | |
+} | |
+ | |
+static void __init plat_setup_iocoherency(void) | |
+{ | |
+ /* | |
+ * Kernel has been configured with software coherency | |
+ * but we might choose to turn it off and use hardware | |
+ * coherency instead. | |
+ */ | |
+ if (plat_enable_iocoherency()) { | |
+ coherentio = 1; | |
+ hw_coherentio = 1; | |
+ pr_info("Hardware DMA cache coherency enabled\n"); | |
+ } | |
+} | |
+#endif | |
+ | |
+void __init plat_mem_setup(void) | |
+{ | |
+ char *argptr; | |
+ | |
+ iomem_resource.start = 0; | |
+ iomem_resource.end = ~0; | |
+ ioport_resource.start = 0; | |
+ ioport_resource.end = 0x1fffffff; | |
+ | |
+ argptr = prom_getcmdline(); | |
+ | |
+ if ((argptr = strstr(argptr, "nofpu")) != NULL) | |
+ cpu_data[0].options &= ~MIPS_CPU_FPU; | |
+ | |
+#ifdef CONFIG_DMA_MAYBE_COHERENT | |
+ plat_setup_iocoherency(); | |
+#endif | |
+ mips_reboot_setup(); | |
+} | |
+ | |
diff --git a/arch/mips/rt2880/time.c b/arch/mips/rt2880/time.c | |
new file mode 100644 | |
index 000000000000..b72d721e1faa | |
--- /dev/null | |
+++ b/arch/mips/rt2880/time.c | |
@@ -0,0 +1,93 @@ | |
+/************************************************************************** | |
+ * | |
+ * BRIEF MODULE DESCRIPTION | |
+ * timer setup for Ralink RT2880 solution | |
+ * | |
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms of the GNU General Public License as published by the | |
+ * Free Software Foundation; either version 2 of the License, or (at your | |
+ * option) any later version. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 675 Mass Ave, Cambridge, MA 02139, USA. | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ * May 2007 Bruce Chang | |
+ * | |
+ * Initial Release | |
+ * | |
+ * | |
+ * | |
+ ************************************************************************** | |
+ */ | |
+ | |
+#include <linux/types.h> | |
+#include <linux/init.h> | |
+#include <linux/module.h> | |
+#include <linux/timex.h> | |
+ | |
+#include <linux/jiffies.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/mipsregs.h> | |
+#include <asm/hardirq.h> | |
+#include <asm/div64.h> | |
+#include <asm/cpu.h> | |
+#include <asm/time.h> | |
+ | |
+#ifdef CONFIG_CLKSRC_MIPS_GIC | |
+#include <linux/irqchip/mips-gic.h> | |
+#endif | |
+ | |
+#include <asm/rt2880/generic.h> | |
+#include <asm/rt2880/prom.h> | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+extern unsigned int mips_hpt_frequency; | |
+extern u32 mips_cpu_feq; | |
+extern u32 surfboard_sysclk; | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+static int udelay_recal(void) | |
+{ | |
+ unsigned int i; | |
+ | |
+ for (i = 1; i < num_present_cpus(); i++) | |
+ cpu_data[i].udelay_val = cpu_data[0].udelay_val; | |
+ | |
+ return 0; | |
+} | |
+postcore_initcall(udelay_recal); | |
+#endif | |
+ | |
+void __init plat_time_init(void) | |
+{ | |
+#ifdef CONFIG_CLKSRC_MIPS_GIC | |
+ gic_clocksource_init(mips_cpu_feq); | |
+#else | |
+ mips_hpt_frequency = mips_cpu_feq / 2; | |
+#endif | |
+} | |
+ | |
+u32 get_surfboard_sysclk(void) | |
+{ | |
+ return surfboard_sysclk; | |
+} | |
+ | |
+EXPORT_SYMBOL(get_surfboard_sysclk); | |
+ | |
diff --git a/arch/mips/rt2880/uphy.c b/arch/mips/rt2880/uphy.c | |
new file mode 100644 | |
index 000000000000..c987d7be0e60 | |
--- /dev/null | |
+++ b/arch/mips/rt2880/uphy.c | |
@@ -0,0 +1,214 @@ | |
+#include <linux/version.h> | |
+#include <linux/module.h> | |
+#include <linux/types.h> | |
+#include <linux/kernel.h> | |
+#include <linux/init.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/rt2880/rt_mmap.h> | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ | |
+#define ADDR_SIFSLV_BASE RALINK_XHCI_UPHY_BASE | |
+#define ADDR_SIFSLV_FMREG_BASE (ADDR_SIFSLV_BASE+0x0100) | |
+#define ADDR_U2_PHY_P0_BASE (ADDR_SIFSLV_BASE+0x0800) | |
+#define ADDR_U2_PHY_P1_BASE (ADDR_SIFSLV_BASE+0x1000) | |
+#define U2_SR_COEFF 28 | |
+ | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ | |
+#define ADDR_SIFSLV_FMREG_BASE (RALINK_USB_DEV_BASE+0xf00) | |
+#define ADDR_U2_PHY_P0_BASE (RALINK_USB_DEV_BASE+0x800) | |
+#define U2_SR_COEFF 32 | |
+ | |
+#endif | |
+ | |
+#define REG_SIFSLV_FMREG_FMCR0 (ADDR_SIFSLV_FMREG_BASE+0x00) | |
+#define REG_SIFSLV_FMREG_FMCR1 (ADDR_SIFSLV_FMREG_BASE+0x04) | |
+#define REG_SIFSLV_FMREG_FMCR2 (ADDR_SIFSLV_FMREG_BASE+0x08) | |
+#define REG_SIFSLV_FMREG_FMMONR0 (ADDR_SIFSLV_FMREG_BASE+0x0C) | |
+#define REG_SIFSLV_FMREG_FMMONR1 (ADDR_SIFSLV_FMREG_BASE+0x10) | |
+ | |
+/* SIFSLV_FMREG_FMCR0 */ | |
+#define RG_LOCKTH (0xf<<28) | |
+#define RG_MONCLK_SEL (0x3<<26) | |
+#define RG_FM_MODE (0x1<<25) | |
+#define RG_FREQDET_EN (0x1<<24) | |
+#define RG_CYCLECNT (0x00ffffff) | |
+ | |
+/* SIFSLV_FMREG_FMMONR1 */ | |
+#define RG_MONCLK_SEL_3 (0x1<<9) | |
+#define RG_FRCK_EN (0x1<<8) | |
+#define USBPLL_LOCK (0x1<<1) | |
+#define USB_FM_VLD (0x1<<0) | |
+ | |
+#define OFS_U2_PHY_AC0 0x00 | |
+#define OFS_U2_PHY_AC1 0x04 | |
+#define OFS_U2_PHY_AC2 0x08 | |
+#define OFS_U2_PHY_ACR0 0x10 | |
+#define OFS_U2_PHY_ACR1 0x14 | |
+#define OFS_U2_PHY_ACR2 0x18 | |
+#define OFS_U2_PHY_ACR3 0x1C | |
+#define OFS_U2_PHY_ACR4 0x20 | |
+#define OFS_U2_PHY_AMON0 0x24 | |
+#define OFS_U2_PHY_DCR0 0x60 | |
+#define OFS_U2_PHY_DCR1 0x64 | |
+#define OFS_U2_PHY_DTM0 0x68 | |
+#define OFS_U2_PHY_DTM1 0x6C | |
+ | |
+/* U2_PHY_ACR0 */ | |
+#define RG_USB20_ICUSB_EN (0x1<<24) | |
+#define RG_USB20_HSTX_SRCAL_EN (0x1<<23) | |
+#define RG_USB20_HSTX_SRCTRL (0x7<<16) | |
+#define RG_USB20_LS_CR (0x7<<12) | |
+#define RG_USB20_FS_CR (0x7<<8) | |
+#define RG_USB20_LS_SR (0x7<<4) | |
+#define RG_USB20_FS_SR (0x7<<0) | |
+ | |
+static atomic_t uphy_init_instance = ATOMIC_INIT(0); | |
+ | |
+static void | |
+u2_slew_rate_calibration(int port_id, u32 u2_phy_reg_base) | |
+{ | |
+ int i; | |
+ u32 reg_val; | |
+ u32 u4FmOut = 0; | |
+ | |
+ // => RG_USB20_HSTX_SRCAL_EN = 1 | |
+ // enable HS TX SR calibration | |
+ reg_val = sysRegRead(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val |= RG_USB20_HSTX_SRCAL_EN; | |
+ sysRegWrite(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+ msleep(1); | |
+ | |
+ // => RG_FRCK_EN = 1 | |
+ // Enable free run clock | |
+ reg_val = sysRegRead(REG_SIFSLV_FMREG_FMMONR1); | |
+ reg_val |= RG_FRCK_EN; | |
+ sysRegWrite(REG_SIFSLV_FMREG_FMMONR1, reg_val); | |
+ | |
+ // MT6290 HS signal quality patch | |
+ // => RG_CYCLECNT = 400 | |
+ // Setting cyclecnt = 400 | |
+ reg_val = sysRegRead(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val &= ~RG_CYCLECNT; | |
+ reg_val |= 0x400; | |
+ sysRegWrite(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ // => RG_FREQDET_EN = 1 | |
+ // Enable frequency meter | |
+ reg_val = sysRegRead(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val |= RG_FREQDET_EN; | |
+ sysRegWrite(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ // wait for FM detection done, set 10ms timeout | |
+ for (i = 0; i < 10; i++) { | |
+ // => u4FmOut = USB_FM_OUT | |
+ // read FM_OUT | |
+ u4FmOut = sysRegRead(REG_SIFSLV_FMREG_FMMONR0); | |
+ | |
+ // check if FM detection done | |
+ if (u4FmOut != 0) | |
+ break; | |
+ | |
+ msleep(1); | |
+ } | |
+ | |
+ // => RG_FREQDET_EN = 0 | |
+ // disable frequency meter | |
+ reg_val = sysRegRead(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val &= ~RG_FREQDET_EN; | |
+ sysRegWrite(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ // => RG_FRCK_EN = 0 | |
+ // disable free run clock | |
+ reg_val = sysRegRead(REG_SIFSLV_FMREG_FMMONR1); | |
+ reg_val &= ~RG_FRCK_EN; | |
+ sysRegWrite(REG_SIFSLV_FMREG_FMMONR1, reg_val); | |
+ | |
+ // => RG_USB20_HSTX_SRCAL_EN = 0 | |
+ // disable HS TX SR calibration | |
+ reg_val = sysRegRead(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val &= ~RG_USB20_HSTX_SRCAL_EN; | |
+ sysRegWrite(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+ msleep(1); | |
+ | |
+ // => RG_USB20_HSTX_SRCTRL | |
+ reg_val = sysRegRead(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val &= ~RG_USB20_HSTX_SRCTRL; | |
+ if (u4FmOut != 0) { | |
+ // set reg = (1024/FM_OUT) * 25 * 0.028 (round to the nearest digits) | |
+ u32 u4Tmp = (((1024 * 25 * U2_SR_COEFF) / u4FmOut) + 500) / 1000; | |
+ reg_val |= ((u4Tmp & 0x07)<<16); | |
+ printk(KERN_INFO "U2PHY P%d set SRCTRL %s value: %d\n", port_id, "calibration", u4Tmp); | |
+ } else { | |
+ reg_val |= (0x4<<16); | |
+ printk(KERN_INFO "U2PHY P%d set SRCTRL %s value: %d\n", port_id, "default", 4); | |
+ } | |
+ sysRegWrite(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+} | |
+ | |
+#if defined(CONFIG_RALINK_MT7621) | |
+ | |
+static void | |
+u2_phy_init(u32 u2_phy_reg_base) | |
+{ | |
+ u32 reg_val; | |
+ | |
+ /* set SW PLL Stable mode to 1 for U2 LPM device remote wakeup */ | |
+ reg_val = sysRegRead(u2_phy_reg_base + OFS_U2_PHY_DCR1); | |
+ reg_val &= ~(0x3 << 18); | |
+ reg_val |= (0x1 << 18); | |
+ sysRegWrite(u2_phy_reg_base + OFS_U2_PHY_DCR1, reg_val); | |
+} | |
+ | |
+void | |
+uphy_init(void) | |
+{ | |
+ if (atomic_inc_return(&uphy_init_instance) != 1) | |
+ return; | |
+ | |
+ u2_phy_init(ADDR_U2_PHY_P0_BASE); | |
+ u2_phy_init(ADDR_U2_PHY_P1_BASE); | |
+ | |
+ u2_slew_rate_calibration(0, ADDR_U2_PHY_P0_BASE); | |
+ u2_slew_rate_calibration(1, ADDR_U2_PHY_P1_BASE); | |
+} | |
+ | |
+#elif defined(CONFIG_RALINK_MT7628) | |
+ | |
+static inline void | |
+u2_phy_init(void) | |
+{ | |
+ u32 reg_val; | |
+ | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_AC2); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_ACR0); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0); | |
+ | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0, 0x00ffff02); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0, 0x00555502); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0, 0x00aaaa02); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0, 0x00000402); | |
+ reg_val = sysRegRead(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DCR0); | |
+ | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_AC0, 0x0048086a); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_AC1, 0x4400001c); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_ACR3, 0xc0200000); | |
+ sysRegWrite(ADDR_U2_PHY_P0_BASE + OFS_U2_PHY_DTM0, 0x02000000); | |
+} | |
+ | |
+void | |
+uphy_init(void) | |
+{ | |
+ if (atomic_inc_return(&uphy_init_instance) != 1) | |
+ return; | |
+ | |
+ u2_phy_init(); | |
+ u2_slew_rate_calibration(0, ADDR_U2_PHY_P0_BASE); | |
+} | |
+ | |
+#endif | |
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c | |
index f9ae6a8fa7c7..bb8a96b3d3bf 100644 | |
--- a/arch/mips/sgi-ip27/ip27-smp.c | |
+++ b/arch/mips/sgi-ip27/ip27-smp.c | |
@@ -191,7 +191,7 @@ static void ip27_smp_finish(void) | |
* set sp to the kernel stack of the newly created idle process, gp to the proc | |
* struct so that current_thread_info() will work. | |
*/ | |
-static void ip27_boot_secondary(int cpu, struct task_struct *idle) | |
+static int ip27_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
unsigned long gp = (unsigned long)task_thread_info(idle); | |
unsigned long sp = __KSTK_TOS(idle); | |
@@ -199,6 +199,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle) | |
LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), | |
(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), | |
0, (void *) sp, (void *) gp); | |
+ return 0; | |
} | |
static void __init ip27_smp_setup(void) | |
@@ -227,7 +228,7 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus) | |
/* We already did everything necessary earlier */ | |
} | |
-struct plat_smp_ops ip27_smp_ops = { | |
+const struct plat_smp_ops ip27_smp_ops = { | |
.send_ipi_single = ip27_send_ipi_single, | |
.send_ipi_mask = ip27_send_ipi_mask, | |
.init_secondary = ip27_init_secondary, | |
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c | |
index 4c71aea25663..03a4cdde5ad2 100644 | |
--- a/arch/mips/sibyte/bcm1480/smp.c | |
+++ b/arch/mips/sibyte/bcm1480/smp.c | |
@@ -116,7 +116,7 @@ static void bcm1480_smp_finish(void) | |
* Setup the PC, SP, and GP of a secondary processor and start it | |
* running! | |
*/ | |
-static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) | |
+static int bcm1480_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
int retval; | |
@@ -125,6 +125,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) | |
(unsigned long)task_thread_info(idle), 0); | |
if (retval != 0) | |
printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); | |
+ return retval; | |
} | |
/* | |
@@ -156,7 +157,7 @@ static void __init bcm1480_prepare_cpus(unsigned int max_cpus) | |
{ | |
} | |
-struct plat_smp_ops bcm1480_smp_ops = { | |
+const struct plat_smp_ops bcm1480_smp_ops = { | |
.send_ipi_single = bcm1480_send_ipi_single, | |
.send_ipi_mask = bcm1480_send_ipi_mask, | |
.init_secondary = bcm1480_init_secondary, | |
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c | |
index c1a11a11db7f..115399202eab 100644 | |
--- a/arch/mips/sibyte/common/cfe.c | |
+++ b/arch/mips/sibyte/common/cfe.c | |
@@ -229,8 +229,8 @@ static int __init initrd_setup(char *str) | |
#endif | |
-extern struct plat_smp_ops sb_smp_ops; | |
-extern struct plat_smp_ops bcm1480_smp_ops; | |
+extern const struct plat_smp_ops sb_smp_ops; | |
+extern const struct plat_smp_ops bcm1480_smp_ops; | |
/* | |
* prom_init is called just after the cpu type is determined, from setup_arch() | |
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c | |
index 1cf66f5ff23d..1308d564a6d3 100644 | |
--- a/arch/mips/sibyte/sb1250/smp.c | |
+++ b/arch/mips/sibyte/sb1250/smp.c | |
@@ -106,7 +106,7 @@ static void sb1250_smp_finish(void) | |
* Setup the PC, SP, and GP of a secondary processor and start it | |
* running! | |
*/ | |
-static void sb1250_boot_secondary(int cpu, struct task_struct *idle) | |
+static int sb1250_boot_secondary(int cpu, struct task_struct *idle) | |
{ | |
int retval; | |
@@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle) | |
(unsigned long)task_thread_info(idle), 0); | |
if (retval != 0) | |
printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); | |
+ return retval; | |
} | |
/* | |
@@ -146,7 +147,7 @@ static void __init sb1250_prepare_cpus(unsigned int max_cpus) | |
{ | |
} | |
-struct plat_smp_ops sb_smp_ops = { | |
+const struct plat_smp_ops sb_smp_ops = { | |
.send_ipi_single = sb1250_send_ipi_single, | |
.send_ipi_mask = sb1250_send_ipi_mask, | |
.init_secondary = sb1250_init_secondary, | |
diff --git a/arch/mips/tc3262/Kconfig b/arch/mips/tc3262/Kconfig | |
new file mode 100644 | |
index 000000000000..873635341569 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/Kconfig | |
@@ -0,0 +1,49 @@ | |
+if MIPS_TC3262 | |
+ | |
+config PCIE_PORT1 | |
+ bool "Second PCIe port support" | |
+ default n | |
+ | |
+#-------------------------- | |
+ | |
+if (ECONET_EN7512 || ECONET_EN7516) | |
+ | |
+config TC3162_ADSL | |
+ bool "Enable ADSL support" | |
+ default n | |
+ | |
+config RALINK_VDSL | |
+ bool "Enable VDSL support" | |
+ default n | |
+ | |
+endif | |
+ | |
+#-------------------------- | |
+ | |
+if !MIPS_TC3262_1004K | |
+ | |
+config TC3262_IMEM | |
+ bool "Enable SPRAM IMEM" | |
+ default y | |
+ | |
+endif | |
+ | |
+config TC3262_CPU_TIMER | |
+ bool "Use CPU External Timer (per-VPE)" | |
+ default y | |
+ | |
+choice | |
+ prompt "HWFQ flat buffer allocation mode" | |
+ default TC3262_HWFQ_ALLOC | |
+ | |
+ config TC3262_HWFQ_ALLOC | |
+ bool "Use dma_alloc_coherent (fragmentation issue)" | |
+ config TC3262_HWFQ_MAP_4M | |
+ bool "Map 4MB beyond RAM size" | |
+ config TC3262_HWFQ_MAP_8M | |
+ bool "Map 8MB beyond RAM size" | |
+ config TC3262_HWFQ_MAP_16M | |
+ bool "Map 16MB beyond RAM size" | |
+endchoice | |
+ | |
+endif # MIPS_TC3262 | |
diff --git a/arch/mips/tc3262/Makefile b/arch/mips/tc3262/Makefile | |
new file mode 100644 | |
index 000000000000..baaf984417b1 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/Makefile | |
@@ -0,0 +1,26 @@ | |
+ | |
+obj-y := prom.o cmdline.o printf.o setup.o time.o | |
+ | |
+ifdef CONFIG_IRQ_GIC | |
+obj-y += irq-gic.o | |
+else | |
+obj-y += irq.o | |
+endif | |
+ | |
+obj-$(CONFIG_TC3262_CPU_TIMER) += hpt.o | |
+obj-$(CONFIG_PCI) += pci_en75xx.o | |
+obj-$(CONFIG_MIPS_CMP) += malta-amon.o | |
+ | |
+ifdef CONFIG_MIPS_MT_SMP | |
+obj-$(CONFIG_MIPS_TC3262_34K) += malta-smp.o | |
+endif | |
+ | |
+ifdef CONFIG_USB_XHCI_MTK | |
+obj-y += dev-xhci.o uphy.o | |
+endif | |
+ | |
+ifneq ($(strip \ | |
+ $(CONFIG_MT7615_WHNAT_SUPPORT) \ | |
+ $(CONFIG_MT7915_WHNAT_SUPPORT)),) | |
+obj-y += dev-woe.o | |
+endif | |
diff --git a/arch/mips/tc3262/Platform b/arch/mips/tc3262/Platform | |
new file mode 100644 | |
index 000000000000..1a03feabe82a | |
--- /dev/null | |
+++ b/arch/mips/tc3262/Platform | |
@@ -0,0 +1,9 @@ | |
+# | |
+# Econet EN75xx boards | |
+# | |
+platform-$(CONFIG_MIPS_TC3262) += tc3262/ | |
+cflags-$(CONFIG_MIPS_TC3262) += -I$(srctree)/arch/mips/include/asm/tc3162/ | |
+cflags-$(CONFIG_MIPS_TC3262_34K) += -mtune=34kc | |
+cflags-$(CONFIG_MIPS_TC3262_1004K) += -mtune=1004kc | |
+load-$(CONFIG_MIPS_TC3262) += 0xffffffff80020000 | |
+all-$(CONFIG_MIPS_TC3262) := $(COMPRESSION_FNAME).bin | |
diff --git a/arch/mips/tc3262/cmdline.c b/arch/mips/tc3262/cmdline.c | |
new file mode 100644 | |
index 000000000000..82851a9565c7 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/cmdline.c | |
@@ -0,0 +1,64 @@ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+ | |
+#include <asm/bootinfo.h> | |
+ | |
+#if defined(CONFIG_RT2880_UART_115200) | |
+#define TTY_UART_CONSOLE "console=ttyS0,115200n8" | |
+#else | |
+#define TTY_UART_CONSOLE "console=ttyS0,57600n8" | |
+#endif | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+extern int prom_argc; | |
+extern int *_prom_argv; | |
+ | |
+/* | |
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | |
+ * This macro take care of sign extension. | |
+ */ | |
+#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) | |
+#endif | |
+ | |
+extern char arcs_cmdline[COMMAND_LINE_SIZE]; | |
+ | |
+char * __init prom_getcmdline(void) | |
+{ | |
+ return &(arcs_cmdline[0]); | |
+} | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+void __init uboot_cmdline(char *s, size_t size) | |
+{ | |
+ int i; | |
+ | |
+ for (i = 1; i < prom_argc; i++) { /* Skip argv[0] */ | |
+ strlcat(s, prom_argv(i), size); | |
+ | |
+ /* Prevent last space */ | |
+ if (i != prom_argc - 1) | |
+ strlcat(s, " ", size); | |
+ } | |
+} | |
+#else | |
+static inline void uboot_cmdline(char *s, size_t size) {} | |
+#endif | |
+ | |
+static inline void fixup_cmdline(char *s, size_t size) | |
+{ | |
+ const char *p = TTY_UART_CONSOLE; | |
+ | |
+ if (strstr(s, "console=")) | |
+ return; | |
+ | |
+ /* Add space if there are symbols in buffer */ | |
+ if (*s) | |
+ strlcat(s, " ", size); | |
+ strlcat(s, p, size); | |
+} | |
+ | |
+void __init prom_init_cmdline(void) | |
+{ | |
+ uboot_cmdline(arcs_cmdline, sizeof(arcs_cmdline)); | |
+ fixup_cmdline(arcs_cmdline, sizeof(arcs_cmdline)); | |
+} | |
diff --git a/arch/mips/tc3262/dev-woe.c b/arch/mips/tc3262/dev-woe.c | |
new file mode 100644 | |
index 000000000000..1264c4648a6c | |
--- /dev/null | |
+++ b/arch/mips/tc3262/dev-woe.c | |
@@ -0,0 +1,72 @@ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/err.h> | |
+#include <linux/dma-mapping.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/tc3162/rt_mmap.h> | |
+ | |
+#include <soc/ralink/dev_woe.h> | |
+ | |
+static struct resource en75xx_woe_resources[] = { | |
+ [0] = { | |
+ .start = RALINK_WOE0_BASE, | |
+ .end = RALINK_WOE0_BASE + 0xfff, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ [1] = { | |
+ .start = RALINK_WOE1_BASE, | |
+ .end = RALINK_WOE1_BASE + 0xfff, | |
+ .flags = IORESOURCE_MEM, | |
+ }, | |
+ [2] = { | |
+ .start = WOE0_INTR, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+ [3] = { | |
+ .start = WOE1_INTR, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static struct whnat_mtk_pdata en75xx_woe_pdata = { | |
+ .wdma_base = { | |
+ RALINK_WDMA0_BASE, | |
+ RALINK_WDMA1_BASE | |
+ }, | |
+ .wdma_irq = { | |
+ { WDMA0_P0_INTR, WDMA0_P1_INTR, WDMA0_WOE_INTR }, | |
+ { WDMA1_P0_INTR, WDMA1_P1_INTR, WDMA1_WOE_INTR } | |
+ }, | |
+}; | |
+ | |
+static u64 en75xx_woe_dmamask = DMA_BIT_MASK(32); | |
+ | |
+static struct platform_device en75xx_woe_device = { | |
+ .name = WHNAT_MTK_DRV_NAME, | |
+ .id = -1, | |
+ .dev = { | |
+ .platform_data = &en75xx_woe_pdata, | |
+ .dma_mask = &en75xx_woe_dmamask, | |
+ .coherent_dma_mask = DMA_BIT_MASK(32), | |
+ }, | |
+ .num_resources = ARRAY_SIZE(en75xx_woe_resources), | |
+ .resource = en75xx_woe_resources, | |
+}; | |
+ | |
+int __init init_en75xx_woe(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_device_register(&en75xx_woe_device); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "WoE"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+device_initcall(init_en75xx_woe); | |
diff --git a/arch/mips/tc3262/dev-xhci.c b/arch/mips/tc3262/dev-xhci.c | |
new file mode 100644 | |
index 000000000000..ffde30f048bc | |
--- /dev/null | |
+++ b/arch/mips/tc3262/dev-xhci.c | |
@@ -0,0 +1,66 @@ | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/err.h> | |
+#include <linux/dma-mapping.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include <asm/irq.h> | |
+#include <asm/tc3162/rt_mmap.h> | |
+ | |
+#include <soc/ralink/dev_xhci.h> | |
+ | |
+static struct resource en75xx_xhci_resources[] = { | |
+ [0] = { | |
+ .start = RALINK_USB_HOST_BASE, | |
+ .end = RALINK_USB_HOST_BASE + RALINK_USB_HOST_SIZE - 1, | |
+ .flags = IORESOURCE_MEM, | |
+ .name = "mac", | |
+ }, | |
+ [1] = { | |
+ .start = RALINK_USB_IPPC_BASE, | |
+ .end = RALINK_USB_IPPC_BASE + 0xff, | |
+ .flags = IORESOURCE_MEM, | |
+ .name = "ippc", | |
+ }, | |
+ [2] = { | |
+ .start = SURFBOARDINT_USB, | |
+ .flags = IORESOURCE_IRQ, | |
+ }, | |
+}; | |
+ | |
+static u64 en75xx_xhci_dmamask = DMA_BIT_MASK(32); | |
+ | |
+extern void uphy_init(void); | |
+ | |
+static struct xhci_mtk_pdata en75xx_xhci_pdata = { | |
+ .uphy_init = uphy_init, | |
+ .usb3_lpm_capable = true, | |
+}; | |
+ | |
+static struct platform_device en75xx_xhci_device = { | |
+ .name = XHCI_MTK_DRV_NAME, | |
+ .id = -1, | |
+ .dev = { | |
+ .platform_data = &en75xx_xhci_pdata, | |
+ .dma_mask = &en75xx_xhci_dmamask, | |
+ .coherent_dma_mask = DMA_BIT_MASK(32), | |
+ }, | |
+ .num_resources = ARRAY_SIZE(en75xx_xhci_resources), | |
+ .resource = en75xx_xhci_resources, | |
+}; | |
+ | |
+int __init init_en75xx_xhci(void) | |
+{ | |
+ int retval = 0; | |
+ | |
+ retval = platform_device_register(&en75xx_xhci_device); | |
+ if (retval != 0) { | |
+ printk(KERN_ERR "register %s device fail!\n", "xHCI"); | |
+ return retval; | |
+ } | |
+ | |
+ return retval; | |
+} | |
+ | |
+device_initcall(init_en75xx_xhci); | |
diff --git a/arch/mips/tc3262/hpt.c b/arch/mips/tc3262/hpt.c | |
new file mode 100644 | |
index 000000000000..8e83c0b1421d | |
--- /dev/null | |
+++ b/arch/mips/tc3262/hpt.c | |
@@ -0,0 +1,238 @@ | |
+#define pr_fmt(fmt) "hpt: " fmt | |
+ | |
+#include <linux/io.h> | |
+#include <linux/cache.h> | |
+#include <linux/kernel.h> | |
+#include <linux/atomic.h> | |
+#include <linux/cpumask.h> | |
+#include <linux/irqflags.h> | |
+#include <linux/interrupt.h> | |
+#include <linux/clockchips.h> | |
+#include <linux/sched_clock.h> | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#define HPT_BITS 32 | |
+ | |
+#define HPT_MIN_DELTA 0x00000300 | |
+#define HPT_MAX_DELTA GENMASK(HPT_BITS - 1, 0) | |
+ | |
+#define HPT_IRQ SI_TIMER_INT | |
+ | |
+static inline void hpt_w32(const u32 reg, const u32 val) | |
+{ | |
+ __raw_writel(val, (void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+static inline u32 hpt_r32(const u32 reg) | |
+{ | |
+ return __raw_readl((void __iomem *)(unsigned long)reg); | |
+} | |
+ | |
+struct hpt_regs { | |
+ u32 lvr; /* compare value */ | |
+ u32 cvr; /* count */ | |
+ u32 ctl; /* control */ | |
+ u32 ctl_enabled; /* enabled mask */ | |
+ u32 ctl_pending; /* pending mask */ | |
+}; | |
+ | |
+struct hpt { | |
+ struct clock_event_device cd; | |
+ struct hpt_regs regs; | |
+} ____cacheline_aligned_in_smp; | |
+ | |
+static inline u32 hpt_read_count(const struct hpt *hpt) | |
+{ | |
+ return hpt_r32(hpt->regs.cvr); | |
+} | |
+ | |
+static inline void hpt_write_compare(const struct hpt *hpt, | |
+ const u32 lvr) | |
+{ | |
+ hpt_w32(hpt->regs.lvr, lvr); | |
+} | |
+ | |
+static inline bool hpt_is_pending(const struct hpt *hpt) | |
+{ | |
+ const struct hpt_regs *regs = &hpt->regs; | |
+ | |
+ return hpt_r32(regs->ctl) & regs->ctl_pending; | |
+} | |
+ | |
+static void hpt_init(const struct hpt *hpt) | |
+{ | |
+ const struct hpt_regs *regs = &hpt->regs; | |
+ | |
+ hpt_w32(regs->cvr, 0); | |
+ hpt_w32(regs->lvr, HPT_MAX_DELTA); | |
+} | |
+ | |
+static void hpt_enable(const struct hpt *hpt) | |
+{ | |
+ const struct hpt_regs *regs = &hpt->regs; | |
+ u32 ctl = hpt_r32(regs->ctl); | |
+ | |
+ ctl |= regs->ctl_enabled; | |
+ hpt_w32(regs->ctl, ctl); | |
+} | |
+ | |
+static DEFINE_PER_CPU(struct hpt, hpt_pcpu); | |
+ | |
+static irqreturn_t hpt_compare_interrupt(int irq, void *dev_id) | |
+{ | |
+ struct hpt *hpt = dev_id; | |
+ | |
+ if (!hpt_is_pending(hpt)) | |
+ return IRQ_NONE; | |
+ | |
+ hpt_write_compare(hpt, hpt_read_count(hpt)); | |
+ hpt->cd.event_handler(&hpt->cd); | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static int hpt_set_next_event(unsigned long delta, | |
+ struct clock_event_device *cd) | |
+{ | |
+ /* called by the kernel with disabled local hardware interrupts */ | |
+ const struct hpt *hpt = container_of(cd, struct hpt, cd); | |
+ const u32 next = hpt_read_count(hpt) + delta; | |
+ u32 cnt; | |
+ | |
+ hpt_write_compare(hpt, next); | |
+ cnt = hpt_read_count(hpt); | |
+ | |
+ if (next >= cnt) | |
+ return 0; /* next - cnt <= delta */ | |
+ | |
+ if (HPT_MAX_DELTA - cnt + next > delta) | |
+ return -ETIME; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void hpt_event_handler(struct clock_event_device *cd) | |
+{ | |
+} | |
+ | |
+int r4k_clockevent_init(void) | |
+{ | |
+ static struct irqaction hpt_compare_irqaction = { | |
+ .handler = hpt_compare_interrupt, | |
+ .percpu_dev_id = &hpt_pcpu, | |
+ .flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED, | |
+ .name = "timer" | |
+ }; | |
+ static atomic_t irq_installed = ATOMIC_INIT(0); | |
+ const unsigned int irq = HPT_IRQ; | |
+ const unsigned int cpu = smp_processor_id(); | |
+ struct hpt *hpt = &per_cpu(hpt_pcpu, cpu); | |
+ struct clock_event_device *cd = &hpt->cd; | |
+ | |
+ cd->name = "hpt"; | |
+ cd->features = CLOCK_EVT_FEAT_ONESHOT | | |
+ CLOCK_EVT_FEAT_C3STOP | | |
+ CLOCK_EVT_FEAT_PERCPU; | |
+ cd->rating = 300; | |
+ cd->irq = irq; | |
+ cd->cpumask = cpumask_of(cpu); | |
+ cd->set_next_event = hpt_set_next_event; | |
+ cd->event_handler = hpt_event_handler; | |
+ | |
+ clockevents_config_and_register(cd, CPUTMR_CLK, | |
+ HPT_MIN_DELTA, | |
+ HPT_MAX_DELTA); | |
+ | |
+ hpt_enable(hpt); | |
+ | |
+ if (atomic_cmpxchg(&irq_installed, 0, 1) == 0) { | |
+ int rc = irq_set_percpu_devid(irq); | |
+ | |
+ if (rc) { | |
+ pr_err("unable to configure IRQ%u (%i)\n", irq, rc); | |
+ return rc; | |
+ } | |
+ | |
+ rc = setup_percpu_irq(irq, &hpt_compare_irqaction); | |
+ if (rc) { | |
+ pr_err("unable to setup IRQ%u (%i)\n", irq, rc); | |
+ return rc; | |
+ } | |
+ } | |
+ | |
+ enable_percpu_irq(irq, IRQ_TYPE_NONE); | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* the monotonic clocksource and the scheduler clock are global | |
+ * objects and must use the same value for all threads */ | |
+static inline u32 hpt_read(void) | |
+{ | |
+ return hpt_read_count(&per_cpu(hpt_pcpu, 0)); | |
+} | |
+ | |
+static u64 notrace hpt_read_sched_clock(void) | |
+{ | |
+ return (u64)hpt_read(); | |
+} | |
+ | |
+static cycle_t hpt_clocksource_read(struct clocksource *cs) | |
+{ | |
+ return (cycle_t)hpt_read(); | |
+} | |
+ | |
+int __init init_r4k_clocksource(void) | |
+{ | |
+ static struct clocksource hpt_clocksource = { | |
+ .name = "hpt", | |
+ .mask = CLOCKSOURCE_MASK(HPT_BITS), | |
+ .read = hpt_clocksource_read, | |
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
+ .rating = 300 | |
+ }; | |
+ const int rc = clocksource_register_hz(&hpt_clocksource, CPUTMR_CLK); | |
+ | |
+ if (rc) { | |
+ pr_err("unable to register a clocksource (%i)\n", rc); | |
+ return rc; | |
+ } | |
+ | |
+#ifndef CONFIG_CPU_FREQ | |
+ sched_clock_register(hpt_read_sched_clock, HPT_BITS, CPUTMR_CLK); | |
+#endif | |
+ | |
+ return 0; | |
+} | |
+ | |
+#define HPT_REGS_DEF(cmr, cnt, ctl, enabled_bit, pending_bit) \ | |
+ CR_CPUTMR_##cmr, \ | |
+ CR_CPUTMR_##cnt, \ | |
+ CR_CPUTMR_##ctl, \ | |
+ 1U << enabled_bit, \ | |
+ 1U << pending_bit | |
+ | |
+void __init plat_hpt_init(void) | |
+{ | |
+ unsigned int i; | |
+ const unsigned int freq = CPUTMR_CLK; | |
+ | |
+ for (i = 0; i < NR_CPUS; i++) { | |
+ static const struct hpt_regs HPT_REGS[] = { | |
+ { HPT_REGS_DEF(CMR0, CNT0, CTL, 0, 16) }, | |
+ { HPT_REGS_DEF(CMR1, CNT1, CTL, 1, 17) }, | |
+#ifdef CONFIG_MIPS_TC3262_1004K | |
+ { HPT_REGS_DEF(CMR2, CNT2, 23_CTL, 0, 16) }, | |
+ { HPT_REGS_DEF(CMR3, CNT3, 23_CTL, 1, 17) }, | |
+#endif | |
+ }; | |
+ struct hpt *hpt = &per_cpu(hpt_pcpu, i); | |
+ | |
+ hpt->regs = HPT_REGS[i]; | |
+ hpt_init(hpt); | |
+ } | |
+ | |
+ pr_info("using %u.%03u MHz high precision timer\n", | |
+ ((freq + 500) / 1000) / 1000, | |
+ ((freq + 500) / 1000) % 1000); | |
+} | |
diff --git a/arch/mips/tc3262/irq-gic.c b/arch/mips/tc3262/irq-gic.c | |
new file mode 100644 | |
index 000000000000..5e533adc59a0 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/irq-gic.c | |
@@ -0,0 +1,211 @@ | |
+#include <linux/init.h> | |
+#include <linux/slab.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/setup.h> | |
+#include <asm/mips-cm.h> | |
+#include <asm/gic.h> | |
+ | |
+#include <asm/tc3162/tc3162.h> | |
+#include <asm/tc3162/rt_mmap.h> | |
+#include <asm/tc3162/surfboardint.h> | |
+ | |
+#include "irq.h" | |
+ | |
+#define X GIC_UNUSED | |
+ | |
+static const struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | |
+/* cpu, irqNum - 1, polarity, triggerType, flags, Src Name */ | |
+ { 0, CPU_CM_ERR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 0 CPU Coherence Manager Error */ | |
+ { 0, CPU_CM_PCINT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 1 CPU CM Perf Cnt overflow */ | |
+ { 0, UART_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 2 uart */ | |
+ { X, DRAM_PROTECTION - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 3 dram illegal access */ | |
+ { 0, TIMER0_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 4 timer 0 */ | |
+ { 0, TIMER1_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 5 timer 1 */ | |
+ { 0, TIMER2_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 6 timer 2 */ | |
+ { 0, IPI_RESCHED_INT0 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 7 ipi resched 0 */ | |
+ { 1, IPI_RESCHED_INT1 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 8 ipi resched 1 */ | |
+ { 0, TIMER5_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 9 timer 3 for wdog */ | |
+ { 0, GPIO_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 10 GPIO */ | |
+ { 0, PCM1_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 11 PCM 1 */ | |
+ { 2, IPI_RESCHED_INT2 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 12 ipi resched 2 */ | |
+ { 3, IPI_RESCHED_INT3 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 13 ipi resched 3 */ | |
+ { 0, GDMA_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 14 GDMA */ | |
+ { 0, MAC1_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 15 LAN Giga Switch */ | |
+ { 0, UART2_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 16 uart 2 */ | |
+ { 0, IRQ_RT3XXX_USB - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 17 USB host */ | |
+ { 0, DYINGGASP_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 18 Dying gasp */ | |
+ { 0, DMT_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 19 xDSL DMT */ | |
+ { 0, GIC_EDGE_NMI - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 20 gic edge NMI */ | |
+ { 0, QDMA_LAN0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 21 QDMA LAN 0 */ | |
+ { 0, QDMA_WAN0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 22 QDMA WAN 0 */ | |
+ { 0, PCIE_0_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 23 PCIE port 0 */ | |
+ { 0, PCIE_A_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 24 PCIE port 1 */ | |
+ { 0, PCIE_SERR_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 25 PCIE error */ | |
+ { 0, XPON_MAC_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 26 XPON MAC */ | |
+ { 0, XPON_PHY_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 27 XPON PHY */ | |
+ { 0, CRYPTO_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 28 Crypto engine */ | |
+ { 1, SI_TIMER_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_PERCPU }, /* 29 external CPU timer 1 when bfbf0400[1]=1 */ | |
+ { 0, SI_TIMER_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_PERCPU }, /* 30 external CPU timer 0 when bfbf0400[0]=1 */ | |
+ { 0, BUS_TOUT_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 31 Pbus timeout */ | |
+ { 0, PCM2_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 32 PCM 2 */ | |
+ { 0, FE_ERR_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 33 Frame Engine Error */ | |
+ { 0, IPI_CALL_INT0 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 34 ipi call 0 */ | |
+ { 0, AUTO_MANUAL_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 35 SPI */ | |
+ { 3, SI_TIMER_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_PERCPU }, /* 36 external CPU timer 3 when bfbe0000[1]=1 */ | |
+ { 2, SI_TIMER_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_PERCPU }, /* 37 external CPU timer 2 when bfbe0000[1]=1 */ | |
+ { 0, UART3_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 38 UART3 */ | |
+ { 0, QDMA_LAN1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 39 QDMA LAN 1 */ | |
+ { 0, QDMA_LAN2_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 40 QDMA LAN 2 */ | |
+ { 0, QDMA_LAN3_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 41 QDMA LAN 3 */ | |
+ { 0, QDMA_WAN1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 42 QDMA WAN 1 */ | |
+ { 0, QDMA_WAN2_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 43 QDMA WAN 2 */ | |
+ { 0, QDMA_WAN3_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 44 QDMA WAN 3 */ | |
+ { 0, UART4_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 45 UART 4 */ | |
+ { 0, UART5_INT - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 46 UART 5 */ | |
+ { 0, HSDMA_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 47 High Speed DMA */ | |
+ { 0, USB_HOST_2 - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 48 USB host 2 (port1) */ | |
+ { 0, XSI_MAC_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 49 XFI/HGSMII MAC interface */ | |
+ { 0, XSI_PHY_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 50 XFI/HGSMII PHY interface */ | |
+ { 0, WOE0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 51 WIFI Offload Engine 0 */ | |
+ { 0, WOE1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 52 WIFI Offload Engine 1 */ | |
+ { 0, WDMA0_P0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 53 WIFI DMA 0 port 0 */ | |
+ { 0, WDMA0_P1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 54 WIFI DMA 0 port 1 */ | |
+ { 0, WDMA0_WOE_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 55 WIFI DMA 0 for WOE */ | |
+ { 0, WDMA1_P0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 56 WIFI DMA 1 port 0 */ | |
+ { 0, WDMA1_P1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 56 WIFI DMA 1 port 1 */ | |
+ { 0, WDMA1_WOE_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 58 WIFI DMA 1 for WOE */ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+ { 2, RBUS_TOUT_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 59 rbus timeout interrupt */ | |
+#else | |
+ { 0, EFUSE_ERR0_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 59 efuse error for not setting key */ | |
+#endif | |
+ { 0, EFUSE_ERR1_INTR - 1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, /* 60 efuse error for prev action not finished */ | |
+ { 1, IPI_CALL_INT1 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 61 ipi call 1 */ | |
+ { 2, IPI_CALL_INT2 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 }, /* 62 ipi call 2 */ | |
+ { 3, IPI_CALL_INT3 - 1, GIC_POL_POS, GIC_TRIG_EDGE, 0 } /* 63 ipi call 3 */ | |
+}; | |
+ | |
+#undef X | |
+ | |
+static int get_gic_shared_intr(unsigned int irqNum) | |
+{ | |
+ int intSrc; | |
+ | |
+ for (intSrc = 0; intSrc < GIC_NUM_INTRS; intSrc++) { | |
+ if ((gic_intr_map[intSrc].pin + 1) == irqNum) | |
+ return intSrc; | |
+ } | |
+ | |
+ return -1; | |
+} | |
+ | |
+void tc_disable_irq_all(void) | |
+{ | |
+ unsigned long flags; | |
+ | |
+ if (!gic_present) | |
+ return; | |
+ | |
+ local_irq_save(flags); | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 0x00), 0xffffffff); | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 0x04), 0xffffffff); | |
+ local_irq_restore(flags); | |
+} | |
+ | |
+static irqreturn_t cpu_cm_err_interrupt(int irq, void *dev_id) | |
+{ | |
+ /* clear CM2 error cause */ | |
+ VPint(KSEG1ADDR(RALINK_GCMP_BASE) + 0x0048) = 0; | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static irqreturn_t cpu_cm_pcint_interrupt(int irq, void *dev_id) | |
+{ | |
+ /* clear CM2 Performance Counter Overflow Status Register */ | |
+ VPint(KSEG1ADDR(RALINK_GCMP_BASE) + 0x6120) = 0x7; | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static struct irqaction cpu_cm_err_irqaction = { | |
+ .handler = cpu_cm_err_interrupt, | |
+ .flags = IRQF_NO_THREAD, | |
+ .name = "cpu_cm_err", | |
+}; | |
+ | |
+static struct irqaction cpu_cm_pcint_irqaction = { | |
+ .handler = cpu_cm_pcint_interrupt, | |
+ .flags = IRQF_NO_THREAD, | |
+ .name = "cpu_cm_pcint", | |
+}; | |
+ | |
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | |
+{ | |
+ int i, intSrc; | |
+ | |
+ /* irqVec starts from 1 and ends at 63 */ | |
+ for (i = 1; i < INTR_SOURCES_NUM; i++) | |
+ irq_set_chip(gic_irq_base + i, irq_controller); | |
+ | |
+ /* Initialize IRQ action handlers */ | |
+ for (i = 1; i < INTR_SOURCES_NUM; i++) { | |
+ unsigned int irq; | |
+ | |
+ if (i >= IPI_RESCHED_INT0) | |
+ break; | |
+ | |
+ irq = gic_irq_base + i; | |
+ | |
+ if (i == SI_TIMER_INT) | |
+ irq_set_handler(irq, handle_percpu_devid_irq); | |
+ else if (i == GIC_EDGE_NMI) | |
+ irq_set_handler(irq, handle_edge_irq); | |
+ else | |
+ irq_set_handler(irq, handle_level_irq); | |
+ } | |
+ | |
+ /* bind watchdog Intr to CPU1 */ | |
+ intSrc = get_gic_shared_intr(TIMER5_INT); | |
+ if (intSrc >= 0) | |
+ GIC_SH_MAP_TO_VPE_SMASK(intSrc, 1); | |
+ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+ /* set rbus timeout intr as NMI */ | |
+ intSrc = get_gic_shared_intr(RBUS_TOUT_INTR); | |
+ if (intSrc >= 0) | |
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intSrc)), GIC_MAP_TO_NMI_MSK); | |
+#endif | |
+} | |
+ | |
+void __init arch_init_irq(void) | |
+{ | |
+ phys_addr_t gic_base = RALINK_GIC_BASE; | |
+ | |
+ /* Disable all hardware interrupts */ | |
+ clear_c0_status(ST0_IM); | |
+ clear_c0_cause(CAUSEF_IP); | |
+ | |
+ if (mips_cm_present()) { | |
+ gic_base = read_gcr_gic_base() & ~CM_GCR_GIC_BASE_GICEN_MSK; | |
+ | |
+ write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); | |
+ __sync(); | |
+ } | |
+ | |
+ gic_present = true; | |
+ | |
+ gic_init(gic_base, RALINK_GIC_ADDRSPACE_SZ, gic_intr_map, | |
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | |
+ | |
+ setup_irq(CPU_CM_ERR, &cpu_cm_err_irqaction); | |
+ setup_irq(CPU_CM_PCINT, &cpu_cm_pcint_irqaction); | |
+} | |
+ | |
+asmlinkage void plat_irq_dispatch(void) | |
+{ | |
+ unsigned int irq = (read_c0_cause() & ST0_IM) >> 10; | |
+ | |
+ do_IRQ(irq); | |
+} | |
diff --git a/arch/mips/tc3262/irq.c b/arch/mips/tc3262/irq.c | |
new file mode 100644 | |
index 000000000000..15b9a71f60ef | |
--- /dev/null | |
+++ b/arch/mips/tc3262/irq.c | |
@@ -0,0 +1,306 @@ | |
+/* | |
+ * Interrupt service routines for Trendchip board | |
+ */ | |
+#include <linux/init.h> | |
+#include <linux/slab.h> | |
+#include <linux/types.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/setup.h> | |
+#include <asm/mipsregs.h> | |
+#include <asm/mipsmtregs.h> | |
+ | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#include "irq.h" | |
+ | |
+extern void vsmp_int_init(void); | |
+extern int plat_set_irq_affinity(struct irq_data *d, | |
+ const struct cpumask *affinity, bool force); | |
+ | |
+__IMEM | |
+static inline bool mips_mt_cpu_is_irq0(const struct irq_data *d) | |
+{ | |
+ return d->irq == SI_SWINT_INT0 || d->irq == SI_SWINT1_INT0; | |
+} | |
+ | |
+__IMEM | |
+static inline unsigned long mips_mt_cpu_irq_mask(const struct irq_data *d) | |
+{ | |
+ if (mips_mt_cpu_is_irq0(d)) | |
+ return CAUSEF_IP0; | |
+ | |
+ return CAUSEF_IP1; | |
+} | |
+ | |
+__IMEM | |
+static inline void unmask_mips_mt_irq(struct irq_data *d) | |
+{ | |
+ const unsigned int vpflags = dvpe(); | |
+ | |
+ set_c0_status(mips_mt_cpu_irq_mask(d)); | |
+ irq_enable_hazard(); | |
+ evpe(vpflags); | |
+} | |
+ | |
+__IMEM | |
+static inline void mask_mips_mt_irq(struct irq_data *d) | |
+{ | |
+ const unsigned int vpflags = dvpe(); | |
+ | |
+ clear_c0_status(mips_mt_cpu_irq_mask(d)); | |
+ irq_disable_hazard(); | |
+ evpe(vpflags); | |
+} | |
+ | |
+__IMEM | |
+static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) | |
+{ | |
+ const unsigned int vpflags = dvpe(); | |
+ const unsigned int mask = mips_mt_cpu_irq_mask(d); | |
+ unsigned int reg_imr = VPint(CR_INTC_IMR); | |
+ | |
+ if (mips_mt_cpu_is_irq0(d)) | |
+ reg_imr |= (1u << (SI_SWINT_INT0 - 1)) | | |
+ (1u << (SI_SWINT1_INT0 - 1)); | |
+ else | |
+ reg_imr |= (1u << (SI_SWINT_INT1 - 1)) | | |
+ (1u << (SI_SWINT1_INT1 - 1)); | |
+ | |
+ VPint(CR_INTC_IMR) = reg_imr; | |
+ | |
+ clear_c0_cause(mask); | |
+ set_c0_status(mask); | |
+ irq_enable_hazard(); | |
+ evpe(vpflags); | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* | |
+ * While we ack the interrupt interrupts are disabled and thus we don't need | |
+ * to deal with concurrency issues. Same for mips_cpu_irq_end. | |
+ */ | |
+__IMEM | |
+static void mips_mt_cpu_irq_ack(struct irq_data *d) | |
+{ | |
+ const unsigned int vpflags = dvpe(); | |
+ const unsigned int mask = mips_mt_cpu_irq_mask(d); | |
+ | |
+ clear_c0_cause(mask); | |
+ clear_c0_status(mask); | |
+ irq_disable_hazard(); | |
+ evpe(vpflags); | |
+} | |
+ | |
+static struct irq_chip mips_mt_cpu_irq_controller = { | |
+ .name = "MIPS", | |
+ .irq_startup = mips_mt_cpu_irq_startup, | |
+ .irq_ack = mips_mt_cpu_irq_ack, | |
+ .irq_mask = mask_mips_mt_irq, | |
+ .irq_mask_ack = mips_mt_cpu_irq_ack, | |
+ .irq_unmask = unmask_mips_mt_irq, | |
+ .irq_eoi = unmask_mips_mt_irq, | |
+ .irq_disable = mask_mips_mt_irq, | |
+ .irq_enable = unmask_mips_mt_irq, | |
+}; | |
+ | |
+static DEFINE_SPINLOCK(tc3262_irq_lock); | |
+ | |
+__IMEM | |
+static inline void unmask_mips_irq(struct irq_data *d) | |
+{ | |
+ unsigned long flags; | |
+ unsigned int irq = d->irq; | |
+ | |
+ spin_lock_irqsave(&tc3262_irq_lock, flags); | |
+ | |
+ if (smp_processor_id() != 0 && irq == SI_TIMER_INT) | |
+ irq = SI_TIMER1_INT; | |
+ | |
+ if (irq <= 32) | |
+ VPint(CR_INTC_IMR) |= (1u << (irq - 1)); | |
+ else | |
+ VPint(CR_INTC_IMR_1) |= (1u << (irq - 33)); | |
+ | |
+ spin_unlock_irqrestore(&tc3262_irq_lock, flags); | |
+} | |
+ | |
+__IMEM | |
+static inline void mask_mips_irq(struct irq_data *d) | |
+{ | |
+ unsigned long flags; | |
+ unsigned int irq = d->irq; | |
+ | |
+ spin_lock_irqsave(&tc3262_irq_lock, flags); | |
+ | |
+ if (smp_processor_id() != 0 && irq == SI_TIMER_INT) | |
+ irq = SI_TIMER1_INT; | |
+ | |
+ if (irq <= 32) | |
+ VPint(CR_INTC_IMR) &= ~(1u << (irq - 1)); | |
+ else | |
+ VPint(CR_INTC_IMR_1) &= ~(1u << (irq - 33)); | |
+ | |
+ spin_unlock_irqrestore(&tc3262_irq_lock, flags); | |
+} | |
+ | |
+static struct irq_chip tc3262_irq_chip = { | |
+ .name = "INTC", | |
+ .irq_ack = mask_mips_irq, | |
+ .irq_mask = mask_mips_irq, | |
+ .irq_mask_ack = mask_mips_irq, | |
+ .irq_unmask = unmask_mips_irq, | |
+ .irq_eoi = unmask_mips_irq, | |
+ .irq_disable = mask_mips_irq, | |
+ .irq_enable = unmask_mips_irq, | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ .irq_set_affinity = plat_set_irq_affinity, | |
+#endif | |
+}; | |
+ | |
+#define __BUILD_IRQ_DISPATCH(irq_n) \ | |
+__IMEM \ | |
+static void __tc3262_irq_dispatch##irq_n(void) \ | |
+{ \ | |
+ do_IRQ(irq_n); \ | |
+} | |
+ | |
+#define __BUILD_IRQ_DISPATCH_FUNC(irq_n) __tc3262_irq_dispatch##irq_n | |
+ | |
+/* pre-built 41 irq dispatch function */ | |
+__BUILD_IRQ_DISPATCH(0) | |
+__BUILD_IRQ_DISPATCH(1) | |
+__BUILD_IRQ_DISPATCH(2) | |
+__BUILD_IRQ_DISPATCH(3) | |
+__BUILD_IRQ_DISPATCH(4) | |
+__BUILD_IRQ_DISPATCH(5) | |
+__BUILD_IRQ_DISPATCH(6) | |
+__BUILD_IRQ_DISPATCH(7) | |
+__BUILD_IRQ_DISPATCH(8) | |
+__BUILD_IRQ_DISPATCH(9) | |
+__BUILD_IRQ_DISPATCH(10) | |
+__BUILD_IRQ_DISPATCH(11) | |
+__BUILD_IRQ_DISPATCH(12) | |
+__BUILD_IRQ_DISPATCH(13) | |
+__BUILD_IRQ_DISPATCH(14) | |
+__BUILD_IRQ_DISPATCH(15) | |
+__BUILD_IRQ_DISPATCH(16) | |
+__BUILD_IRQ_DISPATCH(17) | |
+__BUILD_IRQ_DISPATCH(18) | |
+__BUILD_IRQ_DISPATCH(19) | |
+__BUILD_IRQ_DISPATCH(20) | |
+__BUILD_IRQ_DISPATCH(21) | |
+__BUILD_IRQ_DISPATCH(22) | |
+__BUILD_IRQ_DISPATCH(23) | |
+__BUILD_IRQ_DISPATCH(24) | |
+__BUILD_IRQ_DISPATCH(25) | |
+__BUILD_IRQ_DISPATCH(26) | |
+__BUILD_IRQ_DISPATCH(27) | |
+__BUILD_IRQ_DISPATCH(28) | |
+__BUILD_IRQ_DISPATCH(29) | |
+__BUILD_IRQ_DISPATCH(30) | |
+__BUILD_IRQ_DISPATCH(31) | |
+__BUILD_IRQ_DISPATCH(32) | |
+__BUILD_IRQ_DISPATCH(33) | |
+__BUILD_IRQ_DISPATCH(34) | |
+__BUILD_IRQ_DISPATCH(35) | |
+__BUILD_IRQ_DISPATCH(36) | |
+__BUILD_IRQ_DISPATCH(37) | |
+__BUILD_IRQ_DISPATCH(38) | |
+__BUILD_IRQ_DISPATCH(39) | |
+__BUILD_IRQ_DISPATCH(40) | |
+ | |
+/* register pre-built 41 irq dispatch function */ | |
+static void (*irq_dispatch_tab[])(void) = | |
+{ | |
+__BUILD_IRQ_DISPATCH_FUNC(0), | |
+__BUILD_IRQ_DISPATCH_FUNC(1), | |
+__BUILD_IRQ_DISPATCH_FUNC(2), | |
+__BUILD_IRQ_DISPATCH_FUNC(3), | |
+__BUILD_IRQ_DISPATCH_FUNC(4), | |
+__BUILD_IRQ_DISPATCH_FUNC(5), | |
+__BUILD_IRQ_DISPATCH_FUNC(6), | |
+__BUILD_IRQ_DISPATCH_FUNC(7), | |
+__BUILD_IRQ_DISPATCH_FUNC(8), | |
+__BUILD_IRQ_DISPATCH_FUNC(9), | |
+__BUILD_IRQ_DISPATCH_FUNC(10), | |
+__BUILD_IRQ_DISPATCH_FUNC(11), | |
+__BUILD_IRQ_DISPATCH_FUNC(12), | |
+__BUILD_IRQ_DISPATCH_FUNC(13), | |
+__BUILD_IRQ_DISPATCH_FUNC(14), | |
+__BUILD_IRQ_DISPATCH_FUNC(15), | |
+__BUILD_IRQ_DISPATCH_FUNC(16), | |
+__BUILD_IRQ_DISPATCH_FUNC(17), | |
+__BUILD_IRQ_DISPATCH_FUNC(18), | |
+__BUILD_IRQ_DISPATCH_FUNC(19), | |
+__BUILD_IRQ_DISPATCH_FUNC(20), | |
+__BUILD_IRQ_DISPATCH_FUNC(21), | |
+__BUILD_IRQ_DISPATCH_FUNC(22), | |
+__BUILD_IRQ_DISPATCH_FUNC(23), | |
+__BUILD_IRQ_DISPATCH_FUNC(24), | |
+__BUILD_IRQ_DISPATCH_FUNC(25), | |
+__BUILD_IRQ_DISPATCH_FUNC(26), | |
+__BUILD_IRQ_DISPATCH_FUNC(27), | |
+__BUILD_IRQ_DISPATCH_FUNC(28), | |
+__BUILD_IRQ_DISPATCH_FUNC(29), | |
+__BUILD_IRQ_DISPATCH_FUNC(30), | |
+__BUILD_IRQ_DISPATCH_FUNC(31), | |
+__BUILD_IRQ_DISPATCH_FUNC(32), | |
+__BUILD_IRQ_DISPATCH_FUNC(33), | |
+__BUILD_IRQ_DISPATCH_FUNC(34), | |
+__BUILD_IRQ_DISPATCH_FUNC(35), | |
+__BUILD_IRQ_DISPATCH_FUNC(36), | |
+__BUILD_IRQ_DISPATCH_FUNC(37), | |
+__BUILD_IRQ_DISPATCH_FUNC(38), | |
+__BUILD_IRQ_DISPATCH_FUNC(39), | |
+__BUILD_IRQ_DISPATCH_FUNC(40) | |
+}; | |
+ | |
+void tc_disable_irq_all(void) | |
+{ | |
+ unsigned long flags; | |
+ | |
+ spin_lock_irqsave(&tc3262_irq_lock, flags); | |
+ VPint(CR_INTC_IMR) = 0x0; | |
+ VPint(CR_INTC_IMR_1) = 0x0; | |
+ spin_unlock_irqrestore(&tc3262_irq_lock, flags); | |
+} | |
+ | |
+void __init arch_init_irq(void) | |
+{ | |
+ unsigned int i; | |
+ | |
+ /* disable all hardware interrupts */ | |
+ clear_c0_status(ST0_IM); | |
+ clear_c0_cause(CAUSEF_IP); | |
+ | |
+ for (i = 0; i < NR_IRQS; i++) { | |
+ if (i == SI_SWINT_INT0 || i == SI_SWINT1_INT0 || | |
+ i == SI_SWINT_INT1 || i == SI_SWINT1_INT1) { | |
+ irq_set_chip(i, &mips_mt_cpu_irq_controller); | |
+ } else if (i == SI_TIMER_INT || i == SI_TIMER1_INT) | |
+ irq_set_chip_and_handler(i, &tc3262_irq_chip, | |
+ handle_percpu_devid_irq); | |
+ else | |
+ irq_set_chip_and_handler(i, &tc3262_irq_chip, | |
+ handle_level_irq); | |
+ set_vi_handler(i, irq_dispatch_tab[i]); | |
+ } | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ vsmp_int_init(); | |
+#endif | |
+ | |
+ /* enable MIPS IRQ0 and IRQ1 */ | |
+ write_c0_status((read_c0_status() & ~ST0_IM) | | |
+ (STATUSF_IP0 | STATUSF_IP1)); | |
+} | |
+ | |
+__IMEM | |
+asmlinkage void plat_irq_dispatch(void) | |
+{ | |
+ unsigned int irq = (read_c0_cause() & ST0_IM) >> 10; | |
+ | |
+ do_IRQ(irq); | |
+} | |
diff --git a/arch/mips/tc3262/irq.h b/arch/mips/tc3262/irq.h | |
new file mode 100644 | |
index 000000000000..109686797c4c | |
--- /dev/null | |
+++ b/arch/mips/tc3262/irq.h | |
@@ -0,0 +1,6 @@ | |
+#ifndef _TC3262_IRQ_H | |
+#define _TC3262_IRQ_H | |
+ | |
+void tc_disable_irq_all(void); | |
+ | |
+#endif | |
diff --git a/arch/mips/tc3262/malta-amon.c b/arch/mips/tc3262/malta-amon.c | |
new file mode 100644 | |
index 000000000000..24c637b04987 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/malta-amon.c | |
@@ -0,0 +1,88 @@ | |
+/* | |
+ * This file is subject to the terms and conditions of the GNU General Public | |
+ * License. See the file "COPYING" in the main directory of this archive | |
+ * for more details. | |
+ * | |
+ * Copyright (C) 2007 MIPS Technologies, Inc. All rights reserved. | |
+ * Copyright (C) 2013 Imagination Technologies Ltd. | |
+ * | |
+ * Arbitrary Monitor Interface | |
+ */ | |
+#include <linux/kernel.h> | |
+#include <linux/smp.h> | |
+ | |
+#include <asm/addrspace.h> | |
+#include <asm/mipsmtregs.h> | |
+#include <asm/tc3162/launch.h> | |
+#include <asm/vpe.h> | |
+ | |
+int amon_cpu_avail(int cpu) | |
+{ | |
+ struct cpulaunch *launch = (struct cpulaunch *)CPU_LAUNCH_BASE; | |
+ | |
+ if (cpu < 0 || cpu >= NCPULAUNCH) { | |
+ pr_debug("avail: cpu%d is out of range\n", cpu); | |
+ return 0; | |
+ } | |
+ | |
+ launch += cpu; | |
+ if (!(launch->flags & LAUNCH_FREADY)) { | |
+ pr_debug("avail: cpu%d is not ready\n", cpu); | |
+ return 0; | |
+ } | |
+ if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) { | |
+ pr_debug("avail: too late.. cpu%d is already gone\n", cpu); | |
+ return 0; | |
+ } | |
+ | |
+ return 1; | |
+} | |
+ | |
+int amon_cpu_start(int cpu, | |
+ unsigned long pc, unsigned long sp, | |
+ unsigned long gp, unsigned long a0) | |
+{ | |
+ volatile struct cpulaunch *launch = | |
+ (struct cpulaunch *)CPU_LAUNCH_BASE; | |
+ | |
+ if (!amon_cpu_avail(cpu)) | |
+ return -1; | |
+ if (cpu == smp_processor_id()) { | |
+ pr_debug("launch: I am cpu%d!\n", cpu); | |
+ return -1; | |
+ } | |
+ launch += cpu; | |
+ | |
+ pr_debug("launch: starting cpu%d\n", cpu); | |
+ | |
+ launch->pc = pc; | |
+ launch->gp = gp; | |
+ launch->sp = sp; | |
+ launch->a0 = a0; | |
+ | |
+ smp_wmb(); /* Target must see parameters before go */ | |
+ launch->flags |= LAUNCH_FGO; | |
+ smp_wmb(); /* Target must see go before we poll */ | |
+ | |
+ while ((launch->flags & LAUNCH_FGONE) == 0) | |
+ ; | |
+ smp_rmb(); /* Target will be updating flags soon */ | |
+ pr_debug("launch: cpu%d gone!\n", cpu); | |
+ | |
+ return 0; | |
+} | |
+ | |
+#ifdef CONFIG_MIPS_VPE_LOADER_CMP | |
+int vpe_run(struct vpe *v) | |
+{ | |
+ struct vpe_notifications *n; | |
+ | |
+ if (amon_cpu_start(aprp_cpu_index(), v->__start, 0, 0, 0) < 0) | |
+ return -1; | |
+ | |
+ list_for_each_entry(n, &v->notify, list) | |
+ n->start(VPE_MODULE_MINOR); | |
+ | |
+ return 0; | |
+} | |
+#endif | |
diff --git a/arch/mips/tc3262/malta-smp.c b/arch/mips/tc3262/malta-smp.c | |
new file mode 100644 | |
index 000000000000..00f6c9665ed5 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/malta-smp.c | |
@@ -0,0 +1,152 @@ | |
+/* | |
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. | |
+ * Copyright (C) 2001 Ralf Baechle | |
+ * Copyright (C) 2010 PMC-Sierra, Inc. | |
+ * | |
+ * VSMP support for MSP platforms . Derived from malta vsmp support. | |
+ * | |
+ * This program is free software; you can distribute it and/or modify it | |
+ * under the terms of the GNU General Public License (Version 2) as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope it will be useful, but WITHOUT | |
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
+ * for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License along | |
+ * with this program; if not, write to the Free Software Foundation, Inc., | |
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
+ * | |
+ */ | |
+#include <linux/init.h> | |
+#include <linux/smp.h> | |
+#include <linux/sched.h> | |
+#include <linux/interrupt.h> | |
+ | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ | |
+#define MIPS_CPU_IPI_RESCHED_IRQ SI_SWINT_INT0 /* SW int 0 for resched */ | |
+#define MIPS_CPU_IPI_CALL_IRQ SI_SWINT_INT1 /* SW int 1 for call */ | |
+ | |
+static void ipi_resched_dispatch(void) | |
+{ | |
+ do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ); | |
+} | |
+ | |
+static void ipi_call_dispatch(void) | |
+{ | |
+ do_IRQ(MIPS_CPU_IPI_CALL_IRQ); | |
+} | |
+ | |
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | |
+{ | |
+ scheduler_ipi(); | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | |
+{ | |
+ generic_smp_call_function_interrupt(); | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static struct irqaction irq_resched = { | |
+ .handler = ipi_resched_interrupt, | |
+ .flags = IRQF_PERCPU, | |
+ .name = "ipi_resched" | |
+}; | |
+ | |
+static struct irqaction irq_call = { | |
+ .handler = ipi_call_interrupt, | |
+ .flags = IRQF_PERCPU, | |
+ .name = "ipi_call" | |
+}; | |
+ | |
+void __init arch_init_ipiirq(int irq, struct irqaction *action) | |
+{ | |
+ setup_irq(irq, action); | |
+ irq_set_handler(irq, handle_percpu_irq); | |
+} | |
+ | |
+void __init vsmp_int_init(void) | |
+{ | |
+ set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | |
+ set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | |
+ | |
+ arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched); | |
+ arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call); | |
+} | |
+ | |
+/* | |
+ * IRQ affinity hook | |
+ */ | |
+int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, | |
+ bool force) | |
+{ | |
+ cpumask_t tmask; | |
+ int cpu = 0; | |
+ int irq_vpe0 = 0; | |
+ int irq_vpe1 = 0; | |
+ unsigned int offset1, offset2; | |
+ | |
+ /* | |
+ * On the legacy Malta development board, all I/O interrupts | |
+ * are routed through the 8259 and combined in a single signal | |
+ * to the CPU daughterboard, and on the CoreFPGA2/3 34K models, | |
+ * that signal is brought to IP2 of both VPEs. To avoid racing | |
+ * concurrent interrupt service events, IP2 is enabled only on | |
+ * one VPE, by convention VPE0. So long as no bits are ever | |
+ * cleared in the affinity mask, there will never be any | |
+ * interrupt forwarding. But as soon as a program or operator | |
+ * sets affinity for one of the related IRQs, we need to make | |
+ * sure that we don't ever try to forward across the VPE boundry, | |
+ * at least not until we engineer a system where the interrupt | |
+ * _ack() or _end() function can somehow know that it corresponds | |
+ * to an interrupt taken on another VPE, and perform the appropriate | |
+ * restoration of Status.IM state using MFTR/MTTR instead of the | |
+ * normal local behavior. We also ensure that no attempt will | |
+ * be made to forward to an offline "CPU". | |
+ */ | |
+ | |
+ cpumask_copy(&tmask, affinity); | |
+ for_each_cpu(cpu, affinity) { | |
+ if (!cpu_online(cpu)) { | |
+ cpumask_clear_cpu(cpu, &tmask); | |
+ } else { | |
+ if (cpu == 0) | |
+ irq_vpe0++; | |
+ else | |
+ irq_vpe1++; | |
+ } | |
+ } | |
+ | |
+ cpumask_copy(irq_data_get_affinity_mask(d), &tmask); | |
+ | |
+ /* change IRQ binding to VPE0 or VPE1 */ | |
+ offset1 = 32 - d->irq; | |
+ offset2 = ((d->irq - 1) % 4) * 8 + 4; | |
+ offset1 = (offset1 >> 2) << 2; | |
+ if (irq_vpe0 >= irq_vpe1) | |
+ VPint(CR_INTC_IVSR0 + offset1) &= ~(1u << offset2); | |
+ else | |
+ VPint(CR_INTC_IVSR0 + offset1) |= (1u << offset2); | |
+ | |
+ if (cpumask_empty(&tmask)) { | |
+ /* | |
+ * We could restore a default mask here, but the | |
+ * runtime code can anyway deal with the null set | |
+ */ | |
+ printk(KERN_WARNING | |
+ "IRQ affinity leaves no legal CPU for IRQ %d\n", d->irq); | |
+ } | |
+ | |
+ return IRQ_SET_MASK_OK_NOCOPY; | |
+} | |
+ | |
+#endif /* CONFIG_MIPS_MT_SMP */ | |
+ | |
diff --git a/arch/mips/tc3262/pci_en75xx.c b/arch/mips/tc3262/pci_en75xx.c | |
new file mode 100644 | |
index 000000000000..598d08546e3d | |
--- /dev/null | |
+++ b/arch/mips/tc3262/pci_en75xx.c | |
@@ -0,0 +1,643 @@ | |
+#include <linux/types.h> | |
+#include <linux/pci.h> | |
+#include <linux/kernel.h> | |
+#include <linux/version.h> | |
+#include <linux/init.h> | |
+#include <linux/mod_devicetable.h> | |
+#include <linux/slab.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/pci.h> | |
+#include <asm/io.h> | |
+#include <asm/irq.h> | |
+ | |
+#ifdef CONFIG_PCI | |
+#include <asm/tc3162/rt_mmap.h> | |
+#include <asm/tc3162/surfboardint.h> | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#define ECONET_RSTCTRL_REG (RALINK_SYSCTL_BASE + 0x834) | |
+#define ECONET_PCIEC_REG (RALINK_SYSCTL_BASE + 0x088) | |
+ | |
+#define ECONET_PCIE_ERR_IRQ_EN (RALINK_PCI_BASE + 0x0040) | |
+#define ECONET_PCIE_LINKUP (RALINK_PCI_BASE + 0x0050) | |
+#define ECONET_PCIE0_MAC_BASE (RALINK_PCI_BASE + 0x1000) | |
+#define ECONET_PCIE1_MAC_BASE (RALINK_PCI_BASE + 0x3000) | |
+ | |
+#define ECONET_PCI_MM_MAP_BASE 0x20000000 | |
+#define ECONET_PCI_IO_MAP_BASE 0x1F600000 | |
+ | |
+static int pcie_link_status; | |
+static DEFINE_SPINLOCK(asic_pcr_lock); | |
+ | |
+static u32 en75xx_get_rc_port(u32 busn, u32 slot) | |
+{ | |
+ u32 rc = 2; | |
+ | |
+ if (busn == 0 && slot < 2) | |
+ rc = slot; | |
+ else if (busn == 1 && slot == 0 && (pcie_link_status & 0x1)) | |
+ rc = 0; | |
+ else if (busn == 2 && slot == 0 && (pcie_link_status & 0x2)) | |
+ rc = 1; | |
+ | |
+ return rc; | |
+} | |
+ | |
+static int | |
+en75xx_write_config_word(u32 busn, u32 slot, u32 func, u32 reg, u32 value) | |
+{ | |
+ u32 val, rc, mac_offset; | |
+ | |
+ rc = en75xx_get_rc_port(busn, slot); | |
+ if (rc == 0) | |
+ mac_offset = ECONET_PCIE0_MAC_BASE; | |
+ else if (rc == 1) | |
+ mac_offset = ECONET_PCIE1_MAC_BASE; | |
+ else | |
+ return -1; | |
+ | |
+ /* fmt=2 | type=4 | length=1 */ | |
+ val = (2 << 29) | (4 << 24) | 1; | |
+ | |
+ /* write TLP header offset 0..3 */ | |
+ sysRegWrite(mac_offset + 0x0460, val); | |
+ | |
+ /* write requester ID */ | |
+ val = (rc << 19) | 0x070f; | |
+ | |
+ /* write TLP header offset 4..7 */ | |
+ sysRegWrite(mac_offset + 0x0464, val); | |
+ | |
+ val = (busn << 24) | (slot << 19) | (func << 16) | (reg & 0xffc); | |
+ | |
+ /* write TLP header offset 8..11 */ | |
+ sysRegWrite(mac_offset + 0x0468, val); | |
+ | |
+ /* write TLP data */ | |
+ sysRegWrite(mac_offset + 0x0470, value); | |
+ | |
+ /* start TLP request */ | |
+ sysRegWrite(mac_offset + 0x0488, 0x1); | |
+ | |
+ udelay(10); | |
+ | |
+ /* polling TLP request status (max 10ms) */ | |
+ val = 1000; | |
+ while ((val--) > 0) { | |
+ /* TLP request finished or timeout */ | |
+ if ((sysRegRead(mac_offset + 0x0488) & 0x1) == 0) | |
+ break; | |
+ udelay(10); | |
+ } | |
+ | |
+ if (val == 0) { | |
+ printk(KERN_ERR "PCR %s err: bus = %d, dev = %d, func = %d, reg = 0x%08X\n", | |
+ "write", busn, slot, func, reg); | |
+ return -1; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+static u32 | |
+en75xx_read_config_word(u32 busn, u32 slot, u32 func, u32 reg) | |
+{ | |
+ u32 val, rc, mac_offset; | |
+ | |
+ rc = en75xx_get_rc_port(busn, slot); | |
+ if (rc == 0) | |
+ mac_offset = ECONET_PCIE0_MAC_BASE; | |
+ else if (rc == 1) | |
+ mac_offset = ECONET_PCIE1_MAC_BASE; | |
+ else | |
+ return 0xffffffff; | |
+ | |
+ /* initialize the data reg */ | |
+ sysRegWrite(mac_offset + 0x048c, 0xffffffff); | |
+ | |
+ /* fmt=0 | type=4 | length=1 */ | |
+ val = (4 << 24) | 1; | |
+ | |
+ /* write TLP header offset 0..3 */ | |
+ sysRegWrite(mac_offset + 0x0460, val); | |
+ | |
+ /* write requester ID */ | |
+ val = (rc << 19) | 0x070f; | |
+ | |
+ /* write TLP header offset 4..7 */ | |
+ sysRegWrite(mac_offset + 0x0464, val); | |
+ | |
+ val = (busn << 24) | (slot << 19) | (func << 16) | (reg & 0xffc); | |
+ | |
+ /* write TLP header offset 8..11 */ | |
+ sysRegWrite(mac_offset + 0x0468, val); | |
+ | |
+ /* start TLP requuest */ | |
+ sysRegWrite(mac_offset + 0x0488, 0x1); | |
+ | |
+ udelay(10); | |
+ | |
+ /* polling TLP request status (max 10ms) */ | |
+ val = 1000; | |
+ while ((val--) > 0) { | |
+ /* TLP request finished or timeout */ | |
+ if ((sysRegRead(mac_offset + 0x0488) & 0x1) == 0) | |
+ break; | |
+ udelay(10); | |
+ } | |
+ | |
+ if (val == 0) { | |
+ printk(KERN_ERR "PCR %s err: bus = %d, dev = %d, func = %d, reg = 0x%08X\n", | |
+ "read", busn, slot, func, reg); | |
+ return 0xffffffff; | |
+ } | |
+ | |
+ /* return the data from data reg */ | |
+ return sysRegRead(mac_offset + 0x048c); | |
+} | |
+ | |
+static int | |
+en75xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) | |
+{ | |
+ u32 busn = bus->number; | |
+ u32 slot = PCI_SLOT(devfn); | |
+ u32 func = PCI_FUNC(devfn); | |
+ u32 shift, reg, tmp; | |
+ unsigned long flags; | |
+ | |
+ reg = (u32)where; | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ | |
+ tmp = en75xx_read_config_word(busn, slot, func, reg); | |
+ | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+ | |
+ switch (size) { | |
+ case 1: | |
+ shift = (reg & 0x3) << 3; | |
+ *val = (tmp >> shift) & 0xff; | |
+ break; | |
+ case 2: | |
+ shift = (reg & 0x2) << 3; | |
+ *val = (tmp >> shift) & 0xffff; | |
+ break; | |
+ default: | |
+ *val = tmp; | |
+ break; | |
+ } | |
+ | |
+ return PCIBIOS_SUCCESSFUL; | |
+} | |
+ | |
+static int | |
+en75xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) | |
+{ | |
+ u32 busn = bus->number; | |
+ u32 slot = PCI_SLOT(devfn); | |
+ u32 func = PCI_FUNC(devfn); | |
+ u32 shift, reg, tmp; | |
+ unsigned long flags; | |
+ | |
+ reg = (u32)where; | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ | |
+ switch (size) { | |
+ case 1: | |
+ tmp = en75xx_read_config_word(busn, slot, func, reg); | |
+ shift = (reg & 0x3) << 3; | |
+ tmp &= ~(0xff << shift); | |
+ tmp |= ((val & 0xff) << shift); | |
+ break; | |
+ case 2: | |
+ tmp = en75xx_read_config_word(busn, slot, func, reg); | |
+ shift = (reg & 0x2) << 3; | |
+ tmp &= ~(0xffff << shift); | |
+ tmp |= ((val & 0xffff) << shift); | |
+ break; | |
+ default: | |
+ tmp = val; | |
+ break; | |
+ } | |
+ | |
+ en75xx_write_config_word(busn, slot, func, reg, tmp); | |
+ | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+ | |
+ return PCIBIOS_SUCCESSFUL; | |
+} | |
+ | |
+/* | |
+ * General-purpose PCI functions. | |
+ */ | |
+ | |
+struct pci_ops en75xx_pci_ops = { | |
+ .read = en75xx_pci_config_read, | |
+ .write = en75xx_pci_config_write, | |
+}; | |
+ | |
+static struct resource en75xx_res_pci_mem1 = { | |
+ .name = "PCI MEM1", | |
+ .start = ECONET_PCI_MM_MAP_BASE, | |
+ .end = ECONET_PCI_MM_MAP_BASE + 0x0fffffff, | |
+ .flags = IORESOURCE_MEM, | |
+}; | |
+ | |
+static struct resource en75xx_res_pci_io1 = { | |
+ .name = "PCI I/O1", | |
+ .start = ECONET_PCI_IO_MAP_BASE, | |
+ .end = ECONET_PCI_IO_MAP_BASE + 0xffff, | |
+ .flags = IORESOURCE_IO, | |
+}; | |
+ | |
+struct pci_controller en75xx_pci_controller = { | |
+ .pci_ops = &en75xx_pci_ops, | |
+ .mem_resource = &en75xx_res_pci_mem1, | |
+ .io_resource = &en75xx_res_pci_io1, | |
+ .mem_offset = 0x00000000UL, | |
+ .io_offset = 0x00000000UL, | |
+}; | |
+ | |
+#if defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) || \ | |
+ defined(CONFIG_PCIE_PORT1) | |
+static u32 en75xx_pcie_get_pos(u32 busn, u32 slot) | |
+{ | |
+ u32 val, pos; | |
+ | |
+ val = en75xx_read_config_word(busn, slot, 0, 0x34); | |
+ pos = val & 0xff; | |
+ | |
+ while (pos && pos != 0xff) { | |
+ val = en75xx_read_config_word(busn, slot, 0, pos); | |
+ if ((val & 0xff) == 0x10) | |
+ return pos; | |
+ | |
+ pos = (val >> 0x08) & 0xff; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#endif | |
+ | |
+static inline void en75xx_pcie_rc0_retrain(void) | |
+{ | |
+#if defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) | |
+ u32 pos, ppos; | |
+ u32 linkcap, plinkcap, plinksta[2]; | |
+ unsigned long flags; | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ | |
+ ppos = en75xx_pcie_get_pos(0, 0); | |
+ pos = en75xx_pcie_get_pos(1, 0); | |
+ | |
+ if (pos < 0x40 || ppos < 0x40) | |
+ goto exit_unlock; | |
+ | |
+ plinkcap = en75xx_read_config_word(0, 0, 0, ppos + 0x0c); | |
+ linkcap = en75xx_read_config_word(1, 0, 0, pos + 0x0c); | |
+ | |
+ if ((linkcap & 0x0f) == 1 || (plinkcap & 0x0f) == 1) | |
+ goto exit_unlock; | |
+ | |
+ plinksta[0] = en75xx_read_config_word(0, 0, 0, ppos + 0x10); | |
+ if (((plinksta[0] >> 16) & 0x0f) == (plinkcap & 0x0f)) | |
+ goto exit_unlock; | |
+ | |
+ /* train link Gen1 -> Gen2 */ | |
+ plinksta[0] = en75xx_read_config_word(0, 0, 0, ppos + 0x10); | |
+ plinksta[0] |= 0x20; | |
+ en75xx_write_config_word(0, 0, 0, ppos + 0x10, plinksta[0]); | |
+ | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+ | |
+ msleep(250); | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ plinksta[1] = en75xx_read_config_word(0, 0, 0, ppos + 0x10); | |
+ | |
+ printk(KERN_INFO "PCIe RC0 link trained: %x -> %x\n", | |
+ ((plinksta[0] >> 16) & 0x0f), ((plinksta[1] >> 16) & 0x0f)); | |
+ | |
+exit_unlock: | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+#endif | |
+} | |
+ | |
+#ifdef CONFIG_PCIE_PORT1 | |
+static inline void en75xx_pcie_rc1_retrain(void) | |
+{ | |
+ u32 pos, ppos; | |
+ u32 linkcap, plinkcap, plinksta[2]; | |
+ unsigned long flags; | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ | |
+ ppos = en75xx_pcie_get_pos(0, 1); | |
+ pos = en75xx_pcie_get_pos(2, 0); | |
+ | |
+ if (pos < 0x40 || ppos < 0x40) | |
+ goto exit_unlock; | |
+ | |
+ plinkcap = en75xx_read_config_word(0, 1, 0, ppos + 0x0c); | |
+ linkcap = en75xx_read_config_word(2, 0, 0, pos + 0x0c); | |
+ | |
+ if ((linkcap & 0x0f) == 1 || (plinkcap & 0x0f) == 1) | |
+ goto exit_unlock; | |
+ | |
+ plinksta[0] = en75xx_read_config_word(0, 1, 0, ppos + 0x10); | |
+ if (((plinksta[0] >> 16) & 0x0f) == (plinkcap & 0x0f)) | |
+ goto exit_unlock; | |
+ | |
+ /* train link Gen1 -> Gen2 */ | |
+ plinksta[0] = en75xx_read_config_word(0, 1, 0, ppos + 0x10); | |
+ plinksta[0] |= 0x20; | |
+ en75xx_write_config_word(0, 1, 0, ppos + 0x10, plinksta[0]); | |
+ | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+ | |
+ msleep(250); | |
+ | |
+ spin_lock_irqsave(&asic_pcr_lock, flags); | |
+ plinksta[1] = en75xx_read_config_word(0, 1, 0, ppos + 0x10); | |
+ | |
+ printk(KERN_INFO "PCIe RC1 link trained: %x -> %x\n", | |
+ ((plinksta[0] >> 16) & 0x0f), ((plinksta[1] >> 16) & 0x0f)); | |
+ | |
+exit_unlock: | |
+ spin_unlock_irqrestore(&asic_pcr_lock, flags); | |
+} | |
+#endif | |
+ | |
+int pcibios_plat_dev_init(struct pci_dev *dev) | |
+{ | |
+ u32 busn = dev->bus->number; | |
+ u32 slot = PCI_SLOT(dev->devfn); | |
+ u32 i, val, tmp; | |
+ | |
+ /* P2P bridge */ | |
+ if (busn == 0) { | |
+ /* set CLS */ | |
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, | |
+ (L1_CACHE_BYTES >> 2)); | |
+ } | |
+ | |
+ if (busn == 0 && slot == 0 && (pcie_link_status & 0x1)) { | |
+ val = 0; | |
+ pci_read_config_dword(dev, 0x20, &val); | |
+ tmp = (val & 0xffff) << 16; | |
+ val = (val & 0xffff0000) + 0x100000; | |
+ val = val - tmp; | |
+ | |
+ i = 0; | |
+ while (i < 32) { | |
+ if ((1u << i) >= val) | |
+ break; | |
+ i++; | |
+ } | |
+ | |
+ /* config RC0 to EP addr window */ | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE + 0x438, tmp | i); | |
+ mdelay(1); | |
+ | |
+ /* enable EP to RC0 access */ | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE + 0x448, 0x80); | |
+ | |
+ en75xx_pcie_rc0_retrain(); | |
+ } | |
+ | |
+#ifdef CONFIG_PCIE_PORT1 | |
+ if (busn == 0 && slot == 1 && (pcie_link_status & 0x2)) { | |
+ val = 0; | |
+ pci_read_config_dword(dev, 0x20, &val); | |
+ tmp = (val & 0xffff) << 16; | |
+ val = (val & 0xffff0000) + 0x100000; | |
+ val = val - tmp; | |
+ | |
+ i = 0; | |
+ while (i < 32) { | |
+ if ((1 << i) >= val) | |
+ break; | |
+ i++; | |
+ } | |
+ | |
+ /* config RC1 to EP addr window */ | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE + 0x438, tmp | i); | |
+ mdelay(1); | |
+ | |
+ /* enable EP to RC1 access */ | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE + 0x448, 0x80); | |
+ | |
+ en75xx_pcie_rc1_retrain(); | |
+ } | |
+#endif | |
+ | |
+ return 0; | |
+} | |
+ | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+{ | |
+ int pci_irq = 0; | |
+ | |
+ if (slot == 0x0) | |
+ pci_irq = SURFBOARDINT_PCIE0; | |
+ else if (slot == 0x1) | |
+ pci_irq = SURFBOARDINT_PCIE1; | |
+ | |
+ return pci_irq; | |
+} | |
+ | |
+static inline void en75xx_pcie_init_phy(void) | |
+{ | |
+ u32 __maybe_unused reg_val; | |
+ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+ | |
+ /* LCDDS_CLK_PH_INV */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY0_BASE + 0x04a0); | |
+ reg_val |= (0x1 << 5); | |
+ sysRegWrite(RALINK_PCI_PHY0_BASE + 0x04a0, reg_val); | |
+ mdelay(1); | |
+ | |
+ /* Patch TxDetRx Timing for 7512 E1, from DR 20160421, Biker_20160516 */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY1_BASE + 0x0a28); | |
+ reg_val &= ~(0x1ff << 9); | |
+ reg_val |= (0x010 << 9); | |
+ sysRegWrite(RALINK_PCI_PHY1_BASE + 0x0a28, reg_val); | |
+ mdelay(1); | |
+ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY1_BASE + 0x0a2c); | |
+ reg_val &= ~0x1ff; | |
+ reg_val |= 0x010; | |
+ sysRegWrite(RALINK_PCI_PHY1_BASE + 0x0a2c, reg_val); | |
+ mdelay(1); | |
+ | |
+#ifdef CONFIG_PCIE_PORT1 | |
+ if (isEN7512) | |
+#endif | |
+ { | |
+ /* disable gen2 port PHY for COC test */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY1_BASE + 0x030c); | |
+ reg_val |= (1u << 31); /* IP_SW_RESET */ | |
+ sysRegWrite(RALINK_PCI_PHY1_BASE + 0x030c, reg_val); | |
+ mdelay(1); | |
+ } | |
+ | |
+#elif defined(CONFIG_ECONET_EN7528) | |
+ | |
+ /* LCDDS_CLK_PH_INV */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY0_BASE + 0x04a0); | |
+ reg_val |= (0x1 << 5); | |
+ sysRegWrite(RALINK_PCI_PHY0_BASE + 0x04a0, reg_val); | |
+ mdelay(1); | |
+ | |
+ /* combo phy Rx R FT mean value too high, tune target R -5 Ohm */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY1_BASE + 0x0b2c); | |
+ reg_val &= ~(0x3 << 12); | |
+ reg_val |= (0x1 << 12); | |
+ sysRegWrite(RALINK_PCI_PHY1_BASE + 0x0b2c, reg_val); | |
+ mdelay(1); | |
+ | |
+#endif | |
+} | |
+ | |
+int __init init_en75xx_pci(void) | |
+{ | |
+ u32 i, reg_val; | |
+ | |
+ /* reset PCIe devices by pulse low */ | |
+ reg_val = sysRegRead(ECONET_PCIEC_REG); | |
+ reg_val &= ~((1 << 29) | (1 << 26)); | |
+ sysRegWrite(ECONET_PCIEC_REG, reg_val); | |
+ mdelay(1); | |
+ | |
+ en75xx_pcie_init_phy(); | |
+ | |
+ /* enabled PCIe RC1 clock */ | |
+ reg_val = sysRegRead(ECONET_PCIEC_REG); | |
+ reg_val |= (1 << 22); | |
+ sysRegWrite(ECONET_PCIEC_REG, reg_val); | |
+ mdelay(1); | |
+ | |
+ /* de-assert PCIe RC0/RC1/HB reset signal */ | |
+ reg_val = sysRegRead(ECONET_RSTCTRL_REG); | |
+ reg_val &= ~(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIEHB_RST); | |
+ sysRegWrite(ECONET_RSTCTRL_REG, reg_val); | |
+ mdelay(1); | |
+ | |
+ /* assert PCIe RC0/RC1/HB reset signal */ | |
+ reg_val |= (RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIEHB_RST); | |
+ sysRegWrite(ECONET_RSTCTRL_REG, reg_val); | |
+ mdelay(100); | |
+ | |
+ /* de-assert PCIe RC0/RC1/HB reset signal */ | |
+ reg_val &= ~(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIEHB_RST); | |
+ sysRegWrite(ECONET_RSTCTRL_REG, reg_val); | |
+ mdelay(10); | |
+ | |
+ /* release PCIe devices reset */ | |
+ reg_val = sysRegRead(ECONET_PCIEC_REG); | |
+ reg_val |= ((1 << 29) | (1 << 26)); | |
+ sysRegWrite(ECONET_PCIEC_REG, reg_val); | |
+ | |
+ /* wait before detect card in slots */ | |
+ mdelay(250); | |
+ for (i = 0; i < 20; i++) { | |
+ pcie_link_status = (sysRegRead(ECONET_PCIE_LINKUP) >> 1) & 0x3; | |
+ | |
+ if ((pcie_link_status & 0x1) | |
+#ifdef CONFIG_PCIE_PORT1 | |
+ && (pcie_link_status & 0x2) | |
+#endif | |
+ ) | |
+ break; | |
+ msleep(20); | |
+ } | |
+ | |
+ if ((pcie_link_status & 0x1) == 0) { | |
+ printk(KERN_WARNING "PCIe RC%d no card, disable PHY\n", 0); | |
+ | |
+ /* disable gen1 port PHY */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY0_BASE); | |
+ reg_val &= ~(1 << 5); /* rg_pe1_phy_en */ | |
+ reg_val |= (1 << 4); /* rg_pe1_frc_phy_en */ | |
+ sysRegWrite(RALINK_PCI_PHY0_BASE, reg_val); | |
+ mdelay(1); | |
+ } | |
+ | |
+#ifdef CONFIG_PCIE_PORT1 | |
+ if ((pcie_link_status & 0x2) == 0) { | |
+ printk(KERN_WARNING "PCIe RC%d no card, disable PHY\n", 1); | |
+ | |
+ /* disable gen2 port PHY */ | |
+ reg_val = sysRegRead(RALINK_PCI_PHY1_BASE + 0x030c); | |
+ reg_val |= (1u << 31); /* IP_SW_RESET */ | |
+ sysRegWrite(RALINK_PCI_PHY1_BASE + 0x030c, reg_val); | |
+ mdelay(1); | |
+ } | |
+#endif | |
+ | |
+ if (!pcie_link_status) | |
+ return 0; | |
+ | |
+ /* change class to pci-pci class */ | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE + 0x104, 0x06040001); | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE + 0x104, 0x06040001); | |
+ mdelay(1); | |
+ | |
+ /* set host mode */ | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE, 0x00804201); | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE, 0x00804201); | |
+ mdelay(1); | |
+ | |
+ /* disable MSI interrupt */ | |
+ reg_val = sysRegRead(ECONET_PCIE0_MAC_BASE + 0x11c); | |
+ reg_val &= ~(1 << 5); | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE + 0x11c, reg_val); | |
+ | |
+ reg_val = sysRegRead(ECONET_PCIE1_MAC_BASE + 0x11c); | |
+ reg_val &= ~(1 << 5); | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE + 0x11c, reg_val); | |
+ | |
+ /* setup PCIe port0 MAC */ | |
+ if (pcie_link_status & 0x1) { | |
+ /* enable interrupt */ | |
+ reg_val = sysRegRead(ECONET_PCIE0_MAC_BASE + 0x420); | |
+ reg_val &= ~(1 << 16); | |
+ sysRegWrite(ECONET_PCIE0_MAC_BASE + 0x420, reg_val); | |
+ | |
+ /* enable error interrupt */ | |
+ reg_val = sysRegRead(ECONET_PCIE_ERR_IRQ_EN); | |
+ reg_val |= 0x03; | |
+ sysRegWrite(ECONET_PCIE_ERR_IRQ_EN, reg_val); | |
+ } | |
+ | |
+#ifdef CONFIG_PCIE_PORT1 | |
+ /* setup PCIe port1 MAC */ | |
+ if (pcie_link_status & 0x2) { | |
+ /* enable interrupt */ | |
+ reg_val = sysRegRead(ECONET_PCIE1_MAC_BASE + 0x420); | |
+ reg_val &= ~(1 << 16); | |
+ sysRegWrite(ECONET_PCIE1_MAC_BASE + 0x420, reg_val); | |
+ | |
+ /* enable error interrupt */ | |
+ reg_val = sysRegRead(ECONET_PCIE_ERR_IRQ_EN); | |
+ reg_val |= (0x03 << 2); | |
+ sysRegWrite(ECONET_PCIE_ERR_IRQ_EN, reg_val); | |
+ } | |
+#endif | |
+ | |
+ en75xx_pci_controller.io_map_base = mips_io_port_base; | |
+ | |
+ register_pci_controller(&en75xx_pci_controller); | |
+ | |
+ return 0; | |
+} | |
+ | |
+arch_initcall(init_en75xx_pci); | |
+ | |
+#endif /* CONFIG_PCI */ | |
diff --git a/arch/mips/tc3262/printf.c b/arch/mips/tc3262/printf.c | |
new file mode 100644 | |
index 000000000000..e941d01d26c4 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/printf.c | |
@@ -0,0 +1,47 @@ | |
+#include <linux/init.h> | |
+#include <linux/kernel.h> | |
+#include <linux/spinlock.h> | |
+#include <asm/io.h> | |
+ | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+static char ppbuf[1024]; | |
+ | |
+void prom_putchar(char data) | |
+{ | |
+ while (!(LSR_INDICATOR & LSR_THRE)) | |
+ ; | |
+ VPchar(CR_UART_THR) = data; | |
+} | |
+ | |
+char prom_getchar(void) | |
+{ | |
+ while (!(LSR_INDICATOR & LSR_RECEIVED_DATA_READY)) | |
+ ; | |
+ return VPchar(CR_UART_RBR); | |
+} | |
+ | |
+static void uart_write_buf(const char *buf, unsigned int n) | |
+{ | |
+ char ch; | |
+ | |
+ while (n != 0) { | |
+ --n; | |
+ if ((ch = *buf++) == '\n') | |
+ prom_putchar('\r'); | |
+ prom_putchar(ch); | |
+ } | |
+} | |
+ | |
+void prom_printf(const char *fmt, ...) | |
+{ | |
+ va_list args; | |
+ int i; | |
+ | |
+ va_start(args, fmt); | |
+ i = vscnprintf(ppbuf, sizeof(ppbuf), fmt, args); | |
+ va_end(args); | |
+ | |
+ uart_write_buf(ppbuf, i); | |
+} | |
+EXPORT_SYMBOL(prom_printf); | |
diff --git a/arch/mips/tc3262/prom.c b/arch/mips/tc3262/prom.c | |
new file mode 100644 | |
index 000000000000..78220aa30acb | |
--- /dev/null | |
+++ b/arch/mips/tc3262/prom.c | |
@@ -0,0 +1,432 @@ | |
+#include <linux/init.h> | |
+#include <linux/module.h> | |
+#include <linux/string.h> | |
+#include <linux/kernel.h> | |
+#include <linux/delay.h> | |
+#include <asm/bootinfo.h> | |
+#include <asm/cacheflush.h> | |
+#include <asm/traps.h> | |
+#include <asm/io.h> | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+#include <asm/smp-ops.h> | |
+#include <asm/mips-cm.h> | |
+#include <asm/mips-cpc.h> | |
+#include <asm/tc3162/launch.h> | |
+#endif | |
+ | |
+#include <asm/tc3162/prom.h> | |
+#include <asm/tc3162/rt_mmap.h> | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+unsigned int surfboard_sysclk; | |
+unsigned int tc_mips_cpu_freq; | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+int prom_argc; | |
+int *_prom_argv, *_prom_envp; | |
+ | |
+/* | |
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | |
+ * This macro take care of sign extension, if running in 64-bit mode. | |
+ */ | |
+#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)])) | |
+#endif | |
+ | |
+char *prom_getenv(char *envname) | |
+{ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+ /* | |
+ * Return a pointer to the given environment variable. | |
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers | |
+ * in the PROM structures are only 32-bit, so we need some | |
+ * workarounds, if we are running in 64-bit mode. | |
+ */ | |
+ int i, index=0; | |
+ char *p, *q; | |
+ | |
+ i = strlen(envname); | |
+ while (prom_envp(index)) { | |
+ p = (char*) KSEG0ADDR(prom_envp(index)); | |
+ if(!strncmp(envname, p, i)) { | |
+ q = strchr(p, '='); | |
+ if (q) | |
+ q++; | |
+ return q; | |
+ } | |
+ index++; | |
+ } | |
+#endif | |
+ return NULL; | |
+} | |
+ | |
+const char *get_system_type(void) | |
+{ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+ if (isEN7561DU) | |
+ return "EcoNet EN7561DU SoC"; | |
+ if (isEN7528DU) | |
+ return "EcoNet EN7528DU SoC"; | |
+ if (isEN7528) | |
+ return "EcoNet EN7528 SoC"; | |
+#endif | |
+#ifdef CONFIG_ECONET_EN7527 | |
+ if (isEN7561G) | |
+ return "EcoNet EN7561G SoC"; | |
+ if (isEN7527G) | |
+ return "EcoNet EN7527G SoC"; | |
+ if (isEN7527H) | |
+ return "EcoNet EN7527H SoC"; | |
+#endif | |
+#ifdef CONFIG_ECONET_EN7516 | |
+ if (isEN7516G) | |
+ return "EcoNet EN7516G SoC"; | |
+#endif | |
+#ifdef CONFIG_ECONET_EN7512 | |
+ if (isEN7513G) | |
+ return "EcoNet EN7513G SoC"; | |
+ if (isEN7513) | |
+ return "EcoNet EN7513 SoC"; | |
+ if (isEN7512) | |
+ return "EcoNet EN7512 SoC"; | |
+#endif | |
+ return "EcoNet SoC"; | |
+} | |
+ | |
+static inline void prom_show_pstat(void) | |
+{ | |
+ unsigned long status; | |
+ const char *const s = prom_getenv("pstat"); | |
+ | |
+ if (!s) | |
+ return; | |
+ | |
+ status = simple_strtoul(s, NULL, 0); | |
+ | |
+ switch (status) { | |
+ default: | |
+ pr_err("SoC power status: unknown (%08lx)\n", status); | |
+ break; | |
+ case 3: | |
+ pr_warn("SoC power status: hardware watchdog reset\n"); | |
+ break; | |
+ case 2: | |
+ pr_info("SoC power status: software reset\n"); | |
+ break; | |
+ case 1: | |
+ pr_info("SoC power status: power-on reset\n"); | |
+ break; | |
+ } | |
+} | |
+ | |
+static inline void tc_mips_setup(void) | |
+{ | |
+#ifdef CONFIG_MIPS_TC3262_34K | |
+ /* enable 34K external sync */ | |
+#ifndef CONFIG_SMP | |
+ unsigned int oconfig7 = read_c0_config7(); | |
+ unsigned int nconfig7 = oconfig7; | |
+ | |
+ nconfig7 |= (1 << 8); | |
+ if (oconfig7 != nconfig7) { | |
+ __asm__ __volatile("sync"); | |
+ write_c0_config7(nconfig7); | |
+ } | |
+#else | |
+ strcat(arcs_cmdline, " es=1"); | |
+#endif | |
+#endif | |
+} | |
+ | |
+#if defined(CONFIG_MIPS_CMP) || \ | |
+ defined(CONFIG_MIPS_CPS) | |
+phys_addr_t mips_cpc_default_phys_base(void) | |
+{ | |
+ return RALINK_CPC_BASE; | |
+} | |
+ | |
+static inline void prom_init_cm(void) | |
+{ | |
+ /* early detection of CMP support */ | |
+ mips_cm_probe(); | |
+ mips_cpc_probe(); | |
+ | |
+#ifdef CONFIG_MIPS_MT_SMP | |
+ if (register_cps_smp_ops() == 0) | |
+ return; | |
+ if (register_cmp_smp_ops() == 0) | |
+ return; | |
+ if (register_vsmp_smp_ops() == 0) | |
+ return; | |
+#endif | |
+} | |
+ | |
+bool plat_cpu_core_present(int core) | |
+{ | |
+ struct cpulaunch *launch = (struct cpulaunch *)CPU_LAUNCH_BASE; | |
+ | |
+ if (!core) | |
+ return true; | |
+ | |
+ launch += core * 2; /* 2 VPEs per core */ | |
+ if (!(launch->flags & LAUNCH_FREADY)) | |
+ return false; | |
+ | |
+ if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE)) | |
+ return false; | |
+ | |
+ return true; | |
+} | |
+#endif | |
+ | |
+static inline void tc_uart_setup(void) | |
+{ | |
+ unsigned int div_x, div_y, word; | |
+ | |
+ /* Set FIFO controo enable, reset RFIFO, TFIFO, 16550 mode, watermark=0x00 (1 byte) */ | |
+ VPchar(CR_HSUART_FCR) = UART_FCR | UART_WATERMARK; | |
+ | |
+ /* Set modem control to 0 */ | |
+ VPchar(CR_HSUART_MCR) = UART_MCR; | |
+ | |
+ /* Disable IRDA, Disable Power Saving Mode, RTS , CTS flow control */ | |
+ VPchar(CR_HSUART_MISCC) = UART_MISCC; | |
+ | |
+ /* Access the baudrate divider */ | |
+ VPchar(CR_HSUART_LCR) = UART_BRD_ACCESS; | |
+ | |
+ div_y = UART_XYD_Y; | |
+#if defined(CONFIG_RT2880_UART_115200) | |
+ div_x = 59904; // Baud rate 115200 | |
+#else | |
+ div_x = 29952; // Baud rate 57600 | |
+#endif | |
+ word = (div_x << 16) | div_y; | |
+ VPint(CR_HSUART_XYD) = word; | |
+ | |
+ /* Set Baud Rate Divisor to 1*16 */ | |
+ VPchar(CR_HSUART_BRDL) = UART_BRDL_20M; | |
+ VPchar(CR_HSUART_BRDH) = UART_BRDH_20M; | |
+ | |
+ /* Set DLAB = 0, clength = 8, stop = 1, no parity check */ | |
+ VPchar(CR_HSUART_LCR) = UART_LCR; | |
+} | |
+ | |
+static inline void tc_ahb_setup(void) | |
+{ | |
+ /* setup bus timeout value */ | |
+ VPint(CR_AHB_AACS) = 0xffff; | |
+} | |
+ | |
+static inline void tc_usb_setup(void) | |
+{ | |
+#if !IS_ENABLED(CONFIG_USB) | |
+ /* disable both ports UPHY */ | |
+ VPint(RALINK_USB_UPHY_P0_BASE + 0x1c) = 0xC0241580; | |
+ VPint(RALINK_USB_UPHY_P1_BASE + 0x1c) = 0xC0241580; | |
+ | |
+ /* assert USB host reset */ | |
+ VPint(CR_AHB_BASE + 0x834) |= (1U << 22); | |
+#endif | |
+} | |
+ | |
+static inline void tc_dmt_setup(void) | |
+{ | |
+ /* assert DMT reset */ | |
+ VPint(CR_AHB_DMTCR) = 0x1; | |
+ | |
+#if !defined(CONFIG_TC3162_ADSL) && \ | |
+ !defined(CONFIG_RALINK_VDSL) | |
+ udelay(100); | |
+ | |
+ /* disable DMT clock to power save */ | |
+ VPint(CR_AHB_DMTCR) = 0x3; | |
+#endif | |
+ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+ /* Power down SIMLDO */ | |
+ VPint(0xBFA20168) |= (1 << 8); | |
+#endif | |
+ | |
+ /* assert PON PHY reset */ | |
+ VPint(CR_AHB_BASE + 0x830) |= (1U << 0); | |
+ | |
+ /* assert PON MAC reset */ | |
+ VPint(CR_AHB_BASE + 0x834) |= (1U << 31); | |
+} | |
+ | |
+static inline void tc_pcm_setup(void) | |
+{ | |
+ /* assert PCM/ZSI/ICI reset */ | |
+ VPint(CR_AHB_BASE + 0x834) |= (1U << 0) | (1U << 4) | (1U << 17); | |
+ | |
+ /* assert SFC2 reset */ | |
+ VPint(CR_AHB_BASE + 0x834) |= (1U << 25); | |
+} | |
+ | |
+static inline void tc_fe_setup(void) | |
+{ | |
+ unsigned int reg_val; | |
+ | |
+ reg_val = VPint(CR_AHB_BASE + 0x834); | |
+ | |
+ /* check GSW not in reset state */ | |
+ if (!(reg_val & (1U << 23))) { | |
+ /* disable GSW P6 link */ | |
+ VPint(RALINK_ETH_SW_BASE + 0x3600) = 0x8000; | |
+ } | |
+ | |
+ /* assert FE, QDMA2, QDMA1 reset */ | |
+ reg_val |= ((1U << 21) | (1U << 2) | (1U << 1)); | |
+ VPint(CR_AHB_BASE + 0x834) = reg_val; | |
+ udelay(100); | |
+ | |
+ /* de-assert FE, QDMA2, QDMA1 reset */ | |
+ reg_val &= ~((1U << 21) | (1U << 2) | (1U << 1)); | |
+ VPint(CR_AHB_BASE + 0x834) = reg_val; | |
+} | |
+ | |
+#define VECTORSPACING 0x100 /* for EI/VI mode */ | |
+ | |
+void __init mips_nmi_setup(void) | |
+{ | |
+ void *base; | |
+ extern char except_vec_nmi; | |
+ | |
+ base = cpu_has_veic ? | |
+ (void *)(ebase + 0x200 + VECTORSPACING * 64) : | |
+ (void *)(ebase + 0x380); | |
+ | |
+ pr_info("NMI base is %08x\n", (unsigned int)base); | |
+ | |
+ /* | |
+ * Fill the NMI_Handler address in a register, which is a R/W register | |
+ * start.S will read it, then jump to NMI_Handler address | |
+ */ | |
+ VPint(0xbfb00244) = (unsigned int)base; | |
+ | |
+ memcpy(base, &except_vec_nmi, 0x80); | |
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | |
+} | |
+ | |
+static inline void cpu_dma_round_robin(int mode) | |
+{ | |
+ unsigned int reg_arb; | |
+ | |
+ reg_arb = VPint(ARB_CFG); | |
+ | |
+ if (mode == ENABLE) | |
+ reg_arb |= ROUND_ROBIN_ENABLE; | |
+ else | |
+ reg_arb &= ROUND_ROBIN_DISABLE; | |
+ | |
+ VPint(ARB_CFG) = reg_arb; | |
+} | |
+ | |
+void __init prom_init(void) | |
+{ | |
+ unsigned long memsize, memresv, memregn, memoffs, memhigh = 0; | |
+ unsigned int bus_freq, cpu_freq, cpu_ratio; | |
+ const char *ram_type; | |
+ | |
+ /* Test supported hardware */ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+ if (!isEN751221) | |
+#elif defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) | |
+ if (!isEN751627) | |
+#elif defined(CONFIG_ECONET_EN7528) | |
+ if (!isEN7528) | |
+#endif | |
+ BUG(); | |
+ | |
+#ifdef CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER | |
+ prom_argc = fw_arg0; | |
+ _prom_argv = (int*) fw_arg1; | |
+ _prom_envp = (int*) fw_arg2; | |
+#endif | |
+ | |
+ set_io_port_base(KSEG1); | |
+ | |
+ prom_init_cmdline(); | |
+ | |
+ tc_mips_setup(); | |
+ tc_uart_setup(); | |
+ tc_ahb_setup(); | |
+ tc_usb_setup(); | |
+ tc_dmt_setup(); | |
+ tc_pcm_setup(); | |
+ tc_fe_setup(); | |
+ | |
+ ram_type = (VPint(CR_DMC_BASE + 0xE4) & (1 << 7)) ? "DDR3" : "DDR2"; | |
+ memsize = (GET_DRAM_SIZE) << 20; | |
+ cpu_ratio = 4; | |
+ | |
+ memresv = 0; | |
+#if defined(CONFIG_TC3262_HWFQ_MAP_4M) | |
+ memresv = 4 << 20; | |
+#elif defined(CONFIG_TC3262_HWFQ_MAP_8M) | |
+ memresv = 8 << 20; | |
+#elif defined(CONFIG_TC3262_HWFQ_MAP_16M) | |
+ memresv = 16 << 20; | |
+#endif | |
+ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+ memoffs = 0x20000; | |
+#else | |
+ memoffs = 0x02000; | |
+#endif | |
+ | |
+ if (memsize > EN75XX_PALMBUS_START) { | |
+ memhigh = memsize - EN75XX_PALMBUS_START; | |
+ memsize = EN75XX_PALMBUS_START; | |
+ } | |
+ | |
+ /* 1. Initial reserved region. */ | |
+ if (memoffs != 0) | |
+ add_memory_region(0, memoffs, BOOT_MEM_RESERVED); | |
+ | |
+ /* 2. Normal region. */ | |
+ memregn = memsize - memoffs - memresv; | |
+ add_memory_region(memoffs, memregn, BOOT_MEM_RAM); | |
+ | |
+ /* 3. HWQ reserved region. */ | |
+ if (memresv != 0) | |
+ add_memory_region(memoffs + memregn, memresv, | |
+ BOOT_MEM_RESERVED); | |
+ | |
+#ifdef CONFIG_HIGHMEM | |
+ /* 4. Highmem region. */ | |
+ if (memhigh != 0) | |
+ add_memory_region(EN75XX_HIGHMEM_START, memhigh, | |
+ BOOT_MEM_RAM); | |
+#endif | |
+ | |
+ bus_freq = SYS_HCLK; | |
+ cpu_freq = bus_freq * cpu_ratio; | |
+ if (cpu_freq % 2) | |
+ cpu_freq += 1; | |
+ | |
+ surfboard_sysclk = bus_freq * 1000 * 1000; | |
+ tc_mips_cpu_freq = cpu_freq * 1000 * 1000; | |
+ | |
+ pr_info("%s: RAM: %s %i MB\n", | |
+ get_system_type(), ram_type, GET_DRAM_SIZE); | |
+ pr_info("CPU/SYS frequency: %u/%u MHz\n", cpu_freq, bus_freq); | |
+ | |
+ board_nmi_handler_setup = mips_nmi_setup; | |
+ cpu_dma_round_robin(ENABLE); | |
+ | |
+#if defined(CONFIG_MIPS_CMP) || \ | |
+ defined(CONFIG_MIPS_CPS) | |
+ prom_init_cm(); | |
+#elif defined(CONFIG_MIPS_MT_SMP) | |
+ register_vsmp_smp_ops(); | |
+#endif | |
+ prom_show_pstat(); | |
+} | |
+ | |
+void __init prom_free_prom_memory(void) | |
+{ | |
+ /* We do not have any memory to free */ | |
+} | |
diff --git a/arch/mips/tc3262/setup.c b/arch/mips/tc3262/setup.c | |
new file mode 100644 | |
index 000000000000..85e5981dfbf9 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/setup.c | |
@@ -0,0 +1,134 @@ | |
+#include <linux/init.h> | |
+#include <linux/string.h> | |
+#include <linux/ioport.h> | |
+#include <linux/delay.h> | |
+#include <asm/cpu.h> | |
+#include <asm/cpu-info.h> | |
+#include <asm/bootinfo.h> | |
+ | |
+#include <asm/time.h> | |
+#include <asm/reboot.h> | |
+#include <asm/pbus-timer.h> | |
+ | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#include "irq.h" | |
+ | |
+#if defined(CONFIG_TC3162_ADSL) || \ | |
+ defined(CONFIG_RALINK_VDSL) | |
+struct sk_buff; | |
+ | |
+#define ADSL_SET_DMT_CLOSE (0x001a) | |
+ | |
+typedef struct { | |
+ void (*query)(unsigned short query_id, void *result1, void *result2); | |
+ void (*set)(unsigned short set_id, void *value1, void *value2); | |
+ | |
+ void (*rts_rcv)(struct sk_buff *skb); | |
+ | |
+ int (*rts_cmd)(int argc,char *argv[],void *p); | |
+ int (*dmt_cmd)(int argc,char *argv[],void *p); | |
+ int (*dmt2_cmd)(int argc,char *argv[],void *p); | |
+ int (*hw_cmd)(int argc,char *argv[],void *p); | |
+ int (*sw_cmd)(int argc,char *argv[],void *p); | |
+ int (*ghs_cmd)(int argc,char *argv[],void *p); | |
+ int (*tcif_cmd)(int argc,char *argv[],void *p); | |
+} adsldev_ops; | |
+ | |
+adsldev_ops *adsl_dev_ops = NULL; | |
+EXPORT_SYMBOL(adsl_dev_ops); | |
+ | |
+static inline void stop_dsl_dmt(void) | |
+{ | |
+ if (adsl_dev_ops) | |
+ adsl_dev_ops->set(ADSL_SET_DMT_CLOSE, NULL, NULL); | |
+} | |
+#else | |
+static inline void stop_dsl_dmt(void) {} | |
+#endif | |
+ | |
+static inline void hw_uninit(void) | |
+{ | |
+ /* stop the DMT module */ | |
+ stop_dsl_dmt(); | |
+ | |
+ /* stop each module dma task */ | |
+ tc_disable_irq_all(); | |
+ | |
+#if !defined(CONFIG_ECONET_EN7528) | |
+ /* stop atm sar dma */ | |
+ TSARM_GFR &= ~((1 << 1) | (1 << 0)); | |
+#endif | |
+ | |
+ /* stop all APB module timers except an active watchdog */ | |
+ pbus_timer_disable(PBUS_TIMER_0); | |
+ pbus_timer_disable(PBUS_TIMER_1); | |
+ pbus_timer_disable(PBUS_TIMER_2); | |
+ | |
+ /* timer 3 is in a non-watchdog mode */ | |
+ if (!(pbus_timer_r32(PBUS_TIMER_CTRL) & PBUS_TIMER_CTRL_WDG_ENABLE)) | |
+ pbus_timer_disable(PBUS_TIMER_3); | |
+} | |
+ | |
+static void hw_reset(bool do_reboot) | |
+{ | |
+ hw_uninit(); | |
+ | |
+ if (do_reboot) { | |
+ /* system software reset */ | |
+ VPint(CR_AHB_RSTCR) |= (1U << 31); | |
+ } | |
+} | |
+ | |
+static void tc_machine_restart(char *command) | |
+{ | |
+ pr_warn("Machine restart...\n"); | |
+ hw_reset(true); | |
+} | |
+ | |
+static void tc_machine_halt(void) | |
+{ | |
+ pr_warn("Machine halted...\n"); | |
+ hw_reset(false); | |
+} | |
+ | |
+static void tc_machine_power_off(void) | |
+{ | |
+ pr_warn("Machine poweroff...\n"); | |
+ hw_reset(false); | |
+} | |
+ | |
+static int tc_panic_event(struct notifier_block *nb, | |
+ unsigned long action, void *data) | |
+{ | |
+ if (action == PANIC_ACTION_RESTART) | |
+ tc_machine_restart(NULL); | |
+ else | |
+ tc_machine_halt(); | |
+ | |
+ return NOTIFY_DONE; | |
+} | |
+ | |
+static struct notifier_block tc_panic_block = { | |
+ .notifier_call = tc_panic_event, | |
+}; | |
+ | |
+static void tc_reboot_setup(void) | |
+{ | |
+ _machine_restart = tc_machine_restart; | |
+ _machine_halt = tc_machine_halt; | |
+ pm_power_off = tc_machine_power_off; | |
+ | |
+ atomic_notifier_chain_register(&panic_notifier_list, &tc_panic_block); | |
+} | |
+ | |
+void __init plat_mem_setup(void) | |
+{ | |
+ iomem_resource.start = 0; | |
+ iomem_resource.end = ~0; | |
+ | |
+ ioport_resource.start = 0; | |
+ ioport_resource.end = 0x1fffffff; | |
+ | |
+ tc_reboot_setup(); | |
+} | |
diff --git a/arch/mips/tc3262/time.c b/arch/mips/tc3262/time.c | |
new file mode 100644 | |
index 000000000000..d6a20dc295c5 | |
--- /dev/null | |
+++ b/arch/mips/tc3262/time.c | |
@@ -0,0 +1,94 @@ | |
+#include <linux/init.h> | |
+#include <linux/types.h> | |
+#include <linux/module.h> | |
+#include <linux/interrupt.h> | |
+#include <asm/time.h> | |
+#include <asm/pbus-timer.h> | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+extern unsigned int surfboard_sysclk; | |
+extern unsigned int tc_mips_cpu_freq; | |
+ | |
+static irqreturn_t tc_bus_timeout_interrupt(int irq, void *dev_id) | |
+{ | |
+ /* clear an interrupt */ | |
+ VPint(CR_PRATIR) = 1; | |
+ | |
+ pr_warn("bus timeout interrupt, error address is %08lx\n", | |
+ VPint(CR_ERR_ADDR) & 0x3fffffff); | |
+ | |
+ dump_stack(); | |
+ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+irqreturn_t rbus_timeout_interrupt(int irq, void *dev_id) | |
+{ | |
+ /* | |
+ * no chance to run this ISR because rbus timeout interrupt | |
+ * will be set as NMI | |
+ */ | |
+ return IRQ_HANDLED; | |
+} | |
+ | |
+static struct irqaction rbus_timeout_irqaction = { | |
+ .handler = rbus_timeout_interrupt, | |
+ .flags = IRQF_NO_THREAD, | |
+ .name = "rbus timeout", | |
+}; | |
+#endif | |
+ | |
+static struct irqaction tc_bus_timeout_irqaction = { | |
+ .handler = tc_bus_timeout_interrupt, | |
+ .flags = IRQF_NO_THREAD, | |
+ .name = "bus timeout", | |
+}; | |
+ | |
+void __init __weak plat_hpt_init(void) | |
+{ | |
+} | |
+ | |
+void __init plat_time_init(void) | |
+{ | |
+ mips_hpt_frequency = tc_mips_cpu_freq / 2; | |
+ | |
+ /* enable a CPU external timer */ | |
+ plat_hpt_init(); | |
+ | |
+#if defined(CONFIG_TC3162_ADSL) || \ | |
+ defined(CONFIG_RALINK_VDSL) | |
+ /* | |
+ * Configure first timer to 10 ms. periodic infinite mode. | |
+ * The active timer used in the DMT module | |
+ * to implement a microsecond delay function. | |
+ */ | |
+ pbus_timer_enable(PBUS_TIMER_1, 10, PBUS_TIMER_MODE_PERIODIC); | |
+#endif | |
+ | |
+ /* setup a bus timeout interrupt */ | |
+ setup_irq(BUS_TOUT_INT, &tc_bus_timeout_irqaction); | |
+ | |
+#ifdef CONFIG_ECONET_EN7528 | |
+ setup_irq(RBUS_TOUT_INTR, &rbus_timeout_irqaction); | |
+ | |
+ /* ASIC bus_clk: 235MHz */ | |
+ VPint(CR_MON_TMR) = 0x10000000; /* unit: one bus clock */ | |
+ VPint(CR_MON_TMR) = 0x50000000; /* enable it */ | |
+ | |
+ /* enable rbus timeout mechanism */ | |
+ regWrite32(RBUS_TIMEOUT_CFG0, 0x3ffffff); | |
+ regWrite32(RBUS_TIMEOUT_CFG1, 0x3ffffff); | |
+ regWrite32(RBUS_TIMEOUT_CFG2, 0x3ffffff); | |
+ regWrite32(RBUS_TIMEOUT_STS0, 0x80000000); | |
+#else | |
+ VPint(CR_MON_TMR) = 0xcfffffff; | |
+ VPint(CR_BUSTIMEOUT_SWITCH) = 0xffffffff; | |
+#endif | |
+} | |
+ | |
+unsigned int get_surfboard_sysclk(void) | |
+{ | |
+ return surfboard_sysclk; | |
+} | |
+EXPORT_SYMBOL(get_surfboard_sysclk); | |
diff --git a/arch/mips/tc3262/uphy.c b/arch/mips/tc3262/uphy.c | |
new file mode 100644 | |
index 000000000000..a5c1daf29c8e | |
--- /dev/null | |
+++ b/arch/mips/tc3262/uphy.c | |
@@ -0,0 +1,287 @@ | |
+#include <linux/version.h> | |
+#include <linux/module.h> | |
+#include <linux/types.h> | |
+#include <linux/kernel.h> | |
+#include <linux/init.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <asm/tc3162/rt_mmap.h> | |
+#include <asm/tc3162/tc3162.h> | |
+ | |
+#define ADDR_SIFSLV_BASE RALINK_XHCI_UPHY_BASE | |
+#define ADDR_SIFSLV_FMREG_BASE (ADDR_SIFSLV_BASE + 0x0100) | |
+#define ADDR_SIFSLV_PHYD_BASE (ADDR_SIFSLV_BASE + 0x0900) | |
+#define ADDR_SIFSLV_PHYD_B2_BASE (ADDR_SIFSLV_BASE + 0x0a00) | |
+#define ADDR_SIFSLV_PHYA_BASE (ADDR_SIFSLV_BASE + 0x0b00) | |
+#define ADDR_SIFSLV_PHYA_DA_BASE (ADDR_SIFSLV_BASE + 0x0c00) | |
+ | |
+#define ADDR_U2_PHY_P0_BASE RALINK_USB_UPHY_P0_BASE | |
+#define ADDR_U2_PHY_P1_BASE RALINK_USB_UPHY_P1_BASE | |
+ | |
+#define U2_SR_COEFF 28 | |
+#define REF_CK 20 | |
+ | |
+#define REG_SIFSLV_FMREG_FMCR0 (ADDR_SIFSLV_FMREG_BASE + 0x00) | |
+#define REG_SIFSLV_FMREG_FMCR1 (ADDR_SIFSLV_FMREG_BASE + 0x04) | |
+#define REG_SIFSLV_FMREG_FMCR2 (ADDR_SIFSLV_FMREG_BASE + 0x08) | |
+#define REG_SIFSLV_FMREG_FMMONR0 (ADDR_SIFSLV_FMREG_BASE + 0x0C) | |
+#define REG_SIFSLV_FMREG_FMMONR1 (ADDR_SIFSLV_FMREG_BASE + 0x10) | |
+ | |
+/* SIFSLV_FMREG_FMCR0 */ | |
+#define RG_LOCKTH (0xf << 28) | |
+#define RG_MONCLK_SEL (0x3 << 26) | |
+#define RG_FM_MODE (0x1 << 25) | |
+#define RG_FREQDET_EN (0x1 << 24) | |
+#define RG_CYCLECNT (0x00ffffff) | |
+ | |
+/* SIFSLV_FMREG_FMMONR1 */ | |
+#define RG_MONCLK_SEL_3 (0x1 << 9) | |
+#define RG_FRCK_EN (0x1 << 8) | |
+#define USBPLL_LOCK (0x1 << 1) | |
+#define USB_FM_VLD (0x1 << 0) | |
+ | |
+#define OFS_U2_PHY_AC0 0x00 | |
+#define OFS_U2_PHY_AC1 0x04 | |
+#define OFS_U2_PHY_AC2 0x08 | |
+#define OFS_U2_PHY_ACR0 0x10 | |
+#define OFS_U2_PHY_ACR1 0x14 | |
+#define OFS_U2_PHY_ACR2 0x18 | |
+#define OFS_U2_PHY_ACR3 0x1C | |
+#define OFS_U2_PHY_ACR4 0x20 | |
+#define OFS_U2_PHY_AMON0 0x24 | |
+#define OFS_U2_PHY_DCR0 0x60 | |
+#define OFS_U2_PHY_DCR1 0x64 | |
+#define OFS_U2_PHY_DTM0 0x68 | |
+#define OFS_U2_PHY_DTM1 0x6C | |
+ | |
+/* U2_PHY_ACR0 */ | |
+#define RG_USB20_ICUSB_EN (0x1 << 24) | |
+#define RG_USB20_HSTX_SRCAL_EN (0x1 << 23) | |
+#define RG_USB20_HSTX_SRCTRL (0x7 << 16) | |
+#define RG_USB20_LS_CR (0x7 << 12) | |
+#define RG_USB20_FS_CR (0x7 << 8) | |
+#define RG_USB20_LS_SR (0x7 << 4) | |
+#define RG_USB20_FS_SR (0x7 << 0) | |
+ | |
+static atomic_t uphy_init_instance = ATOMIC_INIT(0); | |
+ | |
+static inline u32 | |
+uphy_read32(u32 reg_addr) | |
+{ | |
+ return sysRegRead(reg_addr); | |
+} | |
+ | |
+static inline void | |
+uphy_write32(u32 reg_addr, u32 reg_data) | |
+{ | |
+ sysRegWrite(reg_addr, reg_data); | |
+} | |
+ | |
+static void | |
+uphy_write8(u32 reg_addr, u32 reg_data) | |
+{ | |
+ u32 reg_sfl = (reg_addr % 4) * 8; | |
+ u32 reg_a32 = reg_addr & 0xfffffffc; | |
+ u32 reg_msk = 0xff << reg_sfl; | |
+ u32 reg_tmp = uphy_read32(reg_a32); | |
+ | |
+ reg_tmp &= ~reg_msk; | |
+ reg_tmp |= ((reg_data << reg_sfl) & reg_msk); | |
+ | |
+ uphy_write32(reg_a32, reg_tmp); | |
+} | |
+ | |
+static void | |
+u2_slew_rate_calibration(int port_id, u32 u2_phy_reg_base) | |
+{ | |
+ u32 reg_val, i; | |
+ u32 u4Tmp, u4FmOut = 0; | |
+ | |
+ /* enable HS TX SR calibration */ | |
+ reg_val = uphy_read32(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val |= RG_USB20_HSTX_SRCAL_EN; | |
+ uphy_write32(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+ msleep(1); | |
+ | |
+ /* enable free run clock */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMMONR1); | |
+ reg_val |= RG_FRCK_EN; | |
+ uphy_write32(REG_SIFSLV_FMREG_FMMONR1, reg_val); | |
+ | |
+ /* setting MONCLK_SEL 0x0/0x1 for port0/port1 */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val &= ~RG_MONCLK_SEL; | |
+ reg_val |= (port_id << 26); | |
+ uphy_write32(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ /* setting cyclecnt = 400 */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val &= ~RG_CYCLECNT; | |
+ reg_val |= 0x400; | |
+ uphy_write32(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ /* enable frequency meter */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val |= RG_FREQDET_EN; | |
+ uphy_write32(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ /* wait for FM detection done, set 10ms timeout */ | |
+ for (i = 0; i < 10; i++) { | |
+ /* read FM_OUT */ | |
+ u4FmOut = uphy_read32(REG_SIFSLV_FMREG_FMMONR0); | |
+ | |
+ /* check if FM detection done */ | |
+ if (u4FmOut != 0) | |
+ break; | |
+ | |
+ msleep(1); | |
+ } | |
+ | |
+ /* disable frequency meter */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMCR0); | |
+ reg_val &= ~RG_FREQDET_EN; | |
+ uphy_write32(REG_SIFSLV_FMREG_FMCR0, reg_val); | |
+ | |
+ /* disable free run clock */ | |
+ reg_val = uphy_read32(REG_SIFSLV_FMREG_FMMONR1); | |
+ reg_val &= ~RG_FRCK_EN; | |
+ uphy_write32(REG_SIFSLV_FMREG_FMMONR1, reg_val); | |
+ | |
+ /* disable HS TX SR calibration */ | |
+ reg_val = uphy_read32(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val &= ~RG_USB20_HSTX_SRCAL_EN; | |
+ uphy_write32(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+ msleep(1); | |
+ | |
+ /* update RG_USB20_HSTX_SRCTRL */ | |
+ reg_val = uphy_read32(u2_phy_reg_base + OFS_U2_PHY_ACR0); | |
+ reg_val &= ~RG_USB20_HSTX_SRCTRL; | |
+ if (u4FmOut != 0) { | |
+ /* set reg = (1024/FM_OUT) * 20 * 0.028 (round to the nearest digits) */ | |
+ u4Tmp = (((1024 * REF_CK * U2_SR_COEFF) / u4FmOut) + 500) / 1000; | |
+ reg_val |= ((u4Tmp & 0x07) << 16); | |
+ printk(KERN_INFO "U2PHY P%d set SRCTRL %s value: %d\n", port_id, "calibration", u4Tmp); | |
+ } else { | |
+ reg_val |= (0x4 << 16); | |
+ printk(KERN_INFO "U2PHY P%d set SRCTRL %s value: %d\n", port_id, "default", 4); | |
+ } | |
+ uphy_write32(u2_phy_reg_base + OFS_U2_PHY_ACR0, reg_val); | |
+} | |
+ | |
+static inline void | |
+u2_phy_init(u32 u2_phy_reg_base) | |
+{ | |
+ u32 reg_val; | |
+ | |
+ /* set SW PLL Stable mode to 1 for U2 LPM device remote wakeup */ | |
+ reg_val = uphy_read32(u2_phy_reg_base + OFS_U2_PHY_DCR1); | |
+ reg_val &= ~(0x3 << 18); | |
+ reg_val |= (0x1 << 18); | |
+ uphy_write32(u2_phy_reg_base + OFS_U2_PHY_DCR1, reg_val); | |
+} | |
+ | |
+static inline void | |
+uphy_setup_25mhz_xtal(void) | |
+{ | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1c, 0x18); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1d, 0x18); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x1f, 0x18); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x24, 0x18000000); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x28, 0x18000000); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x30, 0x18000000); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_DA_BASE + 0x38, 0x004a004a); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x3e, 0x4a); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x3f, 0x0); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x42, 0x48); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x43, 0x0); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x44, 0x48); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x45, 0x0); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x48, 0x48); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_DA_BASE + 0x49, 0x0); | |
+ | |
+ uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x24, 0x90); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x25, 0x1); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_BASE + 0x10, 0x1c000000); | |
+ uphy_write8(ADDR_SIFSLV_PHYA_BASE + 0x0b, 0xe); | |
+} | |
+ | |
+void uphy_init(void) | |
+{ | |
+ u32 reg_val; | |
+ | |
+ if (atomic_inc_return(&uphy_init_instance) != 1) | |
+ return; | |
+ | |
+#if defined(CONFIG_ECONET_EN7512) | |
+ | |
+ /* patch TxDetRx Timing for E1, from DR 20160421, Biker_20160516 */ | |
+ reg_val = uphy_read32(ADDR_SIFSLV_PHYD_B2_BASE + 0x28); | |
+ reg_val &= ~(0x1ff << 9); | |
+ reg_val |= (0x010 << 9); | |
+ uphy_write32(ADDR_SIFSLV_PHYD_B2_BASE + 0x28, reg_val); | |
+ | |
+ reg_val = uphy_read32(ADDR_SIFSLV_PHYD_B2_BASE + 0x2c); | |
+ reg_val &= ~0x1ff; | |
+ reg_val |= 0x010; | |
+ uphy_write32(ADDR_SIFSLV_PHYD_B2_BASE + 0x2c, reg_val); | |
+ | |
+ /* patch LFPS Filter Threshold for E1, from DR 20160421, Biker_20160516 */ | |
+ reg_val = uphy_read32(ADDR_SIFSLV_PHYD_BASE + 0x0c); | |
+ reg_val &= ~(0x3f << 16); | |
+ reg_val |= (0x34 << 16); | |
+ uphy_write32(ADDR_SIFSLV_PHYD_BASE + 0x0c, reg_val); | |
+ | |
+ /* configure for XTAL 25MHz */ | |
+ if (VPint(CR_AHB_HWCONF) & 0x01) | |
+ uphy_setup_25mhz_xtal(); | |
+ | |
+ if (isEN7513 || isEN7513G) { | |
+ printk(KERN_INFO "%s USB PHY config\n", "EN7513 (BGA)"); | |
+ | |
+ uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0240008); /* enable port 0 */ | |
+ uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */ | |
+ } else if (isEN7512) { | |
+ printk(KERN_INFO "%s USB PHY config\n", "EN7512 (QFP)"); | |
+ | |
+ uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0241580); /* disable port 0 */ | |
+ uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */ | |
+ } | |
+ | |
+#elif defined(CONFIG_ECONET_EN7516) || \ | |
+ defined(CONFIG_ECONET_EN7527) | |
+ | |
+ /* configure for XTAL 25MHz */ | |
+ reg_val = VPint(CR_AHB_HWCONF); | |
+ if (!(reg_val & 0x40000)) | |
+ uphy_setup_25mhz_xtal(); | |
+ | |
+ uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0240008); /* enable port 0 */ | |
+ uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */ | |
+ | |
+ printk(KERN_INFO "%s USB PHY config\n", "EN7516/EN7527"); | |
+ | |
+#elif defined(CONFIG_ECONET_EN7528) | |
+ | |
+ uphy_write32(ADDR_U2_PHY_P0_BASE + 0x1c, 0xC0240000); /* enable port 0 */ | |
+ uphy_write32(ADDR_U2_PHY_P1_BASE + 0x1c, 0xC0240000); /* enable port 1 */ | |
+ | |
+ /* combo phy Rx R FT mean value too high, tune target R -5 Ohm */ | |
+ reg_val = uphy_read32(ADDR_SIFSLV_PHYA_BASE + 0x2c); | |
+ reg_val &= ~(0x3 << 12); | |
+ reg_val |= (0x1 << 12); | |
+ uphy_write32(ADDR_SIFSLV_PHYA_BASE + 0x2c, reg_val); | |
+ | |
+ printk(KERN_INFO "%s USB PHY config\n", "EN7528"); | |
+ | |
+#endif | |
+ | |
+#if !defined(CONFIG_ECONET_EN7528) | |
+ /* init UPHY */ | |
+ u2_phy_init(ADDR_U2_PHY_P0_BASE); | |
+ u2_phy_init(ADDR_U2_PHY_P1_BASE); | |
+#endif | |
+ | |
+ /* calibrate UPHY */ | |
+ u2_slew_rate_calibration(0, ADDR_U2_PHY_P0_BASE); | |
+ u2_slew_rate_calibration(1, ADDR_U2_PHY_P1_BASE); | |
+} | |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c | |
index 285d84e5c7b9..1c4f0604f48c 100644 | |
--- a/arch/mips/txx9/generic/pci.c | |
+++ b/arch/mips/txx9/generic/pci.c | |
@@ -388,9 +388,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |
return 0; | |
} | |
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
+static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); | |
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |
{ | |
- return txx9_board_vec->pci_map_irq(dev, slot, pin); | |
+ return txx9_pci_map_irq(dev, slot, pin); | |
} | |
char * (*txx9_board_pcibios_setup)(char *str) __initdata; | |
@@ -426,5 +427,8 @@ char *__init txx9_pcibios_setup(char *str) | |
txx9_pci_err_action = TXX9_PCI_ERR_IGNORE; | |
return NULL; | |
} | |
+ | |
+ txx9_pci_map_irq = txx9_board_vec->pci_map_irq; | |
+ | |
return str; | |
} | |
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile | |
index adfaee2dce34..f5b74c52cfe4 100644 | |
--- a/arch/mips/vdso/Makefile | |
+++ b/arch/mips/vdso/Makefile | |
@@ -44,6 +44,7 @@ VDSO_LDFLAGS := \ | |
$(call cc-ldoption, -Wl$(comma)--build-id) | |
GCOV_PROFILE := n | |
+UBSAN_SANITIZE := n | |
# | |
# Shared build commands. | |
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr | |
deleted file mode 100644 | |
index 862d74808236..000000000000 | |
--- a/arch/sh/boot/compressed/vmlinux.scr | |
+++ /dev/null | |
@@ -1,10 +0,0 @@ | |
-SECTIONS | |
-{ | |
- .rodata..compressed : { | |
- input_len = .; | |
- LONG(input_data_end - input_data) input_data = .; | |
- *(.data) | |
- output_len = . - 4; | |
- input_data_end = .; | |
- } | |
-} | |
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr | |
deleted file mode 100644 | |
index 590394e2f5f2..000000000000 | |
--- a/arch/sh/boot/romimage/vmlinux.scr | |
+++ /dev/null | |
@@ -1,8 +0,0 @@ | |
-SECTIONS | |
-{ | |
- .text : { | |
- zero_page_pos = .; | |
- *(.data) | |
- end_data = .; | |
- } | |
-} | |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig | |
index 6219401ae324..dc2b12049749 100644 | |
--- a/arch/x86/Kconfig | |
+++ b/arch/x86/Kconfig | |
@@ -272,9 +272,6 @@ config ZONE_DMA32 | |
config AUDIT_ARCH | |
def_bool y if X86_64 | |
-config ARCH_SUPPORTS_OPTIMIZED_INLINING | |
- def_bool y | |
- | |
config ARCH_SUPPORTS_DEBUG_PAGEALLOC | |
def_bool y | |
@@ -2813,3 +2810,5 @@ source "crypto/Kconfig" | |
source "arch/x86/kvm/Kconfig" | |
source "lib/Kconfig" | |
+ | |
+source "ndm/Kconfig" | |
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug | |
index f09a192260f8..5b98030f7c38 100644 | |
--- a/arch/x86/Kconfig.debug | |
+++ b/arch/x86/Kconfig.debug | |
@@ -287,20 +287,6 @@ config CPA_DEBUG | |
---help--- | |
Do change_page_attr() self-tests every 30 seconds. | |
-config OPTIMIZE_INLINING | |
- bool "Allow gcc to uninline functions marked 'inline'" | |
- ---help--- | |
- This option determines if the kernel forces gcc to inline the functions | |
- developers have marked 'inline'. Doing so takes away freedom from gcc to | |
- do what it thinks is best, which is desirable for the gcc 3.x series of | |
- compilers. The gcc 4.x series have a rewritten inlining algorithm and | |
- enabling this option will generate a smaller kernel there. Hopefully | |
- this algorithm is so good that allowing gcc 4.x and above to make the | |
- decision will become the default in the future. Until then this option | |
- is there to test gcc for this. | |
- | |
- If unsure, say N. | |
- | |
config DEBUG_ENTRY | |
bool "Debug low-level entry code" | |
depends on DEBUG_KERNEL | |
diff --git a/crypto/Kconfig b/crypto/Kconfig | |
index 60ece1b8bfd3..36709c68c6e4 100644 | |
--- a/crypto/Kconfig | |
+++ b/crypto/Kconfig | |
@@ -32,7 +32,7 @@ config CRYPTO_FIPS | |
this is. | |
config CRYPTO_ALGAPI | |
- tristate | |
+ tristate "ALGAPI" | |
select CRYPTO_ALGAPI2 | |
help | |
This option provides the API for cryptographic algorithms. | |
@@ -41,7 +41,7 @@ config CRYPTO_ALGAPI2 | |
tristate | |
config CRYPTO_AEAD | |
- tristate | |
+ tristate "AEAD" | |
select CRYPTO_AEAD2 | |
select CRYPTO_ALGAPI | |
@@ -52,7 +52,7 @@ config CRYPTO_AEAD2 | |
select CRYPTO_RNG2 | |
config CRYPTO_BLKCIPHER | |
- tristate | |
+ tristate "BLKCIPHER" | |
select CRYPTO_BLKCIPHER2 | |
select CRYPTO_ALGAPI | |
@@ -63,7 +63,7 @@ config CRYPTO_BLKCIPHER2 | |
select CRYPTO_WORKQUEUE | |
config CRYPTO_HASH | |
- tristate | |
+ tristate "HASH" | |
select CRYPTO_HASH2 | |
select CRYPTO_ALGAPI | |
@@ -72,7 +72,7 @@ config CRYPTO_HASH2 | |
select CRYPTO_ALGAPI2 | |
config CRYPTO_RNG | |
- tristate | |
+ tristate "RNG" | |
select CRYPTO_RNG2 | |
select CRYPTO_ALGAPI | |
@@ -132,12 +132,12 @@ config CRYPTO_MANAGER | |
cbc(aes). | |
config CRYPTO_MANAGER2 | |
- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) | |
- select CRYPTO_AEAD2 | |
- select CRYPTO_HASH2 | |
- select CRYPTO_BLKCIPHER2 | |
- select CRYPTO_AKCIPHER2 | |
- select CRYPTO_KPP2 | |
+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) | |
+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS | |
+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS | |
+ select CRYPTO_BLKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS | |
+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS | |
+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS | |
config CRYPTO_USER | |
tristate "Userspace cryptographic algorithm configuration" | |
@@ -150,7 +150,6 @@ config CRYPTO_USER | |
config CRYPTO_MANAGER_DISABLE_TESTS | |
bool "Disable run-time self tests" | |
default y | |
- depends on CRYPTO_MANAGER2 | |
help | |
Disable run-time self tests that normally take place at | |
algorithm registration. | |
diff --git a/crypto/algboss.c b/crypto/algboss.c | |
index 5cbc588555ca..31e049b1b604 100644 | |
--- a/crypto/algboss.c | |
+++ b/crypto/algboss.c | |
@@ -246,12 +246,16 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg) | |
type = alg->cra_flags; | |
/* This piece of crap needs to disappear into per-type test hooks. */ | |
+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS | |
+ type |= CRYPTO_ALG_TESTED; | |
+#else | |
if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) & | |
CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV) && | |
((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == | |
CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : | |
alg->cra_ablkcipher.ivsize)) | |
type |= CRYPTO_ALG_TESTED; | |
+#endif | |
param->type = type; | |
diff --git a/crypto/hmac.c b/crypto/hmac.c | |
index ba07fb6221ae..e74730224f0a 100644 | |
--- a/crypto/hmac.c | |
+++ b/crypto/hmac.c | |
@@ -16,6 +16,7 @@ | |
* | |
*/ | |
+#include <crypto/hmac.h> | |
#include <crypto/internal/hash.h> | |
#include <crypto/scatterwalk.h> | |
#include <linux/err.h> | |
@@ -74,8 +75,8 @@ static int hmac_setkey(struct crypto_shash *parent, | |
memcpy(opad, ipad, bs); | |
for (i = 0; i < bs; i++) { | |
- ipad[i] ^= 0x36; | |
- opad[i] ^= 0x5c; | |
+ ipad[i] ^= HMAC_IPAD_VALUE; | |
+ opad[i] ^= HMAC_OPAD_VALUE; | |
} | |
return crypto_shash_init(shash) ?: | |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c | |
index 898ef4d736be..5a291dfd4749 100644 | |
--- a/crypto/testmgr.c | |
+++ b/crypto/testmgr.c | |
@@ -2226,6 +2226,21 @@ static const struct alg_test_desc alg_test_descs[] = { | |
} | |
} | |
} | |
+ }, { | |
+ .alg = "authenc(hmac(md5),cbc(aes))", | |
+ .test = alg_test_aead, | |
+ .suite = { | |
+ .aead = { | |
+ .enc = { | |
+ .vecs = hmac_md5_aes_cbc_enc_tv_temp, | |
+ .count = 2 | |
+ }, | |
+ .dec = { | |
+ .vecs = hmac_md5_aes_cbc_dec_tv_temp, | |
+ .count = 2 | |
+ } | |
+ } | |
+ } | |
}, { | |
.alg = "authenc(hmac(sha1),cbc(aes))", | |
.test = alg_test_aead, | |
@@ -2236,6 +2251,10 @@ static const struct alg_test_desc alg_test_descs[] = { | |
hmac_sha1_aes_cbc_enc_tv_temp, | |
.count = | |
HMAC_SHA1_AES_CBC_ENC_TEST_VEC | |
+ }, | |
+ .dec = { | |
+ .vecs = hmac_sha1_aes_cbc_dec_tv_temp, | |
+ .count = 2 | |
} | |
} | |
} | |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h | |
index 125669f1e725..0da3eb1587be 100644 | |
--- a/crypto/testmgr.h | |
+++ b/crypto/testmgr.h | |
@@ -16449,7 +16449,7 @@ static struct cipher_testvec cast6_xts_dec_tv_template[] = { | |
#define HMAC_MD5_ECB_CIPHER_NULL_DEC_TEST_VECTORS 2 | |
#define HMAC_SHA1_ECB_CIPHER_NULL_ENC_TEST_VEC 2 | |
#define HMAC_SHA1_ECB_CIPHER_NULL_DEC_TEST_VEC 2 | |
-#define HMAC_SHA1_AES_CBC_ENC_TEST_VEC 7 | |
+#define HMAC_SHA1_AES_CBC_ENC_TEST_VEC 8 | |
#define HMAC_SHA256_AES_CBC_ENC_TEST_VEC 7 | |
#define HMAC_SHA512_AES_CBC_ENC_TEST_VEC 7 | |
#define AES_LRW_ENC_TEST_VECTORS 8 | |
@@ -17345,6 +17345,183 @@ static struct aead_testvec hmac_md5_ecb_cipher_null_dec_tv_template[] = { | |
}, | |
}; | |
+static struct aead_testvec hmac_md5_aes_cbc_dec_tv_temp[] = { | |
+ { /* RFC 3602 Case 1 */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x22\x10\xf2\x25\x7f\xe9\x0d\x92" | |
+ "\xfc\x00\x55\xb1\xd0\xb5\x3a\x74", | |
+ .ilen = 16 + 16, | |
+ .result = "Single block msg", | |
+ .rlen = 16, | |
+ }, | |
+ { /* RFC 3602 Case 1 (ICV = 96 bits) */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x22\x10\xf2\x25\x7f\xe9\x0d\x92" | |
+ "\xfc\x00\x55\xb1", | |
+ .ilen = 16 + 12, | |
+ .result = "Single block msg", | |
+ .rlen = 16, | |
+ } | |
+}; | |
+ | |
+static struct aead_testvec hmac_md5_aes_cbc_enc_tv_temp[] = { | |
+ { /* RFC 3602 Case 1 */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "Single block msg", | |
+ .ilen = 16, | |
+ .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x22\x10\xf2\x25\x7f\xe9\x0d\x92" | |
+ "\xfc\x00\x55\xb1\xd0\xb5\x3a\x74", | |
+ .rlen = 16 + 16, | |
+ }, { /* RFC 3602 Case 1 (ICV = 96 bits) */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "Single block msg", | |
+ .ilen = 16, | |
+ .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x22\x10\xf2\x25\x7f\xe9\x0d\x92" | |
+ "\xfc\x00\x55\xb1", | |
+ .rlen = 16 + 12, | |
+ } | |
+}; | |
+ | |
+static struct aead_testvec hmac_sha1_aes_cbc_dec_tv_temp[] = { | |
+ { /* RFC 3602 Case 1 */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x1b\x13\xcb\xaf\x89\x5e\xe1\x2c" | |
+ "\x13\xc5\x2e\xa3\xcc\xed\xdc\xb5" | |
+ "\x03\x71\xa2\x06", | |
+ .ilen = 16 + 20, | |
+ .result = "Single block msg", | |
+ .rlen = 16, | |
+ }, | |
+ { /* RFC 3602 Case 1 (ICV = 96 bits) */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x1b\x13\xcb\xaf\x89\x5e\xe1\x2c" | |
+ "\x13\xc5\x2e\xa3", | |
+ .ilen = 16 + 12, | |
+ .result = "Single block msg", | |
+ .rlen = 16, | |
+ } | |
+}; | |
+ | |
static struct aead_testvec hmac_sha1_aes_cbc_enc_tv_temp[] = { | |
{ /* RFC 3602 Case 1 */ | |
#ifdef __LITTLE_ENDIAN | |
@@ -17374,6 +17551,33 @@ static struct aead_testvec hmac_sha1_aes_cbc_enc_tv_temp[] = { | |
"\x13\xc5\x2e\xa3\xcc\xed\xdc\xb5" | |
"\x03\x71\xa2\x06", | |
.rlen = 16 + 20, | |
+ }, { /* RFC 3602 Case 1 (ICV = 96 bits) */ | |
+#ifdef __LITTLE_ENDIAN | |
+ .key = "\x08\x00" /* rta length */ | |
+ "\x01\x00" /* rta type */ | |
+#else | |
+ .key = "\x00\x08" /* rta length */ | |
+ "\x00\x01" /* rta type */ | |
+#endif | |
+ "\x00\x00\x00\x10" /* enc key length */ | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00\x00\x00\x00\x00" | |
+ "\x00\x00\x00\x00" | |
+ "\x06\xa9\x21\x40\x36\xb8\xa1\x5b" | |
+ "\x51\x2e\x03\xd5\x34\x12\x00\x06", | |
+ .klen = 8 + 20 + 16, | |
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .assoc = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30" | |
+ "\xb4\x22\xda\x80\x2c\x9f\xac\x41", | |
+ .alen = 16, | |
+ .input = "Single block msg", | |
+ .ilen = 16, | |
+ .result = "\xe3\x53\x77\x9c\x10\x79\xae\xb8" | |
+ "\x27\x08\x94\x2d\xbe\x77\x18\x1a" | |
+ "\x1b\x13\xcb\xaf\x89\x5e\xe1\x2c" | |
+ "\x13\xc5\x2e\xa3", | |
+ .rlen = 16 + 12, | |
}, { /* RFC 3602 Case 2 */ | |
#ifdef __LITTLE_ENDIAN | |
.key = "\x08\x00" /* rta length */ | |
diff --git a/crypto/zstd.c b/crypto/zstd.c | |
index 9bfd28f8cc77..b13c029e595f 100644 | |
--- a/crypto/zstd.c | |
+++ b/crypto/zstd.c | |
@@ -22,7 +22,7 @@ | |
#include <linux/zstd.h> | |
-#define ZSTD_DEF_LEVEL 3 | |
+#define ZSTD_DEF_LEVEL 5 | |
struct zstd_ctx { | |
ZSTD_CCtx *cctx; | |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig | |
index a8d4f4b5a77e..9604b2b83d0f 100644 | |
--- a/drivers/ata/Kconfig | |
+++ b/drivers/ata/Kconfig | |
@@ -143,6 +143,18 @@ config AHCI_CEVA | |
If unsure, say N. | |
+config AHCI_MTK | |
+ tristate "MTK AHCI SATA support" | |
+ depends on OF | |
+ help | |
+ This option enables support for Mediatek | |
+ AHCI Serial ATA controllers. | |
+ Its default value is no. Set the value to | |
+ yes when support SATA device in Mediatek | |
+ platform. | |
+ | |
+ If unsure, say N. | |
+ | |
config AHCI_MVEBU | |
tristate "Marvell EBU AHCI SATA support" | |
depends on ARCH_MVEBU | |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile | |
index a46e6b784bda..e013b602096b 100644 | |
--- a/drivers/ata/Makefile | |
+++ b/drivers/ata/Makefile | |
@@ -15,6 +15,7 @@ obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o | |
obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o | |
obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o | |
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o | |
+obj-$(CONFIG_AHCI_MTK) += ahci_mtk.o libahci.o libahci_platform.o | |
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o | |
obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o | |
obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o | |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h | |
index 0cc08f892fea..6f13719da955 100644 | |
--- a/drivers/ata/ahci.h | |
+++ b/drivers/ata/ahci.h | |
@@ -54,7 +54,7 @@ | |
enum { | |
AHCI_MAX_PORTS = 32, | |
- AHCI_MAX_CLKS = 5, | |
+ AHCI_MAX_CLKS = 6, | |
AHCI_MAX_SG = 168, /* hardware max is 64K */ | |
AHCI_DMA_BOUNDARY = 0xffffffff, | |
AHCI_MAX_CMDS = 32, | |
diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c | |
new file mode 100644 | |
index 000000000000..3d071776115d | |
--- /dev/null | |
+++ b/drivers/ata/ahci_mtk.c | |
@@ -0,0 +1,202 @@ | |
+/* | |
+ * MediaTek AHCI SATA driver | |
+ * | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Ryder Lee <ryder.lee@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/ahci_platform.h> | |
+#include <linux/kernel.h> | |
+#include <linux/libata.h> | |
+#include <linux/mfd/syscon.h> | |
+#include <linux/module.h> | |
+#include <linux/platform_device.h> | |
+#include <linux/pm.h> | |
+#include <linux/regmap.h> | |
+#include <linux/reset.h> | |
+#include "ahci.h" | |
+ | |
+#define DRV_NAME "ahci-mtk" | |
+ | |
+#define SYS_CFG0 0x10 | |
+#define SYS_CFG0_SATA_MSK GENMASK(1, 0) | |
+#define SYS_CFG0_SATA_GEN3 BIT(1) | |
+#define SYS_CFG1 0x14 | |
+#define SYS_CFG1_SATA_MSK GENMASK(31, 30) | |
+#define SYS_CFG1_SATA_EN BIT(31) | |
+ | |
+struct mtk_ahci_plat { | |
+ struct regmap *mode; | |
+ struct reset_control *axi_rst; | |
+ struct reset_control *sw_rst; | |
+ struct reset_control *reg_rst; | |
+}; | |
+ | |
+static const struct ata_port_info ahci_port_info = { | |
+ .flags = AHCI_FLAG_COMMON, | |
+ .pio_mask = ATA_PIO4, | |
+ .udma_mask = ATA_UDMA6, | |
+ .port_ops = &ahci_platform_ops, | |
+}; | |
+ | |
+static struct scsi_host_template ahci_platform_sht = { | |
+ AHCI_SHT(DRV_NAME), | |
+}; | |
+ | |
+static int mtk_ahci_platform_resets(struct ahci_host_priv *hpriv, | |
+ struct device *dev) | |
+{ | |
+ struct mtk_ahci_plat *plat = hpriv->plat_data; | |
+ int err; | |
+ | |
+ /* reset AXI bus and PHY part */ | |
+ plat->axi_rst = devm_reset_control_get_optional_exclusive(dev, "axi"); | |
+ if (PTR_ERR(plat->axi_rst) == -EPROBE_DEFER) | |
+ return PTR_ERR(plat->axi_rst); | |
+ | |
+ plat->sw_rst = devm_reset_control_get_optional_exclusive(dev, "sw"); | |
+ if (PTR_ERR(plat->sw_rst) == -EPROBE_DEFER) | |
+ return PTR_ERR(plat->sw_rst); | |
+ | |
+ plat->reg_rst = devm_reset_control_get_optional_exclusive(dev, "reg"); | |
+ if (PTR_ERR(plat->reg_rst) == -EPROBE_DEFER) | |
+ return PTR_ERR(plat->reg_rst); | |
+ | |
+ err = reset_control_assert(plat->axi_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to assert AXI bus\n"); | |
+ return err; | |
+ } | |
+ | |
+ err = reset_control_assert(plat->sw_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to assert PHY digital part\n"); | |
+ return err; | |
+ } | |
+ | |
+ err = reset_control_assert(plat->reg_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to assert PHY register part\n"); | |
+ return err; | |
+ } | |
+ | |
+ err = reset_control_deassert(plat->reg_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to deassert PHY register part\n"); | |
+ return err; | |
+ } | |
+ | |
+ err = reset_control_deassert(plat->sw_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to deassert PHY digital part\n"); | |
+ return err; | |
+ } | |
+ | |
+ err = reset_control_deassert(plat->axi_rst); | |
+ if (err) { | |
+ dev_err(dev, "failed to deassert AXI bus\n"); | |
+ return err; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int mtk_ahci_parse_property(struct ahci_host_priv *hpriv, | |
+ struct device *dev) | |
+{ | |
+ struct mtk_ahci_plat *plat = hpriv->plat_data; | |
+ struct device_node *np = dev->of_node; | |
+ | |
+ /* enable SATA function if needed */ | |
+ if (of_find_property(np, "mediatek,phy-mode", NULL)) { | |
+ plat->mode = syscon_regmap_lookup_by_phandle( | |
+ np, "mediatek,phy-mode"); | |
+ if (IS_ERR(plat->mode)) { | |
+ dev_err(dev, "missing phy-mode phandle\n"); | |
+ return PTR_ERR(plat->mode); | |
+ } | |
+ | |
+ regmap_update_bits(plat->mode, SYS_CFG0, SYS_CFG0_SATA_MSK, | |
+ SYS_CFG0_SATA_GEN3); | |
+ | |
+ regmap_update_bits(plat->mode, SYS_CFG1, SYS_CFG1_SATA_MSK, | |
+ SYS_CFG1_SATA_EN); | |
+ } | |
+ | |
+ of_property_read_u32(np, "ports-implemented", &hpriv->force_port_map); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int mtk_ahci_probe(struct platform_device *pdev) | |
+{ | |
+ struct device *dev = &pdev->dev; | |
+ struct mtk_ahci_plat *plat; | |
+ struct ahci_host_priv *hpriv; | |
+ int err; | |
+ | |
+ plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); | |
+ if (!plat) | |
+ return -ENOMEM; | |
+ | |
+ hpriv = ahci_platform_get_resources(pdev); | |
+ if (IS_ERR(hpriv)) | |
+ return PTR_ERR(hpriv); | |
+ | |
+ hpriv->plat_data = plat; | |
+ | |
+ err = mtk_ahci_parse_property(hpriv, dev); | |
+ if (err) | |
+ return err; | |
+ | |
+ err = mtk_ahci_platform_resets(hpriv, dev); | |
+ if (err) | |
+ return err; | |
+ | |
+ err = ahci_platform_enable_resources(hpriv); | |
+ if (err) | |
+ return err; | |
+ | |
+ err = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, | |
+ &ahci_platform_sht); | |
+ if (err) | |
+ goto disable_resources; | |
+ | |
+ return 0; | |
+ | |
+disable_resources: | |
+ ahci_platform_disable_resources(hpriv); | |
+ return err; | |
+} | |
+ | |
+static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, | |
+ ahci_platform_resume); | |
+ | |
+static const struct of_device_id ahci_of_match[] = { | |
+ { .compatible = "mediatek,mtk-ahci", }, | |
+ {}, | |
+}; | |
+MODULE_DEVICE_TABLE(of, ahci_of_match); | |
+ | |
+static struct platform_driver mtk_ahci_driver = { | |
+ .probe = mtk_ahci_probe, | |
+ .remove = ata_platform_remove_one, | |
+ .driver = { | |
+ .name = DRV_NAME, | |
+ .of_match_table = ahci_of_match, | |
+ .pm = &ahci_pm_ops, | |
+ }, | |
+}; | |
+module_platform_driver(mtk_ahci_driver); | |
+ | |
+MODULE_DESCRIPTION("MediaTek SATA AHCI Driver"); | |
+MODULE_LICENSE("GPL v2"); | |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c | |
index a95e1e572697..b6a0b3b654b7 100644 | |
--- a/drivers/base/firmware_class.c | |
+++ b/drivers/base/firmware_class.c | |
@@ -291,9 +291,11 @@ static void fw_free_buf(struct firmware_buf *buf) | |
static char fw_path_para[256]; | |
static const char * const fw_path[] = { | |
fw_path_para, | |
+#ifndef CONFIG_EMBEDDED | |
"/lib/firmware/updates/" UTS_RELEASE, | |
"/lib/firmware/updates", | |
"/lib/firmware/" UTS_RELEASE, | |
+#endif | |
"/lib/firmware" | |
}; | |
@@ -604,11 +606,6 @@ static ssize_t firmware_loading_show(struct device *dev, | |
return sprintf(buf, "%d\n", loading); | |
} | |
-/* Some architectures don't have PAGE_KERNEL_RO */ | |
-#ifndef PAGE_KERNEL_RO | |
-#define PAGE_KERNEL_RO PAGE_KERNEL | |
-#endif | |
- | |
/* one pages buffer should be mapped/unmapped only once */ | |
static int fw_map_pages_buf(struct firmware_buf *buf) | |
{ | |
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c | |
index e494a938a9f1..309de35d57cb 100644 | |
--- a/drivers/base/power/opp/core.c | |
+++ b/drivers/base/power/opp/core.c | |
@@ -1519,6 +1519,83 @@ static int _opp_set_availability(struct device *dev, unsigned long freq, | |
return r; | |
} | |
+/* | |
+ * dev_pm_opp_adjust_voltage() - helper to change the voltage of an OPP | |
+ * @dev: device for which we do this operation | |
+ * @freq: OPP frequency to adjust voltage of | |
+ * @u_volt: new OPP voltage | |
+ * | |
+ * Change the voltage of an OPP with an RCU operation. | |
+ * | |
+ * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the | |
+ * copy operation, returns 0 if no modifcation was done OR modification was | |
+ * successful. | |
+ * | |
+ * Locking: The internal device_opp and opp structures are RCU protected. | |
+ * Hence this function internally uses RCU updater strategy with mutex locks to | |
+ * keep the integrity of the internal data structures. Callers should ensure | |
+ * that this function is *NOT* called under RCU protection or in contexts where | |
+ * mutex locking or synchronize_rcu() blocking calls cannot be used. | |
+ */ | |
+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq, | |
+ unsigned long u_volt) | |
+{ | |
+ struct opp_table *opp_table; | |
+ struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV); | |
+ int r = 0; | |
+ | |
+ /* keep the node allocated */ | |
+ new_opp = kmalloc(sizeof(*new_opp), GFP_KERNEL); | |
+ if (!new_opp) | |
+ return -ENOMEM; | |
+ | |
+ mutex_lock(&opp_table_lock); | |
+ | |
+ /* Find the device_opp */ | |
+ opp_table = _find_opp_table(dev); | |
+ if (IS_ERR(opp_table)) { | |
+ r = PTR_ERR(opp_table); | |
+ dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); | |
+ goto unlock; | |
+ } | |
+ | |
+ /* Do we have the frequency? */ | |
+ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) { | |
+ if (tmp_opp->rate == freq) { | |
+ opp = tmp_opp; | |
+ break; | |
+ } | |
+ } | |
+ if (IS_ERR(opp)) { | |
+ r = PTR_ERR(opp); | |
+ goto unlock; | |
+ } | |
+ | |
+ /* Is update really needed? */ | |
+ if (opp->u_volt == u_volt) | |
+ goto unlock; | |
+ /* copy the old data over */ | |
+ *new_opp = *opp; | |
+ | |
+ /* plug in new node */ | |
+ new_opp->u_volt = u_volt; | |
+ | |
+ list_replace_rcu(&opp->node, &new_opp->node); | |
+ mutex_unlock(&opp_table_lock); | |
+ call_srcu(&opp_table->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu); | |
+ | |
+ /* Notify the change of the OPP */ | |
+ srcu_notifier_call_chain(&opp_table->srcu_head, OPP_EVENT_ADJUST_VOLTAGE, | |
+ new_opp); | |
+ | |
+ return 0; | |
+ | |
+unlock: | |
+ mutex_unlock(&opp_table_lock); | |
+ kfree(new_opp); | |
+ return r; | |
+} | |
+ | |
/** | |
* dev_pm_opp_enable() - Enable a specific OPP | |
* @dev: device for which we do this operation | |
diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig | |
index db9d00c36a3e..48b3fc1ee514 100644 | |
--- a/drivers/base/regmap/Kconfig | |
+++ b/drivers/base/regmap/Kconfig | |
@@ -4,9 +4,12 @@ | |
config REGMAP | |
default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) | |
+ select IRQ_DOMAIN if REGMAP_IRQ | |
+ bool | |
+ | |
+config REGCACHE_COMPRESSED | |
select LZO_COMPRESS | |
select LZO_DECOMPRESS | |
- select IRQ_DOMAIN if REGMAP_IRQ | |
bool | |
config REGMAP_AC97 | |
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile | |
index 609e4c84f485..6271ea9b758a 100644 | |
--- a/drivers/base/regmap/Makefile | |
+++ b/drivers/base/regmap/Makefile | |
@@ -2,7 +2,8 @@ | |
CFLAGS_regmap.o := -I$(src) | |
obj-$(CONFIG_REGMAP) += regmap.o regcache.o | |
-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o regcache-flat.o | |
+obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o | |
+obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o | |
obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o | |
obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o | |
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o | |
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c | |
index c0fdbb392758..86466acab563 100644 | |
--- a/drivers/base/regmap/regcache-rbtree.c | |
+++ b/drivers/base/regmap/regcache-rbtree.c | |
@@ -33,7 +33,7 @@ struct regcache_rbtree_node { | |
unsigned int blklen; | |
/* the actual rbtree node holding this block */ | |
struct rb_node node; | |
-} __attribute__ ((packed)); | |
+}; | |
struct regcache_rbtree_ctx { | |
struct rb_root root; | |
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c | |
index 4e582561e1e7..3644fe8b27c3 100644 | |
--- a/drivers/base/regmap/regcache.c | |
+++ b/drivers/base/regmap/regcache.c | |
@@ -21,7 +21,9 @@ | |
static const struct regcache_ops *cache_types[] = { | |
®cache_rbtree_ops, | |
+#if IS_ENABLED(CONFIG_REGCACHE_COMPRESSED) | |
®cache_lzo_ops, | |
+#endif | |
®cache_flat_ops, | |
}; | |
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c | |
index 5189fd6182f6..38d418418a62 100644 | |
--- a/drivers/base/regmap/regmap-mmio.c | |
+++ b/drivers/base/regmap/regmap-mmio.c | |
@@ -363,4 +363,13 @@ struct regmap *__devm_regmap_init_mmio_clk(struct device *dev, | |
} | |
EXPORT_SYMBOL_GPL(__devm_regmap_init_mmio_clk); | |
+void __iomem *regmap_get_iomem(struct regmap *map) | |
+{ | |
+ if (map->bus != ®map_mmio) | |
+ return ERR_PTR(-EINVAL); | |
+ | |
+ return ((struct regmap_mmio_context *)map->bus_context)->regs; | |
+} | |
+EXPORT_SYMBOL(regmap_get_iomem); | |
+ | |
MODULE_LICENSE("GPL v2"); | |
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c | |
index 40a9e5378633..0f247fb9f597 100644 | |
--- a/drivers/base/regmap/regmap.c | |
+++ b/drivers/base/regmap/regmap.c | |
@@ -2908,6 +2908,18 @@ int regmap_parse_val(struct regmap *map, const void *buf, | |
} | |
EXPORT_SYMBOL_GPL(regmap_parse_val); | |
+void regmap_lock_map(struct regmap *map) | |
+{ | |
+ map->lock(map->lock_arg); | |
+} | |
+EXPORT_SYMBOL(regmap_lock_map); | |
+ | |
+void regmap_unlock_map(struct regmap *map) | |
+{ | |
+ map->unlock(map->lock_arg); | |
+} | |
+EXPORT_SYMBOL(regmap_unlock_map); | |
+ | |
static int __init regmap_initcall(void) | |
{ | |
regmap_debugfs_initcall(); | |
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig | |
index b5c48a8d485f..f7d5f1febb04 100644 | |
--- a/drivers/bcma/Kconfig | |
+++ b/drivers/bcma/Kconfig | |
@@ -1,7 +1,7 @@ | |
config BCMA_POSSIBLE | |
bool | |
depends on HAS_IOMEM && HAS_DMA | |
- default y | |
+ default n | |
menu "Broadcom specific AMBA" | |
depends on BCMA_POSSIBLE | |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c | |
index dece26f119d4..ab62b81c2ca7 100644 | |
--- a/drivers/block/drbd/drbd_bitmap.c | |
+++ b/drivers/block/drbd/drbd_bitmap.c | |
@@ -1070,7 +1070,7 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned | |
.done = 0, | |
.flags = flags, | |
.error = 0, | |
- .kref = KREF_INIT(2), | |
+ .kref = { ATOMIC_INIT(2) }, | |
}; | |
if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in drbd_bm_aio_ctx_destroy() */ | |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c | |
index 29abf344a4b6..40325d7527b2 100644 | |
--- a/drivers/block/zram/zram_drv.c | |
+++ b/drivers/block/zram/zram_drv.c | |
@@ -17,6 +17,7 @@ | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
+#include <linux/major.h> | |
#include <linux/bio.h> | |
#include <linux/bitops.h> | |
#include <linux/blkdev.h> | |
@@ -2119,8 +2120,8 @@ static int __init zram_init(void) | |
} | |
zram_debugfs_create(); | |
- zram_major = register_blkdev(0, "zram"); | |
- if (zram_major <= 0) { | |
+ zram_major = ZRAM_MAJOR; | |
+ if (register_blkdev(zram_major, "zram")) { | |
pr_err("Unable to get major number\n"); | |
class_unregister(&zram_control_class); | |
return -EBUSY; | |
@@ -2156,3 +2157,4 @@ MODULE_PARM_DESC(num_devices, "Number of pre-created zram devices"); | |
MODULE_LICENSE("Dual BSD/GPL"); | |
MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>"); | |
MODULE_DESCRIPTION("Compressed RAM Block Device"); | |
+MODULE_ALIAS_BLOCKDEV_MAJOR(ZRAM_MAJOR); | |
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig | |
index 78751057164a..3c1a88472244 100644 | |
--- a/drivers/bus/Kconfig | |
+++ b/drivers/bus/Kconfig | |
@@ -167,4 +167,14 @@ config VEXPRESS_CONFIG | |
help | |
Platform configuration infrastructure for the ARM Ltd. | |
Versatile Express. | |
+ | |
+config MTK_SUBSYS_IOC | |
+ bool "MediaTek Subsys IO Coherence" | |
+ depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST) | |
+ depends on OF | |
+ select REGMAP | |
+ select MFD_SYSCON | |
+ help | |
+ Say yes here to add support IO coherence feature for the MediaTek | |
+ peripheral device. | |
endmenu | |
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile | |
index c6cfa6b2606e..b1af1f451bfc 100644 | |
--- a/drivers/bus/Makefile | |
+++ b/drivers/bus/Makefile | |
@@ -10,6 +10,8 @@ obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o | |
obj-$(CONFIG_IMX_WEIM) += imx-weim.o | |
obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o | |
obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o | |
+obj-$(CONFIG_MTK_SUBSYS_IOC) += mtk-subsys-ioc.o | |
+obj-$(CONFIG_ARCH_MEDIATEK) += mtk-rbus.o | |
# Interconnect bus driver for OMAP SoCs. | |
obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o | |
diff --git a/drivers/bus/mtk-rbus.c b/drivers/bus/mtk-rbus.c | |
new file mode 100644 | |
index 000000000000..9a383a7ef24d | |
--- /dev/null | |
+++ b/drivers/bus/mtk-rbus.c | |
@@ -0,0 +1,76 @@ | |
+#include <linux/module.h> | |
+#include <linux/dma-mapping.h> | |
+#include <linux/pm_runtime.h> | |
+#include <linux/mtk-rbus.h> | |
+ | |
+int rbus_driver_register(struct platform_driver *drv, struct module *owner) | |
+{ | |
+ return __platform_driver_register(drv, owner); | |
+} | |
+EXPORT_SYMBOL(rbus_driver_register); | |
+ | |
+void rbus_driver_unregister(struct platform_driver *drv) | |
+{ | |
+ driver_unregister(&drv->driver); | |
+} | |
+EXPORT_SYMBOL(rbus_driver_unregister); | |
+ | |
+struct platform_device *rbus_device_alloc(const char *name, int id) | |
+{ | |
+ return platform_device_alloc(name, id); | |
+} | |
+EXPORT_SYMBOL(rbus_device_alloc); | |
+ | |
+void rbus_device_put(struct platform_device *pdev) | |
+{ | |
+ return platform_device_put(pdev); | |
+} | |
+EXPORT_SYMBOL(rbus_device_put); | |
+ | |
+int rbus_get_irq(struct platform_device *pdev, unsigned int num) | |
+{ | |
+ return platform_get_irq(pdev, num); | |
+} | |
+EXPORT_SYMBOL(rbus_get_irq); | |
+ | |
+int rbus_init_dummy_netdev(struct net_device *dev) | |
+{ | |
+ return init_dummy_netdev(dev); | |
+} | |
+EXPORT_SYMBOL(rbus_init_dummy_netdev); | |
+ | |
+int rbus_clk_enable(struct clk *clk, bool enable) | |
+{ | |
+ if (enable) | |
+ return clk_prepare_enable(clk); | |
+ | |
+ clk_disable_unprepare(clk); | |
+ | |
+ return 0; | |
+} | |
+EXPORT_SYMBOL(rbus_clk_enable); | |
+ | |
+void rbus_pm_runtime_enable(struct device *dev, bool enable) | |
+{ | |
+ if (enable) { | |
+ pm_runtime_enable(dev); | |
+ pm_runtime_get_sync(dev); | |
+ } else { | |
+ pm_runtime_put_sync(dev); | |
+ pm_runtime_disable(dev); | |
+ } | |
+} | |
+EXPORT_SYMBOL(rbus_pm_runtime_enable); | |
+ | |
+int rbus_init_wakeup(struct device *dev, bool enable) | |
+{ | |
+ return device_init_wakeup(dev, enable); | |
+} | |
+EXPORT_SYMBOL(rbus_init_wakeup); | |
+ | |
+void rbus_set_dma_coherent(struct device *dev, bool coherent) | |
+{ | |
+ arch_setup_dma_ops(dev, 0, 0, NULL, coherent); | |
+} | |
+EXPORT_SYMBOL(rbus_set_dma_coherent); | |
+ | |
diff --git a/drivers/bus/mtk-subsys-ioc.c b/drivers/bus/mtk-subsys-ioc.c | |
new file mode 100644 | |
index 000000000000..51618b5dbbd1 | |
--- /dev/null | |
+++ b/drivers/bus/mtk-subsys-ioc.c | |
@@ -0,0 +1,201 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Ryder Lee <ryder.lee@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/mfd/syscon.h> | |
+#include <linux/of.h> | |
+#include <linux/of_platform.h> | |
+#include <linux/of_address.h> | |
+#include <linux/io.h> | |
+#include <linux/regmap.h> | |
+ | |
+#define CCI400_S4_OF_NODE "arm,cci-400-s4" | |
+#define CCI400_SCR_OFFS 0x000 | |
+#define CCI400_SCR_SNOOP BIT(0) | |
+#define CCI400_SCR_DVM BIT(1) | |
+ | |
+#define WBSYS_OF_NODE "mediatek,wbsys" | |
+#define WBSYS_IOC_PDMA BIT(31) | |
+ | |
+#define HIFSYS_OF_NODE "mediatek,hifsys" | |
+#define HIFSYS_IOC_PCIE0 BIT(0) | |
+#define HIFSYS_IOC_PCIE1_SATA BIT(1) | |
+#define HIFSYS_IOC_PCIE_SATA_MASK GENMASK(1, 0) | |
+ | |
+#define HIFSYS_IOC_SSUSB_XHCI_MAS BIT(2) | |
+#define HIFSYS_IOC_SSUSB_XHCI_U3DATA BIT(3) | |
+#define HIFSYS_IOC_SSUSB_DEV BIT(4) | |
+#define HIFSYS_IOC_SSUSB_MASK GENMASK(4, 2) | |
+ | |
+#define ETHSYS_OF_NODE "mediatek,ethsys" | |
+#define ETHSYS_IOC_PDMA BIT(0) | |
+#define ETHSYS_IOC_QDMA BIT(1) | |
+#define ETHSYS_IOC_PPE BIT(2) | |
+#define ETHSYS_IOC_WDMA0 BIT(3) | |
+#define ETHSYS_IOC_HSDMA BIT(4) | |
+#define ETHSYS_IOC_GDMA BIT(5) | |
+#define ETHSYS_IOC_WDMA1 BIT(6) | |
+#define ETHSYS_IOC_ETH_MASK GENMASK(1, 0) | |
+ | |
+struct mtk_subsys_ioc_pdata { | |
+ bool has_wbsys; | |
+ bool has_hifsys; | |
+ bool has_ethsys; | |
+ | |
+ unsigned int wb_ioc_off; | |
+ unsigned int hif_ioc_off; | |
+ unsigned int eth_ioc_off; | |
+}; | |
+ | |
+static int arm_cci400_slave_snoop(struct device_node *np, const char *sp) | |
+{ | |
+ struct device_node *sl_np; | |
+ void __iomem *sl_base; | |
+ u32 reg_val; | |
+ | |
+ sl_np = of_parse_phandle(np, sp, 0); | |
+ if (!sl_np) | |
+ return -ENODEV; | |
+ | |
+ sl_base = of_iomap(sl_np, 0); | |
+ of_node_put(sl_np); | |
+ | |
+ if (!sl_base) | |
+ return -ENOMEM; | |
+ | |
+ reg_val = __raw_readl(sl_base + CCI400_SCR_OFFS); | |
+ if (!(reg_val & CCI400_SCR_DVM) || | |
+ !(reg_val & CCI400_SCR_SNOOP)) { | |
+ reg_val |= (CCI400_SCR_DVM | CCI400_SCR_SNOOP); | |
+ __raw_writel(reg_val, sl_base + CCI400_SCR_OFFS); | |
+ } | |
+ | |
+ iounmap(sl_base); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static bool of_dma_coherent(struct device_node *np, const char *sp) | |
+{ | |
+ struct device_node *dma_np; | |
+ bool dma_ioc = false; | |
+ | |
+ dma_np = of_parse_phandle(np, sp, 0); | |
+ if (dma_np) { | |
+ dma_ioc = of_property_read_bool(dma_np, "dma-coherent"); | |
+ of_node_put(dma_np); | |
+ } | |
+ | |
+ return dma_ioc; | |
+} | |
+ | |
+static int mtk_subsys_ioc_probe(struct platform_device *pdev) | |
+{ | |
+ struct device *dev = &pdev->dev; | |
+ struct device_node *np = dev->of_node; | |
+ const struct mtk_subsys_ioc_pdata *data; | |
+ struct regmap *wbsys, *hifsys, *ethsys; | |
+ bool is_wbsys_ioc = false; | |
+ bool is_ethsys_ioc = false; | |
+ | |
+ data = of_device_get_match_data(dev); | |
+ if (!data) | |
+ return -ENODEV; | |
+ | |
+ if (data->has_wbsys) | |
+ is_wbsys_ioc = of_dma_coherent(np, "mediatek,wifi"); | |
+ | |
+ if (data->has_ethsys) | |
+ is_ethsys_ioc = of_dma_coherent(np, "mediatek,eth"); | |
+ | |
+ /* enable Snoop & DVM message requests on ARM CCI slave interface 4 */ | |
+ if (is_wbsys_ioc || is_ethsys_ioc) | |
+ arm_cci400_slave_snoop(np, CCI400_S4_OF_NODE); | |
+ | |
+ /* enable wbsys IOC if needed */ | |
+ if (is_wbsys_ioc) { | |
+ wbsys = syscon_regmap_lookup_by_phandle(np, WBSYS_OF_NODE); | |
+ if (!IS_ERR(wbsys)) { | |
+ regmap_update_bits(wbsys, data->wb_ioc_off, | |
+ WBSYS_IOC_PDMA, | |
+ WBSYS_IOC_PDMA); | |
+ } | |
+ } | |
+ | |
+ /* enable ethernet IOC if needed */ | |
+ if (is_ethsys_ioc) { | |
+ ethsys = syscon_regmap_lookup_by_phandle(np, ETHSYS_OF_NODE); | |
+ if (!IS_ERR(ethsys)) { | |
+ unsigned int reg_val = ETHSYS_IOC_PDMA; | |
+ | |
+ /* hwnat HWFQ path is SW coherence only */ | |
+ if (!IS_ENABLED(CONFIG_RA_HW_NAT_QDMA)) | |
+ reg_val |= ETHSYS_IOC_QDMA; | |
+ | |
+ regmap_update_bits(ethsys, data->eth_ioc_off, | |
+ ETHSYS_IOC_ETH_MASK, | |
+ reg_val); | |
+ } | |
+ } | |
+ | |
+ /* enable USB/PCIe/SATA IOC if needed */ | |
+ if (data->has_hifsys) { | |
+ hifsys = syscon_regmap_lookup_by_phandle(np, HIFSYS_OF_NODE); | |
+ if (!IS_ERR(hifsys)) { | |
+ if (of_property_read_bool(np, "mediatek,en_usb")) | |
+ regmap_update_bits(hifsys, data->hif_ioc_off, | |
+ HIFSYS_IOC_SSUSB_MASK, | |
+ HIFSYS_IOC_SSUSB_XHCI_MAS | | |
+ HIFSYS_IOC_SSUSB_XHCI_U3DATA | | |
+ HIFSYS_IOC_SSUSB_DEV); | |
+ | |
+ if (of_property_read_bool(np, "mediatek,en_pcie_sata")) | |
+ regmap_update_bits(hifsys, data->hif_ioc_off, | |
+ HIFSYS_IOC_PCIE_SATA_MASK, | |
+ HIFSYS_IOC_PCIE0 | | |
+ HIFSYS_IOC_PCIE1_SATA); | |
+ } | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+static const struct mtk_subsys_ioc_pdata subsys_ioc_v1 = { | |
+ .has_wbsys = true, | |
+ .has_hifsys = true, | |
+ .has_ethsys = true, | |
+ .wb_ioc_off = 0x320, | |
+ .hif_ioc_off = 0x08, | |
+ .eth_ioc_off = 0x408, | |
+}; | |
+ | |
+static const struct of_device_id of_subsys_ioc_id_table[] = { | |
+ { | |
+ .compatible = "mediatek,mt7622-subsys-ioc", | |
+ .data = &subsys_ioc_v1, | |
+ }, { | |
+ /* sentinel */ | |
+ } | |
+}; | |
+ | |
+static struct platform_driver mtk_subsys_ioc_driver = { | |
+ .probe = mtk_subsys_ioc_probe, | |
+ .driver = { | |
+ .name = "mtk_subsys_ioc", | |
+ .of_match_table = of_subsys_ioc_id_table, | |
+ .suppress_bind_attrs = true, | |
+ }, | |
+}; | |
+ | |
+builtin_platform_driver(mtk_subsys_ioc_driver); | |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig | |
index 200dab5136a7..a15dcefaad29 100644 | |
--- a/drivers/char/hw_random/Kconfig | |
+++ b/drivers/char/hw_random/Kconfig | |
@@ -423,6 +423,20 @@ config HW_RANDOM_CAVIUM | |
If unsure, say Y. | |
+config HW_RANDOM_MTK | |
+ tristate "Mediatek Random Number Generator support" | |
+ depends on HW_RANDOM | |
+ depends on ARCH_MEDIATEK || COMPILE_TEST | |
+ default y | |
+ ---help--- | |
+ This driver provides kernel-side support for the Random Number | |
+ Generator hardware found on Mediatek SoCs. | |
+ | |
+ To compile this driver as a module, choose M here. the | |
+ module will be called mtk-rng. | |
+ | |
+ If unsure, say Y. | |
+ | |
endif # HW_RANDOM | |
config UML_RANDOM | |
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile | |
index 5f52b1e4e7be..59eacb79ac1a 100644 | |
--- a/drivers/char/hw_random/Makefile | |
+++ b/drivers/char/hw_random/Makefile | |
@@ -36,3 +36,4 @@ obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o | |
obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o | |
obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o | |
obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o | |
+obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o | |
diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c | |
new file mode 100644 | |
index 000000000000..7f99cd52b40e | |
--- /dev/null | |
+++ b/drivers/char/hw_random/mtk-rng.c | |
@@ -0,0 +1,211 @@ | |
+/* | |
+ * Driver for Mediatek Hardware Random Number Generator | |
+ * | |
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or | |
+ * modify it under the terms of the GNU General Public License as | |
+ * published by the Free Software Foundation; either version 2 of | |
+ * the License, or (at your option) any later version. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+#define MTK_RNG_DEV KBUILD_MODNAME | |
+ | |
+#include <linux/clk.h> | |
+#include <linux/delay.h> | |
+#include <linux/err.h> | |
+#include <linux/hw_random.h> | |
+#include <linux/io.h> | |
+#include <linux/iopoll.h> | |
+#include <linux/kernel.h> | |
+#include <linux/module.h> | |
+#include <linux/of.h> | |
+#include <linux/platform_device.h> | |
+#include <linux/pm_runtime.h> | |
+ | |
+/* Runtime PM autosuspend timeout: */ | |
+#define RNG_AUTOSUSPEND_TIMEOUT 100 | |
+ | |
+#define USEC_POLL 2 | |
+#define TIMEOUT_POLL 20 | |
+ | |
+#define RNG_CTRL 0x00 | |
+#define RNG_EN BIT(0) | |
+#define RNG_READY BIT(31) | |
+ | |
+#define RNG_DATA 0x08 | |
+ | |
+#define to_mtk_rng(p) container_of(p, struct mtk_rng, rng) | |
+ | |
+struct mtk_rng { | |
+ void __iomem *base; | |
+ struct clk *clk; | |
+ struct hwrng rng; | |
+}; | |
+ | |
+static int mtk_rng_init(struct hwrng *rng) | |
+{ | |
+ struct mtk_rng *priv = to_mtk_rng(rng); | |
+ u32 val; | |
+ int err; | |
+ | |
+ err = clk_prepare_enable(priv->clk); | |
+ if (err) | |
+ return err; | |
+ | |
+ val = readl(priv->base + RNG_CTRL); | |
+ val |= RNG_EN; | |
+ writel(val, priv->base + RNG_CTRL); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void mtk_rng_cleanup(struct hwrng *rng) | |
+{ | |
+ struct mtk_rng *priv = to_mtk_rng(rng); | |
+ u32 val; | |
+ | |
+ val = readl(priv->base + RNG_CTRL); | |
+ val &= ~RNG_EN; | |
+ writel(val, priv->base + RNG_CTRL); | |
+ | |
+ clk_disable_unprepare(priv->clk); | |
+} | |
+ | |
+static bool mtk_rng_wait_ready(struct hwrng *rng, bool wait) | |
+{ | |
+ struct mtk_rng *priv = to_mtk_rng(rng); | |
+ int ready; | |
+ | |
+ ready = readl(priv->base + RNG_CTRL) & RNG_READY; | |
+ if (!ready && wait) | |
+ readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready, | |
+ ready & RNG_READY, USEC_POLL, | |
+ TIMEOUT_POLL); | |
+ return !!ready; | |
+} | |
+ | |
+static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) | |
+{ | |
+ struct mtk_rng *priv = to_mtk_rng(rng); | |
+ int retval = 0; | |
+ | |
+ pm_runtime_get_sync((struct device *)priv->rng.priv); | |
+ | |
+ while (max >= sizeof(u32)) { | |
+ if (!mtk_rng_wait_ready(rng, wait)) | |
+ break; | |
+ | |
+ *(u32 *)buf = readl(priv->base + RNG_DATA); | |
+ retval += sizeof(u32); | |
+ buf += sizeof(u32); | |
+ max -= sizeof(u32); | |
+ } | |
+ | |
+ pm_runtime_mark_last_busy((struct device *)priv->rng.priv); | |
+ pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv); | |
+ | |
+ return retval || !wait ? retval : -EIO; | |
+} | |
+ | |
+static int mtk_rng_probe(struct platform_device *pdev) | |
+{ | |
+ struct resource *res; | |
+ int ret; | |
+ struct mtk_rng *priv; | |
+ | |
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
+ if (!res) { | |
+ dev_err(&pdev->dev, "no iomem resource\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | |
+ if (!priv) | |
+ return -ENOMEM; | |
+ | |
+ priv->rng.name = pdev->name; | |
+#ifndef CONFIG_PM | |
+ priv->rng.init = mtk_rng_init; | |
+ priv->rng.cleanup = mtk_rng_cleanup; | |
+#endif | |
+ priv->rng.read = mtk_rng_read; | |
+ priv->rng.priv = (unsigned long)&pdev->dev; | |
+ priv->rng.quality = 900; | |
+ | |
+ priv->clk = devm_clk_get(&pdev->dev, "rng"); | |
+ if (IS_ERR(priv->clk)) { | |
+ ret = PTR_ERR(priv->clk); | |
+ dev_err(&pdev->dev, "no clock for device: %d\n", ret); | |
+ return ret; | |
+ } | |
+ | |
+ priv->base = devm_ioremap_resource(&pdev->dev, res); | |
+ if (IS_ERR(priv->base)) | |
+ return PTR_ERR(priv->base); | |
+ | |
+ ret = devm_hwrng_register(&pdev->dev, &priv->rng); | |
+ if (ret) { | |
+ dev_err(&pdev->dev, "failed to register rng device: %d\n", | |
+ ret); | |
+ return ret; | |
+ } | |
+ | |
+ dev_set_drvdata(&pdev->dev, priv); | |
+ pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT); | |
+ pm_runtime_use_autosuspend(&pdev->dev); | |
+ pm_runtime_enable(&pdev->dev); | |
+ | |
+ dev_info(&pdev->dev, "registered RNG driver\n"); | |
+ | |
+ return 0; | |
+} | |
+ | |
+#ifdef CONFIG_PM | |
+static int mtk_rng_runtime_suspend(struct device *dev) | |
+{ | |
+ struct mtk_rng *priv = dev_get_drvdata(dev); | |
+ | |
+ mtk_rng_cleanup(&priv->rng); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int mtk_rng_runtime_resume(struct device *dev) | |
+{ | |
+ struct mtk_rng *priv = dev_get_drvdata(dev); | |
+ | |
+ return mtk_rng_init(&priv->rng); | |
+} | |
+ | |
+static UNIVERSAL_DEV_PM_OPS(mtk_rng_pm_ops, mtk_rng_runtime_suspend, | |
+ mtk_rng_runtime_resume, NULL); | |
+#define MTK_RNG_PM_OPS (&mtk_rng_pm_ops) | |
+#else /* CONFIG_PM */ | |
+#define MTK_RNG_PM_OPS NULL | |
+#endif /* CONFIG_PM */ | |
+ | |
+static const struct of_device_id mtk_rng_match[] = { | |
+ { .compatible = "mediatek,mt7623-rng" }, | |
+ {}, | |
+}; | |
+MODULE_DEVICE_TABLE(of, mtk_rng_match); | |
+ | |
+static struct platform_driver mtk_rng_driver = { | |
+ .probe = mtk_rng_probe, | |
+ .driver = { | |
+ .name = MTK_RNG_DEV, | |
+ .pm = MTK_RNG_PM_OPS, | |
+ .of_match_table = mtk_rng_match, | |
+ }, | |
+}; | |
+ | |
+module_platform_driver(mtk_rng_driver); | |
+ | |
+MODULE_DESCRIPTION("Mediatek Random Number Generator Driver"); | |
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | |
+MODULE_LICENSE("GPL"); | |
diff --git a/drivers/char/random.c b/drivers/char/random.c | |
index 5c877ec9c6a8..dd82479bc0a3 100644 | |
--- a/drivers/char/random.c | |
+++ b/drivers/char/random.c | |
@@ -823,7 +823,7 @@ static int crng_fast_load(const char *cp, size_t len) | |
if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { | |
crng_init = 1; | |
wake_up_interruptible(&crng_init_wait); | |
- pr_notice("random: fast init done\n"); | |
+ pr_info("random: fast init done\n"); | |
} | |
spin_unlock_irqrestore(&primary_crng.lock, flags); | |
return 1; | |
@@ -914,7 +914,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) | |
spin_unlock_irqrestore(&crng->lock, flags); | |
process_random_ready_list(); | |
wake_up_interruptible(&crng_init_wait); | |
- pr_notice("random: crng init done\n"); | |
+ pr_info("random: crng init done\n"); | |
if (unseeded_warning.missed) { | |
pr_notice("random: %d get_random_xx warning(s) missed " | |
"due to ratelimiting\n", | |
@@ -1971,6 +1971,24 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, | |
return urandom_read(NULL, buf, count, NULL); | |
} | |
+#ifdef CONFIG_NDM_RNG_SEED | |
+int random_add_entropy(void *p, size_t size, size_t ent_count) | |
+{ | |
+ int retval = write_pool(&input_pool, p, size); | |
+ | |
+ if (retval < 0) | |
+ return retval; | |
+ | |
+ return credit_entropy_bits_safe(&input_pool, ent_count); | |
+} | |
+ | |
+void crng_wait_ready_external(void) | |
+{ | |
+ if (!crng_ready()) | |
+ crng_wait_ready(); | |
+} | |
+#endif | |
+ | |
/******************************************************************** | |
* | |
* Sysctl interface | |
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig | |
index f042bd2a6a99..1a1dff0c4fba 100644 | |
--- a/drivers/clk/mediatek/Kconfig | |
+++ b/drivers/clk/mediatek/Kconfig | |
@@ -6,6 +6,22 @@ config COMMON_CLK_MEDIATEK | |
---help--- | |
Mediatek SoCs' clock support. | |
+config COMMON_CLK_MT2701 | |
+ bool "Clock driver for Mediatek MT2701" | |
+ depends on ARCH_MEDIATEK || COMPILE_TEST | |
+ select COMMON_CLK_MEDIATEK | |
+ default ARCH_MEDIATEK | |
+ ---help--- | |
+ This driver supports Mediatek MT2701 clocks. | |
+ | |
+config COMMON_CLK_MT7622 | |
+ bool "Clock driver for Mediatek MT7622" | |
+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST | |
+ select COMMON_CLK_MEDIATEK | |
+ default ARCH_MEDIATEK && ARM64 | |
+ ---help--- | |
+ This driver supports Mediatek MT7622 clocks. | |
+ | |
config COMMON_CLK_MT8135 | |
bool "Clock driver for Mediatek MT8135" | |
depends on ARCH_MEDIATEK || COMPILE_TEST | |
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile | |
index 32e7222e7305..92a58b9d1662 100644 | |
--- a/drivers/clk/mediatek/Makefile | |
+++ b/drivers/clk/mediatek/Makefile | |
@@ -1,4 +1,12 @@ | |
-obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o | |
+obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o | |
obj-$(CONFIG_RESET_CONTROLLER) += reset.o | |
+obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o | |
+obj-$(CONFIG_COMMON_CLK_MT7622) += clk-mt7622.o clkchk-mt7622.o | |
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o | |
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o | |
+obj-y += clk-bringup.o | |
+ | |
+ifeq ($(CONFIG_DEBUG_FS),y) | |
+#obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clkdbg.o | |
+#obj-$(CONFIG_COMMON_CLK_MT7622) += clkdbg-mt7622.o | |
+endif | |
diff --git a/drivers/clk/mediatek/clk-bringup.c b/drivers/clk/mediatek/clk-bringup.c | |
new file mode 100644 | |
index 000000000000..8ca6ad36fabc | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clk-bringup.c | |
@@ -0,0 +1,61 @@ | |
+/* | |
+ * Copyright (c) 2015 MediaTek Inc. | |
+ * Author: James Liao <jamesjj.liao@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/kernel.h> | |
+#include <linux/init.h> | |
+#include <linux/clk.h> | |
+#include <linux/of.h> | |
+#include <linux/of_platform.h> | |
+ | |
+static const struct of_device_id bring_up_id_table[] = { | |
+ { .compatible = "mediatek,clk-bring-up",}, | |
+ { .compatible = "mediatek,mt8163-bring-up",}, | |
+ { .compatible = "mediatek,mt8173-bring-up",}, | |
+ { }, | |
+}; | |
+ | |
+static int bring_up_probe(struct platform_device *pdev) | |
+{ | |
+ const int NR_CLKS = 300; | |
+ char clk_name_buf[16]; | |
+ struct clk *clk; | |
+ int i; | |
+ | |
+ for (i = 0; i < NR_CLKS; i++) { | |
+ sprintf(clk_name_buf, "%d", i); | |
+ | |
+ clk = devm_clk_get(&pdev->dev, clk_name_buf); | |
+ if (!IS_ERR(clk)) | |
+ clk_prepare_enable(clk); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int bring_up_remove(struct platform_device *pdev) | |
+{ | |
+ return 0; | |
+} | |
+ | |
+static struct platform_driver bring_up = { | |
+ .probe = bring_up_probe, | |
+ .remove = bring_up_remove, | |
+ .driver = { | |
+ .name = "bring_up", | |
+ .owner = THIS_MODULE, | |
+ .of_match_table = bring_up_id_table, | |
+ }, | |
+}; | |
+ | |
+builtin_platform_driver(bring_up); | |
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c | |
new file mode 100644 | |
index 000000000000..347d7990b30f | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clk-cpumux.c | |
@@ -0,0 +1,116 @@ | |
+/* | |
+ * Copyright (c) 2015 Linaro Ltd. | |
+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/clk-provider.h> | |
+#include <linux/mfd/syscon.h> | |
+#include <linux/slab.h> | |
+ | |
+#include "clk-mtk.h" | |
+#include "clk-cpumux.h" | |
+ | |
+static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw) | |
+{ | |
+ return container_of(_hw, struct mtk_clk_cpumux, hw); | |
+} | |
+ | |
+static u8 clk_cpumux_get_parent(struct clk_hw *hw) | |
+{ | |
+ struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); | |
+ unsigned int val; | |
+ | |
+ regmap_read(mux->regmap, mux->reg, &val); | |
+ | |
+ val >>= mux->shift; | |
+ val &= mux->mask; | |
+ | |
+ return val; | |
+} | |
+ | |
+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index) | |
+{ | |
+ struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); | |
+ u32 mask, val; | |
+ | |
+ val = index << mux->shift; | |
+ mask = mux->mask << mux->shift; | |
+ | |
+ return regmap_update_bits(mux->regmap, mux->reg, mask, val); | |
+} | |
+ | |
+static const struct clk_ops clk_cpumux_ops = { | |
+ .get_parent = clk_cpumux_get_parent, | |
+ .set_parent = clk_cpumux_set_parent, | |
+}; | |
+ | |
+static struct clk __init * | |
+mtk_clk_register_cpumux(const struct mtk_composite *mux, | |
+ struct regmap *regmap) | |
+{ | |
+ struct mtk_clk_cpumux *cpumux; | |
+ struct clk *clk; | |
+ struct clk_init_data init; | |
+ | |
+ cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL); | |
+ if (!cpumux) | |
+ return ERR_PTR(-ENOMEM); | |
+ | |
+ init.name = mux->name; | |
+ init.ops = &clk_cpumux_ops; | |
+ init.parent_names = mux->parent_names; | |
+ init.num_parents = mux->num_parents; | |
+ init.flags = mux->flags; | |
+ | |
+ cpumux->reg = mux->mux_reg; | |
+ cpumux->shift = mux->mux_shift; | |
+ cpumux->mask = BIT(mux->mux_width) - 1; | |
+ cpumux->regmap = regmap; | |
+ cpumux->hw.init = &init; | |
+ | |
+ clk = clk_register(NULL, &cpumux->hw); | |
+ if (IS_ERR(clk)) | |
+ kfree(cpumux); | |
+ | |
+ return clk; | |
+} | |
+ | |
+int __init mtk_clk_register_cpumuxes(struct device_node *node, | |
+ const struct mtk_composite *clks, int num, | |
+ struct clk_onecell_data *clk_data) | |
+{ | |
+ int i; | |
+ struct clk *clk; | |
+ struct regmap *regmap; | |
+ | |
+ regmap = syscon_node_to_regmap(node); | |
+ if (IS_ERR(regmap)) { | |
+ pr_err("Cannot find regmap for %s: %ld\n", node->full_name, | |
+ PTR_ERR(regmap)); | |
+ return PTR_ERR(regmap); | |
+ } | |
+ | |
+ for (i = 0; i < num; i++) { | |
+ const struct mtk_composite *mux = &clks[i]; | |
+ | |
+ clk = mtk_clk_register_cpumux(mux, regmap); | |
+ if (IS_ERR(clk)) { | |
+ pr_err("Failed to register clk %s: %ld\n", | |
+ mux->name, PTR_ERR(clk)); | |
+ continue; | |
+ } | |
+ | |
+ clk_data->clks[mux->id] = clk; | |
+ } | |
+ | |
+ return 0; | |
+} | |
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h | |
new file mode 100644 | |
index 000000000000..dddaad57454d | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clk-cpumux.h | |
@@ -0,0 +1,30 @@ | |
+/* | |
+ * Copyright (c) 2015 Linaro Ltd. | |
+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#ifndef __DRV_CLK_CPUMUX_H | |
+#define __DRV_CLK_CPUMUX_H | |
+ | |
+struct mtk_clk_cpumux { | |
+ struct clk_hw hw; | |
+ struct regmap *regmap; | |
+ u32 reg; | |
+ u32 mask; | |
+ u8 shift; | |
+}; | |
+ | |
+int mtk_clk_register_cpumuxes(struct device_node *node, | |
+ const struct mtk_composite *clks, int num, | |
+ struct clk_onecell_data *clk_data); | |
+ | |
+#endif /* __DRV_CLK_CPUMUX_H */ | |
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c | |
index d8787bf444eb..934bf0e45e26 100644 | |
--- a/drivers/clk/mediatek/clk-gate.c | |
+++ b/drivers/clk/mediatek/clk-gate.c | |
@@ -61,6 +61,22 @@ static void mtk_cg_clr_bit(struct clk_hw *hw) | |
regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); | |
} | |
+static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw) | |
+{ | |
+ struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); | |
+ u32 cgbit = BIT(cg->bit); | |
+ | |
+ regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, cgbit); | |
+} | |
+ | |
+static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw) | |
+{ | |
+ struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); | |
+ u32 cgbit = BIT(cg->bit); | |
+ | |
+ regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, 0); | |
+} | |
+ | |
static int mtk_cg_enable(struct clk_hw *hw) | |
{ | |
mtk_cg_clr_bit(hw); | |
@@ -85,6 +101,30 @@ static void mtk_cg_disable_inv(struct clk_hw *hw) | |
mtk_cg_clr_bit(hw); | |
} | |
+static int mtk_cg_enable_no_setclr(struct clk_hw *hw) | |
+{ | |
+ mtk_cg_clr_bit_no_setclr(hw); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void mtk_cg_disable_no_setclr(struct clk_hw *hw) | |
+{ | |
+ mtk_cg_set_bit_no_setclr(hw); | |
+} | |
+ | |
+static int mtk_cg_enable_inv_no_setclr(struct clk_hw *hw) | |
+{ | |
+ mtk_cg_set_bit_no_setclr(hw); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void mtk_cg_disable_inv_no_setclr(struct clk_hw *hw) | |
+{ | |
+ mtk_cg_clr_bit_no_setclr(hw); | |
+} | |
+ | |
const struct clk_ops mtk_clk_gate_ops_setclr = { | |
.is_enabled = mtk_cg_bit_is_cleared, | |
.enable = mtk_cg_enable, | |
@@ -97,6 +137,18 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = { | |
.disable = mtk_cg_disable_inv, | |
}; | |
+const struct clk_ops mtk_clk_gate_ops_no_setclr = { | |
+ .is_enabled = mtk_cg_bit_is_cleared, | |
+ .enable = mtk_cg_enable_no_setclr, | |
+ .disable = mtk_cg_disable_no_setclr, | |
+}; | |
+ | |
+const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = { | |
+ .is_enabled = mtk_cg_bit_is_set, | |
+ .enable = mtk_cg_enable_inv_no_setclr, | |
+ .disable = mtk_cg_disable_inv_no_setclr, | |
+}; | |
+ | |
struct clk *mtk_clk_register_gate( | |
const char *name, | |
const char *parent_name, | |
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h | |
index b1821603b887..72ef89b3ad7b 100644 | |
--- a/drivers/clk/mediatek/clk-gate.h | |
+++ b/drivers/clk/mediatek/clk-gate.h | |
@@ -36,6 +36,8 @@ static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw) | |
extern const struct clk_ops mtk_clk_gate_ops_setclr; | |
extern const struct clk_ops mtk_clk_gate_ops_setclr_inv; | |
+extern const struct clk_ops mtk_clk_gate_ops_no_setclr; | |
+extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv; | |
struct clk *mtk_clk_register_gate( | |
const char *name, | |
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c | |
new file mode 100644 | |
index 000000000000..0f8a7c65d597 | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clk-mt2701.c | |
@@ -0,0 +1,1404 @@ | |
+/* | |
+ * Copyright (c) 2014 MediaTek Inc. | |
+ * Author: Shunli Wang <shunli.wang@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/clk.h> | |
+#include <linux/of.h> | |
+#include <linux/of_address.h> | |
+#include <linux/platform_device.h> | |
+ | |
+#include "clk-mtk.h" | |
+#include "clk-gate.h" | |
+#include "clk-cpumux.h" | |
+ | |
+#include <dt-bindings/clock/mt2701-clk.h> | |
+ | |
+/* | |
+ * For some clocks, we don't care what their actual rates are. And these | |
+ * clocks may change their rate on different products or different scenarios. | |
+ * So we model these clocks' rate as 0, to denote it's not an actual rate. | |
+ */ | |
+#define DUMMY_RATE 0 | |
+ | |
+static DEFINE_SPINLOCK(lock); | |
+ | |
+static const struct mtk_fixed_clk top_fixed_clks[] __initconst = { | |
+ FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m", | |
+ 108 * MHZ), | |
+ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m", | |
+ 400 * MHZ), | |
+ FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m", | |
+ 295750000), | |
+ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m", | |
+ 340 * MHZ), | |
+ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m", | |
+ 340 * MHZ), | |
+ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m", | |
+ 340 * MHZ), | |
+ FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m", | |
+ 27 * MHZ), | |
+ FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m", | |
+ 416 * MHZ), | |
+ FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, "dsi0_lntc_dsi", "clk26m", | |
+ 143 * MHZ), | |
+ FIXED_CLK(CLK_TOP_HDMI_SCL_RX, "hdmi_scl_rx", "clk26m", | |
+ 27 * MHZ), | |
+ FIXED_CLK(CLK_TOP_AUD_EXT1, "aud_ext1", "clk26m", | |
+ DUMMY_RATE), | |
+ FIXED_CLK(CLK_TOP_AUD_EXT2, "aud_ext2", "clk26m", | |
+ DUMMY_RATE), | |
+ FIXED_CLK(CLK_TOP_NFI1X_PAD, "nfi1x_pad", "clk26m", | |
+ DUMMY_RATE), | |
+}; | |
+ | |
+static const struct mtk_fixed_factor top_fixed_divs[] __initconst = { | |
+ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1), | |
+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3), | |
+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), | |
+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7), | |
+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4), | |
+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8), | |
+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16), | |
+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4), | |
+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8), | |
+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4), | |
+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4), | |
+ | |
+ FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1), | |
+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), | |
+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), | |
+ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), | |
+ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26), | |
+ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52), | |
+ FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108), | |
+ FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8), | |
+ FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8), | |
+ | |
+ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1), | |
+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), | |
+ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), | |
+ FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8), | |
+ | |
+ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1), | |
+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), | |
+ | |
+ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2), | |
+ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4), | |
+ FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1), | |
+ | |
+ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1), | |
+ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2), | |
+ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), | |
+ | |
+ FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1), | |
+ FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1), | |
+ FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2), | |
+ | |
+ FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1), | |
+ FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2), | |
+ FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4), | |
+ | |
+ FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1), | |
+ FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2), | |
+ FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3), | |
+ | |
+ FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1), | |
+ | |
+ FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1), | |
+ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4), | |
+ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8), | |
+ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16), | |
+ FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24), | |
+ | |
+ FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3), | |
+ FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3), | |
+ FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3), | |
+ FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1), | |
+ FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1), | |
+ FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8), | |
+ FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793), | |
+ FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1), | |
+ FACTOR(CLK_TOP_AXISEL_D4, "axisel_d4", "axi_sel", 1, 4), | |
+}; | |
+ | |
+static const char * const axi_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d2", | |
+ "syspll_d5", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll2_d2", | |
+ "mmpll_d2", | |
+ "dmpll_d2" | |
+}; | |
+ | |
+static const char * const mem_parents[] __initconst = { | |
+ "clk26m", | |
+ "dmpll_ck" | |
+}; | |
+ | |
+static const char * const ddrphycfg_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d8" | |
+}; | |
+ | |
+static const char * const mm_parents[] __initconst = { | |
+ "clk26m", | |
+ "vencpll_ck", | |
+ "syspll1_d2", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll1_d2", | |
+ "univpll2_d2", | |
+ "dmpll_ck" | |
+}; | |
+ | |
+static const char * const pwm_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll2_d4", | |
+ "univpll3_d2", | |
+ "univpll1_d4", | |
+}; | |
+ | |
+static const char * const vdec_parents[] __initconst = { | |
+ "clk26m", | |
+ "vdecpll_ck", | |
+ "syspll_d5", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll2_d2", | |
+ "vencpll_ck", | |
+ "msdcpll_d2", | |
+ "mmpll_d2" | |
+}; | |
+ | |
+static const char * const mfg_parents[] __initconst = { | |
+ "clk26m", | |
+ "mmpll_ck", | |
+ "dmpll_x2_ck", | |
+ "msdcpll_ck", | |
+ "clk26m", | |
+ "syspll_d3", | |
+ "univpll_d3", | |
+ "univpll1_d2" | |
+}; | |
+ | |
+static const char * const camtg_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll_d26", | |
+ "univpll2_d2", | |
+ "syspll3_d2", | |
+ "syspll3_d4", | |
+ "msdcpll_d2", | |
+ "mmpll_d2" | |
+}; | |
+ | |
+static const char * const uart_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll2_d8" | |
+}; | |
+ | |
+static const char * const spi_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll3_d2", | |
+ "syspll4_d2", | |
+ "univpll2_d4", | |
+ "univpll1_d8" | |
+}; | |
+ | |
+static const char * const usb20_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll1_d8", | |
+ "univpll3_d4" | |
+}; | |
+ | |
+static const char * const msdc30_parents[] __initconst = { | |
+ "clk26m", | |
+ "msdcpll_d2", | |
+ "syspll2_d2", | |
+ "syspll1_d4", | |
+ "univpll1_d4", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const audio_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d16" | |
+}; | |
+ | |
+static const char * const aud_intbus_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d4", | |
+ "syspll3_d2", | |
+ "syspll4_d2", | |
+ "univpll3_d2", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const pmicspi_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d8", | |
+ "syspll2_d4", | |
+ "syspll4_d2", | |
+ "syspll3_d4", | |
+ "syspll2_d8", | |
+ "syspll1_d16", | |
+ "univpll3_d4", | |
+ "univpll_d26", | |
+ "dmpll_d2", | |
+ "dmpll_d4" | |
+}; | |
+ | |
+static const char * const scp_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d8", | |
+ "dmpll_d2", | |
+ "dmpll_d4" | |
+}; | |
+ | |
+static const char * const dpi0_parents[] __initconst = { | |
+ "clk26m", | |
+ "mipipll", | |
+ "mipipll_d2", | |
+ "mipipll_d4", | |
+ "clk26m", | |
+ "tvdpll_ck", | |
+ "tvdpll_d2", | |
+ "tvdpll_d4" | |
+}; | |
+ | |
+static const char * const dpi1_parents[] __initconst = { | |
+ "clk26m", | |
+ "tvdpll_ck", | |
+ "tvdpll_d2", | |
+ "tvdpll_d4" | |
+}; | |
+ | |
+static const char * const tve_parents[] __initconst = { | |
+ "clk26m", | |
+ "mipipll", | |
+ "mipipll_d2", | |
+ "mipipll_d4", | |
+ "clk26m", | |
+ "tvdpll_ck", | |
+ "tvdpll_d2", | |
+ "tvdpll_d4" | |
+}; | |
+ | |
+static const char * const hdmi_parents[] __initconst = { | |
+ "clk26m", | |
+ "hdmitx_dig_cts", | |
+ "hdmipll_ck", | |
+ "hdmipll_d2", | |
+ "hdmipll_d3" | |
+}; | |
+ | |
+static const char * const apll_parents[] __initconst = { | |
+ "clk26m", | |
+ "audpll", | |
+ "audpll_d4", | |
+ "audpll_d8", | |
+ "audpll_d16", | |
+ "audpll_d24", | |
+ "clk26m", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const rtc_parents[] __initconst = { | |
+ "32k_internal", | |
+ "32k_external", | |
+ "clk26m", | |
+ "univpll3_d8" | |
+}; | |
+ | |
+static const char * const nfi2x_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll2_d2", | |
+ "syspll_d7", | |
+ "univpll3_d2", | |
+ "syspll2_d4", | |
+ "univpll3_d4", | |
+ "syspll4_d4", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const emmc_hclk_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d2", | |
+ "syspll1_d4", | |
+ "syspll2_d2" | |
+}; | |
+ | |
+static const char * const flash_parents[] __initconst = { | |
+ "clk26m_d8", | |
+ "clk26m", | |
+ "syspll2_d8", | |
+ "syspll3_d4", | |
+ "univpll3_d4", | |
+ "syspll4_d2", | |
+ "syspll2_d4", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const di_parents[] __initconst = { | |
+ "clk26m", | |
+ "tvd2pll_ck", | |
+ "tvd2pll_d2", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const nr_osd_parents[] __initconst = { | |
+ "clk26m", | |
+ "vencpll_ck", | |
+ "syspll1_d2", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll1_d2", | |
+ "univpll2_d2", | |
+ "dmpll_ck" | |
+}; | |
+ | |
+static const char * const hdmirx_bist_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll_d3", | |
+ "clk26m", | |
+ "syspll1_d16", | |
+ "syspll4_d2", | |
+ "syspll1_d4", | |
+ "vencpll_ck", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const intdir_parents[] __initconst = { | |
+ "clk26m", | |
+ "mmpll_ck", | |
+ "syspll_d2", | |
+ "univpll_d2" | |
+}; | |
+ | |
+static const char * const asm_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll2_d4", | |
+ "univpll2_d2", | |
+ "syspll_d5" | |
+}; | |
+ | |
+static const char * const ms_card_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll3_d8", | |
+ "syspll4_d4" | |
+}; | |
+ | |
+static const char * const ethif_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d2", | |
+ "syspll_d5", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll1_d2", | |
+ "dmpll_ck", | |
+ "dmpll_d2" | |
+}; | |
+ | |
+static const char * const hdmirx_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll_d52" | |
+}; | |
+ | |
+static const char * const cmsys_parents[] __initconst = { | |
+ "clk26m", | |
+ "syspll1_d2", | |
+ "univpll1_d2", | |
+ "univpll_d5", | |
+ "syspll_d5", | |
+ "syspll2_d2", | |
+ "syspll1_d4", | |
+ "syspll3_d2", | |
+ "syspll2_d4", | |
+ "syspll1_d8", | |
+ "clk26m", | |
+ "clk26m", | |
+ "clk26m", | |
+ "clk26m", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const clk_8bdac_parents[] __initconst = { | |
+ "32k_internal", | |
+ "8bdac_ck", | |
+ "clk26m", | |
+ "clk26m" | |
+}; | |
+ | |
+static const char * const aud2dvd_parents[] __initconst = { | |
+ "a1sys_hp_ck", | |
+ "a2sys_hp_ck" | |
+}; | |
+ | |
+static const char * const padmclk_parents[] __initconst = { | |
+ "clk26m", | |
+ "univpll_d26", | |
+ "univpll_d52", | |
+ "univpll_d108", | |
+ "univpll2_d8", | |
+ "univpll2_d16", | |
+ "univpll2_d32" | |
+}; | |
+ | |
+static const char * const aud_mux_parents[] __initconst = { | |
+ "clk26m", | |
+ "aud1pll_98m_ck", | |
+ "aud2pll_90m_ck", | |
+ "hadds2pll_98m", | |
+ "audio_ext1_ck", | |
+ "audio_ext2_ck" | |
+}; | |
+ | |
+static const char * const aud_src_parents[] __initconst = { | |
+ "aud_mux1_sel", | |
+ "aud_mux2_sel" | |
+}; | |
+ | |
+static const char * const cpu_parents[] __initconst = { | |
+ "clk26m", | |
+ "armpll", | |
+ "mainpll", | |
+ "mmpll" | |
+}; | |
+ | |
+static const struct mtk_composite cpu_muxes[] __initconst = { | |
+ MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2), | |
+}; | |
+ | |
+static const struct mtk_composite top_muxes[] __initconst = { | |
+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, | |
+ 0x0040, 0, 3, INVALID_MUX_GATE_BIT), | |
+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, | |
+ 0x0040, 8, 1, 15), | |
+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, | |
+ 0x0040, 16, 1, 23), | |
+ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, | |
+ 0x0040, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, | |
+ 0x0050, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, | |
+ 0x0050, 8, 4, 15), | |
+ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, | |
+ 0x0050, 16, 3, 23), | |
+ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, | |
+ 0x0050, 24, 3, 31), | |
+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, | |
+ 0x0060, 0, 1, 7), | |
+ | |
+ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents, | |
+ 0x0060, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, | |
+ 0x0060, 16, 2, 23), | |
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, | |
+ 0x0060, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, | |
+ 0x0070, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, | |
+ 0x0070, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents, | |
+ 0x0070, 16, 1, 23), | |
+ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, | |
+ 0x0070, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, | |
+ 0x0080, 0, 4, 7), | |
+ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, | |
+ 0x0080, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, | |
+ 0x0080, 16, 3, 23), | |
+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, | |
+ 0x0080, 24, 2, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, | |
+ 0x0090, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, | |
+ 0x0090, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, | |
+ 0x0090, 16, 3, 23), | |
+ | |
+ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, | |
+ 0x00A0, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, | |
+ 0x00A0, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents, | |
+ 0x00A0, 24, 2, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, | |
+ 0x00B0, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents, | |
+ 0x00B0, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents, | |
+ 0x00B0, 16, 3, 23), | |
+ MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents, | |
+ 0x00B0, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel", | |
+ hdmirx_bist_parents, 0x00C0, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, | |
+ 0x00C0, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents, | |
+ 0x00C0, 16, 2, 23), | |
+ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents, | |
+ 0x00C0, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents, | |
+ 0x00D0, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents, | |
+ 0x00D0, 16, 2, 23), | |
+ MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents, | |
+ 0x00D0, 24, 3, 31), | |
+ | |
+ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents, | |
+ 0x00E0, 0, 1, 7), | |
+ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, | |
+ 0x00E0, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents, | |
+ 0x00E0, 16, 4, 23), | |
+ | |
+ MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents, | |
+ 0x00E0, 24, 3, 31), | |
+ MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents, | |
+ 0x00F0, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents, | |
+ 0x00F0, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents, | |
+ 0x00F0, 16, 1, 23), | |
+ | |
+ MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents, | |
+ 0x0100, 0, 3), | |
+ | |
+ MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents, | |
+ 0x012c, 0, 3), | |
+ MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents, | |
+ 0x012c, 3, 3), | |
+ MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents, | |
+ 0x012c, 6, 3), | |
+ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents, | |
+ 0x012c, 15, 1, 23), | |
+ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents, | |
+ 0x012c, 16, 1, 24), | |
+ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents, | |
+ 0x012c, 17, 1, 25), | |
+ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents, | |
+ 0x012c, 18, 1, 26), | |
+ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents, | |
+ 0x012c, 19, 1, 27), | |
+ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents, | |
+ 0x012c, 20, 1, 28), | |
+}; | |
+ | |
+static const struct mtk_clk_divider top_adj_divs[] __initconst = { | |
+ DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext1", | |
+ 0x0120, 0, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext2", | |
+ 0x0120, 8, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel", | |
+ 0x0120, 16, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel", | |
+ 0x0120, 24, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel", | |
+ 0x0124, 0, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel", | |
+ 0x0124, 8, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel", | |
+ 0x0124, 16, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel", | |
+ 0x0124, 24, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel", | |
+ 0x0128, 0, 8), | |
+ DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel", | |
+ 0x0128, 8, 8), | |
+}; | |
+ | |
+static const struct mtk_gate_regs top_aud_cg_regs __initconst = { | |
+ .sta_ofs = 0x012C, | |
+}; | |
+ | |
+#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &top_aud_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate top_clks[] __initconst = { | |
+ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div", | |
+ 21), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div", | |
+ 22), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div", | |
+ 23), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div", | |
+ 24), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div", | |
+ 25), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div", | |
+ 26), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div", | |
+ 27), | |
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", | |
+ 28), | |
+}; | |
+ | |
+static struct clk_onecell_data *top_clk_data __initdata; | |
+static struct clk_onecell_data *pll_clk_data __initdata; | |
+ | |
+static void __init mtk_clk_enable_critical(void) | |
+{ | |
+ if (!top_clk_data || !pll_clk_data) | |
+ return; | |
+ | |
+ clk_prepare_enable(pll_clk_data->clks[CLK_APMIXED_ARMPLL]); | |
+ clk_prepare_enable(top_clk_data->clks[CLK_TOP_AXI_SEL]); | |
+ clk_prepare_enable(top_clk_data->clks[CLK_TOP_MEM_SEL]); | |
+ clk_prepare_enable(top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]); | |
+ clk_prepare_enable(top_clk_data->clks[CLK_TOP_RTC_SEL]); | |
+} | |
+ | |
+static void __init mtk_topckgen_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ void __iomem *base; | |
+ int r; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR); | |
+ | |
+ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), | |
+ clk_data); | |
+ | |
+ mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), | |
+ clk_data); | |
+ | |
+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), | |
+ base, &lock, clk_data); | |
+ | |
+ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), | |
+ base, &lock, clk_data); | |
+ | |
+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_clk_enable_critical(); | |
+} | |
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init); | |
+ | |
+static const struct mtk_gate_regs infra_cg_regs __initconst = { | |
+ .set_ofs = 0x0040, | |
+ .clr_ofs = 0x0044, | |
+ .sta_ofs = 0x0048, | |
+}; | |
+ | |
+#define GATE_ICG(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &infra_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate infra_clks[] __initconst = { | |
+ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0), | |
+ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1), | |
+ GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2), | |
+ GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2pll_294m", 4), | |
+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk26m", 5), | |
+ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6), | |
+ GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7), | |
+ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), | |
+ GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12), | |
+ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13), | |
+ GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14), | |
+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15), | |
+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16), | |
+ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18), | |
+ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19), | |
+ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22), | |
+ GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23), | |
+ GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24), | |
+}; | |
+ | |
+static const struct mtk_fixed_factor infra_fixed_divs[] __initconst = { | |
+ FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2), | |
+}; | |
+ | |
+static void __init mtk_infrasys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); | |
+ | |
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), | |
+ clk_data); | |
+ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs), | |
+ clk_data); | |
+ | |
+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 2, 0x30); | |
+} | |
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init); | |
+ | |
+static const struct mtk_gate_regs peri0_cg_regs __initconst = { | |
+ .set_ofs = 0x0008, | |
+ .clr_ofs = 0x0010, | |
+ .sta_ofs = 0x0018, | |
+}; | |
+ | |
+static const struct mtk_gate_regs peri1_cg_regs __initconst = { | |
+ .set_ofs = 0x000c, | |
+ .clr_ofs = 0x0014, | |
+ .sta_ofs = 0x001c, | |
+}; | |
+ | |
+#define GATE_PERI0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &peri0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+#define GATE_PERI1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &peri1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate peri_clks[] __initconst = { | |
+ GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31), | |
+ GATE_PERI0(CLK_PERI_ETH, "eth_ck", "clk26m", 30), | |
+ GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29), | |
+ GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28), | |
+ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27), | |
+ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26), | |
+ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25), | |
+ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24), | |
+ GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23), | |
+ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22), | |
+ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21), | |
+ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20), | |
+ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19), | |
+ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18), | |
+ GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17), | |
+ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16), | |
+ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15), | |
+ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14), | |
+ GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13), | |
+ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12), | |
+ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), | |
+ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), | |
+ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), | |
+ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axisel_d4", 8), | |
+ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axisel_d4", 7), | |
+ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axisel_d4", 6), | |
+ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axisel_d4", 5), | |
+ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axisel_d4", 4), | |
+ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axisel_d4", 3), | |
+ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axisel_d4", 2), | |
+ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), | |
+ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0), | |
+ | |
+ GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card_sel", 11), | |
+ GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10), | |
+ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9), | |
+ GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8), | |
+ GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7), | |
+ GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6), | |
+ GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5), | |
+ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi1x_pad", 4), | |
+ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi1x_pad", 3), | |
+ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2), | |
+ GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1), | |
+ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0), | |
+}; | |
+ | |
+static const char * const uart_ck_sel_parents[] __initconst = { | |
+ "clk26m", | |
+ "uart_sel", | |
+}; | |
+ | |
+static const struct mtk_composite peri_muxs[] __initconst = { | |
+ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, | |
+ 0x40c, 0, 1), | |
+ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, | |
+ 0x40c, 1, 1), | |
+ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, | |
+ 0x40c, 2, 1), | |
+ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, | |
+ 0x40c, 3, 1), | |
+}; | |
+ | |
+static void __init mtk_pericfg_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ void __iomem *base; | |
+ int r; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR); | |
+ | |
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), | |
+ clk_data); | |
+ | |
+ mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base, | |
+ &lock, clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 2, 0x0); | |
+} | |
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init); | |
+ | |
+static const struct mtk_gate_regs disp0_cg_regs __initconst = { | |
+ .set_ofs = 0x0104, | |
+ .clr_ofs = 0x0108, | |
+ .sta_ofs = 0x0100, | |
+}; | |
+ | |
+static const struct mtk_gate_regs disp1_cg_regs __initconst = { | |
+ .set_ofs = 0x0114, | |
+ .clr_ofs = 0x0118, | |
+ .sta_ofs = 0x0110, | |
+}; | |
+ | |
+#define GATE_DISP0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &disp0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+#define GATE_DISP1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &disp1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate mm_clks[] __initconst = { | |
+ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0), | |
+ GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), | |
+ GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2), | |
+ GATE_DISP0(CLK_MM_MUTEX, "mm_mutex", "mm_sel", 3), | |
+ GATE_DISP0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 4), | |
+ GATE_DISP0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_sel", 5), | |
+ GATE_DISP0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_sel", 6), | |
+ GATE_DISP0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_sel", 7), | |
+ GATE_DISP0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_sel", 8), | |
+ GATE_DISP0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9), | |
+ GATE_DISP0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "mm_sel", 10), | |
+ GATE_DISP0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11), | |
+ GATE_DISP0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 12), | |
+ GATE_DISP0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 13), | |
+ GATE_DISP0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "mm_sel", 14), | |
+ GATE_DISP0(CLK_MM_MDP_BLS_26M, "mm_mdp_bls_26m", "pwm_sel", 15), | |
+ GATE_DISP0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 16), | |
+ GATE_DISP0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 17), | |
+ GATE_DISP0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 18), | |
+ GATE_DISP0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19), | |
+ GATE_DISP0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 20), | |
+ GATE_DISP1(CLK_MM_DSI_ENGINE, "mm_dsi_eng", "mm_sel", 0), | |
+ GATE_DISP1(CLK_MM_DSI_DIG, "mm_dsi_dig", "dsi0_lntc_dsi", 1), | |
+ GATE_DISP1(CLK_MM_DPI_DIGL, "mm_dpi_digl", "dpi0_sel", 2), | |
+ GATE_DISP1(CLK_MM_DPI_ENGINE, "mm_dpi_eng", "mm_sel", 3), | |
+ GATE_DISP1(CLK_MM_DPI1_DIGL, "mm_dpi1_digl", "dpi1_sel", 4), | |
+ GATE_DISP1(CLK_MM_DPI1_ENGINE, "mm_dpi1_eng", "mm_sel", 5), | |
+ GATE_DISP1(CLK_MM_TVE_OUTPUT, "mm_tve_output", "tve_sel", 6), | |
+ GATE_DISP1(CLK_MM_TVE_INPUT, "mm_tve_input", "dpi0_sel", 7), | |
+ GATE_DISP1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi1_sel", 8), | |
+ GATE_DISP1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmi_sel", 9), | |
+ GATE_DISP1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll_sel", 10), | |
+ GATE_DISP1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll_sel", 11), | |
+ GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14), | |
+}; | |
+ | |
+static void __init mtk_mmsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_MM_NR); | |
+ | |
+ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+ | |
+static const struct mtk_gate_regs img_cg_regs __initconst = { | |
+ .set_ofs = 0x0004, | |
+ .clr_ofs = 0x0008, | |
+ .sta_ofs = 0x0000, | |
+}; | |
+ | |
+#define GATE_IMG(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &img_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate img_clks[] __initconst = { | |
+ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0), | |
+ GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1), | |
+ GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5), | |
+ GATE_IMG(CLK_IMG_JPGDEC, "img_jpgdec", "mm_sel", 6), | |
+ GATE_IMG(CLK_IMG_VENC_LT, "img_venc_lt", "mm_sel", 8), | |
+ GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9), | |
+}; | |
+ | |
+static void __init mtk_imgsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_IMG_NR); | |
+ | |
+ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+ | |
+static const struct mtk_gate_regs vdec0_cg_regs __initconst = { | |
+ .set_ofs = 0x0000, | |
+ .clr_ofs = 0x0004, | |
+ .sta_ofs = 0x0000, | |
+}; | |
+ | |
+static const struct mtk_gate_regs vdec1_cg_regs __initconst = { | |
+ .set_ofs = 0x0008, | |
+ .clr_ofs = 0x000c, | |
+ .sta_ofs = 0x0008, | |
+}; | |
+ | |
+#define GATE_VDEC0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &vdec0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr_inv, \ | |
+ } | |
+ | |
+#define GATE_VDEC1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &vdec1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate vdec_clks[] __initconst = { | |
+ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0), | |
+ GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0), | |
+}; | |
+ | |
+static void __init mtk_vdecsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_VDEC_NR); | |
+ | |
+ mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+ | |
+static const struct mtk_gate_regs hif_cg_regs __initconst = { | |
+ .sta_ofs = 0x0030, | |
+}; | |
+ | |
+#define GATE_HIF(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &hif_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate hif_clks[] __initconst = { | |
+ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21), | |
+ GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22), | |
+ GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24), | |
+ GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25), | |
+ GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26), | |
+}; | |
+ | |
+static void __init mtk_hifsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR); | |
+ | |
+ mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 1, 0x34); | |
+} | |
+ | |
+static const struct mtk_gate_regs eth_cg_regs __initconst = { | |
+ .sta_ofs = 0x0030, | |
+}; | |
+ | |
+#define GATE_ETH(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = ð_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate eth_clks[] __initconst = { | |
+ GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5), | |
+ GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6), | |
+ GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7), | |
+ GATE_ETH(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8), | |
+ GATE_ETH(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11), | |
+ GATE_ETH(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14), | |
+ GATE_ETH(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17), | |
+ GATE_ETH(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29), | |
+}; | |
+ | |
+static void __init mtk_ethsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR); | |
+ | |
+ mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 1, 0x34); | |
+} | |
+ | |
+static const struct mtk_gate_regs bdp0_cg_regs __initconst = { | |
+ .set_ofs = 0x0104, | |
+ .clr_ofs = 0x0108, | |
+ .sta_ofs = 0x0100, | |
+}; | |
+ | |
+static const struct mtk_gate_regs bdp1_cg_regs __initconst = { | |
+ .set_ofs = 0x0114, | |
+ .clr_ofs = 0x0118, | |
+ .sta_ofs = 0x0110, | |
+}; | |
+ | |
+#define GATE_BDP0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &bdp0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr_inv, \ | |
+ } | |
+ | |
+#define GATE_BDP1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &bdp1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate bdp_clks[] __initconst = { | |
+ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0), | |
+ GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1), | |
+ GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2), | |
+ GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3), | |
+ GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4), | |
+ GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5), | |
+ GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6), | |
+ GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi1_sel", 7), | |
+ GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8), | |
+ GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9), | |
+ GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10), | |
+ GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11), | |
+ GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12), | |
+ GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13), | |
+ GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14), | |
+ GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15), | |
+ GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16), | |
+ GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17), | |
+ GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18), | |
+ GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19), | |
+ GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20), | |
+ GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21), | |
+ GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22), | |
+ GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23), | |
+ GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24), | |
+ GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25), | |
+ GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26), | |
+ GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27), | |
+ GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28), | |
+ GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29), | |
+ GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30), | |
+ GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31), | |
+ GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0), | |
+ GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1), | |
+ GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2), | |
+ GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3), | |
+ GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4), | |
+ GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5), | |
+ GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6), | |
+ GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7), | |
+ GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8), | |
+ GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9), | |
+ GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10), | |
+ GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11), | |
+ GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12), | |
+ GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13), | |
+ GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14), | |
+ GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15), | |
+ GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_pll340m", 16), | |
+}; | |
+ | |
+static void __init mtk_bdpsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_BDP_NR); | |
+ | |
+ mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks), | |
+ clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+ | |
+#define MT8590_PLL_FMAX (2000 * MHZ) | |
+#define CON0_MT8590_RST_BAR BIT(27) | |
+ | |
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \ | |
+ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .reg = _reg, \ | |
+ .pwr_reg = _pwr_reg, \ | |
+ .en_mask = _en_mask, \ | |
+ .flags = _flags, \ | |
+ .rst_bar_mask = CON0_MT8590_RST_BAR, \ | |
+ .fmax = MT8590_PLL_FMAX, \ | |
+ .pcwbits = _pcwbits, \ | |
+ .pd_reg = _pd_reg, \ | |
+ .pd_shift = _pd_shift, \ | |
+ .tuner_reg = _tuner_reg, \ | |
+ .pcw_reg = _pcw_reg, \ | |
+ .pcw_shift = _pcw_shift, \ | |
+ } | |
+ | |
+static const struct mtk_pll_data apmixed_plls[] = { | |
+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0, | |
+ 21, 0x204, 24, 0x0, 0x204, 0), | |
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001, | |
+ HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0), | |
+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001, | |
+ HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14), | |
+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, | |
+ 21, 0x230, 4, 0x0, 0x234, 0), | |
+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, | |
+ 21, 0x240, 4, 0x0, 0x244, 0), | |
+ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0, | |
+ 21, 0x250, 4, 0x0, 0x254, 0), | |
+ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0, | |
+ 31, 0x270, 4, 0x0, 0x274, 0), | |
+ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0, | |
+ 31, 0x280, 4, 0x0, 0x284, 0), | |
+ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0, | |
+ 31, 0x290, 4, 0x0, 0x294, 0), | |
+ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0, | |
+ 31, 0x2a0, 4, 0x0, 0x2a4, 0), | |
+ PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0, | |
+ 31, 0x2b0, 4, 0x0, 0x2b4, 0), | |
+ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0, | |
+ 31, 0x2c0, 4, 0x0, 0x2c4, 0), | |
+ PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0, | |
+ 21, 0x2d0, 4, 0x0, 0x2d4, 0), | |
+}; | |
+ | |
+static void __init mtk_apmixedsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ struct clk *clk; | |
+ void __iomem *base; | |
+ int r; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR); | |
+ if (!clk_data) | |
+ return; | |
+ | |
+ mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls), | |
+ clk_data); | |
+ | |
+ clk = clk_register_divider(NULL, "hdmi_ref", "tvdpll", 0, base + 0x40, | |
+ 16, 3, CLK_DIVIDER_POWER_OF_TWO, NULL); | |
+ | |
+ clk_data->clks[CLK_APMIXED_HDMI_REF] = clk; | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_clk_enable_critical(); | |
+} | |
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys", | |
+ mtk_apmixedsys_init); | |
+ | |
+static const struct of_device_id of_clk_match_tbl[] = { | |
+ { | |
+ .compatible = "mediatek,mt2701-mmsys", | |
+ .data = mtk_mmsys_init, | |
+ }, { | |
+ .compatible = "mediatek,mt2701-imgsys", | |
+ .data = mtk_imgsys_init, | |
+ }, { | |
+ .compatible = "mediatek,mt2701-vdecsys", | |
+ .data = mtk_vdecsys_init, | |
+ }, { | |
+ .compatible = "mediatek,mt2701-hifsys", | |
+ .data = mtk_hifsys_init, | |
+ }, { | |
+ .compatible = "mediatek,mt2701-ethsys", | |
+ .data = mtk_ethsys_init, | |
+ }, { | |
+ .compatible = "mediatek,mt2701-bdpsys", | |
+ .data = mtk_bdpsys_init, | |
+ }, { | |
+ /* sentinel */ | |
+ } | |
+}; | |
+ | |
+static int __init clk_probe(struct platform_device *pdev) | |
+{ | |
+ void (*clk_init)(struct device_node *); | |
+ const struct of_device_id *of_id; | |
+ | |
+ of_id = of_match_node(of_clk_match_tbl, pdev->dev.of_node); | |
+ if (!of_id || !of_id->data) | |
+ return -EINVAL; | |
+ | |
+ clk_init = of_id->data; | |
+ clk_init(pdev->dev.of_node); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static struct platform_driver clk_drv = { | |
+ .driver = { | |
+ .name = "mtk-clk", | |
+ .owner = THIS_MODULE, | |
+ .of_match_table = of_match_ptr(of_clk_match_tbl), | |
+ }, | |
+}; | |
+ | |
+builtin_platform_driver_probe(clk_drv, clk_probe); | |
diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c | |
new file mode 100644 | |
index 000000000000..8d0dd8fc146e | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clk-mt7622.c | |
@@ -0,0 +1,958 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Chen Zhong <chen.zhong@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/clk.h> | |
+#include <linux/delay.h> | |
+#include <linux/of.h> | |
+#include <linux/of_address.h> | |
+#include <linux/slab.h> | |
+#include <linux/mfd/syscon.h> | |
+ | |
+#include "clk-mtk.h" | |
+#include "clk-gate.h" | |
+ | |
+#include <dt-bindings/clock/mt7622-clk.h> | |
+ | |
+static DEFINE_SPINLOCK(mt7622_clk_lock); | |
+ | |
+static const struct mtk_fixed_clk top_fixed_clks[] __initconst = { | |
+ FIXED_CLK(CLK_TOP_TO_U2_PHY, "to_u2_phy", "clkxtal", 31250000), | |
+ FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, "to_u2_phy_1p", "clkxtal", 31250000), | |
+ FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, "pcie0_pipe_en", "clkxtal", 125000000), | |
+ FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, "pcie1_pipe_en", "clkxtal", 125000000), | |
+ FIXED_CLK(CLK_TOP_SSUSB_TX250M, "ssusb_tx250m", "clkxtal", 250000000), | |
+ FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, "ssusb_eq_rx250m", "clkxtal", 250000000), | |
+ FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, "ssusb_cdr_ref", "clkxtal", 33333333), | |
+ FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, "ssusb_cdr_fb", "clkxtal", 50000000), | |
+ FIXED_CLK(CLK_TOP_SATA_ASIC, "sata_asic", "clkxtal", 50000000), | |
+ FIXED_CLK(CLK_TOP_SATA_RBC, "sata_rbc", "clkxtal", 50000000), | |
+}; | |
+ | |
+static const struct mtk_fixed_factor top_divs[] __initconst = { | |
+ FACTOR(CLK_TOP_TO_USB3_SYS, "to_usb3_sys", "eth1pll", 1, 4), | |
+ FACTOR(CLK_TOP_P1_1MHZ, "p1_1mhz", "eth1pll", 1, 500), | |
+ FACTOR(CLK_TOP_4MHZ, "free_run_4mhz", "eth1pll", 1, 125), | |
+ FACTOR(CLK_TOP_P0_1MHZ, "p0_1mhz", "eth1pll", 1, 500), | |
+ FACTOR(CLK_TOP_TXCLK_SRC_PRE, "txclk_src_pre", "sgmiipll_d2", 1, 1), | |
+ FACTOR(CLK_TOP_RTC, "rtc", "clkxtal", 1, 1024), | |
+ FACTOR(CLK_TOP_MEMPLL, "mempll", "clkxtal", 32, 1), | |
+ FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1), | |
+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), | |
+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 4), | |
+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 8), | |
+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 16), | |
+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 12), | |
+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll", 1, 24), | |
+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), | |
+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 10), | |
+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 20), | |
+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 14), | |
+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 28), | |
+ FACTOR(CLK_TOP_SYSPLL4_D16, "syspll4_d16", "mainpll", 1, 112), | |
+ FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 4), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 8), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 16), | |
+ FACTOR(CLK_TOP_UNIVPLL1_D16, "univpll1_d16", "univpll", 1, 32), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 6), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 12), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 24), | |
+ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll", 1, 48), | |
+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 10), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 20), | |
+ FACTOR(CLK_TOP_UNIVPLL3_D16, "univpll3_d16", "univpll", 1, 80), | |
+ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), | |
+ FACTOR(CLK_TOP_UNIVPLL_D80_D4, "univpll_d80_d4", "univpll", 1, 320), | |
+ FACTOR(CLK_TOP_UNIV48M, "univ48m", "univpll", 1, 25), | |
+ FACTOR(CLK_TOP_SGMIIPLL, "sgmiipll_ck", "sgmipll", 1, 1), | |
+ FACTOR(CLK_TOP_SGMIIPLL_D2, "sgmiipll_d2", "sgmipll", 1, 2), | |
+ FACTOR(CLK_TOP_AUD1PLL, "aud1pll_ck", "aud1pll", 1, 1), | |
+ FACTOR(CLK_TOP_AUD2PLL, "aud2pll_ck", "aud2pll", 1, 1), | |
+ FACTOR(CLK_TOP_AUD_I2S2_MCK, "aud_i2s2_mck", "i2s2_mck_sel", 1, 2), | |
+ FACTOR(CLK_TOP_TO_USB3_REF, "to_usb3_ref", "univpll2_d4", 1, 4), | |
+ FACTOR(CLK_TOP_PCIE1_MAC_EN, "pcie1_mac_en", "univpll1_d4", 1, 1), | |
+ FACTOR(CLK_TOP_PCIE0_MAC_EN, "pcie0_mac_en", "univpll1_d4", 1, 1), | |
+ FACTOR(CLK_TOP_ETH_500M, "eth_500m", "eth1pll", 1, 1), | |
+}; | |
+ | |
+static const char * const axi_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll1_d2", | |
+ "syspll_d5", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "univpll2_d2", | |
+ "univpll_d7" | |
+}; | |
+ | |
+static const char * const mem_parents[] __initconst = { | |
+ "clkxtal", | |
+ "dmpll_ck" | |
+}; | |
+ | |
+static const char * const ddrphycfg_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll1_d8" | |
+}; | |
+ | |
+static const char * const eth_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll1_d2", | |
+ "univpll1_d2", | |
+ "syspll1_d4", | |
+ "univpll_d5", | |
+ "clk_null", | |
+ "univpll_d7" | |
+}; | |
+ | |
+static const char * const pwm_parents[] __initconst = { | |
+ "clkxtal", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const f10m_ref_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll4_d16" | |
+}; | |
+ | |
+static const char * const nfi_infra_parents[] __initconst = { | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "clkxtal", | |
+ "univpll2_d8", | |
+ "syspll1_d8", | |
+ "univpll1_d8", | |
+ "syspll4_d2", | |
+ "univpll2_d4", | |
+ "univpll3_d2", | |
+ "syspll1_d4" | |
+}; | |
+ | |
+static const char * const flash_parents[] __initconst = { | |
+ "clkxtal", | |
+ "univpll_d80_d4", | |
+ "syspll2_d8", | |
+ "syspll3_d4", | |
+ "univpll3_d4", | |
+ "univpll1_d8", | |
+ "syspll2_d4", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const uart_parents[] __initconst = { | |
+ "clkxtal", | |
+ "univpll2_d8" | |
+}; | |
+ | |
+static const char * const spi0_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll3_d2", | |
+ "clkxtal", | |
+ "syspll2_d4", | |
+ "syspll4_d2", | |
+ "univpll2_d4", | |
+ "univpll1_d8", | |
+ "clkxtal" | |
+}; | |
+ | |
+static const char * const spi1_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll3_d2", | |
+ "clkxtal", | |
+ "syspll4_d4", | |
+ "syspll4_d2", | |
+ "univpll2_d4", | |
+ "univpll1_d8", | |
+ "clkxtal" | |
+}; | |
+ | |
+static const char * const msdc30_0_parents[] __initconst = { | |
+ "clkxtal", | |
+ "univpll2_d16", | |
+ "univ48m" | |
+}; | |
+ | |
+static const char * const a1sys_hp_parents[] __initconst = { | |
+ "clkxtal", | |
+ "aud1pll_ck", | |
+ "aud2pll_ck", | |
+ "clkxtal" | |
+}; | |
+ | |
+static const char * const intdir_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll_d2", | |
+ "univpll_d2", | |
+ "sgmiipll_ck" | |
+}; | |
+ | |
+static const char * const aud_intbus_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll1_d4", | |
+ "syspll4_d2", | |
+ "syspll3_d2" | |
+}; | |
+ | |
+static const char * const pmicspi_parents[] __initconst = { | |
+ "clkxtal", | |
+ "clk_null", | |
+ "clk_null", | |
+ "clk_null", | |
+ "clk_null", | |
+ "univpll2_d16" | |
+}; | |
+ | |
+static const char * const atb_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll1_d2", | |
+ "syspll_d5" | |
+}; | |
+ | |
+static const char * const audio_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll3_d4", | |
+ "syspll4_d4", | |
+ "univpll1_d16" | |
+}; | |
+ | |
+static const char * const usb20_parents[] __initconst = { | |
+ "clkxtal", | |
+ "univpll3_d4", | |
+ "syspll1_d8", | |
+ "clkxtal" | |
+}; | |
+ | |
+static const char * const aud1_parents[] __initconst = { | |
+ "clkxtal", | |
+ "aud1pll_ck" | |
+}; | |
+ | |
+static const char * const aud2_parents[] __initconst = { | |
+ "clkxtal", | |
+ "aud2pll_ck" | |
+}; | |
+ | |
+static const char * const asm_l_parents[] __initconst = { | |
+ "clkxtal", | |
+ "syspll_d5", | |
+ "univpll2_d2", | |
+ "univpll2_d4" | |
+}; | |
+ | |
+static const char * const apll1_ck_parents[] __initconst = { | |
+ "aud1_sel", | |
+ "aud2_sel" | |
+}; | |
+ | |
+static struct mtk_composite top_muxes[] __initdata = { | |
+ /* CLK_CFG_0 */ | |
+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x040, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x040, 8, 1, 15), | |
+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x040, 16, 1, 23), | |
+ MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents, 0x040, 24, 3, 31), | |
+ /* CLK_CFG_1 */ | |
+ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x050, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_F10M_REF_SEL, "f10m_ref_sel", f10m_ref_parents, 0x050, 8, 1, 15), | |
+ MUX_GATE(CLK_TOP_NFI_INFRA_SEL, "nfi_infra_sel", nfi_infra_parents, 0x050, 16, 4, 23), | |
+ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, 0x050, 24, 3, 31), | |
+ /* CLK_CFG_2 */ | |
+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x060, 0, 1, 7), | |
+ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi0_parents, 0x060, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_SPI1_SEL, "spi1_sel", spi1_parents, 0x060, 16, 3, 23), | |
+ MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", uart_parents, 0x060, 24, 3, 31), | |
+ /* CLK_CFG_3 */ | |
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_parents, 0x070, 0, 3, 7), | |
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_0_parents, 0x070, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_A1SYS_HP_SEL, "a1sys_hp_sel", a1sys_hp_parents, 0x070, 16, 2, 23), | |
+ MUX_GATE(CLK_TOP_A2SYS_HP_SEL, "a2sys_hp_sel", a1sys_hp_parents, 0x070, 24, 2, 31), | |
+ /* CLK_CFG_4 */ | |
+ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, 0x080, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x080, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x080, 16, 3, 23), | |
+ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", ddrphycfg_parents, 0x080, 24, 2, 31), | |
+ /* CLK_CFG_5 */ | |
+ MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, 0x090, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_HIF_SEL, "hif_sel", eth_parents, 0x090, 8, 3, 15), | |
+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x090, 16, 2, 23), | |
+ MUX_GATE(CLK_TOP_U2_SEL, "usb20_sel", usb20_parents, 0x090, 24, 2, 31), | |
+ /* CLK_CFG_6 */ | |
+ MUX_GATE(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents, 0x0A0, 0, 1, 7), | |
+ MUX_GATE(CLK_TOP_AUD2_SEL, "aud2_sel", aud2_parents, 0x0A0, 8, 1, 15), | |
+ MUX_GATE(CLK_TOP_IRRX_SEL, "irrx_sel", f10m_ref_parents, 0x0A0, 16, 1, 23), | |
+ MUX_GATE(CLK_TOP_IRTX_SEL, "irtx_sel", f10m_ref_parents, 0x0A0, 24, 1, 31), | |
+ /* CLK_CFG_7 */ | |
+ MUX_GATE(CLK_TOP_ASM_L_SEL, "asm_l_sel", asm_l_parents, 0x0B0, 0, 2, 7), | |
+ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_l_parents, 0x0B0, 8, 2, 15), | |
+ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_l_parents, 0x0B0, 16, 2, 23), | |
+ /* CLK_AUDDIV_0 */ | |
+ MUX(CLK_TOP_APLL1_SEL, "apll1_ck_sel", apll1_ck_parents, 0x120, 6, 1), | |
+ MUX(CLK_TOP_APLL2_SEL, "apll2_ck_sel", apll1_ck_parents, 0x120, 7, 1), | |
+ MUX(CLK_TOP_I2S0_MCK_SEL, "i2s0_mck_sel", apll1_ck_parents, 0x120, 8, 1), | |
+ MUX(CLK_TOP_I2S1_MCK_SEL, "i2s1_mck_sel", apll1_ck_parents, 0x120, 9, 1), | |
+ MUX(CLK_TOP_I2S2_MCK_SEL, "i2s2_mck_sel", apll1_ck_parents, 0x120, 10, 1), | |
+ MUX(CLK_TOP_I2S3_MCK_SEL, "i2s3_mck_sel", apll1_ck_parents, 0x120, 11, 1), | |
+}; | |
+ | |
+static const char * const peribus_ck_parents[] __initconst = { | |
+ "syspll1_d8", | |
+ "syspll1_d4" | |
+}; | |
+ | |
+static struct mtk_composite peri_muxes[] __initdata = { | |
+ /* PERI_GLOBALCON_CKSEL */ | |
+ MUX(CLK_PERIBUS_SEL, "peribus_ck_sel", peribus_ck_parents, 0x05C, 0, 1), | |
+}; | |
+ | |
+static const char * const infra_mux1_parents[] __initconst = { | |
+ "clkxtal", | |
+ "armpll", | |
+ "main_core_en", | |
+ "armpll" | |
+}; | |
+ | |
+static struct mtk_composite infra_muxes[] __initdata = { | |
+ /* INFRA_TOPCKGEN_CKMUXSEL */ | |
+ MUX(CLK_INFRA_MUX1_SEL, "infra_mux1_sel", infra_mux1_parents, 0x000, 2, 2), | |
+}; | |
+ | |
+static const struct mtk_clk_divider top_adj_divs[] = { | |
+ DIV_ADJ(CLK_TOP_APLL1_DIV, "apll1_ck_div", "apll1_ck_sel", 0x120, 24, 3), | |
+ DIV_ADJ(CLK_TOP_APLL2_DIV, "apll2_ck_div", "apll2_ck_sel", 0x120, 28, 3), | |
+ DIV_ADJ(CLK_TOP_I2S0_MCK_DIV, "i2s0_mck_div", "i2s0_mck_sel", 0x124, 0, 7), | |
+ DIV_ADJ(CLK_TOP_I2S1_MCK_DIV, "i2s1_mck_div", "i2s1_mck_sel", 0x124, 8, 7), | |
+ DIV_ADJ(CLK_TOP_I2S2_MCK_DIV, "i2s2_mck_div", "aud_i2s2_mck", 0x124, 16, 7), | |
+ DIV_ADJ(CLK_TOP_I2S3_MCK_DIV, "i2s3_mck_div", "i2s3_mck_sel", 0x124, 24, 7), | |
+ DIV_ADJ(CLK_TOP_A1SYS_HP_DIV, "a1sys_div", "a1sys_hp_sel", 0x128, 8, 7), | |
+ DIV_ADJ(CLK_TOP_A2SYS_HP_DIV, "a2sys_div", "a2sys_hp_sel", 0x128, 24, 7), | |
+}; | |
+ | |
+static const struct mtk_gate_regs top0_cg_regs = { | |
+ .set_ofs = 0x120, | |
+ .clr_ofs = 0x120, | |
+ .sta_ofs = 0x120, | |
+}; | |
+ | |
+static const struct mtk_gate_regs top1_cg_regs = { | |
+ .set_ofs = 0x128, | |
+ .clr_ofs = 0x128, | |
+ .sta_ofs = 0x128, | |
+}; | |
+ | |
+#define GATE_TOP0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &top0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+#define GATE_TOP1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &top1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate top_clks[] __initconst = { | |
+ /* TOP0 */ | |
+ GATE_TOP0(CLK_TOP_APLL1_DIV_PD, "apll1_ck_div_pd", "apll1_ck_div", 0), | |
+ GATE_TOP0(CLK_TOP_APLL2_DIV_PD, "apll2_ck_div_pd", "apll2_ck_div", 1), | |
+ GATE_TOP0(CLK_TOP_I2S0_MCK_DIV_PD, "i2s0_mck_div_pd", "i2s0_mck_div", 2), | |
+ GATE_TOP0(CLK_TOP_I2S1_MCK_DIV_PD, "i2s1_mck_div_pd", "i2s1_mck_div", 3), | |
+ GATE_TOP0(CLK_TOP_I2S2_MCK_DIV_PD, "i2s2_mck_div_pd", "i2s2_mck_div", 4), | |
+ GATE_TOP0(CLK_TOP_I2S3_MCK_DIV_PD, "i2s3_mck_div_pd", "i2s3_mck_div", 5), | |
+ /* TOP1 */ | |
+ GATE_TOP1(CLK_TOP_A1SYS_HP_DIV_PD, "a1sys_div_pd", "a1sys_div", 0), | |
+ GATE_TOP1(CLK_TOP_A2SYS_HP_DIV_PD, "a2sys_div_pd", "a2sys_div", 16), | |
+}; | |
+ | |
+static const struct mtk_gate_regs infra_cg_regs = { | |
+ .set_ofs = 0x40, | |
+ .clr_ofs = 0x44, | |
+ .sta_ofs = 0x48, | |
+}; | |
+ | |
+#define GATE_INFRA(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &infra_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate infra_clks[] __initconst = { | |
+ GATE_INFRA(CLK_INFRA_DBGCLK_PD, "infra_dbgclk_pd", "axi_sel", 0), | |
+ GATE_INFRA(CLK_INFRA_TRNG_PD, "infra_trng_pd", "axi_sel", 2), | |
+ GATE_INFRA(CLK_INFRA_AUDIO_PD, "infra_audio_pd", "aud_intbus_sel", 5), | |
+ GATE_INFRA(CLK_INFRA_IRRX_PD, "infra_irrx_pd", "irrx_sel", 16), | |
+ GATE_INFRA(CLK_INFRA_APXGPT_PD, "infra_apxgpt_pd", "f10m_ref_sel", 18), | |
+ GATE_INFRA(CLK_INFRA_PMIC_PD, "infra_pmic_pd", "pmicspi_sel", 22), | |
+}; | |
+ | |
+static const struct mtk_gate_regs peri0_cg_regs = { | |
+ .set_ofs = 0x8, | |
+ .clr_ofs = 0x10, | |
+ .sta_ofs = 0x18, | |
+}; | |
+ | |
+static const struct mtk_gate_regs peri1_cg_regs = { | |
+ .set_ofs = 0xC, | |
+ .clr_ofs = 0x14, | |
+ .sta_ofs = 0x1C, | |
+}; | |
+ | |
+#define GATE_PERI0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &peri0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+#define GATE_PERI1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &peri1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate peri_clks[] __initconst = { | |
+ /* PERI0 */ | |
+ GATE_PERI0(CLK_PERI_THERM_PD, "peri_therm_pd", "axi_sel", 1), | |
+ GATE_PERI0(CLK_PERI_PWM1_PD, "peri_pwm1_pd", "clkxtal", 2), | |
+ GATE_PERI0(CLK_PERI_PWM2_PD, "peri_pwm2_pd", "clkxtal", 3), | |
+ GATE_PERI0(CLK_PERI_PWM3_PD, "peri_pwm3_pd", "clkxtal", 4), | |
+ GATE_PERI0(CLK_PERI_PWM4_PD, "peri_pwm4_pd", "clkxtal", 5), | |
+ GATE_PERI0(CLK_PERI_PWM5_PD, "peri_pwm5_pd", "clkxtal", 6), | |
+ GATE_PERI0(CLK_PERI_PWM6_PD, "peri_pwm6_pd", "clkxtal", 7), | |
+ GATE_PERI0(CLK_PERI_PWM7_PD, "peri_pwm7_pd", "clkxtal", 8), | |
+ GATE_PERI0(CLK_PERI_PWM_PD, "peri_pwm_pd", "clkxtal", 9), | |
+ GATE_PERI0(CLK_PERI_AP_DMA_PD, "peri_ap_dma_pd", "axi_sel", 12), | |
+ GATE_PERI0(CLK_PERI_MSDC30_0_PD, "peri_msdc30_0", "msdc30_0_sel", 13), | |
+ GATE_PERI0(CLK_PERI_MSDC30_1_PD, "peri_msdc30_1", "msdc30_1_sel", 14), | |
+ GATE_PERI0(CLK_PERI_UART0_PD, "peri_uart0_pd", "axi_sel", 17), | |
+ GATE_PERI0(CLK_PERI_UART1_PD, "peri_uart1_pd", "axi_sel", 18), | |
+ GATE_PERI0(CLK_PERI_UART2_PD, "peri_uart2_pd", "axi_sel", 19), | |
+ GATE_PERI0(CLK_PERI_UART3_PD, "peri_uart3_pd", "axi_sel", 20), | |
+ GATE_PERI0(CLK_PERI_UART4_PD, "peri_uart4_pd", "axi_sel", 21), | |
+ GATE_PERI0(CLK_PERI_BTIF_PD, "peri_btif_pd", "axi_sel", 22), | |
+ GATE_PERI0(CLK_PERI_I2C0_PD, "peri_i2c0_pd", "axi_sel", 23), | |
+ GATE_PERI0(CLK_PERI_I2C1_PD, "peri_i2c1_pd", "axi_sel", 24), | |
+ GATE_PERI0(CLK_PERI_I2C2_PD, "peri_i2c2_pd", "axi_sel", 25), | |
+ GATE_PERI0(CLK_PERI_SPI1_PD, "peri_spi1_pd", "spi1_sel", 26), | |
+ GATE_PERI0(CLK_PERI_AUXADC_PD, "peri_auxadc_pd", "clkxtal", 27), | |
+ GATE_PERI0(CLK_PERI_SPI0_PD, "peri_spi0_pd", "spi0_sel", 28), | |
+ GATE_PERI0(CLK_PERI_SNFI_PD, "peri_snfi_pd", "nfi_infra_sel", 29), | |
+ GATE_PERI0(CLK_PERI_NFI_PD, "peri_nfi_pd", "axi_sel", 30), | |
+ GATE_PERI0(CLK_PERI_NFIECC_PD, "peri_nfiecc_pd", "axi_sel", 31), | |
+ /* PERI1 */ | |
+ GATE_PERI1(CLK_PERI_FLASH_PD, "peri_flash_pd", "flash_sel", 1), | |
+ GATE_PERI1(CLK_PERI_IRTX_PD, "peri_irtx_pd", "irtx_sel", 2), | |
+}; | |
+ | |
+static const struct mtk_gate_regs apmixed_cg_regs = { | |
+ .set_ofs = 0x8, | |
+ .clr_ofs = 0x8, | |
+ .sta_ofs = 0x8, | |
+}; | |
+ | |
+#define GATE_APMIXED(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &apmixed_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate apmixed_clks[] __initconst = { | |
+ GATE_APMIXED(CLK_APMIXED_MAIN_CORE_EN, "main_core_en", "mainpll", 5), | |
+}; | |
+ | |
+static const struct mtk_gate_regs audio0_cg_regs = { | |
+ .set_ofs = 0x0, | |
+ .clr_ofs = 0x0, | |
+ .sta_ofs = 0x0, | |
+}; | |
+ | |
+static const struct mtk_gate_regs audio1_cg_regs = { | |
+ .set_ofs = 0x10, | |
+ .clr_ofs = 0x10, | |
+ .sta_ofs = 0x10, | |
+}; | |
+ | |
+static const struct mtk_gate_regs audio2_cg_regs = { | |
+ .set_ofs = 0x14, | |
+ .clr_ofs = 0x14, | |
+ .sta_ofs = 0x14, | |
+}; | |
+ | |
+static const struct mtk_gate_regs audio3_cg_regs = { | |
+ .set_ofs = 0x634, | |
+ .clr_ofs = 0x634, | |
+ .sta_ofs = 0x634, | |
+}; | |
+ | |
+#define GATE_AUDIO0(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &audio0_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+#define GATE_AUDIO1(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &audio1_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+#define GATE_AUDIO2(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &audio2_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+#define GATE_AUDIO3(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &audio3_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr, \ | |
+ } | |
+ | |
+static const struct mtk_gate audio_clks[] __initconst = { | |
+ /* AUDIO0 */ | |
+ GATE_AUDIO0(CLK_AUDIO_AFE, "audio_afe", "rtc", 2), | |
+ GATE_AUDIO0(CLK_AUDIO_HDMI, "audio_hdmi", "apll1_ck_sel", 20), | |
+ GATE_AUDIO0(CLK_AUDIO_SPDF, "audio_spdf", "apll1_ck_sel", 21), | |
+ GATE_AUDIO0(CLK_AUDIO_APLL, "audio_apll", "apll1_ck_sel", 23), | |
+ /* AUDIO1 */ | |
+ GATE_AUDIO1(CLK_AUDIO_I2SIN1, "audio_i2sin1", "a1sys_hp_sel", 0), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SIN2, "audio_i2sin2", "a1sys_hp_sel", 1), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SIN3, "audio_i2sin3", "a1sys_hp_sel", 2), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SIN4, "audio_i2sin4", "a1sys_hp_sel", 3), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SO1, "audio_i2so1", "a1sys_hp_sel", 6), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SO2, "audio_i2so2", "a1sys_hp_sel", 7), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SO3, "audio_i2so3", "a1sys_hp_sel", 8), | |
+ GATE_AUDIO1(CLK_AUDIO_I2SO4, "audio_i2so4", "a1sys_hp_sel", 9), | |
+ GATE_AUDIO1(CLK_AUDIO_ASRCI1, "audio_asrci1", "asm_h_sel", 12), | |
+ GATE_AUDIO1(CLK_AUDIO_ASRCI2, "audio_asrci2", "asm_h_sel", 13), | |
+ GATE_AUDIO1(CLK_AUDIO_ASRCO1, "audio_asrco1", "asm_h_sel", 14), | |
+ GATE_AUDIO1(CLK_AUDIO_ASRCO2, "audio_asrco2", "asm_h_sel", 15), | |
+ GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20), | |
+ GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21), | |
+ GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22), | |
+ /* AUDIO2 */ | |
+ GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0), | |
+ GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1), | |
+ GATE_AUDIO2(CLK_AUDIO_UL3, "audio_ul3", "a1sys_hp_sel", 2), | |
+ GATE_AUDIO2(CLK_AUDIO_UL4, "audio_ul4", "a1sys_hp_sel", 3), | |
+ GATE_AUDIO2(CLK_AUDIO_UL5, "audio_ul5", "a1sys_hp_sel", 4), | |
+ GATE_AUDIO2(CLK_AUDIO_UL6, "audio_ul6", "a1sys_hp_sel", 5), | |
+ GATE_AUDIO2(CLK_AUDIO_DL1, "audio_dl1", "a1sys_hp_sel", 6), | |
+ GATE_AUDIO2(CLK_AUDIO_DL2, "audio_dl2", "a1sys_hp_sel", 7), | |
+ GATE_AUDIO2(CLK_AUDIO_DL3, "audio_dl3", "a1sys_hp_sel", 8), | |
+ GATE_AUDIO2(CLK_AUDIO_DL4, "audio_dl4", "a1sys_hp_sel", 9), | |
+ GATE_AUDIO2(CLK_AUDIO_DL5, "audio_dl5", "a1sys_hp_sel", 10), | |
+ GATE_AUDIO2(CLK_AUDIO_DL6, "audio_dl6", "a1sys_hp_sel", 11), | |
+ GATE_AUDIO2(CLK_AUDIO_DLMCH, "audio_dlmch", "a1sys_hp_sel", 12), | |
+ GATE_AUDIO2(CLK_AUDIO_ARB1, "audio_arb1", "a1sys_hp_sel", 13), | |
+ GATE_AUDIO2(CLK_AUDIO_AWB, "audio_awb", "a1sys_hp_sel", 14), | |
+ GATE_AUDIO2(CLK_AUDIO_AWB2, "audio_awb2", "a1sys_hp_sel", 15), | |
+ GATE_AUDIO2(CLK_AUDIO_DAI, "audio_dai", "a1sys_hp_sel", 16), | |
+ GATE_AUDIO2(CLK_AUDIO_MOD, "audio_mod", "a1sys_hp_sel", 17), | |
+ /* AUDIO3 */ | |
+ GATE_AUDIO3(CLK_AUDIO_ASRCI3, "audio_asrci3", "asm_h_sel", 2), | |
+ GATE_AUDIO3(CLK_AUDIO_ASRCI4, "audio_asrci4", "asm_h_sel", 3), | |
+ GATE_AUDIO3(CLK_AUDIO_ASRCO3, "audio_asrco3", "asm_h_sel", 6), | |
+ GATE_AUDIO3(CLK_AUDIO_ASRCO4, "audio_asrco4", "asm_h_sel", 7), | |
+ GATE_AUDIO3(CLK_AUDIO_MEM_ASRC1, "audio_mem_asrc1", "asm_h_sel", 10), | |
+ GATE_AUDIO3(CLK_AUDIO_MEM_ASRC2, "audio_mem_asrc2", "asm_h_sel", 11), | |
+ GATE_AUDIO3(CLK_AUDIO_MEM_ASRC3, "audio_mem_asrc3", "asm_h_sel", 12), | |
+ GATE_AUDIO3(CLK_AUDIO_MEM_ASRC4, "audio_mem_asrc4", "asm_h_sel", 13), | |
+ GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14), | |
+}; | |
+ | |
+static const struct mtk_gate_regs ssusb_cg_regs = { | |
+ .set_ofs = 0x30, | |
+ .clr_ofs = 0x30, | |
+ .sta_ofs = 0x30, | |
+}; | |
+ | |
+#define GATE_SSUSB(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &ssusb_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate ssusb_clks[] __initconst = { | |
+ GATE_SSUSB(CLK_SSUSB_U2_PHY_1P_EN, "ssusb_u2_phy_1p", "to_u2_phy_1p", 0), | |
+ GATE_SSUSB(CLK_SSUSB_U2_PHY_EN, "ssusb_u2_phy_en", "to_u2_phy", 1), | |
+ GATE_SSUSB(CLK_SSUSB_REF_EN, "ssusb_ref_en", "to_usb3_ref", 5), | |
+ GATE_SSUSB(CLK_SSUSB_SYS_EN, "ssusb_sys_en", "to_usb3_sys", 6), | |
+ GATE_SSUSB(CLK_SSUSB_MCU_EN, "ssusb_mcu_en", "axi_sel", 7), | |
+ GATE_SSUSB(CLK_SSUSB_DMA_EN, "ssusb_dma_en", "hif_sel", 8), | |
+}; | |
+ | |
+static const struct mtk_gate_regs pcie_cg_regs = { | |
+ .set_ofs = 0x30, | |
+ .clr_ofs = 0x30, | |
+ .sta_ofs = 0x30, | |
+}; | |
+ | |
+#define GATE_PCIE(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &pcie_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate pcie_clks[] __initconst = { | |
+ GATE_PCIE(CLK_PCIE_P1_AUX_EN, "pcie_p1_aux_en", "p1_1mhz", 12), | |
+ GATE_PCIE(CLK_PCIE_P1_OBFF_EN, "pcie_p1_obff_en", "free_run_4mhz", 13), | |
+ GATE_PCIE(CLK_PCIE_P1_AHB_EN, "pcie_p1_ahb_en", "axi_sel", 14), | |
+ GATE_PCIE(CLK_PCIE_P1_AXI_EN, "pcie_p1_axi_en", "hif_sel", 15), | |
+ GATE_PCIE(CLK_PCIE_P1_MAC_EN, "pcie_p1_mac_en", "pcie1_mac_en", 16), | |
+ GATE_PCIE(CLK_PCIE_P1_PIPE_EN, "pcie_p1_pipe_en", "pcie1_pipe_en", 17), | |
+ GATE_PCIE(CLK_PCIE_P0_AUX_EN, "pcie_p0_aux_en", "p0_1mhz", 18), | |
+ GATE_PCIE(CLK_PCIE_P0_OBFF_EN, "pcie_p0_obff_en", "free_run_4mhz", 19), | |
+ GATE_PCIE(CLK_PCIE_P0_AHB_EN, "pcie_p0_ahb_en", "axi_sel", 20), | |
+ GATE_PCIE(CLK_PCIE_P0_AXI_EN, "pcie_p0_axi_en", "hif_sel", 21), | |
+ GATE_PCIE(CLK_PCIE_P0_MAC_EN, "pcie_p0_mac_en", "pcie0_mac_en", 22), | |
+ GATE_PCIE(CLK_PCIE_P0_PIPE_EN, "pcie_p0_pipe_en", "pcie0_pipe_en", 23), | |
+ GATE_PCIE(CLK_SATA_AHB_EN, "sata_ahb_en", "axi_sel", 26), | |
+ GATE_PCIE(CLK_SATA_AXI_EN, "sata_axi_en", "hif_sel", 27), | |
+ GATE_PCIE(CLK_SATA_ASIC_EN, "sata_asic_en", "sata_asic", 28), | |
+ GATE_PCIE(CLK_SATA_RBC_EN, "sata_rbc_en", "sata_rbc", 29), | |
+ GATE_PCIE(CLK_SATA_PM_EN, "sata_pm_en", "univpll2_d4", 30), | |
+}; | |
+ | |
+static const struct mtk_gate_regs eth_cg_regs = { | |
+ .set_ofs = 0x30, | |
+ .clr_ofs = 0x30, | |
+ .sta_ofs = 0x30, | |
+}; | |
+ | |
+#define GATE_ETH(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = ð_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate eth_clks[] __initconst = { | |
+ GATE_ETH(CLK_ETH_HSDMA_EN, "eth_hsdma_en", "eth_sel", 5), | |
+ GATE_ETH(CLK_ETH_ESW_EN, "eth_esw_en", "eth_500m", 6), | |
+ GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "txclk_src_pre", 7), | |
+ GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "txclk_src_pre", 8), | |
+ GATE_ETH(CLK_ETH_GP0_EN, "eth_gp0_en", "txclk_src_pre", 9), | |
+}; | |
+ | |
+static const struct mtk_gate_regs sgmii_cg_regs = { | |
+ .set_ofs = 0xE4, | |
+ .clr_ofs = 0xE4, | |
+ .sta_ofs = 0xE4, | |
+}; | |
+ | |
+#define GATE_SGMII(_id, _name, _parent, _shift) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .regs = &sgmii_cg_regs, \ | |
+ .shift = _shift, \ | |
+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
+ } | |
+ | |
+static const struct mtk_gate sgmii_clks[] __initconst = { | |
+ GATE_SGMII(CLK_SGMII_TX250M_EN, "sgmii_tx250m_en", "ssusb_tx250m", 2), | |
+ GATE_SGMII(CLK_SGMII_RX250M_EN, "sgmii_rx250m_en", "ssusb_eq_rx250m", 3), | |
+ GATE_SGMII(CLK_SGMII_CDR_REF, "sgmii_cdr_ref", "ssusb_cdr_ref", 4), | |
+ GATE_SGMII(CLK_SGMII_CDR_FB, "sgmii_cdr_fb", "ssusb_cdr_fb", 5), | |
+}; | |
+ | |
+#define MT7622_PLL_FMAX (2500UL * MHZ) | |
+ | |
+#define CON0_MT7622_RST_BAR BIT(27) | |
+ | |
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | |
+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \ | |
+ _pcw_shift, _div_table, _parent_name) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .reg = _reg, \ | |
+ .pwr_reg = _pwr_reg, \ | |
+ .en_mask = _en_mask, \ | |
+ .flags = _flags, \ | |
+ .rst_bar_mask = CON0_MT7622_RST_BAR, \ | |
+ .fmax = MT7622_PLL_FMAX, \ | |
+ .pcwbits = _pcwbits, \ | |
+ .pd_reg = _pd_reg, \ | |
+ .pd_shift = _pd_shift, \ | |
+ .tuner_reg = _tuner_reg, \ | |
+ .pcw_reg = _pcw_reg, \ | |
+ .pcw_shift = _pcw_shift, \ | |
+ .div_table = _div_table, \ | |
+ .parent_name = _parent_name, \ | |
+ } | |
+ | |
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | |
+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \ | |
+ _pcw_shift, _parent_name) \ | |
+ PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \ | |
+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \ | |
+ NULL, _parent_name) | |
+ | |
+static const struct mtk_pll_data plls[] = { | |
+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, | |
+ 0, 21, 0x0204, 24, 0, 0x0204, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0210, 0x021C, 0x00000001, | |
+ HAVE_RST_BAR, 21, 0x0214, 24, 0, 0x0214, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0220, 0x022C, 0x00000001, | |
+ HAVE_RST_BAR, 7, 0x0224, 24, 0, 0x0224, 14, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_ETH1PLL, "eth1pll", 0x0300, 0x0310, 0x00000001, | |
+ 0, 21, 0x0300, 1, 0, 0x0304, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_ETH2PLL, "eth2pll", 0x0314, 0x0320, 0x00000001, | |
+ 0, 21, 0x0314, 1, 0, 0x0318, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x0324, 0x0330, 0x00000001, | |
+ 0, 31, 0x0324, 1, 0, 0x0328, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x0334, 0x0340, 0x00000001, | |
+ 0, 31, 0x0334, 1, 0, 0x0338, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x0344, 0x0354, 0x00000001, | |
+ 0, 21, 0x0344, 1, 0, 0x0348, 0, "clksrc_pll"), | |
+ PLL(CLK_APMIXED_SGMIPLL, "sgmipll", 0x0358, 0x0368, 0x00000001, | |
+ 0, 21, 0x0358, 1, 0, 0x035C, 0, "clksrc_pll"), | |
+}; | |
+ | |
+static struct clk_onecell_data *mt7622_top_clk_data __initdata; | |
+static struct clk_onecell_data *mt7622_pll_clk_data __initdata; | |
+ | |
+static void __init mtk_clk_enable_critical(void) | |
+{ | |
+ if (!mt7622_top_clk_data || !mt7622_pll_clk_data) | |
+ return; | |
+ | |
+ clk_prepare_enable(mt7622_pll_clk_data->clks[CLK_APMIXED_ARMPLL]); | |
+ clk_prepare_enable(mt7622_top_clk_data->clks[CLK_TOP_AXI_SEL]); | |
+ clk_prepare_enable(mt7622_top_clk_data->clks[CLK_TOP_MEM_SEL]); | |
+ clk_prepare_enable(mt7622_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]); | |
+} | |
+ | |
+static void __init mtk_topckgen_init(struct device_node *node) | |
+{ | |
+ int r; | |
+ void __iomem *base; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ mt7622_top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); | |
+ | |
+ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), mt7622_top_clk_data); | |
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), mt7622_top_clk_data); | |
+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, &mt7622_clk_lock, mt7622_top_clk_data); | |
+ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base, &mt7622_clk_lock, mt7622_top_clk_data); | |
+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), mt7622_top_clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, mt7622_top_clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_clk_enable_critical(); | |
+} | |
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt7622-topckgen", mtk_topckgen_init); | |
+ | |
+static void __init mtk_infracfg_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ void __iomem *base; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); | |
+ | |
+ mtk_clk_register_composites(infra_muxes, ARRAY_SIZE(infra_muxes), base, &mt7622_clk_lock, clk_data); | |
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+CLK_OF_DECLARE(mtk_infracfg, "mediatek,mt7622-infracfg", mtk_infracfg_init); | |
+ | |
+static void __init mtk_pericfg_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ void __iomem *base; | |
+ | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); | |
+ | |
+ mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base, &mt7622_clk_lock, clk_data); | |
+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt7622-pericfg", mtk_pericfg_init); | |
+ | |
+static void __init mtk_apmixedsys_init(struct device_node *node) | |
+{ | |
+ int r; | |
+ | |
+ mt7622_pll_clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); | |
+ | |
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), mt7622_pll_clk_data); | |
+ mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), mt7622_pll_clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, mt7622_pll_clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_clk_enable_critical(); | |
+} | |
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt7622-apmixedsys", mtk_apmixedsys_init); | |
+ | |
+static void __init mtk_audiosys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK); | |
+ | |
+ mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+CLK_OF_DECLARE(mtk_audiosys, "mediatek,mt7622-audiosys", mtk_audiosys_init); | |
+ | |
+static void __init mtk_ssusbsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK); | |
+ | |
+ mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+CLK_OF_DECLARE(mtk_ssusbsys, "mediatek,mt7622-ssusbsys", mtk_ssusbsys_init); | |
+ | |
+static void __init mtk_pciesys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK); | |
+ | |
+ mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 1, 0x34); | |
+} | |
+CLK_OF_DECLARE(mtk_pciesys, "mediatek,mt7622-pciesys", mtk_pciesys_init); | |
+ | |
+static void __init mtk_ethsys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK); | |
+ | |
+ mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+ | |
+ mtk_register_reset_controller(node, 1, 0x34); | |
+} | |
+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7622-ethsys", mtk_ethsys_init); | |
+ | |
+static void __init mtk_sgmiisys_init(struct device_node *node) | |
+{ | |
+ struct clk_onecell_data *clk_data; | |
+ int r; | |
+ | |
+ clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK); | |
+ | |
+ mtk_clk_register_gates(node, sgmii_clks, ARRAY_SIZE(sgmii_clks), clk_data); | |
+ | |
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
+ if (r) | |
+ pr_err("%s(): could not register clock provider: %d\n", | |
+ __func__, r); | |
+} | |
+CLK_OF_DECLARE(mtk_sgmiisys, "mediatek,mt7622-sgmiisys", mtk_sgmiisys_init); | |
+ | |
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c | |
index 0ac3aee87726..7929e5f9497e 100644 | |
--- a/drivers/clk/mediatek/clk-mt8173.c | |
+++ b/drivers/clk/mediatek/clk-mt8173.c | |
@@ -525,6 +525,25 @@ static const char * const i2s3_b_ck_parents[] __initconst = { | |
"apll2_div5" | |
}; | |
+static const char * const ca53_parents[] __initconst = { | |
+ "clk26m", | |
+ "armca7pll", | |
+ "mainpll", | |
+ "univpll" | |
+}; | |
+ | |
+static const char * const ca57_parents[] __initconst = { | |
+ "clk26m", | |
+ "armca15pll", | |
+ "mainpll", | |
+ "univpll" | |
+}; | |
+ | |
+static const struct mtk_composite cpu_muxes[] __initconst = { | |
+ MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2), | |
+ MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2), | |
+}; | |
+ | |
static const struct mtk_composite top_muxes[] __initconst = { | |
/* CLK_CFG_0 */ | |
MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3), | |
@@ -940,14 +959,24 @@ CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init); | |
static void __init mtk_infrasys_init(struct device_node *node) | |
{ | |
struct clk_onecell_data *clk_data; | |
+ void __iomem *base; | |
int r; | |
+ base = of_iomap(node, 0); | |
+ if (!base) { | |
+ pr_err("%s(): ioremap failed\n", __func__); | |
+ return; | |
+ } | |
+ | |
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); | |
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), | |
clk_data); | |
mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data); | |
+ mtk_clk_register_composites(cpu_muxes, ARRAY_SIZE(cpu_muxes), base, | |
+ &mt8173_clk_lock, clk_data); | |
+ | |
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
if (r) | |
pr_err("%s(): could not register clock provider: %d\n", | |
@@ -1096,11 +1125,6 @@ static void __init mtk_apmixedsys_init(struct device_node *node) | |
clk_data->clks[cku->id] = clk; | |
} | |
- clk = clk_register_divider(NULL, "hdmi_ref", "tvdpll_594m", 0, | |
- base + 0x40, 16, 3, CLK_DIVIDER_POWER_OF_TWO, | |
- NULL); | |
- clk_data->clks[CLK_APMIXED_HDMI_REF] = clk; | |
- | |
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
if (r) | |
pr_err("%s(): could not register clock provider: %d\n", | |
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c | |
index bb30f7063569..20f792d8e196 100644 | |
--- a/drivers/clk/mediatek/clk-mtk.c | |
+++ b/drivers/clk/mediatek/clk-mtk.c | |
@@ -244,3 +244,28 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs, | |
clk_data->clks[mc->id] = clk; | |
} | |
} | |
+ | |
+void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, | |
+ int num, void __iomem *base, spinlock_t *lock, | |
+ struct clk_onecell_data *clk_data) | |
+{ | |
+ struct clk *clk; | |
+ int i; | |
+ | |
+ for (i = 0; i < num; i++) { | |
+ const struct mtk_clk_divider *mcd = &mcds[i]; | |
+ | |
+ clk = clk_register_divider(NULL, mcd->name, mcd->parent_name, | |
+ mcd->flags, base + mcd->div_reg, mcd->div_shift, | |
+ mcd->div_width, mcd->clk_divider_flags, lock); | |
+ | |
+ if (IS_ERR(clk)) { | |
+ pr_err("Failed to register clk %s: %ld\n", | |
+ mcd->name, PTR_ERR(clk)); | |
+ continue; | |
+ } | |
+ | |
+ if (clk_data) | |
+ clk_data->clks[mcd->id] = clk; | |
+ } | |
+} | |
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h | |
index e425e50173c5..72db918790e2 100644 | |
--- a/drivers/clk/mediatek/clk-mtk.h | |
+++ b/drivers/clk/mediatek/clk-mtk.h | |
@@ -121,7 +121,8 @@ struct mtk_composite { | |
.flags = CLK_SET_RATE_PARENT, \ | |
} | |
-#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \ | |
+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ | |
+ _div_width, _div_shift) { \ | |
.id = _id, \ | |
.parent = _parent, \ | |
.name = _name, \ | |
@@ -156,8 +157,35 @@ struct mtk_gate { | |
const struct clk_ops *ops; | |
}; | |
-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, | |
- int num, struct clk_onecell_data *clk_data); | |
+int mtk_clk_register_gates(struct device_node *node, | |
+ const struct mtk_gate *clks, int num, | |
+ struct clk_onecell_data *clk_data); | |
+ | |
+struct mtk_clk_divider { | |
+ int id; | |
+ const char *name; | |
+ const char *parent_name; | |
+ unsigned long flags; | |
+ | |
+ uint32_t div_reg; | |
+ unsigned char div_shift; | |
+ unsigned char div_width; | |
+ unsigned char clk_divider_flags; | |
+ const struct clk_div_table *clk_div_table; | |
+}; | |
+ | |
+#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \ | |
+ .id = _id, \ | |
+ .name = _name, \ | |
+ .parent_name = _parent, \ | |
+ .div_reg = _reg, \ | |
+ .div_shift = _shift, \ | |
+ .div_width = _width, \ | |
+} | |
+ | |
+void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, | |
+ int num, void __iomem *base, spinlock_t *lock, | |
+ struct clk_onecell_data *clk_data); | |
struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); | |
diff --git a/drivers/clk/mediatek/clkchk-mt7622.c b/drivers/clk/mediatek/clkchk-mt7622.c | |
new file mode 100644 | |
index 000000000000..5ffef15bf7fa | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clkchk-mt7622.c | |
@@ -0,0 +1,418 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Chen Zhong <chen.zhong@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/clk-provider.h> | |
+#include <linux/syscore_ops.h> | |
+#include <linux/version.h> | |
+ | |
+#define WARN_ON_CHECK_PLL_FAIL 0 | |
+#define CLKDBG_CCF_API_4_4 1 | |
+ | |
+#define TAG "[clkchk] " | |
+ | |
+#define clk_warn(fmt, args...) pr_warn(TAG fmt, ##args) | |
+ | |
+#if !CLKDBG_CCF_API_4_4 | |
+ | |
+/* backward compatible */ | |
+ | |
+static const char *clk_hw_get_name(const struct clk_hw *hw) | |
+{ | |
+ return __clk_get_name(hw->clk); | |
+} | |
+ | |
+static bool clk_hw_is_prepared(const struct clk_hw *hw) | |
+{ | |
+ return __clk_is_prepared(hw->clk); | |
+} | |
+ | |
+static bool clk_hw_is_enabled(const struct clk_hw *hw) | |
+{ | |
+ return __clk_is_enabled(hw->clk); | |
+} | |
+ | |
+#endif /* !CLKDBG_CCF_API_4_4 */ | |
+ | |
+static const char * const *get_all_clk_names(void) | |
+{ | |
+ static const char * const clks[] = { | |
+ /* plls */ | |
+ "armpll", | |
+ "mainpll", | |
+ "univ2pll", | |
+ "eth1pll", | |
+ "eth2pll", | |
+ "aud1pll", | |
+ "aud2pll", | |
+ "trgpll", | |
+ "sgmipll", | |
+ /* topckgen */ | |
+ "to_u2_phy", | |
+ "to_u2_phy_1p", | |
+ "pcie0_pipe_en", | |
+ "pcie1_pipe_en", | |
+ "ssusb_tx250m", | |
+ "ssusb_eq_rx250m", | |
+ "ssusb_cdr_ref", | |
+ "ssusb_cdr_fb", | |
+ "sata_asic", | |
+ "sata_rbc", | |
+ "to_usb3_sys", | |
+ "p1_1mhz", | |
+ "free_run_4mhz", | |
+ "p0_1mhz", | |
+ "txclk_src_pre", | |
+ "rtc", | |
+ "mempll", | |
+ "dmpll_ck", | |
+ "syspll_d2", | |
+ "syspll1_d2", | |
+ "syspll1_d4", | |
+ "syspll1_d8", | |
+ "syspll2_d4", | |
+ "syspll2_d8", | |
+ "syspll_d5", | |
+ "syspll3_d2", | |
+ "syspll3_d4", | |
+ "syspll4_d2", | |
+ "syspll4_d4", | |
+ "syspll4_d16", | |
+ "univpll", | |
+ "univpll_d2", | |
+ "univpll1_d2", | |
+ "univpll1_d4", | |
+ "univpll1_d8", | |
+ "univpll1_d16", | |
+ "univpll2_d2", | |
+ "univpll2_d4", | |
+ "univpll2_d8", | |
+ "univpll2_d16", | |
+ "univpll_d5", | |
+ "univpll3_d2", | |
+ "univpll3_d4", | |
+ "univpll3_d16", | |
+ "univpll_d7", | |
+ "univpll_d80_d4", | |
+ "univ48m", | |
+ "sgmiipll_ck", | |
+ "sgmiipll_d2", | |
+ "aud1pll_ck", | |
+ "aud2pll_ck", | |
+ "aud_i2s2_mck", | |
+ "to_usb3_ref", | |
+ "pcie1_mac_en", | |
+ "pcie0_mac_en", | |
+ "eth_500m", | |
+ "axi_sel", | |
+ "mem_sel", | |
+ "ddrphycfg_sel", | |
+ "eth_sel", | |
+ "pwm_sel", | |
+ "f10m_ref_sel", | |
+ "nfi_infra_sel", | |
+ "flash_sel", | |
+ "uart_sel", | |
+ "spi0_sel", | |
+ "spi1_sel", | |
+ "msdc50_0_sel", | |
+ "msdc30_0_sel", | |
+ "msdc30_1_sel", | |
+ "a1sys_hp_sel", | |
+ "a2sys_hp_sel", | |
+ "intdir_sel", | |
+ "aud_intbus_sel", | |
+ "pmicspi_sel", | |
+ "scp_sel", | |
+ "atb_sel", | |
+ "hif_sel", | |
+ "audio_sel", | |
+ "usb20_sel", | |
+ "aud1_sel", | |
+ "aud2_sel", | |
+ "irrx_sel", | |
+ "irtx_sel", | |
+ "asm_l_sel", | |
+ "asm_m_sel", | |
+ "asm_h_sel", | |
+ "apll1_ck_sel", | |
+ "apll2_ck_sel", | |
+ "i2s0_mck_sel", | |
+ "i2s1_mck_sel", | |
+ "i2s2_mck_sel", | |
+ "i2s3_mck_sel", | |
+ "apll1_ck_div", | |
+ "apll2_ck_div", | |
+ "i2s0_mck_div", | |
+ "i2s1_mck_div", | |
+ "i2s2_mck_div", | |
+ "i2s3_mck_div", | |
+ "a1sys_div", | |
+ "a2sys_div", | |
+ "apll1_ck_div_pd", | |
+ "apll2_ck_div_pd", | |
+ "i2s0_mck_div_pd", | |
+ "i2s1_mck_div_pd", | |
+ "i2s2_mck_div_pd", | |
+ "i2s3_mck_div_pd", | |
+ "a1sys_div_pd", | |
+ "a2sys_div_pd", | |
+ /* infracfg */ | |
+ "infra_mux1_sel", | |
+ "infra_dbgclk_pd", | |
+ "infra_audio_pd", | |
+ "infra_irrx_pd", | |
+ "infra_apxgpt_pd", | |
+ "infra_pmic_pd", | |
+ /* pericfg */ | |
+ "peribus_ck_sel", | |
+ "peri_therm_pd", | |
+ "peri_pwm1_pd", | |
+ "peri_pwm2_pd", | |
+ "peri_pwm3_pd", | |
+ "peri_pwm4_pd", | |
+ "peri_pwm5_pd", | |
+ "peri_pwm6_pd", | |
+ "peri_pwm7_pd", | |
+ "peri_pwm_pd", | |
+ "peri_ap_dma_pd", | |
+ "peri_msdc30_0", | |
+ "peri_msdc30_1", | |
+ "peri_uart0_pd", | |
+ "peri_uart1_pd", | |
+ "peri_uart2_pd", | |
+ "peri_uart3_pd", | |
+ "peri_uart4_pd", | |
+ "peri_btif_pd", | |
+ "peri_i2c0_pd", | |
+ "peri_i2c1_pd", | |
+ "peri_i2c2_pd", | |
+ "peri_spi1_pd", | |
+ "peri_auxadc_pd", | |
+ "peri_spi0_pd", | |
+ "peri_snfi_pd", | |
+ "peri_nfi_pd", | |
+ "peri_nfiecc_pd", | |
+ "peri_flash_pd", | |
+ "peri_irtx_pd", | |
+ /* audiosys */ | |
+ "audio_afe", | |
+ "audio_hdmi", | |
+ "audio_spdf", | |
+ "audio_apll", | |
+ "audio_i2sin1", | |
+ "audio_i2sin2", | |
+ "audio_i2sin3", | |
+ "audio_i2sin4", | |
+ "audio_i2so1", | |
+ "audio_i2so2", | |
+ "audio_i2so3", | |
+ "audio_i2so4", | |
+ "audio_asrci1", | |
+ "audio_asrci2", | |
+ "audio_asrco1", | |
+ "audio_asrco2", | |
+ "audio_intdir", | |
+ "audio_a1sys", | |
+ "audio_a2sys", | |
+ "audio_ul1", | |
+ "audio_ul2", | |
+ "audio_ul3", | |
+ "audio_ul4", | |
+ "audio_ul5", | |
+ "audio_ul6", | |
+ "audio_dl1", | |
+ "audio_dl2", | |
+ "audio_dl3", | |
+ "audio_dl4", | |
+ "audio_dl5", | |
+ "audio_dl6", | |
+ "audio_dlmch", | |
+ "audio_arb1", | |
+ "audio_awb", | |
+ "audio_awb2", | |
+ "audio_dai", | |
+ "audio_mod", | |
+ "audio_asrci3", | |
+ "audio_asrci4", | |
+ "audio_asrco3", | |
+ "audio_asrco4", | |
+ "audio_mem_asrc1", | |
+ "audio_mem_asrc2", | |
+ "audio_mem_asrc3", | |
+ "audio_mem_asrc4", | |
+ "audio_mem_asrc5", | |
+ /* ssusbsys */ | |
+ "ssusb_u2_phy_1p", | |
+ "ssusb_u2_phy_en", | |
+ "ssusb_ref_en", | |
+ "ssusb_sys_en", | |
+ "ssusb_mcu_en", | |
+ "ssusb_dma_en", | |
+ /* pciesys */ | |
+ "pcie_p1_aux_en", | |
+ "pcie_p1_obff_en", | |
+ "pcie_p1_ahb_en", | |
+ "pcie_p1_axi_en", | |
+ "pcie_p1_mac_en", | |
+ "pcie_p1_pipe_en", | |
+ "pcie_p0_aux_en", | |
+ "pcie_p0_obff_en", | |
+ "pcie_p0_ahb_en", | |
+ "pcie_p0_axi_en", | |
+ "pcie_p0_mac_en", | |
+ "pcie_p0_pipe_en", | |
+ "sata_ahb_en", | |
+ "sata_axi_en", | |
+ "sata_asic_en", | |
+ "sata_rbc_en", | |
+ "sata_pm_en", | |
+ /* ethsys */ | |
+ "eth_hsdma_en", | |
+ "eth_esw_en", | |
+ "eth_gp2_en", | |
+ "eth_gp1_en", | |
+ "eth_gp0_en", | |
+ /* sgmiisys */ | |
+ "sgmii_tx250m_en", | |
+ "sgmii_rx250m_en", | |
+ "sgmii_cdr_ref", | |
+ "sgmii_cdr_fb", | |
+ /* end */ | |
+ NULL | |
+ }; | |
+ | |
+ return clks; | |
+} | |
+ | |
+static const char *ccf_state(struct clk_hw *hw) | |
+{ | |
+ if (__clk_get_enable_count(hw->clk)) | |
+ return "enabled"; | |
+ | |
+ if (clk_hw_is_prepared(hw)) | |
+ return "prepared"; | |
+ | |
+ return "disabled"; | |
+} | |
+ | |
+static void print_enabled_clks(void) | |
+{ | |
+ const char * const *cn = get_all_clk_names(); | |
+ | |
+ clk_warn("enabled clks:\n"); | |
+ | |
+ for (; *cn; cn++) { | |
+ struct clk *c = __clk_lookup(*cn); | |
+ struct clk_hw *c_hw = __clk_get_hw(c); | |
+ struct clk_hw *p_hw; | |
+ | |
+ if (IS_ERR_OR_NULL(c) || !c_hw) | |
+ continue; | |
+ | |
+ p_hw = clk_hw_get_parent(c_hw); | |
+ | |
+ if (!p_hw) | |
+ continue; | |
+ | |
+ if (!clk_hw_is_prepared(c_hw) && !__clk_get_enable_count(c)) | |
+ continue; | |
+ | |
+ clk_warn("[%-17s: %8s, %3d, %3d, %10ld, %17s]\n", | |
+ clk_hw_get_name(c_hw), | |
+ ccf_state(c_hw), | |
+ clk_hw_is_prepared(c_hw), | |
+ __clk_get_enable_count(c), | |
+ clk_hw_get_rate(c_hw), | |
+ p_hw ? clk_hw_get_name(p_hw) : "- "); | |
+ } | |
+} | |
+ | |
+static void check_pll_off(void) | |
+{ | |
+ static const char * const off_pll_names[] = { | |
+ "univ2pll", | |
+ "eth1pll", | |
+ "eth2pll", | |
+ "aud1pll", | |
+ "aud2pll", | |
+ "trgpll", | |
+ "sgmipll", | |
+ NULL | |
+ }; | |
+ | |
+ static struct clk *off_plls[ARRAY_SIZE(off_pll_names)]; | |
+ | |
+ struct clk **c; | |
+ int invalid = 0; | |
+ char buf[128] = {0}; | |
+ int n = 0; | |
+ | |
+ if (!off_plls[0]) { | |
+ const char * const *pn; | |
+ | |
+ for (pn = off_pll_names, c = off_plls; *pn; pn++, c++) | |
+ *c = __clk_lookup(*pn); | |
+ } | |
+ | |
+ for (c = off_plls; *c; c++) { | |
+ struct clk_hw *c_hw = __clk_get_hw(*c); | |
+ | |
+ if (!c_hw) | |
+ continue; | |
+ | |
+ if (!clk_hw_is_prepared(c_hw) && !clk_hw_is_enabled(c_hw)) | |
+ continue; | |
+ | |
+ n += snprintf(buf + n, sizeof(buf) - n, "%s ", | |
+ clk_hw_get_name(c_hw)); | |
+ | |
+ invalid++; | |
+ } | |
+ | |
+ if (invalid) { | |
+ clk_warn("unexpected unclosed PLL: %s\n", buf); | |
+ print_enabled_clks(); | |
+ | |
+#if WARN_ON_CHECK_PLL_FAIL | |
+ WARN_ON(1); | |
+#endif | |
+ } | |
+} | |
+ | |
+static int clkchk_syscore_suspend(void) | |
+{ | |
+ check_pll_off(); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void clkchk_syscore_resume(void) | |
+{ | |
+} | |
+ | |
+static struct syscore_ops clkchk_syscore_ops = { | |
+ .suspend = clkchk_syscore_suspend, | |
+ .resume = clkchk_syscore_resume, | |
+}; | |
+ | |
+static int __init clkchk_init(void) | |
+{ | |
+ if (!of_machine_is_compatible("mediatek,mt7622")) | |
+ return -ENODEV; | |
+ | |
+ register_syscore_ops(&clkchk_syscore_ops); | |
+ | |
+ return 0; | |
+} | |
+subsys_initcall(clkchk_init); | |
diff --git a/drivers/clk/mediatek/clkdbg-mt7622.c b/drivers/clk/mediatek/clkdbg-mt7622.c | |
new file mode 100644 | |
index 000000000000..dae6b1656410 | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clkdbg-mt7622.c | |
@@ -0,0 +1,713 @@ | |
+/* | |
+ * Copyright (c) 2017 MediaTek Inc. | |
+ * Author: Chen Zhong <chen.zhong@mediatek.com> | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/clk-provider.h> | |
+#include <linux/io.h> | |
+ | |
+#include "clkdbg.h" | |
+ | |
+#define DUMP_INIT_STATE 0 | |
+ | |
+/* | |
+ * clkdbg dump_regs | |
+ */ | |
+ | |
+enum { | |
+ infrasys, | |
+ perisys, | |
+ scpsys, | |
+ apmixed, | |
+ fhctl, | |
+ topckgen, | |
+ audio, | |
+ ssusb, | |
+ pcie, | |
+ ethdma, | |
+ sgmii, | |
+}; | |
+ | |
+#define REGBASE_V(_phys, _id_name) { .phys = _phys, .name = #_id_name } | |
+ | |
+/* | |
+ * checkpatch.pl ERROR:COMPLEX_MACRO | |
+ * | |
+ * #define REGBASE(_phys, _id_name) [_id_name] = REGBASE_V(_phys, _id_name) | |
+ */ | |
+ | |
+static struct regbase rb[] = { | |
+ [infrasys] = REGBASE_V(0x10000000, infrasys), | |
+ [perisys] = REGBASE_V(0x10002000, perisys), | |
+ [scpsys] = REGBASE_V(0x10006000, scpsys), | |
+ [apmixed] = REGBASE_V(0x10209000, apmixed), | |
+ [fhctl] = REGBASE_V(0x10209f00, fhctl), | |
+ [topckgen] = REGBASE_V(0x10210000, topckgen), | |
+ [audio] = REGBASE_V(0x11220000, audio), | |
+ [ssusb] = REGBASE_V(0x1A000000, ssusb), | |
+ [pcie] = REGBASE_V(0x1A100800, pcie), | |
+ [ethdma] = REGBASE_V(0x1B000000, ethdma), | |
+ [sgmii] = REGBASE_V(0x1B128000, sgmii), | |
+}; | |
+ | |
+#define REGNAME(_base, _ofs, _name) \ | |
+ { .base = &rb[_base], .ofs = _ofs, .name = #_name } | |
+ | |
+static struct regname rn[] = { | |
+ REGNAME(infrasys, 0x040, INFRA_GLOBALCON_PDN0), | |
+ REGNAME(infrasys, 0x044, INFRA_GLOBALCON_PDN1), | |
+ REGNAME(infrasys, 0x048, INFRA_PDN_STA), | |
+ REGNAME(perisys, 0x008, PERI_GLOBALCON_PDN0_SET), | |
+ REGNAME(perisys, 0x00C, PERI_GLOBALCON_PDN1_SET), | |
+ REGNAME(perisys, 0x010, PERI_GLOBALCON_PDN0_CLR), | |
+ REGNAME(perisys, 0x014, PERI_GLOBALCON_PDN1_CLR), | |
+ REGNAME(perisys, 0x018, PERI_GLOBALCON_PDN0_STA), | |
+ REGNAME(perisys, 0x01C, PERI_GLOBALCON_PDN1_STA), | |
+ REGNAME(scpsys, 0x2E0, SPM_ETH_PWR_CON), | |
+ REGNAME(scpsys, 0x2E4, SPM_HIF0_PWR_CON), | |
+ REGNAME(scpsys, 0x2E8, SPM_HIF1_PWR_CON), | |
+ REGNAME(scpsys, 0x60c, SPM_PWR_STATUS), | |
+ REGNAME(scpsys, 0x610, SPM_PWR_STATUS_2ND), | |
+ REGNAME(apmixed, 0x200, ARMPLL_CON0), | |
+ REGNAME(apmixed, 0x204, ARMPLL_CON1), | |
+ REGNAME(apmixed, 0x20C, ARMPLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x210, MAINPLL_CON0), | |
+ REGNAME(apmixed, 0x214, MAINPLL_CON1), | |
+ REGNAME(apmixed, 0x21C, MAINPLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x220, UNIVPLL_CON0), | |
+ REGNAME(apmixed, 0x224, UNIVPLL_CON1), | |
+ REGNAME(apmixed, 0x22C, UNIVPLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x300, ETH1PLL_CON0), | |
+ REGNAME(apmixed, 0x304, ETH1PLL_CON1), | |
+ REGNAME(apmixed, 0x310, ETH1PLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x314, ETH2PLL_CON0), | |
+ REGNAME(apmixed, 0x318, ETH2PLL_CON1), | |
+ REGNAME(apmixed, 0x320, ETH2PLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x324, APLL1_CON0), | |
+ REGNAME(apmixed, 0x328, APLL1_CON1), | |
+ REGNAME(apmixed, 0x330, APLL1_PWR_CON0), | |
+ REGNAME(apmixed, 0x334, APLL2_CON0), | |
+ REGNAME(apmixed, 0x338, APLL2_CON1), | |
+ REGNAME(apmixed, 0x340, APLL2_PWR_CON0), | |
+ REGNAME(apmixed, 0x344, TRGPLL_CON0), | |
+ REGNAME(apmixed, 0x348, TRGPLL_CON1), | |
+ REGNAME(apmixed, 0x354, TRGPLL_PWR_CON0), | |
+ REGNAME(apmixed, 0x358, SGMIPLL_CON0), | |
+ REGNAME(apmixed, 0x35C, SGMIPLL_CON1), | |
+ REGNAME(apmixed, 0x368, SGMIPLL_PWR_CON0), | |
+ REGNAME(topckgen, 0x040, CLK_CFG_0), | |
+ REGNAME(topckgen, 0x050, CLK_CFG_1), | |
+ REGNAME(topckgen, 0x060, CLK_CFG_2), | |
+ REGNAME(topckgen, 0x070, CLK_CFG_3), | |
+ REGNAME(topckgen, 0x080, CLK_CFG_4), | |
+ REGNAME(topckgen, 0x090, CLK_CFG_5), | |
+ REGNAME(topckgen, 0x0A0, CLK_CFG_6), | |
+ REGNAME(topckgen, 0x0B0, CLK_CFG_7), | |
+ REGNAME(topckgen, 0x120, CLK_AUDDIV_0), | |
+ REGNAME(topckgen, 0x128, CLK_AUDDIV_2), | |
+ REGNAME(audio, 0x000, AUDIO_TOP_CON0), | |
+ REGNAME(audio, 0x010, AUDIO_TOP_CON4), | |
+ REGNAME(audio, 0x014, AUDIO_TOP_CON5), | |
+ REGNAME(audio, 0x634, PWR2_TOP_CON), | |
+ REGNAME(ssusb, 0x30, USB23_CSR_O_CLKCFG1), | |
+ REGNAME(pcie, 0x30, COMBO_CSR_O_CLKCFG1), | |
+ REGNAME(ethdma, 0x30, ETHDMACTL_CLKCFG1), | |
+ REGNAME(sgmii, 0xE4, SGMII_QPHY_CTRL), | |
+ {NULL, 0, NULL} | |
+}; | |
+ | |
+static const struct regname *get_all_regnames(void) | |
+{ | |
+ return rn; | |
+} | |
+ | |
+static void __init init_regbase(void) | |
+{ | |
+ int i; | |
+ | |
+ for (i = 0; i < ARRAY_SIZE(rb); i++) | |
+ rb[i].virt = ioremap(rb[i].phys, PAGE_SIZE); | |
+} | |
+ | |
+/* | |
+ * clkdbg fmeter | |
+ */ | |
+ | |
+#include <linux/delay.h> | |
+ | |
+#ifndef GENMASK | |
+#define GENMASK(h, l) (((1U << ((h) - (l) + 1)) - 1) << (l)) | |
+#endif | |
+ | |
+#define ALT_BITS(o, h, l, v) \ | |
+ (((o) & ~GENMASK(h, l)) | (((v) << (l)) & GENMASK(h, l))) | |
+ | |
+#define clk_readl(addr) readl(addr) | |
+#define clk_writel(addr, val) \ | |
+ do { writel(val, addr); wmb(); } while (0) /* sync write */ | |
+#define clk_writel_mask(addr, mask, val) \ | |
+ clk_writel(addr, (clk_readl(addr) & ~(mask)) | (val)) | |
+ | |
+#define ABS_DIFF(a, b) ((a) > (b) ? (a) - (b) : (b) - (a)) | |
+ | |
+enum FMETER_TYPE { | |
+ FT_NULL, | |
+ ABIST, | |
+ CKGEN | |
+}; | |
+ | |
+#define FMCLK(_t, _i, _n) { .type = _t, .id = _i, .name = _n } | |
+ | |
+static const struct fmeter_clk fclks[] = { | |
+ FMCLK(ABIST, 1, "AD_MEMPLL2_CKOUT0_PRE_ISO"), | |
+ FMCLK(ABIST, 2, "AD_MAIN_DIV2_CK"), | |
+ FMCLK(ABIST, 3, "AD_MAIN_DIV3_CK"), | |
+ FMCLK(ABIST, 4, "AD_MAIN_DIV5_CK"), | |
+ FMCLK(ABIST, 5, "AD_MAIN_DIV7_CK"), | |
+ FMCLK(ABIST, 6, "AD_UNIV_DIV2_CK"), | |
+ FMCLK(ABIST, 7, "AD_UNIV_DIV3_CK"), | |
+ FMCLK(ABIST, 8, "AD_UNIV_DIV5_CK"), | |
+ FMCLK(ABIST, 9, "AD_UNIV_DIV7_CK"), | |
+ FMCLK(ABIST, 10, "AD_UNIV_DIV80_CK"), | |
+ FMCLK(ABIST, 11, "AD_UNIV_48M_CK"), | |
+ FMCLK(ABIST, 12, "AD_SGMIIPLL_CK"), | |
+ FMCLK(ABIST, 13, "XTAL"), | |
+ FMCLK(ABIST, 14, "AD_AUD1PLL_CK"), | |
+ FMCLK(ABIST, 15, "AD_AUD2PLL_CK"), | |
+ FMCLK(ABIST, 16, "RTC"), | |
+ FMCLK(ABIST, 17, "AD_ARMPLL_TOP_TST_CK"), | |
+ FMCLK(ABIST, 18, "AD_USB_48M_CK"), | |
+ FMCLK(ABIST, 19, "AD_MAINPLL_CORE_CK"), | |
+ FMCLK(ABIST, 20, "AD_TRGPLL_CK"), | |
+ FMCLK(ABIST, 21, "AD_MEM_25M_CK"), | |
+ FMCLK(ABIST, 22, "AD_PLLGP_TST_CK"), | |
+ FMCLK(ABIST, 23, "AD_ETH1PLL_CK"), | |
+ FMCLK(ABIST, 24, "AD_ETH2PLL_CK"), | |
+ FMCLK(ABIST, 25, "AD_UNIVPLL_CK"), | |
+ FMCLK(ABIST, 26, "AD_MEM2MIPI_26M_CK"), | |
+ FMCLK(ABIST, 27, "AD_MEMPLL_MONCLK"), | |
+ FMCLK(ABIST, 28, "AD_MEMPLL2_MONCLK"), | |
+ FMCLK(ABIST, 29, "AD_MEMPLL3_MONCLK"), | |
+ FMCLK(ABIST, 30, "AD_MEMPLL4_MONCLK"), | |
+ FMCLK(ABIST, 31, "AD_MEMPLL_REFCLK_BUF"), | |
+ FMCLK(ABIST, 32, "AD_MEMPLL_FBCLK_BUF"), | |
+ FMCLK(ABIST, 33, "AD_MEMPLL2_REFCLK_BUF"), | |
+ FMCLK(ABIST, 34, "AD_MEMPLL2_FBCLK_BUF"), | |
+ FMCLK(ABIST, 35, "AD_MEMPLL3_REFCLK_BUF"), | |
+ FMCLK(ABIST, 36, "AD_MEMPLL3_FBCLK_BUF"), | |
+ FMCLK(ABIST, 37, "AD_MEMPLL4_REFCLK_BUF"), | |
+ FMCLK(ABIST, 38, "AD_MEMPLL4_FBCLK_BUF"), | |
+ FMCLK(ABIST, 39, "AD_MEMPLL_TSTDIV2_CK"), | |
+ FMCLK(CKGEN, 1, "hf_fmem_ck"), | |
+ FMCLK(CKGEN, 2, "hf_fddrphycfg_ck"), | |
+ FMCLK(CKGEN, 3, "hf_feth_ck"), | |
+ FMCLK(CKGEN, 4, "f_fpwm_ck"), | |
+ FMCLK(CKGEN, 5, "hf_f10m_ck"), | |
+ FMCLK(CKGEN, 6, "hf_fspinfi_infra_bclk_ck"), | |
+ FMCLK(CKGEN, 7, "hf_fflash_ck"), | |
+ FMCLK(CKGEN, 8, "f_fuart_ck"), | |
+ FMCLK(CKGEN, 9, "hf_fspi0_ck"), | |
+ FMCLK(CKGEN, 10, "hf_fspi1_ck"), | |
+ FMCLK(CKGEN, 11, "hf_fmsdc50_0_ck"), | |
+ FMCLK(CKGEN, 12, "hf_fmsdc30_0_ck"), | |
+ FMCLK(CKGEN, 13, "hf_fmsdc30_1_ck"), | |
+ FMCLK(CKGEN, 14, "f_fa1sys_hp_ck"), | |
+ FMCLK(CKGEN, 15, "f_fa2sys_hp_ck"), | |
+ FMCLK(CKGEN, 16, "hf_fintdir_ck"), | |
+ FMCLK(CKGEN, 17, "hf_faud_intbus_ck"), | |
+ FMCLK(CKGEN, 18, "hf_fpmicspi_ck"), | |
+ FMCLK(CKGEN, 19, "hf_fscp_ck"), | |
+ FMCLK(CKGEN, 20, "hf_fatb_ck"), | |
+ FMCLK(CKGEN, 21, "hf_fhif_ck"), | |
+ FMCLK(CKGEN, 22, "hf_faudio_ck"), | |
+ FMCLK(CKGEN, 23, "hf_fusb20_ck"), | |
+ FMCLK(CKGEN, 24, "f_faud1_ck"), | |
+ FMCLK(CKGEN, 25, "f_faud2_ck"), | |
+ FMCLK(CKGEN, 26, "hf_firrx_ck"), | |
+ FMCLK(CKGEN, 27, "hf_firtx_ck"), | |
+ FMCLK(CKGEN, 28, "hf_fasm_l_ck"), | |
+ FMCLK(CKGEN, 29, "hf_fasm_m_ck"), | |
+ FMCLK(CKGEN, 30, "hf_fasm_h_ck"), | |
+ FMCLK(CKGEN, 31, "f_faud26m_ck"), | |
+ FMCLK(CKGEN, 32, "hf_fpmicspi_ck_scan"), | |
+ FMCLK(CKGEN, 33, "hf_fsgmii_ref_ck"), | |
+ FMCLK(CKGEN, 34, "f_fsata_ck"), | |
+ FMCLK(CKGEN, 35, "f_f75k_ck"), | |
+ FMCLK(CKGEN, 36, "f_fmsdc_ext_ck"), | |
+ FMCLK(CKGEN, 37, "hf_fddrphycfg_ck_scan"), | |
+ FMCLK(CKGEN, 38, "f_frtc_fddrphyperi_ck"), | |
+ FMCLK(CKGEN, 39, "f_fddrphyperi_ck_scan"), | |
+ FMCLK(CKGEN, 40, "f_fckrtc_ck_scan"), | |
+ FMCLK(CKGEN, 41, "f_frtc_ck"), | |
+ FMCLK(CKGEN, 42, "f_fxtal_ck"), | |
+ FMCLK(CKGEN, 43, "f_fckbus_ck_scan"), | |
+ FMCLK(CKGEN, 44, "f_fxtal_ck_cg"), | |
+ FMCLK(CKGEN, 45, "hd_qaxidcm_ck"), | |
+ FMCLK(CKGEN, 46, "hf_fspi0_pad_ck"), | |
+ FMCLK(CKGEN, 47, "hf_fspi1_pad_ck"), | |
+ FMCLK(CKGEN, 48, "f_fefuse_ck"), | |
+ FMCLK(CKGEN, 49, "f_fapmixed_ck"), | |
+ FMCLK(CKGEN, 50, "f_fclkmux_ck"), | |
+ FMCLK(CKGEN, 51, "f_frtc_apmixed_ck"), | |
+ FMCLK(CKGEN, 52, "f_fsata_ref_ck"), | |
+ FMCLK(CKGEN, 53, "f_fpcie_ref_ck"), | |
+ FMCLK(CKGEN, 54, "f_fssusb_ref_ck"), | |
+ FMCLK(CKGEN, 55, "f_funivpll3_d16_ck"), | |
+ FMCLK(CKGEN, 56, "f_fauxadc_ck"), | |
+ FMCLK(CKGEN, 57, "hf_fap2wbmcu_ck"), | |
+ FMCLK(CKGEN, 58, "hf_fap2wbhif_ck"), | |
+ FMCLK(CKGEN, 59, "hf_fsata_mcu_ck"), | |
+ FMCLK(CKGEN, 60, "hf_fpcie0_mcu_ck"), | |
+ FMCLK(CKGEN, 61, "hf_fpcie1_mcu_ck"), | |
+ FMCLK(CKGEN, 62, "hf_fssusb_mcu_ck"), | |
+ FMCLK(CKGEN, 63, "f_fpcie_2ln_ck"), | |
+ {} | |
+}; | |
+ | |
+#define FHCTL_HP_EN (rb[fhctl].virt + 0x000) | |
+#define CLK_CFG_M0 (rb[topckgen].virt + 0x100) | |
+#define CLK_CFG_M1 (rb[topckgen].virt + 0x104) | |
+#define CLK_MISC_CFG_1 (rb[topckgen].virt + 0x214) | |
+#define CLK_MISC_CFG_2 (rb[topckgen].virt + 0x218) | |
+#define CLK26CALI_0 (rb[topckgen].virt + 0x220) | |
+#define CLK26CALI_1 (rb[topckgen].virt + 0x224) | |
+#define CLK26CALI_2 (rb[topckgen].virt + 0x228) | |
+ | |
+#define RG_FRMTR_WINDOW 1023 | |
+ | |
+static void set_fmeter_divider_arm(u32 k1) | |
+{ | |
+ u32 v = clk_readl(CLK_MISC_CFG_1); | |
+ | |
+ v = ALT_BITS(v, 15, 8, k1); | |
+ clk_writel(CLK_MISC_CFG_1, v); | |
+} | |
+ | |
+static void set_fmeter_divider(u32 k1) | |
+{ | |
+ u32 v = clk_readl(CLK_MISC_CFG_1); | |
+ | |
+ v = ALT_BITS(v, 7, 0, k1); | |
+ v = ALT_BITS(v, 31, 24, k1); | |
+ clk_writel(CLK_MISC_CFG_1, v); | |
+} | |
+ | |
+static u8 wait_fmeter_done(u32 tri_bit) | |
+{ | |
+ static int max_wait_count; | |
+ int wait_count = (max_wait_count > 0) ? (max_wait_count * 2 + 2) : 100; | |
+ int i; | |
+ | |
+ /* wait fmeter */ | |
+ for (i = 0; i < wait_count && (clk_readl(CLK26CALI_0) & tri_bit); i++) | |
+ udelay(20); | |
+ | |
+ if (!(clk_readl(CLK26CALI_0) & tri_bit)) { | |
+ max_wait_count = max(max_wait_count, i); | |
+ return 1; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+static u32 fmeter_freq(enum FMETER_TYPE type, int k1, int clk) | |
+{ | |
+ void __iomem *clk_cfg_reg = (type == CKGEN) ? CLK_CFG_M1 : CLK_CFG_M0; | |
+ void __iomem *cnt_reg = (type == CKGEN) ? CLK26CALI_2 : CLK26CALI_1; | |
+ u32 cksw_mask = (type == CKGEN) ? GENMASK(21, 16) : GENMASK(13, 8); | |
+ u32 cksw_val = (type == CKGEN) ? (clk << 16) : (clk << 8); | |
+ u32 tri_bit = (type == CKGEN) ? BIT(4) : BIT(0); | |
+ u32 clk_exc = (type == CKGEN) ? BIT(5) : BIT(2); | |
+ u32 clk_misc_cfg_1, clk_misc_cfg_2, clk_cfg_val, cnt, freq = 0; | |
+ | |
+ /* setup fmeter */ | |
+ clk_setl(CLK26CALI_0, BIT(7)); /* enable fmeter_en */ | |
+ clk_clrl(CLK26CALI_0, clk_exc); /* set clk_exc */ | |
+ clk_writel_mask(cnt_reg, GENMASK(25, 16), RG_FRMTR_WINDOW << 16); /* load_cnt */ | |
+ | |
+ clk_misc_cfg_1 = clk_readl(CLK_MISC_CFG_1); /* backup CLK_MISC_CFG_1 value */ | |
+ clk_misc_cfg_2 = clk_readl(CLK_MISC_CFG_2); /* backup CLK_MISC_CFG_2 value */ | |
+ clk_cfg_val = clk_readl(clk_cfg_reg); /* backup clk_cfg_reg value */ | |
+ | |
+ set_fmeter_divider(k1); /* set divider (0 = /1) */ | |
+ set_fmeter_divider_arm(k1); | |
+ clk_writel_mask(clk_cfg_reg, cksw_mask, cksw_val); /* select cksw */ | |
+ | |
+ clk_setl(CLK26CALI_0, tri_bit); /* start fmeter */ | |
+ | |
+ if (wait_fmeter_done(tri_bit)) { | |
+ cnt = clk_readl(cnt_reg) & 0xFFFF; | |
+ freq = (cnt * 25000) * (k1 + 1) / (RG_FRMTR_WINDOW + 1); /* (KHz) ; freq = counter * 26M / 1024 */ | |
+ } | |
+ | |
+ /* restore register settings */ | |
+ clk_writel(clk_cfg_reg, clk_cfg_val); | |
+ clk_writel(CLK_MISC_CFG_2, clk_misc_cfg_2); | |
+ clk_writel(CLK_MISC_CFG_1, clk_misc_cfg_1); | |
+ | |
+ clk_clrl(CLK26CALI_0, BIT(7)); /* disable fmeter_en */ | |
+ | |
+ return freq; | |
+} | |
+ | |
+static u32 measure_stable_fmeter_freq(enum FMETER_TYPE type, int k1, int clk) | |
+{ | |
+ u32 last_freq = 0; | |
+ u32 freq = fmeter_freq(type, k1, clk); | |
+ u32 maxfreq = max(freq, last_freq); | |
+ | |
+ while (maxfreq > 0 && ABS_DIFF(freq, last_freq) * 100 / maxfreq > 10) { | |
+ last_freq = freq; | |
+ freq = fmeter_freq(type, k1, clk); | |
+ maxfreq = max(freq, last_freq); | |
+ } | |
+ | |
+ return freq; | |
+} | |
+ | |
+static const struct fmeter_clk *get_all_fmeter_clks(void) | |
+{ | |
+ return fclks; | |
+} | |
+ | |
+struct bak { | |
+ u32 fhctl_hp_en; | |
+}; | |
+ | |
+static void *prepare_fmeter(void) | |
+{ | |
+ static struct bak regs; | |
+ | |
+ regs.fhctl_hp_en = clk_readl(FHCTL_HP_EN); | |
+ | |
+ clk_writel(FHCTL_HP_EN, 0x0); /* disable PLL hopping */ | |
+ udelay(10); | |
+ | |
+ return ®s; | |
+} | |
+ | |
+static void unprepare_fmeter(void *data) | |
+{ | |
+ struct bak *regs = data; | |
+ | |
+ /* restore old setting */ | |
+ clk_writel(FHCTL_HP_EN, regs->fhctl_hp_en); | |
+} | |
+ | |
+static u32 fmeter_freq_op(const struct fmeter_clk *fclk) | |
+{ | |
+ if (fclk->type) | |
+ return measure_stable_fmeter_freq(fclk->type, 0, fclk->id); | |
+ | |
+ return 0; | |
+} | |
+ | |
+/* | |
+ * clkdbg dump_state | |
+ */ | |
+ | |
+static const char * const *get_all_clk_names(void) | |
+{ | |
+ static const char * const clks[] = { | |
+ /* plls */ | |
+ "armpll", | |
+ "mainpll", | |
+ "univ2pll", | |
+ "eth1pll", | |
+ "eth2pll", | |
+ "aud1pll", | |
+ "aud2pll", | |
+ "trgpll", | |
+ "sgmipll", | |
+ /* topckgen */ | |
+ "to_u2_phy", | |
+ "to_u2_phy_1p", | |
+ "pcie0_pipe_en", | |
+ "pcie1_pipe_en", | |
+ "ssusb_tx250m", | |
+ "ssusb_eq_rx250m", | |
+ "ssusb_cdr_ref", | |
+ "ssusb_cdr_fb", | |
+ "sata_asic", | |
+ "sata_rbc", | |
+ "to_usb3_sys", | |
+ "p1_1mhz", | |
+ "free_run_4mhz", | |
+ "p0_1mhz", | |
+ "txclk_src_pre", | |
+ "rtc", | |
+ "mempll", | |
+ "dmpll_ck", | |
+ "syspll_d2", | |
+ "syspll1_d2", | |
+ "syspll1_d4", | |
+ "syspll1_d8", | |
+ "syspll2_d4", | |
+ "syspll2_d8", | |
+ "syspll_d5", | |
+ "syspll3_d2", | |
+ "syspll3_d4", | |
+ "syspll4_d2", | |
+ "syspll4_d4", | |
+ "syspll4_d16", | |
+ "univpll", | |
+ "univpll_d2", | |
+ "univpll1_d2", | |
+ "univpll1_d4", | |
+ "univpll1_d8", | |
+ "univpll1_d16", | |
+ "univpll2_d2", | |
+ "univpll2_d4", | |
+ "univpll2_d8", | |
+ "univpll2_d16", | |
+ "univpll_d5", | |
+ "univpll3_d2", | |
+ "univpll3_d4", | |
+ "univpll3_d16", | |
+ "univpll_d7", | |
+ "univpll_d80_d4", | |
+ "univ48m", | |
+ "sgmiipll_ck", | |
+ "sgmiipll_d2", | |
+ "aud1pll_ck", | |
+ "aud2pll_ck", | |
+ "aud_i2s2_mck", | |
+ "to_usb3_ref", | |
+ "pcie1_mac_en", | |
+ "pcie0_mac_en", | |
+ "eth_500m", | |
+ "axi_sel", | |
+ "mem_sel", | |
+ "ddrphycfg_sel", | |
+ "eth_sel", | |
+ "pwm_sel", | |
+ "f10m_ref_sel", | |
+ "nfi_infra_sel", | |
+ "flash_sel", | |
+ "uart_sel", | |
+ "spi0_sel", | |
+ "spi1_sel", | |
+ "msdc50_0_sel", | |
+ "msdc30_0_sel", | |
+ "msdc30_1_sel", | |
+ "a1sys_hp_sel", | |
+ "a2sys_hp_sel", | |
+ "intdir_sel", | |
+ "aud_intbus_sel", | |
+ "pmicspi_sel", | |
+ "scp_sel", | |
+ "atb_sel", | |
+ "hif_sel", | |
+ "audio_sel", | |
+ "usb20_sel", | |
+ "aud1_sel", | |
+ "aud2_sel", | |
+ "irrx_sel", | |
+ "irtx_sel", | |
+ "asm_l_sel", | |
+ "asm_m_sel", | |
+ "asm_h_sel", | |
+ "apll1_ck_sel", | |
+ "apll2_ck_sel", | |
+ "i2s0_mck_sel", | |
+ "i2s1_mck_sel", | |
+ "i2s2_mck_sel", | |
+ "i2s3_mck_sel", | |
+ "apll1_ck_div", | |
+ "apll2_ck_div", | |
+ "i2s0_mck_div", | |
+ "i2s1_mck_div", | |
+ "i2s2_mck_div", | |
+ "i2s3_mck_div", | |
+ "a1sys_div", | |
+ "a2sys_div", | |
+ "apll1_ck_div_pd", | |
+ "apll2_ck_div_pd", | |
+ "i2s0_mck_div_pd", | |
+ "i2s1_mck_div_pd", | |
+ "i2s2_mck_div_pd", | |
+ "i2s3_mck_div_pd", | |
+ "a1sys_div_pd", | |
+ "a2sys_div_pd", | |
+ /* infracfg */ | |
+ "infra_mux1_sel", | |
+ "infra_dbgclk_pd", | |
+ "infra_audio_pd", | |
+ "infra_irrx_pd", | |
+ "infra_apxgpt_pd", | |
+ "infra_pmic_pd", | |
+ /* pericfg */ | |
+ "peribus_ck_sel", | |
+ "peri_therm_pd", | |
+ "peri_pwm1_pd", | |
+ "peri_pwm2_pd", | |
+ "peri_pwm3_pd", | |
+ "peri_pwm4_pd", | |
+ "peri_pwm5_pd", | |
+ "peri_pwm6_pd", | |
+ "peri_pwm7_pd", | |
+ "peri_pwm_pd", | |
+ "peri_ap_dma_pd", | |
+ "peri_msdc30_0", | |
+ "peri_msdc30_1", | |
+ "peri_uart0_pd", | |
+ "peri_uart1_pd", | |
+ "peri_uart2_pd", | |
+ "peri_uart3_pd", | |
+ "peri_uart4_pd", | |
+ "peri_btif_pd", | |
+ "peri_i2c0_pd", | |
+ "peri_i2c1_pd", | |
+ "peri_i2c2_pd", | |
+ "peri_spi1_pd", | |
+ "peri_auxadc_pd", | |
+ "peri_spi0_pd", | |
+ "peri_snfi_pd", | |
+ "peri_nfi_pd", | |
+ "peri_nfiecc_pd", | |
+ "peri_flash_pd", | |
+ "peri_irtx_pd", | |
+ /* audiosys */ | |
+ "audio_afe", | |
+ "audio_hdmi", | |
+ "audio_spdf", | |
+ "audio_apll", | |
+ "audio_i2sin1", | |
+ "audio_i2sin2", | |
+ "audio_i2sin3", | |
+ "audio_i2sin4", | |
+ "audio_i2so1", | |
+ "audio_i2so2", | |
+ "audio_i2so3", | |
+ "audio_i2so4", | |
+ "audio_asrci1", | |
+ "audio_asrci2", | |
+ "audio_asrco1", | |
+ "audio_asrco2", | |
+ "audio_intdir", | |
+ "audio_a1sys", | |
+ "audio_a2sys", | |
+ "audio_ul1", | |
+ "audio_ul2", | |
+ "audio_ul3", | |
+ "audio_ul4", | |
+ "audio_ul5", | |
+ "audio_ul6", | |
+ "audio_dl1", | |
+ "audio_dl2", | |
+ "audio_dl3", | |
+ "audio_dl4", | |
+ "audio_dl5", | |
+ "audio_dl6", | |
+ "audio_dlmch", | |
+ "audio_arb1", | |
+ "audio_awb", | |
+ "audio_awb2", | |
+ "audio_dai", | |
+ "audio_mod", | |
+ "audio_asrci3", | |
+ "audio_asrci4", | |
+ "audio_asrco3", | |
+ "audio_asrco4", | |
+ "audio_mem_asrc1", | |
+ "audio_mem_asrc2", | |
+ "audio_mem_asrc3", | |
+ "audio_mem_asrc4", | |
+ "audio_mem_asrc5", | |
+ /* ssusbsys */ | |
+ "ssusb_u2_phy_1p", | |
+ "ssusb_u2_phy_en", | |
+ "ssusb_ref_en", | |
+ "ssusb_sys_en", | |
+ "ssusb_mcu_en", | |
+ "ssusb_dma_en", | |
+ /* pciesys */ | |
+ "pcie_p1_aux_en", | |
+ "pcie_p1_obff_en", | |
+ "pcie_p1_ahb_en", | |
+ "pcie_p1_axi_en", | |
+ "pcie_p1_mac_en", | |
+ "pcie_p1_pipe_en", | |
+ "pcie_p0_aux_en", | |
+ "pcie_p0_obff_en", | |
+ "pcie_p0_ahb_en", | |
+ "pcie_p0_axi_en", | |
+ "pcie_p0_mac_en", | |
+ "pcie_p0_pipe_en", | |
+ "sata_ahb_en", | |
+ "sata_axi_en", | |
+ "sata_asic_en", | |
+ "sata_rbc_en", | |
+ "sata_pm_en", | |
+ /* ethsys */ | |
+ "eth_hsdma_en", | |
+ "eth_esw_en", | |
+ "eth_gp2_en", | |
+ "eth_gp1_en", | |
+ "eth_gp0_en", | |
+ /* sgmiisys */ | |
+ "sgmii_tx250m_en", | |
+ "sgmii_rx250m_en", | |
+ "sgmii_cdr_ref", | |
+ "sgmii_cdr_fb", | |
+ /* end */ | |
+ NULL | |
+ }; | |
+ | |
+ return clks; | |
+} | |
+ | |
+/* | |
+ * clkdbg pwr_status | |
+ */ | |
+ | |
+static const char * const *get_pwr_names(void) | |
+{ | |
+ static const char * const pwr_names[] = { | |
+ [24] = "ETHSYS", | |
+ [25] = "HIF0", | |
+ [26] = "HIF1", | |
+ }; | |
+ | |
+ return pwr_names; | |
+} | |
+ | |
+/* | |
+ * init functions | |
+ */ | |
+ | |
+static struct clkdbg_ops clkdbg_mt7622_ops = { | |
+ .get_all_fmeter_clks = get_all_fmeter_clks, | |
+ .prepare_fmeter = prepare_fmeter, | |
+ .unprepare_fmeter = unprepare_fmeter, | |
+ .fmeter_freq = fmeter_freq_op, | |
+ .get_all_regnames = get_all_regnames, | |
+ .get_all_clk_names = get_all_clk_names, | |
+ .get_pwr_names = get_pwr_names, | |
+}; | |
+ | |
+static int __init clkdbg_mt7622_init(void) | |
+{ | |
+ if (!of_machine_is_compatible("mediatek,mt7622")) | |
+ return -ENODEV; | |
+ | |
+ init_regbase(); | |
+ | |
+ set_clkdbg_ops(&clkdbg_mt7622_ops); | |
+ | |
+#if DUMP_INIT_STATE | |
+ print_regs(); | |
+ print_fmeter_all(); | |
+#endif /* DUMP_INIT_STATE */ | |
+ | |
+ return 0; | |
+} | |
+device_initcall(clkdbg_mt7622_init); | |
diff --git a/drivers/clk/mediatek/clkdbg.c b/drivers/clk/mediatek/clkdbg.c | |
new file mode 100644 | |
index 000000000000..31be45fe1d9b | |
--- /dev/null | |
+++ b/drivers/clk/mediatek/clkdbg.c | |
@@ -0,0 +1,2165 @@ | |
+/* | |
+ * Copyright (C) 2015 MediaTek Inc. | |
+ * | |
+ * This program is free software: you can redistribute it and/or modify | |
+ * it under the terms of the GNU General Public License version 2 as | |
+ * published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ */ | |
+ | |
+#include <linux/of.h> | |
+#include <linux/of_address.h> | |
+#include <linux/of_platform.h> | |
+#include <linux/slab.h> | |
+#include <linux/delay.h> | |
+ | |
+#include <linux/proc_fs.h> | |
+#include <linux/fs.h> | |
+#include <linux/seq_file.h> | |
+#include <linux/uaccess.h> | |
+ | |
+#include <linux/clk.h> | |
+#include <linux/clk-provider.h> | |
+#include <linux/pm_domain.h> | |
+#include <linux/pm_runtime.h> | |
+#include <linux/module.h> | |
+#include <linux/version.h> | |
+ | |
+#include "clkdbg.h" | |
+ | |
+#define CLKDBG_PM_DOMAIN 1 | |
+#define CLKDBG_CCF_API_4_4 1 | |
+#define CLKDBG_HACK_CLK 0 | |
+#define CLKDBG_HACK_CLK_CORE 1 | |
+ | |
+ | |
+#if !CLKDBG_CCF_API_4_4 | |
+ | |
+/* backward compatible */ | |
+ | |
+static const char *clk_hw_get_name(const struct clk_hw *hw) | |
+{ | |
+ return __clk_get_name(hw->clk); | |
+} | |
+ | |
+static bool clk_hw_is_prepared(const struct clk_hw *hw) | |
+{ | |
+ return __clk_is_prepared(hw->clk); | |
+} | |
+ | |
+static bool clk_hw_is_enabled(const struct clk_hw *hw) | |
+{ | |
+ return __clk_is_enabled(hw->clk); | |
+} | |
+ | |
+static unsigned long clk_hw_get_rate(const struct clk_hw *hw) | |
+{ | |
+ return __clk_get_rate(hw->clk); | |
+} | |
+ | |
+static unsigned int clk_hw_get_num_parents(const struct clk_hw *hw) | |
+{ | |
+ return __clk_get_num_parents(hw->clk); | |
+} | |
+ | |
+static struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, | |
+ unsigned int index) | |
+{ | |
+ return __clk_get_hw(clk_get_parent_by_index(hw->clk, index)); | |
+} | |
+ | |
+#endif /* !CLKDBG_CCF_API_4_4 */ | |
+ | |
+#if CLKDBG_HACK_CLK | |
+ | |
+#include <linux/clk-private.h> | |
+ | |
+static int clk_hw_is_on(struct clk_hw *hw) | |
+{ | |
+ const struct clk_ops *ops = hw->clk->ops; | |
+ | |
+ if (ops->is_enabled) | |
+ return clk_hw_is_enabled(hw); | |
+ else if (ops->is_prepared) | |
+ return clk_hw_is_prepared(hw); | |
+ return clk_hw_is_enabled(hw) || clk_hw_is_prepared(hw); | |
+} | |
+ | |
+#elif CLKDBG_HACK_CLK_CORE | |
+ | |
+struct clk_core { | |
+ const char *name; | |
+ const struct clk_ops *ops; | |
+ struct clk_hw *hw; | |
+}; | |
+ | |
+static int clk_hw_is_on(struct clk_hw *hw) | |
+{ | |
+ const struct clk_ops *ops = hw->core->ops; | |
+ | |
+ if (ops->is_enabled) | |
+ return clk_hw_is_enabled(hw); | |
+ else if (ops->is_prepared) | |
+ return clk_hw_is_prepared(hw); | |
+ return clk_hw_is_enabled(hw) || clk_hw_is_prepared(hw); | |
+} | |
+ | |
+#else | |
+ | |
+static int clk_hw_is_on(struct clk_hw *hw) | |
+{ | |
+ return __clk_get_enable_count(hw->clk) || clk_hw_is_prepared(hw); | |
+} | |
+ | |
+#endif /* !CLKDBG_HACK_CLK && !CLKDBG_HACK_CLK_CORE */ | |
+ | |
+static const struct clkdbg_ops *clkdbg_ops; | |
+ | |
+void set_clkdbg_ops(const struct clkdbg_ops *ops) | |
+{ | |
+ clkdbg_ops = ops; | |
+} | |
+ | |
+static const struct fmeter_clk *get_all_fmeter_clks(void) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->get_all_fmeter_clks) | |
+ return NULL; | |
+ | |
+ return clkdbg_ops->get_all_fmeter_clks(); | |
+} | |
+ | |
+static void *prepare_fmeter(void) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->prepare_fmeter) | |
+ return NULL; | |
+ | |
+ return clkdbg_ops->prepare_fmeter(); | |
+} | |
+ | |
+static void unprepare_fmeter(void *data) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->unprepare_fmeter) | |
+ return; | |
+ | |
+ clkdbg_ops->unprepare_fmeter(data); | |
+} | |
+ | |
+static u32 fmeter_freq(const struct fmeter_clk *fclk) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->fmeter_freq) | |
+ return 0; | |
+ | |
+ return clkdbg_ops->fmeter_freq(fclk); | |
+} | |
+ | |
+static const struct regname *get_all_regnames(void) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->get_all_regnames) | |
+ return NULL; | |
+ | |
+ return clkdbg_ops->get_all_regnames(); | |
+} | |
+ | |
+static const char * const *get_all_clk_names(void) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->get_all_clk_names) | |
+ return NULL; | |
+ | |
+ return clkdbg_ops->get_all_clk_names(); | |
+} | |
+ | |
+static const char * const *get_pwr_names(void) | |
+{ | |
+ static const char * const default_pwr_names[] = { | |
+ [0] = "(MD)", | |
+ [1] = "(CONN)", | |
+ [2] = "(DDRPHY)", | |
+ [3] = "(DISP)", | |
+ [4] = "(MFG)", | |
+ [5] = "(ISP)", | |
+ [6] = "(INFRA)", | |
+ [7] = "(VDEC)", | |
+ [8] = "(CPU, CA7_CPUTOP)", | |
+ [9] = "(FC3, CA7_CPU0, CPUTOP)", | |
+ [10] = "(FC2, CA7_CPU1, CPU3)", | |
+ [11] = "(FC1, CA7_CPU2, CPU2)", | |
+ [12] = "(FC0, CA7_CPU3, CPU1)", | |
+ [13] = "(MCUSYS, CA7_DBG, CPU0)", | |
+ [14] = "(MCUSYS, VEN, BDP)", | |
+ [15] = "(CA15_CPUTOP, ETH, MCUSYS)", | |
+ [16] = "(CA15_CPU0, HIF)", | |
+ [17] = "(CA15_CPU1, CA15-CX0, INFRA_MISC)", | |
+ [18] = "(CA15_CPU2, CA15-CX1)", | |
+ [19] = "(CA15_CPU3, CA15-CPU0)", | |
+ [20] = "(VEN2, MJC, CA15-CPU1)", | |
+ [21] = "(VEN, CA15-CPUTOP)", | |
+ [22] = "(MFG_2D)", | |
+ [23] = "(MFG_ASYNC, DBG)", | |
+ [24] = "(AUDIO, MFG_2D)", | |
+ [25] = "(USB, VCORE_PDN, MFG_ASYNC)", | |
+ [26] = "(ARMPLL_DIV, CPUTOP_SRM_SLPB)", | |
+ [27] = "(MD2, CPUTOP_SRM_PDN)", | |
+ [28] = "(CPU3_SRM_PDN)", | |
+ [29] = "(CPU2_SRM_PDN)", | |
+ [30] = "(CPU1_SRM_PDN)", | |
+ [31] = "(CPU0_SRM_PDN)", | |
+ }; | |
+ | |
+ if (!clkdbg_ops || !clkdbg_ops->get_pwr_names) | |
+ return default_pwr_names; | |
+ | |
+ return clkdbg_ops->get_pwr_names(); | |
+} | |
+ | |
+static void setup_provider_clk(struct provider_clk *pvdck) | |
+{ | |
+ if (!clkdbg_ops || !clkdbg_ops->setup_provider_clk) | |
+ return; | |
+ | |
+ clkdbg_ops->setup_provider_clk(pvdck); | |
+} | |
+ | |
+static bool is_valid_reg(void __iomem *addr) | |
+{ | |
+#ifdef CONFIG_64BIT | |
+ return ((u64)addr & 0xf0000000) || (((u64)addr >> 32) & 0xf0000000); | |
+#else | |
+ return ((u32)addr & 0xf0000000); | |
+#endif | |
+} | |
+ | |
+enum clkdbg_opt { | |
+ CLKDBG_EN_SUSPEND_SAVE_1, | |
+ CLKDBG_EN_SUSPEND_SAVE_2, | |
+ CLKDBG_EN_SUSPEND_SAVE_3, | |
+ CLKDBG_EN_LOG_SAVE_POINTS, | |
+}; | |
+ | |
+static u32 clkdbg_flags; | |
+ | |
+static void set_clkdbg_flag(enum clkdbg_opt opt) | |
+{ | |
+ clkdbg_flags |= BIT(opt); | |
+} | |
+ | |
+static void clr_clkdbg_flag(enum clkdbg_opt opt) | |
+{ | |
+ clkdbg_flags &= ~BIT(opt); | |
+} | |
+ | |
+static bool has_clkdbg_flag(enum clkdbg_opt opt) | |
+{ | |
+ return !!(clkdbg_flags & BIT(opt)); | |
+} | |
+ | |
+typedef void (*fn_fclk_freq_proc)(const struct fmeter_clk *fclk, | |
+ u32 freq, void *data); | |
+ | |
+static void proc_all_fclk_freq(fn_fclk_freq_proc proc, void *data) | |
+{ | |
+ void *fmeter_data; | |
+ const struct fmeter_clk *fclk; | |
+ | |
+ fclk = get_all_fmeter_clks(); | |
+ | |
+ if (!fclk || !proc) | |
+ return; | |
+ | |
+ fmeter_data = prepare_fmeter(); | |
+ | |
+ for (; fclk->type; fclk++) { | |
+ u32 freq; | |
+ | |
+ freq = fmeter_freq(fclk); | |
+ proc(fclk, freq, data); | |
+ } | |
+ | |
+ unprepare_fmeter(fmeter_data); | |
+} | |
+ | |
+static void print_fclk_freq(const struct fmeter_clk *fclk, u32 freq, void *data) | |
+{ | |
+ clk_warn("%2d: %-29s: %u\n", fclk->id, fclk->name, freq); | |
+} | |
+ | |
+void print_fmeter_all(void) | |
+{ | |
+ proc_all_fclk_freq(print_fclk_freq, NULL); | |
+} | |
+ | |
+static void seq_print_fclk_freq(const struct fmeter_clk *fclk, | |
+ u32 freq, void *data) | |
+{ | |
+ struct seq_file *s = data; | |
+ | |
+ seq_printf(s, "%2d: %-29s: %u\n", fclk->id, fclk->name, freq); | |
+} | |
+ | |
+static int seq_print_fmeter_all(struct seq_file *s, void *v) | |
+{ | |
+ proc_all_fclk_freq(seq_print_fclk_freq, s); | |
+ | |
+ return 0; | |
+} | |
+ | |
+typedef void (*fn_regname_proc)(const struct regname *rn, void *data); | |
+ | |
+static void proc_all_regname(fn_regname_proc proc, void *data) | |
+{ | |
+ const struct regname *rn = get_all_regnames(); | |
+ | |
+ if (!rn) | |
+ return; | |
+ | |
+ for (; rn->base; rn++) | |
+ proc(rn, data); | |
+} | |
+ | |
+static void print_reg(const struct regname *rn, void *data) | |
+{ | |
+ if (!is_valid_reg(ADDR(rn))) | |
+ return; | |
+ | |
+ clk_warn("%-21s: [0x%08x][0x%p] = 0x%08x\n", | |
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn))); | |
+} | |
+ | |
+void print_regs(void) | |
+{ | |
+ proc_all_regname(print_reg, NULL); | |
+} | |
+ | |
+static void seq_print_reg(const struct regname *rn, void *data) | |
+{ | |
+ struct seq_file *s = data; | |
+ | |
+ if (!is_valid_reg(ADDR(rn))) | |
+ return; | |
+ | |
+ seq_printf(s, "%-21s: [0x%08x][0x%p] = 0x%08x\n", | |
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn))); | |
+} | |
+ | |
+static int seq_print_regs(struct seq_file *s, void *v) | |
+{ | |
+ proc_all_regname(seq_print_reg, s); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void print_reg2(const struct regname *rn, void *data) | |
+{ | |
+ if (!is_valid_reg(ADDR(rn))) | |
+ return; | |
+ | |
+ clk_warn("%-21s: [0x%08x][0x%p] = 0x%08x\n", | |
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn))); | |
+ | |
+ msleep(20); | |
+} | |
+ | |
+static int clkdbg_dump_regs2(struct seq_file *s, void *v) | |
+{ | |
+ proc_all_regname(print_reg2, s); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static u32 read_spm_pwr_status(void) | |
+{ | |
+ static void __iomem *scpsys_base; | |
+ | |
+ if (!scpsys_base) | |
+ scpsys_base = ioremap(0x10006000, PAGE_SIZE); | |
+ | |
+ return clk_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment