Unified · Split
| @@ -0,0 +1,36 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-or-later) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/fsi/ibm,fsi2spi.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: IBM FSI-attached SPI controllers | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Eddie James <eajames@linux.ibm.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | This binding describes an FSI CFAM engine called the FSI2SPI. Therefore this | ||
| 14 | node will always be a child of an FSI CFAM node; see fsi.txt for details on | ||
| 15 | FSI slave and CFAM nodes. This FSI2SPI engine provides access to a number of | ||
| 16 | SPI controllers. | ||
| 17 | |||
| 18 | properties: | ||
| 19 | compatible: | ||
| 20 | enum: | ||
| 21 | - ibm,fsi2spi | ||
| 22 | |||
| 23 | reg: | ||
| 24 | items: | ||
| 25 | - description: FSI slave address | ||
| 26 | |||
| 27 | required: | ||
| 28 | - compatible | ||
| 29 | - reg | ||
| 30 | |||
| 31 | examples: | ||
| 32 | - | | ||
| 33 | fsi2spi@1c00 { | ||
| 34 | compatible = "ibm,fsi2spi"; | ||
| 35 | reg = <0x1c00 0x400>; | ||
| 36 | }; | ||
| @@ -61,6 +61,7 @@ Regulator nodes are identified by their compatible: · 60 unmodified lines | |||
| 61 | "qcom,rpm-pm8901-regulators" | 61 | "qcom,rpm-pm8901-regulators" |
| 62 | "qcom,rpm-pm8921-regulators" | 62 | "qcom,rpm-pm8921-regulators" |
| 63 | "qcom,rpm-pm8018-regulators" | 63 | "qcom,rpm-pm8018-regulators" |
| 64 | "qcom,rpm-smb208-regulators" | ||
| 64 | 65 | ||
| 65 | - vdd_l0_l1_lvs-supply: | 66 | - vdd_l0_l1_lvs-supply: |
| 66 | - vdd_l2_l11_l12-supply: | 67 | - vdd_l2_l11_l12-supply: |
| @@ -171,6 +172,9 @@ pm8018: · 104 unmodified lines | |||
| 171 | s1, s2, s3, s4, s5, , l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, | 172 | s1, s2, s3, s4, s5, , l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, |
| 172 | l12, l14, lvs1 | 173 | l12, l14, lvs1 |
| 173 | 174 | ||
| 175 | smb208: | ||
| 176 | s1a, s1b, s2a, s2b | ||
| 177 | |||
| 174 | The content of each sub-node is defined by the standard binding for regulators - | 178 | The content of each sub-node is defined by the standard binding for regulators - |
| 175 | see regulator.txt - with additional custom properties described below: | 179 | see regulator.txt - with additional custom properties described below: |
| 176 | 180 | ||
| @@ -0,0 +1,78 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/regulator/mps,mp5416.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Monolithic Power System MP5416 PMIC | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Saravanan Sekar <sravanhome@gmail.com> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | $nodename: | ||
| 14 | pattern: "^pmic@[0-9a-f]{1,2}$" | ||
| 15 | compatible: | ||
| 16 | enum: | ||
| 17 | - mps,mp5416 | ||
| 18 | |||
| 19 | reg: | ||
| 20 | maxItems: 1 | ||
| 21 | |||
| 22 | regulators: | ||
| 23 | type: object | ||
| 24 | description: | | ||
| 25 | list of regulators provided by this controller, must be named | ||
| 26 | after their hardware counterparts BUCK[1-4] and LDO[1-4] | ||
| 27 | |||
| 28 | patternProperties: | ||
| 29 | "^buck[1-4]$": | ||
| 30 | allOf: | ||
| 31 | - $ref: "regulator.yaml#" | ||
| 32 | type: object | ||
| 33 | |||
| 34 | "^ldo[1-4]$": | ||
| 35 | allOf: | ||
| 36 | - $ref: "regulator.yaml#" | ||
| 37 | type: object | ||
| 38 | |||
| 39 | additionalProperties: false | ||
| 40 | additionalProperties: false | ||
| 41 | |||
| 42 | required: | ||
| 43 | - compatible | ||
| 44 | - reg | ||
| 45 | - regulators | ||
| 46 | |||
| 47 | additionalProperties: false | ||
| 48 | |||
| 49 | examples: | ||
| 50 | - | | ||
| 51 | i2c { | ||
| 52 | #address-cells = <1>; | ||
| 53 | #size-cells = <0>; | ||
| 54 | |||
| 55 | pmic@69 { | ||
| 56 | compatible = "mps,mp5416"; | ||
| 57 | reg = <0x69>; | ||
| 58 | |||
| 59 | regulators { | ||
| 60 | |||
| 61 | buck1 { | ||
| 62 | regulator-name = "buck1"; | ||
| 63 | regulator-min-microvolt = <600000>; | ||
| 64 | regulator-max-microvolt = <2187500>; | ||
| 65 | regulator-min-microamp = <3800000>; | ||
| 66 | regulator-max-microamp = <6800000>; | ||
| 67 | regulator-boot-on; | ||
| 68 | }; | ||
| 69 | |||
| 70 | ldo2 { | ||
| 71 | regulator-name = "ldo2"; | ||
| 72 | regulator-min-microvolt = <800000>; | ||
| 73 | regulator-max-microvolt = <3975000>; | ||
| 74 | }; | ||
| 75 | }; | ||
| 76 | }; | ||
| 77 | }; | ||
| 78 | ... | ||
| @@ -22,6 +22,7 @@ properties: · 21 unmodified lines | |||
| 22 | enum: | 22 | enum: |
| 23 | - amlogic,meson-gx-spicc # SPICC controller on Amlogic GX and compatible SoCs | 23 | - amlogic,meson-gx-spicc # SPICC controller on Amlogic GX and compatible SoCs |
| 24 | - amlogic,meson-axg-spicc # SPICC controller on Amlogic AXG and compatible SoCs | 24 | - amlogic,meson-axg-spicc # SPICC controller on Amlogic AXG and compatible SoCs |
| 25 | - amlogic,meson-g12a-spicc # SPICC controller on Amlogic G12A and compatible SoCs | ||
| 25 | 26 | ||
| 26 | interrupts: | 27 | interrupts: |
| 27 | maxItems: 1 | 28 | maxItems: 1 |
| @@ -40,6 +41,27 @@ properties: · 12 unmodified lines | |||
| 40 | items: | 41 | items: |
| 41 | - const: core | 42 | - const: core |
| 42 | 43 | ||
| 44 | if: | ||
| 45 | properties: | ||
| 46 | compatible: | ||
| 47 | contains: | ||
| 48 | enum: | ||
| 49 | - amlogic,meson-g12a-spicc | ||
| 50 | |||
| 51 | then: | ||
| 52 | properties: | ||
| 53 | clocks: | ||
| 54 | contains: | ||
| 55 | items: | ||
| 56 | - description: controller register bus clock | ||
| 57 | - description: baud rate generator and delay control clock | ||
| 58 | |||
| 59 | clock-names: | ||
| 60 | minItems: 2 | ||
| 61 | items: | ||
| 62 | - const: core | ||
| 63 | - const: pclk | ||
| 64 | |||
| 43 | required: | 65 | required: |
| 44 | - compatible | 66 | - compatible |
| 45 | - reg | 67 | - reg |
| @@ -10,7 +10,10 @@ Required properties: · 9 unmodified lines | |||
| 10 | - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 | 10 | - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 |
| 11 | - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 | 11 | - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 |
| 12 | - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc | 12 | - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc |
| 13 | - "fsl,imx8mq-ecspi" for SPI compatible with the one integrated on i.MX8M | 13 | - "fsl,imx8mq-ecspi" for SPI compatible with the one integrated on i.MX8MQ |
| 14 | - "fsl,imx8mm-ecspi" for SPI compatible with the one integrated on i.MX8MM | ||
| 15 | - "fsl,imx8mn-ecspi" for SPI compatible with the one integrated on i.MX8MN | ||
| 16 | - "fsl,imx8mp-ecspi" for SPI compatible with the one integrated on i.MX8MP | ||
| 14 | - reg : Offset and length of the register set for the device | 17 | - reg : Offset and length of the register set for the device |
| 15 | - interrupts : Should contain CSPI/eCSPI interrupt | 18 | - interrupts : Should contain CSPI/eCSPI interrupt |
| 16 | - clocks : Clock specifiers for both ipg and per clocks. | 19 | - clocks : Clock specifiers for both ipg and per clocks. |
| @@ -0,0 +1,41 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/spi/qca,ar934x-spi.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Qualcomm Atheros AR934x/QCA95xx SoC SPI controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Chuanhong Guo <gch981213@gmail.com> | ||
| 11 | |||
| 12 | allOf: | ||
| 13 | - $ref: spi-controller.yaml# | ||
| 14 | |||
| 15 | properties: | ||
| 16 | compatible: | ||
| 17 | const: qca,ar934x-spi | ||
| 18 | |||
| 19 | reg: | ||
| 20 | maxItems: 1 | ||
| 21 | |||
| 22 | clocks: | ||
| 23 | maxItems: 1 | ||
| 24 | |||
| 25 | required: | ||
| 26 | - compatible | ||
| 27 | - reg | ||
| 28 | - clocks | ||
| 29 | - '#address-cells' | ||
| 30 | - '#size-cells' | ||
| 31 | |||
| 32 | examples: | ||
| 33 | - | | ||
| 34 | #include <dt-bindings/clock/ath79-clk.h> | ||
| 35 | spi: spi@1f000000 { | ||
| 36 | compatible = "qca,ar934x-spi"; | ||
| 37 | reg = <0x1f000000 0x1c>; | ||
| 38 | clocks = <&pll ATH79_CLK_AHB>; | ||
| 39 | #address-cells = <1>; | ||
| 40 | #size-cells = <0>; | ||
| 41 | }; | ||
| @@ -52,6 +52,12 @@ properties: · 51 unmodified lines | |||
| 52 | description: | 52 | description: |
| 53 | The SPI controller acts as a slave, instead of a master. | 53 | The SPI controller acts as a slave, instead of a master. |
| 54 | 54 | ||
| 55 | oneOf: | ||
| 56 | - required: | ||
| 57 | - "#address-cells" | ||
| 58 | - required: | ||
| 59 | - spi-slave | ||
| 60 | |||
| 55 | patternProperties: | 61 | patternProperties: |
| 56 | "^slave$": | 62 | "^slave$": |
| 57 | type: object | 63 | type: object |
| @@ -114,7 +120,7 @@ patternProperties: · 56 unmodified lines | |||
| 114 | - enum: [ 1, 2, 4, 8 ] | 120 | - enum: [ 1, 2, 4, 8 ] |
| 115 | - default: 1 | 121 | - default: 1 |
| 116 | description: | 122 | description: |
| 117 | Bus width to the SPI bus used for MISO. | 123 | Bus width to the SPI bus used for read transfers. |
| 118 | 124 | ||
| 119 | spi-rx-delay-us: | 125 | spi-rx-delay-us: |
| 120 | description: | 126 | description: |
| @@ -126,7 +132,7 @@ patternProperties: · 5 unmodified lines | |||
| 126 | - enum: [ 1, 2, 4, 8 ] | 132 | - enum: [ 1, 2, 4, 8 ] |
| 127 | - default: 1 | 133 | - default: 1 |
| 128 | description: | 134 | description: |
| 129 | Bus width to the SPI bus used for MOSI. | 135 | Bus width to the SPI bus used for write transfers. |
| 130 | 136 | ||
| 131 | spi-tx-delay-us: | 137 | spi-tx-delay-us: |
| 132 | description: | 138 | description: |
| @@ -1,12 +1,17 @@ | |||
| 1 | ARM Freescale DSPI controller | 1 | ARM Freescale DSPI controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : "fsl,vf610-dspi", "fsl,ls1021a-v1.0-dspi", | 4 | - compatible : must be one of: |
| 5 | "fsl,ls2085a-dspi" | 5 | "fsl,vf610-dspi", |
| 6 | or | 6 | "fsl,ls1021a-v1.0-dspi", |
| 7 | "fsl,ls2080a-dspi" followed by "fsl,ls2085a-dspi" | 7 | "fsl,ls1012a-dspi" (optionally followed by "fsl,ls1021a-v1.0-dspi"), |
| 8 | "fsl,ls1012a-dspi" followed by "fsl,ls1021a-v1.0-dspi" | 8 | "fsl,ls1028a-dspi", |
| 9 | "fsl,ls1088a-dspi" followed by "fsl,ls1021a-v1.0-dspi" | 9 | "fsl,ls1043a-dspi" (optionally followed by "fsl,ls1021a-v1.0-dspi"), |
| 10 | "fsl,ls1046a-dspi" (optionally followed by "fsl,ls1021a-v1.0-dspi"), | ||
| 11 | "fsl,ls1088a-dspi" (optionally followed by "fsl,ls1021a-v1.0-dspi"), | ||
| 12 | "fsl,ls2080a-dspi" (optionally followed by "fsl,ls2085a-dspi"), | ||
| 13 | "fsl,ls2085a-dspi", | ||
| 14 | "fsl,lx2160a-dspi", | ||
| 10 | - reg : Offset and length of the register set for the device | 15 | - reg : Offset and length of the register set for the device |
| 11 | - interrupts : Should contain SPI controller interrupt | 16 | - interrupts : Should contain SPI controller interrupt |
| 12 | - clocks: from common clock binding: handle to dspi clock. | 17 | - clocks: from common clock binding: handle to dspi clock. |
| @@ -14,11 +19,11 @@ Required properties: · 1 unmodified line | |||
| 14 | - pinctrl-0: pin control group to be used for this controller. | 19 | - pinctrl-0: pin control group to be used for this controller. |
| 15 | - pinctrl-names: must contain a "default" entry. | 20 | - pinctrl-names: must contain a "default" entry. |
| 16 | - spi-num-chipselects : the number of the chipselect signals. | 21 | - spi-num-chipselects : the number of the chipselect signals. |
| 17 | - bus-num : the slave chip chipselect signal number. | ||
| 18 | 22 | ||
| 19 | Optional property: | 23 | Optional property: |
| 20 | - big-endian: If present the dspi device's registers are implemented | 24 | - big-endian: If present the dspi device's registers are implemented |
| 21 | in big endian mode. | 25 | in big endian mode. |
| 26 | - bus-num : the slave chip chipselect signal number. | ||
| 22 | 27 | ||
| 23 | Optional SPI slave node properties: | 28 | Optional SPI slave node properties: |
| 24 | - fsl,spi-cs-sck-delay: a delay in nanoseconds between activating chip | 29 | - fsl,spi-cs-sck-delay: a delay in nanoseconds between activating chip |
| @@ -1,4 +1,4 @@ | |||
| 1 | * Serial NOR flash controller for MediaTek SoCs | 1 | * Serial NOR flash controller for MediaTek ARM SoCs |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: For mt8173, compatible should be "mediatek,mt8173-nor", | 4 | - compatible: For mt8173, compatible should be "mediatek,mt8173-nor", |
| @@ -13,6 +13,7 @@ Required properties: · 8 unmodified lines | |||
| 13 | "mediatek,mt7629-nor", "mediatek,mt8173-nor" | 13 | "mediatek,mt7629-nor", "mediatek,mt8173-nor" |
| 14 | "mediatek,mt8173-nor" | 14 | "mediatek,mt8173-nor" |
| 15 | - reg: physical base address and length of the controller's register | 15 | - reg: physical base address and length of the controller's register |
| 16 | - interrupts: Interrupt number used by the controller. | ||
| 16 | - clocks: the phandle of the clocks needed by the nor controller | 17 | - clocks: the phandle of the clocks needed by the nor controller |
| 17 | - clock-names: the names of the clocks | 18 | - clock-names: the names of the clocks |
| 18 | the clocks should be named "spi" and "sf". "spi" is used for spi bus, | 19 | the clocks should be named "spi" and "sf". "spi" is used for spi bus, |
| @@ -22,20 +23,16 @@ Required properties: · 3 unmodified lines | |||
| 22 | - #address-cells: should be <1> | 23 | - #address-cells: should be <1> |
| 23 | - #size-cells: should be <0> | 24 | - #size-cells: should be <0> |
| 24 | 25 | ||
| 25 | The SPI flash must be a child of the nor_flash node and must have a | 26 | There should be only one spi slave device following generic spi bindings. |
| 26 | compatible property. Also see jedec,spi-nor.txt. | 27 | It's not recommended to use this controller for devices other than SPI NOR |
| 27 | 28 | flash due to limited transfer capability of this controller. | |
| 28 | Required properties: | ||
| 29 | - compatible: May include a device-specific string consisting of the manufacturer | ||
| 30 | and name of the chip. Must also include "jedec,spi-nor" for any | ||
| 31 | SPI NOR flash that can be identified by the JEDEC READ ID opcode (0x9F). | ||
| 32 | - reg : Chip-Select number | ||
| 33 | 29 | ||
| 34 | Example: | 30 | Example: |
| 35 | 31 | ||
| 36 | nor_flash: spi@1100d000 { | 32 | nor_flash: spi@1100d000 { |
| 37 | compatible = "mediatek,mt8173-nor"; | 33 | compatible = "mediatek,mt8173-nor"; |
| 38 | reg = <0 0x1100d000 0 0xe0>; | 34 | reg = <0 0x1100d000 0 0xe0>; |
| 35 | interrupts = <&spi_flash_irq>; | ||
| 39 | clocks = <&pericfg CLK_PERI_SPI>, | 36 | clocks = <&pericfg CLK_PERI_SPI>, |
| 40 | <&topckgen CLK_TOP_SPINFI_IFR_SEL>; | 37 | <&topckgen CLK_TOP_SPINFI_IFR_SEL>; |
| 41 | clock-names = "spi", "sf"; | 38 | clock-names = "spi", "sf"; |
| @@ -0,0 +1,89 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/spi/spi-mux.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Generic SPI Multiplexer | ||
| 8 | |||
| 9 | description: | | ||
| 10 | This binding describes a SPI bus multiplexer to route the SPI chip select | ||
| 11 | signals. This can be used when you need more devices than the SPI controller | ||
| 12 | has chip selects available. An example setup is shown in ASCII art; the actual | ||
| 13 | setting of the multiplexer to a channel needs to be done by a specific SPI mux | ||
| 14 | driver. | ||
| 15 | |||
| 16 | MOSI /--------------------------------+--------+--------+--------\ | ||
| 17 | MISO |/------------------------------+|-------+|-------+|-------\| | ||
| 18 | SCL ||/----------------------------+||------+||------+||------\|| | ||
| 19 | ||| ||| ||| ||| ||| | ||
| 20 | +------------+ ||| ||| ||| ||| | ||
| 21 | | SoC ||| | +-+++-+ +-+++-+ +-+++-+ +-+++-+ | ||
| 22 | | ||| | | dev | | dev | | dev | | dev | | ||
| 23 | | +--+++-+ | CS-X +------+\ +--+--+ +--+--+ +--+--+ +--+--+ | ||
| 24 | | | SPI +-|-------+ Mux |\\ CS-0 | | | | | ||
| 25 | | +------+ | +--+---+\\\-------/ CS-1 | | | | ||
| 26 | | | | \\\----------------/ CS-2 | | | ||
| 27 | | +------+ | | \\-------------------------/ CS-3 | | ||
| 28 | | | ? +-|----------/ \----------------------------------/ | ||
| 29 | | +------+ | | ||
| 30 | +------------+ | ||
| 31 | |||
| 32 | allOf: | ||
| 33 | - $ref: "/schemas/spi/spi-controller.yaml#" | ||
| 34 | |||
| 35 | maintainers: | ||
| 36 | - Chris Packham <chris.packham@alliedtelesis.co.nz> | ||
| 37 | |||
| 38 | properties: | ||
| 39 | compatible: | ||
| 40 | const: spi-mux | ||
| 41 | |||
| 42 | mux-controls: | ||
| 43 | maxItems: 1 | ||
| 44 | |||
| 45 | required: | ||
| 46 | - compatible | ||
| 47 | - reg | ||
| 48 | - spi-max-frequency | ||
| 49 | - mux-controls | ||
| 50 | |||
| 51 | examples: | ||
| 52 | - | | ||
| 53 | #include <dt-bindings/gpio/gpio.h> | ||
| 54 | mux: mux-controller { | ||
| 55 | compatible = "gpio-mux"; | ||
| 56 | #mux-control-cells = <0>; | ||
| 57 | |||
| 58 | mux-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; | ||
| 59 | }; | ||
| 60 | |||
| 61 | spi { | ||
| 62 | #address-cells = <1>; | ||
| 63 | #size-cells = <0>; | ||
| 64 | spi@0 { | ||
| 65 | compatible = "spi-mux"; | ||
| 66 | reg = <0>; | ||
| 67 | #address-cells = <1>; | ||
| 68 | #size-cells = <0>; | ||
| 69 | spi-max-frequency = <100000000>; | ||
| 70 | |||
| 71 | mux-controls = <&mux>; | ||
| 72 | |||
| 73 | spi-flash@0 { | ||
| 74 | compatible = "jedec,spi-nor"; | ||
| 75 | reg = <0>; | ||
| 76 | #address-cells = <1>; | ||
| 77 | #size-cells = <0>; | ||
| 78 | spi-max-frequency = <40000000>; | ||
| 79 | }; | ||
| 80 | |||
| 81 | spi-device@1 { | ||
| 82 | compatible = "lineartechnology,ltc2488"; | ||
| 83 | reg = <1>; | ||
| 84 | #address-cells = <1>; | ||
| 85 | #size-cells = <0>; | ||
| 86 | spi-max-frequency = <10000000>; | ||
| 87 | }; | ||
| 88 | }; | ||
| 89 | }; | ||
| @@ -2,6 +2,9 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : Should be "nxp,lx2160a-fspi" | 4 | - compatible : Should be "nxp,lx2160a-fspi" |
| 5 | "nxp,imx8qxp-fspi" | ||
| 6 | "nxp,imx8mm-fspi" | ||
| 7 | |||
| 5 | - reg : First contains the register location and length, | 8 | - reg : First contains the register location and length, |
| 6 | Second contains the memory mapping address and length | 9 | Second contains the memory mapping address and length |
| 7 | - reg-names : Should contain the resource reg names: | 10 | - reg-names : Should contain the resource reg names: |
| @@ -1,58 +0,0 @@ | |||
| 1 | * Rockchip SPI Controller | ||
| 2 | |||
| 3 | The Rockchip SPI controller is used to interface with various devices such as flash | ||
| 4 | and display controllers using the SPI communication interface. | ||
| 5 | |||
| 6 | Required Properties: | ||
| 7 | |||
| 8 | - compatible: should be one of the following. | ||
| 9 | "rockchip,rv1108-spi" for rv1108 SoCs. | ||
| 10 | "rockchip,px30-spi", "rockchip,rk3066-spi" for px30 SoCs. | ||
| 11 | "rockchip,rk3036-spi" for rk3036 SoCS. | ||
| 12 | "rockchip,rk3066-spi" for rk3066 SoCs. | ||
| 13 | "rockchip,rk3188-spi" for rk3188 SoCs. | ||
| 14 | "rockchip,rk3228-spi" for rk3228 SoCS. | ||
| 15 | "rockchip,rk3288-spi" for rk3288 SoCs. | ||
| 16 | "rockchip,rk3368-spi" for rk3368 SoCs. | ||
| 17 | "rockchip,rk3399-spi" for rk3399 SoCs. | ||
| 18 | - reg: physical base address of the controller and length of memory mapped | ||
| 19 | region. | ||
| 20 | - interrupts: The interrupt number to the cpu. The interrupt specifier format | ||
| 21 | depends on the interrupt controller. | ||
| 22 | - clocks: Must contain an entry for each entry in clock-names. | ||
| 23 | - clock-names: Shall be "spiclk" for the transfer-clock, and "apb_pclk" for | ||
| 24 | the peripheral clock. | ||
| 25 | - #address-cells: should be 1. | ||
| 26 | - #size-cells: should be 0. | ||
| 27 | |||
| 28 | Optional Properties: | ||
| 29 | |||
| 30 | - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, | ||
| 31 | Documentation/devicetree/bindings/dma/dma.txt | ||
| 32 | - dma-names: DMA request names should include "tx" and "rx" if present. | ||
| 33 | - rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling | ||
| 34 | Rx data (may need to be fine tuned for high capacitance lines). | ||
| 35 | No delay (0) by default. | ||
| 36 | - pinctrl-names: Names for the pin configuration(s); may be "default" or | ||
| 37 | "sleep", where the "sleep" configuration may describe the state | ||
| 38 | the pins should be in during system suspend. See also | ||
| 39 | pinctrl/pinctrl-bindings.txt. | ||
| 40 | |||
| 41 | |||
| 42 | Example: | ||
| 43 | |||
| 44 | spi0: spi@ff110000 { | ||
| 45 | compatible = "rockchip,rk3066-spi"; | ||
| 46 | reg = <0xff110000 0x1000>; | ||
| 47 | dmas = <&pdma1 11>, <&pdma1 12>; | ||
| 48 | dma-names = "tx", "rx"; | ||
| 49 | rx-sample-delay-ns = <10>; | ||
| 50 | #address-cells = <1>; | ||
| 51 | #size-cells = <0>; | ||
| 52 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; | ||
| 53 | clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; | ||
| 54 | clock-names = "spiclk", "apb_pclk"; | ||
| 55 | pinctrl-0 = <&spi1_pins>; | ||
| 56 | pinctrl-1 = <&spi1_sleep>; | ||
| 57 | pinctrl-names = "default", "sleep"; | ||
| 58 | }; | ||
| @@ -0,0 +1,107 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/spi/spi-rockchip.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Rockchip SPI Controller | ||
| 8 | |||
| 9 | description: | ||
| 10 | The Rockchip SPI controller is used to interface with various devices such | ||
| 11 | as flash and display controllers using the SPI communication interface. | ||
| 12 | |||
| 13 | allOf: | ||
| 14 | - $ref: "spi-controller.yaml#" | ||
| 15 | |||
| 16 | maintainers: | ||
| 17 | - Heiko Stuebner <heiko@sntech.de> | ||
| 18 | |||
| 19 | # Everything else is described in the common file | ||
| 20 | properties: | ||
| 21 | compatible: | ||
| 22 | oneOf: | ||
| 23 | - const: rockchip,rk3036-spi | ||
| 24 | - const: rockchip,rk3066-spi | ||
| 25 | - const: rockchip,rk3228-spi | ||
| 26 | - const: rockchip,rv1108-spi | ||
| 27 | - items: | ||
| 28 | - enum: | ||
| 29 | - rockchip,px30-spi | ||
| 30 | - rockchip,rk3188-spi | ||
| 31 | - rockchip,rk3288-spi | ||
| 32 | - rockchip,rk3308-spi | ||
| 33 | - rockchip,rk3328-spi | ||
| 34 | - rockchip,rk3368-spi | ||
| 35 | - rockchip,rk3399-spi | ||
| 36 | - const: rockchip,rk3066-spi | ||
| 37 | |||
| 38 | reg: | ||
| 39 | maxItems: 1 | ||
| 40 | |||
| 41 | interrupts: | ||
| 42 | maxItems: 1 | ||
| 43 | |||
| 44 | clocks: | ||
| 45 | items: | ||
| 46 | - description: transfer-clock | ||
| 47 | - description: peripheral clock | ||
| 48 | |||
| 49 | clock-names: | ||
| 50 | items: | ||
| 51 | - const: spiclk | ||
| 52 | - const: apb_pclk | ||
| 53 | |||
| 54 | dmas: | ||
| 55 | items: | ||
| 56 | - description: TX DMA Channel | ||
| 57 | - description: RX DMA Channel | ||
| 58 | |||
| 59 | dma-names: | ||
| 60 | items: | ||
| 61 | - const: tx | ||
| 62 | - const: rx | ||
| 63 | |||
| 64 | rx-sample-delay-ns: | ||
| 65 | default: 0 | ||
| 66 | description: | ||
| 67 | Nano seconds to delay after the SCLK edge before sampling Rx data | ||
| 68 | (may need to be fine tuned for high capacitance lines). | ||
| 69 | If not specified 0 will be used. | ||
| 70 | |||
| 71 | pinctrl-names: | ||
| 72 | minItems: 1 | ||
| 73 | items: | ||
| 74 | - const: default | ||
| 75 | - const: sleep | ||
| 76 | description: | ||
| 77 | Names for the pin configuration(s); may be "default" or "sleep", | ||
| 78 | where the "sleep" configuration may describe the state | ||
| 79 | the pins should be in during system suspend. | ||
| 80 | |||
| 81 | required: | ||
| 82 | - compatible | ||
| 83 | - reg | ||
| 84 | - interrupts | ||
| 85 | - clocks | ||
| 86 | - clock-names | ||
| 87 | |||
| 88 | examples: | ||
| 89 | - | | ||
| 90 | #include <dt-bindings/clock/rk3188-cru-common.h> | ||
| 91 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 92 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 93 | spi0: spi@ff110000 { | ||
| 94 | compatible = "rockchip,rk3066-spi"; | ||
| 95 | reg = <0xff110000 0x1000>; | ||
| 96 | interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; | ||
| 97 | clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; | ||
| 98 | clock-names = "spiclk", "apb_pclk"; | ||
| 99 | dmas = <&pdma1 11>, <&pdma1 12>; | ||
| 100 | dma-names = "tx", "rx"; | ||
| 101 | pinctrl-0 = <&spi1_pins>; | ||
| 102 | pinctrl-1 = <&spi1_sleep>; | ||
| 103 | pinctrl-names = "default", "sleep"; | ||
| 104 | rx-sample-delay-ns = <10>; | ||
| 105 | #address-cells = <1>; | ||
| 106 | #size-cells = <0>; | ||
| 107 | }; | ||
| @@ -2276,6 +2276,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git · 2275 unmodified lines | |||
| 2276 | S: Maintained | 2276 | S: Maintained |
| 2277 | F: Documentation/devicetree/bindings/i2c/i2c-rk3x.txt | 2277 | F: Documentation/devicetree/bindings/i2c/i2c-rk3x.txt |
| 2278 | F: Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml | 2278 | F: Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml |
| 2279 | F: Documentation/devicetree/bindings/spi/spi-rockchip.yaml | ||
| 2279 | F: arch/arm/boot/dts/rk3* | 2280 | F: arch/arm/boot/dts/rk3* |
| 2280 | F: arch/arm/boot/dts/rv1108* | 2281 | F: arch/arm/boot/dts/rv1108* |
| 2281 | F: arch/arm/mach-rockchip/ | 2282 | F: arch/arm/mach-rockchip/ |
| @@ -6858,6 +6859,13 @@ S: Maintained · 4576 unmodified lines | |||
| 6858 | F: drivers/i2c/busses/i2c-fsi.c | 6859 | F: drivers/i2c/busses/i2c-fsi.c |
| 6859 | F: Documentation/devicetree/bindings/i2c/i2c-fsi.txt | 6860 | F: Documentation/devicetree/bindings/i2c/i2c-fsi.txt |
| 6860 | 6861 | ||
| 6862 | FSI-ATTACHED SPI DRIVER | ||
| 6863 | M: Eddie James <eajames@linux.ibm.com> | ||
| 6864 | L: linux-spi@vger.kernel.org | ||
| 6865 | S: Maintained | ||
| 6866 | F: drivers/spi/spi-fsi.c | ||
| 6867 | F: Documentation/devicetree/bindings/fsi/ibm,fsi2spi.yaml | ||
| 6868 | |||
| 6861 | FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE | 6869 | FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE |
| 6862 | M: Jan Kara <jack@suse.cz> | 6870 | M: Jan Kara <jack@suse.cz> |
| 6863 | R: Amir Goldstein <amir73il@gmail.com> | 6871 | R: Amir Goldstein <amir73il@gmail.com> |
| @@ -11256,7 +11264,8 @@ F: drivers/tty/mxser.* · 4392 unmodified lines | |||
| 11256 | MONOLITHIC POWER SYSTEM PMIC DRIVER | 11264 | MONOLITHIC POWER SYSTEM PMIC DRIVER |
| 11257 | M: Saravanan Sekar <sravanhome@gmail.com> | 11265 | M: Saravanan Sekar <sravanhome@gmail.com> |
| 11258 | S: Maintained | 11266 | S: Maintained |
| 11259 | F: Documentation/devicetree/bindings/regulator/mpq7920.yaml | 11267 | F: Documentation/devicetree/bindings/regulator/mps,mp*.yaml |
| 11268 | F: drivers/regulator/mp5416.c | ||
| 11260 | F: drivers/regulator/mpq7920.c | 11269 | F: drivers/regulator/mpq7920.c |
| 11261 | F: drivers/regulator/mpq7920.h | 11270 | F: drivers/regulator/mpq7920.h |
| 11262 | 11271 | ||
| @@ -52,14 +52,6 @@ config SPI_HISI_SFC · 51 unmodified lines | |||
| 52 | help | 52 | help |
| 53 | This enables support for HiSilicon FMC SPI-NOR flash controller. | 53 | This enables support for HiSilicon FMC SPI-NOR flash controller. |
| 54 | 54 | ||
| 55 | config SPI_MTK_QUADSPI | ||
| 56 | tristate "MediaTek Quad SPI controller" | ||
| 57 | depends on HAS_IOMEM | ||
| 58 | help | ||
| 59 | This enables support for the Quad SPI controller in master mode. | ||
| 60 | This controller does not support generic SPI. It only supports | ||
| 61 | SPI NOR. | ||
| 62 | |||
| 63 | config SPI_NXP_SPIFI | 55 | config SPI_NXP_SPIFI |
| 64 | tristate "NXP SPI Flash Interface (SPIFI)" | 56 | tristate "NXP SPI Flash Interface (SPIFI)" |
| 65 | depends on OF && (ARCH_LPC18XX || COMPILE_TEST) | 57 | depends on OF && (ARCH_LPC18XX || COMPILE_TEST) |
| @@ -3,7 +3,6 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o · 2 unmodified lines | |||
| 3 | obj-$(CONFIG_SPI_ASPEED_SMC) += aspeed-smc.o | 3 | obj-$(CONFIG_SPI_ASPEED_SMC) += aspeed-smc.o |
| 4 | obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o | 4 | obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o |
| 5 | obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o | 5 | obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o |
| 6 | obj-$(CONFIG_SPI_MTK_QUADSPI) += mtk-quadspi.o | ||
| 7 | obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o | 6 | obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o |
| 8 | obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o | 7 | obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o |
| 9 | obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o | 8 | obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o |
| @@ -1,565 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2015 MediaTek Inc. | ||
| 4 | * Author: Bayi Cheng <bayi.cheng@mediatek.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/clk.h> | ||
| 8 | #include <linux/delay.h> | ||
| 9 | #include <linux/device.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/io.h> | ||
| 12 | #include <linux/iopoll.h> | ||
| 13 | #include <linux/ioport.h> | ||
| 14 | #include <linux/math64.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/mutex.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/of_device.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/mtd/mtd.h> | ||
| 22 | #include <linux/mtd/partitions.h> | ||
| 23 | #include <linux/mtd/spi-nor.h> | ||
| 24 | |||
| 25 | #define MTK_NOR_CMD_REG 0x00 | ||
| 26 | #define MTK_NOR_CNT_REG 0x04 | ||
| 27 | #define MTK_NOR_RDSR_REG 0x08 | ||
| 28 | #define MTK_NOR_RDATA_REG 0x0c | ||
| 29 | #define MTK_NOR_RADR0_REG 0x10 | ||
| 30 | #define MTK_NOR_RADR1_REG 0x14 | ||
| 31 | #define MTK_NOR_RADR2_REG 0x18 | ||
| 32 | #define MTK_NOR_WDATA_REG 0x1c | ||
| 33 | #define MTK_NOR_PRGDATA0_REG 0x20 | ||
| 34 | #define MTK_NOR_PRGDATA1_REG 0x24 | ||
| 35 | #define MTK_NOR_PRGDATA2_REG 0x28 | ||
| 36 | #define MTK_NOR_PRGDATA3_REG 0x2c | ||
| 37 | #define MTK_NOR_PRGDATA4_REG 0x30 | ||
| 38 | #define MTK_NOR_PRGDATA5_REG 0x34 | ||
| 39 | #define MTK_NOR_SHREG0_REG 0x38 | ||
| 40 | #define MTK_NOR_SHREG1_REG 0x3c | ||
| 41 | #define MTK_NOR_SHREG2_REG 0x40 | ||
| 42 | #define MTK_NOR_SHREG3_REG 0x44 | ||
| 43 | #define MTK_NOR_SHREG4_REG 0x48 | ||
| 44 | #define MTK_NOR_SHREG5_REG 0x4c | ||
| 45 | #define MTK_NOR_SHREG6_REG 0x50 | ||
| 46 | #define MTK_NOR_SHREG7_REG 0x54 | ||
| 47 | #define MTK_NOR_SHREG8_REG 0x58 | ||
| 48 | #define MTK_NOR_SHREG9_REG 0x5c | ||
| 49 | #define MTK_NOR_CFG1_REG 0x60 | ||
| 50 | #define MTK_NOR_CFG2_REG 0x64 | ||
| 51 | #define MTK_NOR_CFG3_REG 0x68 | ||
| 52 | #define MTK_NOR_STATUS0_REG 0x70 | ||
| 53 | #define MTK_NOR_STATUS1_REG 0x74 | ||
| 54 | #define MTK_NOR_STATUS2_REG 0x78 | ||
| 55 | #define MTK_NOR_STATUS3_REG 0x7c | ||
| 56 | #define MTK_NOR_FLHCFG_REG 0x84 | ||
| 57 | #define MTK_NOR_TIME_REG 0x94 | ||
| 58 | #define MTK_NOR_PP_DATA_REG 0x98 | ||
| 59 | #define MTK_NOR_PREBUF_STUS_REG 0x9c | ||
| 60 | #define MTK_NOR_DELSEL0_REG 0xa0 | ||
| 61 | #define MTK_NOR_DELSEL1_REG 0xa4 | ||
| 62 | #define MTK_NOR_INTRSTUS_REG 0xa8 | ||
| 63 | #define MTK_NOR_INTREN_REG 0xac | ||
| 64 | #define MTK_NOR_CHKSUM_CTL_REG 0xb8 | ||
| 65 | #define MTK_NOR_CHKSUM_REG 0xbc | ||
| 66 | #define MTK_NOR_CMD2_REG 0xc0 | ||
| 67 | #define MTK_NOR_WRPROT_REG 0xc4 | ||
| 68 | #define MTK_NOR_RADR3_REG 0xc8 | ||
| 69 | #define MTK_NOR_DUAL_REG 0xcc | ||
| 70 | #define MTK_NOR_DELSEL2_REG 0xd0 | ||
| 71 | #define MTK_NOR_DELSEL3_REG 0xd4 | ||
| 72 | #define MTK_NOR_DELSEL4_REG 0xd8 | ||
| 73 | |||
| 74 | /* commands for mtk nor controller */ | ||
| 75 | #define MTK_NOR_READ_CMD 0x0 | ||
| 76 | #define MTK_NOR_RDSR_CMD 0x2 | ||
| 77 | #define MTK_NOR_PRG_CMD 0x4 | ||
| 78 | #define MTK_NOR_WR_CMD 0x10 | ||
| 79 | #define MTK_NOR_PIO_WR_CMD 0x90 | ||
| 80 | #define MTK_NOR_WRSR_CMD 0x20 | ||
| 81 | #define MTK_NOR_PIO_READ_CMD 0x81 | ||
| 82 | #define MTK_NOR_WR_BUF_ENABLE 0x1 | ||
| 83 | #define MTK_NOR_WR_BUF_DISABLE 0x0 | ||
| 84 | #define MTK_NOR_ENABLE_SF_CMD 0x30 | ||
| 85 | #define MTK_NOR_DUAD_ADDR_EN 0x8 | ||
| 86 | #define MTK_NOR_QUAD_READ_EN 0x4 | ||
| 87 | #define MTK_NOR_DUAL_ADDR_EN 0x2 | ||
| 88 | #define MTK_NOR_DUAL_READ_EN 0x1 | ||
| 89 | #define MTK_NOR_DUAL_DISABLE 0x0 | ||
| 90 | #define MTK_NOR_FAST_READ 0x1 | ||
| 91 | |||
| 92 | #define SFLASH_WRBUF_SIZE 128 | ||
| 93 | |||
| 94 | /* Can shift up to 48 bits (6 bytes) of TX/RX */ | ||
| 95 | #define MTK_NOR_MAX_RX_TX_SHIFT 6 | ||
| 96 | /* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */ | ||
| 97 | #define MTK_NOR_MAX_SHIFT 7 | ||
| 98 | /* nor controller 4-byte address mode enable bit */ | ||
| 99 | #define MTK_NOR_4B_ADDR_EN BIT(4) | ||
| 100 | |||
| 101 | /* Helpers for accessing the program data / shift data registers */ | ||
| 102 | #define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) | ||
| 103 | #define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n)) | ||
| 104 | |||
| 105 | struct mtk_nor { | ||
| 106 | struct spi_nor nor; | ||
| 107 | struct device *dev; | ||
| 108 | void __iomem *base; /* nor flash base address */ | ||
| 109 | struct clk *spi_clk; | ||
| 110 | struct clk *nor_clk; | ||
| 111 | }; | ||
| 112 | |||
| 113 | static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor) | ||
| 114 | { | ||
| 115 | struct spi_nor *nor = &mtk_nor->nor; | ||
| 116 | |||
| 117 | switch (nor->read_proto) { | ||
| 118 | case SNOR_PROTO_1_1_1: | ||
| 119 | writeb(nor->read_opcode, mtk_nor->base + | ||
| 120 | MTK_NOR_PRGDATA3_REG); | ||
| 121 | writeb(MTK_NOR_FAST_READ, mtk_nor->base + | ||
| 122 | MTK_NOR_CFG1_REG); | ||
| 123 | break; | ||
| 124 | case SNOR_PROTO_1_1_2: | ||
| 125 | writeb(nor->read_opcode, mtk_nor->base + | ||
| 126 | MTK_NOR_PRGDATA3_REG); | ||
| 127 | writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base + | ||
| 128 | MTK_NOR_DUAL_REG); | ||
| 129 | break; | ||
| 130 | case SNOR_PROTO_1_1_4: | ||
| 131 | writeb(nor->read_opcode, mtk_nor->base + | ||
| 132 | MTK_NOR_PRGDATA4_REG); | ||
| 133 | writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base + | ||
| 134 | MTK_NOR_DUAL_REG); | ||
| 135 | break; | ||
| 136 | default: | ||
| 137 | writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base + | ||
| 138 | MTK_NOR_DUAL_REG); | ||
| 139 | break; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval) | ||
| 144 | { | ||
| 145 | int reg; | ||
| 146 | u8 val = cmdval & 0x1f; | ||
| 147 | |||
| 148 | writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG); | ||
| 149 | return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg, | ||
| 150 | !(reg & val), 100, 10000); | ||
| 151 | } | ||
| 152 | |||
| 153 | static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op, | ||
| 154 | const u8 *tx, size_t txlen, u8 *rx, size_t rxlen) | ||
| 155 | { | ||
| 156 | size_t len = 1 + txlen + rxlen; | ||
| 157 | int i, ret, idx; | ||
| 158 | |||
| 159 | if (len > MTK_NOR_MAX_SHIFT) | ||
| 160 | return -EINVAL; | ||
| 161 | |||
| 162 | writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG); | ||
| 163 | |||
| 164 | /* start at PRGDATA5, go down to PRGDATA0 */ | ||
| 165 | idx = MTK_NOR_MAX_RX_TX_SHIFT - 1; | ||
| 166 | |||
| 167 | /* opcode */ | ||
| 168 | writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx)); | ||
| 169 | idx--; | ||
| 170 | |||
| 171 | /* program TX data */ | ||
| 172 | for (i = 0; i < txlen; i++, idx--) | ||
| 173 | writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx)); | ||
| 174 | |||
| 175 | /* clear out rest of TX registers */ | ||
| 176 | while (idx >= 0) { | ||
| 177 | writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx)); | ||
| 178 | idx--; | ||
| 179 | } | ||
| 180 | |||
| 181 | ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD); | ||
| 182 | if (ret) | ||
| 183 | return ret; | ||
| 184 | |||
| 185 | /* restart at first RX byte */ | ||
| 186 | idx = rxlen - 1; | ||
| 187 | |||
| 188 | /* read out RX data */ | ||
| 189 | for (i = 0; i < rxlen; i++, idx--) | ||
| 190 | rx[i] = readb(mtk_nor->base + MTK_NOR_SHREG(idx)); | ||
| 191 | |||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* Do a WRSR (Write Status Register) command */ | ||
| 196 | static int mtk_nor_wr_sr(struct mtk_nor *mtk_nor, const u8 sr) | ||
| 197 | { | ||
| 198 | writeb(sr, mtk_nor->base + MTK_NOR_PRGDATA5_REG); | ||
| 199 | writeb(8, mtk_nor->base + MTK_NOR_CNT_REG); | ||
| 200 | return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WRSR_CMD); | ||
| 201 | } | ||
| 202 | |||
| 203 | static int mtk_nor_write_buffer_enable(struct mtk_nor *mtk_nor) | ||
| 204 | { | ||
| 205 | u8 reg; | ||
| 206 | |||
| 207 | /* the bit0 of MTK_NOR_CFG2_REG is pre-fetch buffer | ||
| 208 | * 0: pre-fetch buffer use for read | ||
| 209 | * 1: pre-fetch buffer use for page program | ||
| 210 | */ | ||
| 211 | writel(MTK_NOR_WR_BUF_ENABLE, mtk_nor->base + MTK_NOR_CFG2_REG); | ||
| 212 | return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg, | ||
| 213 | 0x01 == (reg & 0x01), 100, 10000); | ||
| 214 | } | ||
| 215 | |||
| 216 | static int mtk_nor_write_buffer_disable(struct mtk_nor *mtk_nor) | ||
| 217 | { | ||
| 218 | u8 reg; | ||
| 219 | |||
| 220 | writel(MTK_NOR_WR_BUF_DISABLE, mtk_nor->base + MTK_NOR_CFG2_REG); | ||
| 221 | return readb_poll_timeout(mtk_nor->base + MTK_NOR_CFG2_REG, reg, | ||
| 222 | MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100, | ||
| 223 | 10000); | ||
| 224 | } | ||
| 225 | |||
| 226 | static void mtk_nor_set_addr_width(struct mtk_nor *mtk_nor) | ||
| 227 | { | ||
| 228 | u8 val; | ||
| 229 | struct spi_nor *nor = &mtk_nor->nor; | ||
| 230 | |||
| 231 | val = readb(mtk_nor->base + MTK_NOR_DUAL_REG); | ||
| 232 | |||
| 233 | switch (nor->addr_width) { | ||
| 234 | case 3: | ||
| 235 | val &= ~MTK_NOR_4B_ADDR_EN; | ||
| 236 | break; | ||
| 237 | case 4: | ||
| 238 | val |= MTK_NOR_4B_ADDR_EN; | ||
| 239 | break; | ||
| 240 | default: | ||
| 241 | dev_warn(mtk_nor->dev, "Unexpected address width %u.\n", | ||
| 242 | nor->addr_width); | ||
| 243 | break; | ||
| 244 | } | ||
| 245 | |||
| 246 | writeb(val, mtk_nor->base + MTK_NOR_DUAL_REG); | ||
| 247 | } | ||
| 248 | |||
| 249 | static void mtk_nor_set_addr(struct mtk_nor *mtk_nor, u32 addr) | ||
| 250 | { | ||
| 251 | int i; | ||
| 252 | |||
| 253 | mtk_nor_set_addr_width(mtk_nor); | ||
| 254 | |||
| 255 | for (i = 0; i < 3; i++) { | ||
| 256 | writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR0_REG + i * 4); | ||
| 257 | addr >>= 8; | ||
| 258 | } | ||
| 259 | /* Last register is non-contiguous */ | ||
| 260 | writeb(addr & 0xff, mtk_nor->base + MTK_NOR_RADR3_REG); | ||
| 261 | } | ||
| 262 | |||
| 263 | static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length, | ||
| 264 | u_char *buffer) | ||
| 265 | { | ||
| 266 | int i, ret; | ||
| 267 | int addr = (int)from; | ||
| 268 | u8 *buf = (u8 *)buffer; | ||
| 269 | struct mtk_nor *mtk_nor = nor->priv; | ||
| 270 | |||
| 271 | /* set mode for fast read mode ,dual mode or quad mode */ | ||
| 272 | mtk_nor_set_read_mode(mtk_nor); | ||
| 273 | mtk_nor_set_addr(mtk_nor, addr); | ||
| 274 | |||
| 275 | for (i = 0; i < length; i++) { | ||
| 276 | ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD); | ||
| 277 | if (ret < 0) | ||
| 278 | return ret; | ||
| 279 | buf[i] = readb(mtk_nor->base + MTK_NOR_RDATA_REG); | ||
| 280 | } | ||
| 281 | return length; | ||
| 282 | } | ||
| 283 | |||
| 284 | static int mtk_nor_write_single_byte(struct mtk_nor *mtk_nor, | ||
| 285 | int addr, int length, u8 *data) | ||
| 286 | { | ||
| 287 | int i, ret; | ||
| 288 | |||
| 289 | mtk_nor_set_addr(mtk_nor, addr); | ||
| 290 | |||
| 291 | for (i = 0; i < length; i++) { | ||
| 292 | writeb(*data++, mtk_nor->base + MTK_NOR_WDATA_REG); | ||
| 293 | ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_WR_CMD); | ||
| 294 | if (ret < 0) | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int mtk_nor_write_buffer(struct mtk_nor *mtk_nor, int addr, | ||
| 301 | const u8 *buf) | ||
| 302 | { | ||
| 303 | int i, bufidx, data; | ||
| 304 | |||
| 305 | mtk_nor_set_addr(mtk_nor, addr); | ||
| 306 | |||
| 307 | bufidx = 0; | ||
| 308 | for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) { | ||
| 309 | data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 | | ||
| 310 | buf[bufidx + 1]<<8 | buf[bufidx]; | ||
| 311 | bufidx += 4; | ||
| 312 | writel(data, mtk_nor->base + MTK_NOR_PP_DATA_REG); | ||
| 313 | } | ||
| 314 | return mtk_nor_execute_cmd(mtk_nor, MTK_NOR_WR_CMD); | ||
| 315 | } | ||
| 316 | |||
| 317 | static ssize_t mtk_nor_write(struct spi_nor *nor, loff_t to, size_t len, | ||
| 318 | const u_char *buf) | ||
| 319 | { | ||
| 320 | int ret; | ||
| 321 | struct mtk_nor *mtk_nor = nor->priv; | ||
| 322 | size_t i; | ||
| 323 | |||
| 324 | ret = mtk_nor_write_buffer_enable(mtk_nor); | ||
| 325 | if (ret < 0) { | ||
| 326 | dev_warn(mtk_nor->dev, "write buffer enable failed!\n"); | ||
| 327 | return ret; | ||
| 328 | } | ||
| 329 | |||
| 330 | for (i = 0; i + SFLASH_WRBUF_SIZE <= len; i += SFLASH_WRBUF_SIZE) { | ||
| 331 | ret = mtk_nor_write_buffer(mtk_nor, to, buf); | ||
| 332 | if (ret < 0) { | ||
| 333 | dev_err(mtk_nor->dev, "write buffer failed!\n"); | ||
| 334 | return ret; | ||
| 335 | } | ||
| 336 | to += SFLASH_WRBUF_SIZE; | ||
| 337 | buf += SFLASH_WRBUF_SIZE; | ||
| 338 | } | ||
| 339 | ret = mtk_nor_write_buffer_disable(mtk_nor); | ||
| 340 | if (ret < 0) { | ||
| 341 | dev_warn(mtk_nor->dev, "write buffer disable failed!\n"); | ||
| 342 | return ret; | ||
| 343 | } | ||
| 344 | |||
| 345 | if (i < len) { | ||
| 346 | ret = mtk_nor_write_single_byte(mtk_nor, to, | ||
| 347 | (int)(len - i), (u8 *)buf); | ||
| 348 | if (ret < 0) { | ||
| 349 | dev_err(mtk_nor->dev, "write single byte failed!\n"); | ||
| 350 | return ret; | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | return len; | ||
| 355 | } | ||
| 356 | |||
| 357 | static int mtk_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len) | ||
| 358 | { | ||
| 359 | int ret; | ||
| 360 | struct mtk_nor *mtk_nor = nor->priv; | ||
| 361 | |||
| 362 | switch (opcode) { | ||
| 363 | case SPINOR_OP_RDSR: | ||
| 364 | ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_RDSR_CMD); | ||
| 365 | if (ret < 0) | ||
| 366 | return ret; | ||
| 367 | if (len == 1) | ||
| 368 | *buf = readb(mtk_nor->base + MTK_NOR_RDSR_REG); | ||
| 369 | else | ||
| 370 | dev_err(mtk_nor->dev, "len should be 1 for read status!\n"); | ||
| 371 | break; | ||
| 372 | default: | ||
| 373 | ret = mtk_nor_do_tx_rx(mtk_nor, opcode, NULL, 0, buf, len); | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | return ret; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int mtk_nor_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, | ||
| 380 | size_t len) | ||
| 381 | { | ||
| 382 | int ret; | ||
| 383 | struct mtk_nor *mtk_nor = nor->priv; | ||
| 384 | |||
| 385 | switch (opcode) { | ||
| 386 | case SPINOR_OP_WRSR: | ||
| 387 | /* We only handle 1 byte */ | ||
| 388 | ret = mtk_nor_wr_sr(mtk_nor, *buf); | ||
| 389 | break; | ||
| 390 | default: | ||
| 391 | ret = mtk_nor_do_tx_rx(mtk_nor, opcode, buf, len, NULL, 0); | ||
| 392 | if (ret) | ||
| 393 | dev_warn(mtk_nor->dev, "write reg failure!\n"); | ||
| 394 | break; | ||
| 395 | } | ||
| 396 | return ret; | ||
| 397 | } | ||
| 398 | |||
| 399 | static void mtk_nor_disable_clk(struct mtk_nor *mtk_nor) | ||
| 400 | { | ||
| 401 | clk_disable_unprepare(mtk_nor->spi_clk); | ||
| 402 | clk_disable_unprepare(mtk_nor->nor_clk); | ||
| 403 | } | ||
| 404 | |||
| 405 | static int mtk_nor_enable_clk(struct mtk_nor *mtk_nor) | ||
| 406 | { | ||
| 407 | int ret; | ||
| 408 | |||
| 409 | ret = clk_prepare_enable(mtk_nor->spi_clk); | ||
| 410 | if (ret) | ||
| 411 | return ret; | ||
| 412 | |||
| 413 | ret = clk_prepare_enable(mtk_nor->nor_clk); | ||
| 414 | if (ret) { | ||
| 415 | clk_disable_unprepare(mtk_nor->spi_clk); | ||
| 416 | return ret; | ||
| 417 | } | ||
| 418 | |||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | |||
| 422 | static const struct spi_nor_controller_ops mtk_controller_ops = { | ||
| 423 | .read_reg = mtk_nor_read_reg, | ||
| 424 | .write_reg = mtk_nor_write_reg, | ||
| 425 | .read = mtk_nor_read, | ||
| 426 | .write = mtk_nor_write, | ||
| 427 | }; | ||
| 428 | |||
| 429 | static int mtk_nor_init(struct mtk_nor *mtk_nor, | ||
| 430 | struct device_node *flash_node) | ||
| 431 | { | ||
| 432 | const struct spi_nor_hwcaps hwcaps = { | ||
| 433 | .mask = SNOR_HWCAPS_READ | | ||
| 434 | SNOR_HWCAPS_READ_FAST | | ||
| 435 | SNOR_HWCAPS_READ_1_1_2 | | ||
| 436 | SNOR_HWCAPS_PP, | ||
| 437 | }; | ||
| 438 | int ret; | ||
| 439 | struct spi_nor *nor; | ||
| 440 | |||
| 441 | /* initialize controller to accept commands */ | ||
| 442 | writel(MTK_NOR_ENABLE_SF_CMD, mtk_nor->base + MTK_NOR_WRPROT_REG); | ||
| 443 | |||
| 444 | nor = &mtk_nor->nor; | ||
| 445 | nor->dev = mtk_nor->dev; | ||
| 446 | nor->priv = mtk_nor; | ||
| 447 | spi_nor_set_flash_node(nor, flash_node); | ||
| 448 | nor->controller_ops = &mtk_controller_ops; | ||
| 449 | |||
| 450 | nor->mtd.name = "mtk_nor"; | ||
| 451 | /* initialized with NULL */ | ||
| 452 | ret = spi_nor_scan(nor, NULL, &hwcaps); | ||
| 453 | if (ret) | ||
| 454 | return ret; | ||
| 455 | |||
| 456 | return mtd_device_register(&nor->mtd, NULL, 0); | ||
| 457 | } | ||
| 458 | |||
| 459 | static int mtk_nor_drv_probe(struct platform_device *pdev) | ||
| 460 | { | ||
| 461 | struct device_node *flash_np; | ||
| 462 | struct resource *res; | ||
| 463 | int ret; | ||
| 464 | struct mtk_nor *mtk_nor; | ||
| 465 | |||
| 466 | if (!pdev->dev.of_node) { | ||
| 467 | dev_err(&pdev->dev, "No DT found\n"); | ||
| 468 | return -EINVAL; | ||
| 469 | } | ||
| 470 | |||
| 471 | mtk_nor = devm_kzalloc(&pdev->dev, sizeof(*mtk_nor), GFP_KERNEL); | ||
| 472 | if (!mtk_nor) | ||
| 473 | return -ENOMEM; | ||
| 474 | platform_set_drvdata(pdev, mtk_nor); | ||
| 475 | |||
| 476 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 477 | mtk_nor->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 478 | if (IS_ERR(mtk_nor->base)) | ||
| 479 | return PTR_ERR(mtk_nor->base); | ||
| 480 | |||
| 481 | mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi"); | ||
| 482 | if (IS_ERR(mtk_nor->spi_clk)) | ||
| 483 | return PTR_ERR(mtk_nor->spi_clk); | ||
| 484 | |||
| 485 | mtk_nor->nor_clk = devm_clk_get(&pdev->dev, "sf"); | ||
| 486 | if (IS_ERR(mtk_nor->nor_clk)) | ||
| 487 | return PTR_ERR(mtk_nor->nor_clk); | ||
| 488 | |||
| 489 | mtk_nor->dev = &pdev->dev; | ||
| 490 | |||
| 491 | ret = mtk_nor_enable_clk(mtk_nor); | ||
| 492 | if (ret) | ||
| 493 | return ret; | ||
| 494 | |||
| 495 | /* only support one attached flash */ | ||
| 496 | flash_np = of_get_next_available_child(pdev->dev.of_node, NULL); | ||
| 497 | if (!flash_np) { | ||
| 498 | dev_err(&pdev->dev, "no SPI flash device to configure\n"); | ||
| 499 | ret = -ENODEV; | ||
| 500 | goto nor_free; | ||
| 501 | } | ||
| 502 | ret = mtk_nor_init(mtk_nor, flash_np); | ||
| 503 | |||
| 504 | nor_free: | ||
| 505 | if (ret) | ||
| 506 | mtk_nor_disable_clk(mtk_nor); | ||
| 507 | |||
| 508 | return ret; | ||
| 509 | } | ||
| 510 | |||
| 511 | static int mtk_nor_drv_remove(struct platform_device *pdev) | ||
| 512 | { | ||
| 513 | struct mtk_nor *mtk_nor = platform_get_drvdata(pdev); | ||
| 514 | |||
| 515 | mtk_nor_disable_clk(mtk_nor); | ||
| 516 | |||
| 517 | return 0; | ||
| 518 | } | ||
| 519 | |||
| 520 | #ifdef CONFIG_PM_SLEEP | ||
| 521 | static int mtk_nor_suspend(struct device *dev) | ||
| 522 | { | ||
| 523 | struct mtk_nor *mtk_nor = dev_get_drvdata(dev); | ||
| 524 | |||
| 525 | mtk_nor_disable_clk(mtk_nor); | ||
| 526 | |||
| 527 | return 0; | ||
| 528 | } | ||
| 529 | |||
| 530 | static int mtk_nor_resume(struct device *dev) | ||
| 531 | { | ||
| 532 | struct mtk_nor *mtk_nor = dev_get_drvdata(dev); | ||
| 533 | |||
| 534 | return mtk_nor_enable_clk(mtk_nor); | ||
| 535 | } | ||
| 536 | |||
| 537 | static const struct dev_pm_ops mtk_nor_dev_pm_ops = { | ||
| 538 | .suspend = mtk_nor_suspend, | ||
| 539 | .resume = mtk_nor_resume, | ||
| 540 | }; | ||
| 541 | |||
| 542 | #define MTK_NOR_DEV_PM_OPS (&mtk_nor_dev_pm_ops) | ||
| 543 | #else | ||
| 544 | #define MTK_NOR_DEV_PM_OPS NULL | ||
| 545 | #endif | ||
| 546 | |||
| 547 | static const struct of_device_id mtk_nor_of_ids[] = { | ||
| 548 | { .compatible = "mediatek,mt8173-nor"}, | ||
| 549 | { /* sentinel */ } | ||
| 550 | }; | ||
| 551 | MODULE_DEVICE_TABLE(of, mtk_nor_of_ids); | ||
| 552 | |||
| 553 | static struct platform_driver mtk_nor_driver = { | ||
| 554 | .probe = mtk_nor_drv_probe, | ||
| 555 | .remove = mtk_nor_drv_remove, | ||
| 556 | .driver = { | ||
| 557 | .name = "mtk-nor", | ||
| 558 | .pm = MTK_NOR_DEV_PM_OPS, | ||
| 559 | .of_match_table = mtk_nor_of_ids, | ||
| 560 | }, | ||
| 561 | }; | ||
| 562 | |||
| 563 | module_platform_driver(mtk_nor_driver); | ||
| 564 | MODULE_LICENSE("GPL v2"); | ||
| 565 | MODULE_DESCRIPTION("MediaTek SPI NOR Flash Driver"); | ||
| @@ -107,6 +107,7 @@ config REGULATOR_AD5398 · 106 unmodified lines | |||
| 107 | 107 | ||
| 108 | config REGULATOR_ANATOP | 108 | config REGULATOR_ANATOP |
| 109 | tristate "Freescale i.MX on-chip ANATOP LDO regulators" | 109 | tristate "Freescale i.MX on-chip ANATOP LDO regulators" |
| 110 | depends on ARCH_MXC || COMPILE_TEST | ||
| 110 | depends on MFD_SYSCON | 111 | depends on MFD_SYSCON |
| 111 | help | 112 | help |
| 112 | Say y here to support Freescale i.MX on-chip ANATOP LDOs | 113 | Say y here to support Freescale i.MX on-chip ANATOP LDOs |
| @@ -613,6 +614,16 @@ config REGULATOR_MCP16502 · 500 unmodified lines | |||
| 613 | through the regulator interface. In addition it enables | 614 | through the regulator interface. In addition it enables |
| 614 | suspend-to-ram/standby transition. | 615 | suspend-to-ram/standby transition. |
| 615 | 616 | ||
| 617 | config REGULATOR_MP5416 | ||
| 618 | tristate "Monolithic MP5416 PMIC" | ||
| 619 | depends on I2C && OF | ||
| 620 | select REGMAP_I2C | ||
| 621 | help | ||
| 622 | Say y here to support the MP5416 PMIC. This will enable supports | ||
| 623 | the software controllable 4 buck and 4 LDO regulators. | ||
| 624 | Say M here if you want to include support for the regulator as a | ||
| 625 | module. | ||
| 626 | |||
| 616 | config REGULATOR_MP8859 | 627 | config REGULATOR_MP8859 |
| 617 | tristate "MPS MP8859 regulator driver" | 628 | tristate "MPS MP8859 regulator driver" |
| 618 | depends on I2C | 629 | depends on I2C |
| @@ -78,6 +78,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o · 77 unmodified lines | |||
| 78 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | 78 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o |
| 79 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | 79 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o |
| 80 | obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o | 80 | obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o |
| 81 | obj-$(CONFIG_REGULATOR_MP5416) += mp5416.o | ||
| 81 | obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o | 82 | obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o |
| 82 | obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o | 83 | obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o |
| 83 | obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o | 84 | obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o |
| @@ -305,9 +305,13 @@ static int anatop_regulator_probe(struct platform_device *pdev) · 304 unmodified lines | |||
| 305 | /* register regulator */ | 305 | /* register regulator */ |
| 306 | rdev = devm_regulator_register(dev, rdesc, &config); | 306 | rdev = devm_regulator_register(dev, rdesc, &config); |
| 307 | if (IS_ERR(rdev)) { | 307 | if (IS_ERR(rdev)) { |
| 308 | dev_err(dev, "failed to register %s\n", | 308 | ret = PTR_ERR(rdev); |
| 309 | rdesc->name); | 309 | if (ret == -EPROBE_DEFER) |
| 310 | return PTR_ERR(rdev); | 310 | dev_dbg(dev, "failed to register %s, deferring...\n", |
| 311 | rdesc->name); | ||
| 312 | else | ||
| 313 | dev_err(dev, "failed to register %s\n", rdesc->name); | ||
| 314 | return ret; | ||
| 311 | } | 315 | } |
| 312 | 316 | ||
| 313 | platform_set_drvdata(pdev, rdev); | 317 | platform_set_drvdata(pdev, rdev); |
| @@ -381,8 +381,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) · 380 unmodified lines | |||
| 381 | mask = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK | | 381 | mask = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE_MASK | |
| 382 | AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK; | 382 | AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN_MASK; |
| 383 | enable = (ramp > 0) ? | 383 | enable = (ramp > 0) ? |
| 384 | AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN : | 384 | AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN : 0; |
| 385 | !AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_EN; | ||
| 386 | break; | 385 | break; |
| 387 | } | 386 | } |
| 388 | 387 | ||
| @@ -393,8 +392,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) · 4 unmodified lines | |||
| 393 | mask = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK | | 392 | mask = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE_MASK | |
| 394 | AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK; | 393 | AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN_MASK; |
| 395 | enable = (ramp > 0) ? | 394 | enable = (ramp > 0) ? |
| 396 | AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN : | 395 | AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN : 0; |
| 397 | !AXP20X_DCDC2_LDO3_V_RAMP_LDO3_EN; | ||
| 398 | break; | 396 | break; |
| 399 | } | 397 | } |
| 400 | 398 | ||
| @@ -73,7 +73,7 @@ struct da9062_regulators { · 72 unmodified lines | |||
| 73 | int irq_ldo_lim; | 73 | int irq_ldo_lim; |
| 74 | unsigned n_regulators; | 74 | unsigned n_regulators; |
| 75 | /* Array size to be defined during init. Keep at end. */ | 75 | /* Array size to be defined during init. Keep at end. */ |
| 76 | struct da9062_regulator regulator[0]; | 76 | struct da9062_regulator regulator[]; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | /* Regulator operations */ | 79 | /* Regulator operations */ |
| @@ -66,7 +66,7 @@ struct da9063_regulator_data { · 65 unmodified lines | |||
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | struct da9063_regulators_pdata { | 68 | struct da9063_regulators_pdata { |
| 69 | unsigned n_regulators; | 69 | unsigned int n_regulators; |
| 70 | struct da9063_regulator_data *regulator_data; | 70 | struct da9063_regulator_data *regulator_data; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| @@ -131,7 +131,7 @@ struct da9063_regulator_info { · 58 unmodified lines | |||
| 131 | /* Defines asignment of regulators info table to chip model */ | 131 | /* Defines asignment of regulators info table to chip model */ |
| 132 | struct da9063_dev_model { | 132 | struct da9063_dev_model { |
| 133 | const struct da9063_regulator_info *regulator_info; | 133 | const struct da9063_regulator_info *regulator_info; |
| 134 | unsigned n_regulators; | 134 | unsigned int n_regulators; |
| 135 | enum da9063_type type; | 135 | enum da9063_type type; |
| 136 | }; | 136 | }; |
| 137 | 137 | ||
| @@ -150,9 +150,9 @@ struct da9063_regulator { · 12 unmodified lines | |||
| 150 | 150 | ||
| 151 | /* Encapsulates all information for the regulators driver */ | 151 | /* Encapsulates all information for the regulators driver */ |
| 152 | struct da9063_regulators { | 152 | struct da9063_regulators { |
| 153 | unsigned n_regulators; | 153 | unsigned int n_regulators; |
| 154 | /* Array size to be defined during init. Keep at end. */ | 154 | /* Array size to be defined during init. Keep at end. */ |
| 155 | struct da9063_regulator regulator[0]; | 155 | struct da9063_regulator regulator[]; |
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| 158 | /* BUCK modes for DA9063 */ | 158 | /* BUCK modes for DA9063 */ |
| @@ -165,38 +165,46 @@ enum { · 6 unmodified lines | |||
| 165 | 165 | ||
| 166 | /* Regulator operations */ | 166 | /* Regulator operations */ |
| 167 | 167 | ||
| 168 | /* Current limits array (in uA) for BCORE1, BCORE2, BPRO. | 168 | /* |
| 169 | Entry indexes corresponds to register values. */ | 169 | * Current limits array (in uA) for BCORE1, BCORE2, BPRO. |
| 170 | * Entry indexes corresponds to register values. | ||
| 171 | */ | ||
| 170 | static const unsigned int da9063_buck_a_limits[] = { | 172 | static const unsigned int da9063_buck_a_limits[] = { |
| 171 | 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, | 173 | 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, |
| 172 | 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 | 174 | 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 |
| 173 | }; | 175 | }; |
| 174 | 176 | ||
| 175 | /* Current limits array (in uA) for BMEM, BIO, BPERI. | 177 | /* |
| 176 | Entry indexes corresponds to register values. */ | 178 | * Current limits array (in uA) for BMEM, BIO, BPERI. |
| 179 | * Entry indexes corresponds to register values. | ||
| 180 | */ | ||
| 177 | static const unsigned int da9063_buck_b_limits[] = { | 181 | static const unsigned int da9063_buck_b_limits[] = { |
| 178 | 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, | 182 | 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, |
| 179 | 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 | 183 | 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 |
| 180 | }; | 184 | }; |
| 181 | 185 | ||
| 182 | /* Current limits array (in uA) for merged BCORE1 and BCORE2. | 186 | /* |
| 183 | Entry indexes corresponds to register values. */ | 187 | * Current limits array (in uA) for merged BCORE1 and BCORE2. |
| 188 | * Entry indexes corresponds to register values. | ||
| 189 | */ | ||
| 184 | static const unsigned int da9063_bcores_merged_limits[] = { | 190 | static const unsigned int da9063_bcores_merged_limits[] = { |
| 185 | 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2200000, 2400000, | 191 | 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2200000, 2400000, |
| 186 | 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000 | 192 | 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000 |
| 187 | }; | 193 | }; |
| 188 | 194 | ||
| 189 | /* Current limits array (in uA) for merged BMEM and BIO. | 195 | /* |
| 190 | Entry indexes corresponds to register values. */ | 196 | * Current limits array (in uA) for merged BMEM and BIO. |
| 197 | * Entry indexes corresponds to register values. | ||
| 198 | */ | ||
| 191 | static const unsigned int da9063_bmem_bio_merged_limits[] = { | 199 | static const unsigned int da9063_bmem_bio_merged_limits[] = { |
| 192 | 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, | 200 | 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, |
| 193 | 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 | 201 | 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 |
| 194 | }; | 202 | }; |
| 195 | 203 | ||
| 196 | static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned mode) | 204 | static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) |
| 197 | { | 205 | { |
| 198 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 206 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 199 | unsigned val; | 207 | unsigned int val; |
| 200 | 208 | ||
| 201 | switch (mode) { | 209 | switch (mode) { |
| 202 | case REGULATOR_MODE_FAST: | 210 | case REGULATOR_MODE_FAST: |
| @@ -221,7 +229,7 @@ static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned mode) · 18 unmodified lines | |||
| 221 | * There are 3 modes to map to: FAST, NORMAL, and STANDBY. | 229 | * There are 3 modes to map to: FAST, NORMAL, and STANDBY. |
| 222 | */ | 230 | */ |
| 223 | 231 | ||
| 224 | static unsigned da9063_buck_get_mode(struct regulator_dev *rdev) | 232 | static unsigned int da9063_buck_get_mode(struct regulator_dev *rdev) |
| 225 | { | 233 | { |
| 226 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 234 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 227 | struct regmap_field *field; | 235 | struct regmap_field *field; |
| @@ -271,10 +279,10 @@ static unsigned da9063_buck_get_mode(struct regulator_dev *rdev) · 43 unmodified lines | |||
| 271 | * There are 2 modes to map to: NORMAL and STANDBY (sleep) for each state. | 279 | * There are 2 modes to map to: NORMAL and STANDBY (sleep) for each state. |
| 272 | */ | 280 | */ |
| 273 | 281 | ||
| 274 | static int da9063_ldo_set_mode(struct regulator_dev *rdev, unsigned mode) | 282 | static int da9063_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) |
| 275 | { | 283 | { |
| 276 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 284 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 277 | unsigned val; | 285 | unsigned int val; |
| 278 | 286 | ||
| 279 | switch (mode) { | 287 | switch (mode) { |
| 280 | case REGULATOR_MODE_NORMAL: | 288 | case REGULATOR_MODE_NORMAL: |
| @@ -290,7 +298,7 @@ static int da9063_ldo_set_mode(struct regulator_dev *rdev, unsigned mode) · 9 unmodified lines | |||
| 290 | return regmap_field_write(regl->sleep, val); | 298 | return regmap_field_write(regl->sleep, val); |
| 291 | } | 299 | } |
| 292 | 300 | ||
| 293 | static unsigned da9063_ldo_get_mode(struct regulator_dev *rdev) | 301 | static unsigned int da9063_ldo_get_mode(struct regulator_dev *rdev) |
| 294 | { | 302 | { |
| 295 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 303 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 296 | struct regmap_field *field; | 304 | struct regmap_field *field; |
| @@ -383,7 +391,8 @@ static int da9063_suspend_disable(struct regulator_dev *rdev) · 86 unmodified lines | |||
| 383 | return regmap_field_write(regl->suspend, 0); | 391 | return regmap_field_write(regl->suspend, 0); |
| 384 | } | 392 | } |
| 385 | 393 | ||
| 386 | static int da9063_buck_set_suspend_mode(struct regulator_dev *rdev, unsigned mode) | 394 | static int da9063_buck_set_suspend_mode(struct regulator_dev *rdev, |
| 395 | unsigned int mode) | ||
| 387 | { | 396 | { |
| 388 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 397 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 389 | int val; | 398 | int val; |
| @@ -405,10 +414,11 @@ static int da9063_buck_set_suspend_mode(struct regulator_dev *rdev, unsigned mod · 15 unmodified lines | |||
| 405 | return regmap_field_write(regl->mode, val); | 414 | return regmap_field_write(regl->mode, val); |
| 406 | } | 415 | } |
| 407 | 416 | ||
| 408 | static int da9063_ldo_set_suspend_mode(struct regulator_dev *rdev, unsigned mode) | 417 | static int da9063_ldo_set_suspend_mode(struct regulator_dev *rdev, |
| 418 | unsigned int mode) | ||
| 409 | { | 419 | { |
| 410 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); | 420 | struct da9063_regulator *regl = rdev_get_drvdata(rdev); |
| 411 | unsigned val; | 421 | unsigned int val; |
| 412 | 422 | ||
| 413 | switch (mode) { | 423 | switch (mode) { |
| 414 | case REGULATOR_MODE_NORMAL: | 424 | case REGULATOR_MODE_NORMAL: |
| @@ -593,7 +603,7 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data) · 178 unmodified lines | |||
| 593 | struct da9063_regulators *regulators = data; | 603 | struct da9063_regulators *regulators = data; |
| 594 | struct da9063 *hw = regulators->regulator[0].hw; | 604 | struct da9063 *hw = regulators->regulator[0].hw; |
| 595 | struct da9063_regulator *regl; | 605 | struct da9063_regulator *regl; |
| 596 | int bits, i , ret; | 606 | int bits, i, ret; |
| 597 | 607 | ||
| 598 | ret = regmap_read(hw->regmap, DA9063_REG_STATUS_D, &bits); | 608 | ret = regmap_read(hw->regmap, DA9063_REG_STATUS_D, &bits); |
| 599 | if (ret < 0) | 609 | if (ret < 0) |
| @@ -605,10 +615,10 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data) · 5 unmodified lines | |||
| 605 | continue; | 615 | continue; |
| 606 | 616 | ||
| 607 | if (BIT(regl->info->oc_event.lsb) & bits) { | 617 | if (BIT(regl->info->oc_event.lsb) & bits) { |
| 608 | regulator_lock(regl->rdev); | 618 | regulator_lock(regl->rdev); |
| 609 | regulator_notifier_call_chain(regl->rdev, | 619 | regulator_notifier_call_chain(regl->rdev, |
| 610 | REGULATOR_EVENT_OVER_CURRENT, NULL); | 620 | REGULATOR_EVENT_OVER_CURRENT, NULL); |
| 611 | regulator_unlock(regl->rdev); | 621 | regulator_unlock(regl->rdev); |
| 612 | } | 622 | } |
| 613 | } | 623 | } |
| 614 | 624 | ||
| @@ -833,7 +843,7 @@ static int da9063_regulator_probe(struct platform_device *pdev) · 218 unmodified lines | |||
| 833 | 843 | ||
| 834 | if (regl->info->suspend_sleep.reg) { | 844 | if (regl->info->suspend_sleep.reg) { |
| 835 | regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev, | 845 | regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev, |
| 836 | da9063->regmap, regl->info->suspend_sleep); | 846 | da9063->regmap, regl->info->suspend_sleep); |
| 837 | if (IS_ERR(regl->suspend_sleep)) | 847 | if (IS_ERR(regl->suspend_sleep)) |
| 838 | return PTR_ERR(regl->suspend_sleep); | 848 | return PTR_ERR(regl->suspend_sleep); |
| 839 | } | 849 | } |
| @@ -867,12 +877,10 @@ static int da9063_regulator_probe(struct platform_device *pdev) · 27 unmodified lines | |||
| 867 | NULL, da9063_ldo_lim_event, | 877 | NULL, da9063_ldo_lim_event, |
| 868 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 878 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
| 869 | "LDO_LIM", regulators); | 879 | "LDO_LIM", regulators); |
| 870 | if (ret) { | 880 | if (ret) |
| 871 | dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); | 881 | dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); |
| 872 | return ret; | ||
| 873 | } | ||
| 874 | 882 | ||
| 875 | return 0; | 883 | return ret; |
| 876 | } | 884 | } |
| 877 | 885 | ||
| 878 | static struct platform_driver da9063_regulator_driver = { | 886 | static struct platform_driver da9063_regulator_driver = { |
| @@ -0,0 +1,245 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | // | ||
| 3 | // mp5416.c - regulator driver for mps mp5416 | ||
| 4 | // | ||
| 5 | // Copyright 2020 Monolithic Power Systems, Inc | ||
| 6 | // | ||
| 7 | // Author: Saravanan Sekar <sravanhome@gmail.com> | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/regmap.h> | ||
| 15 | #include <linux/regulator/driver.h> | ||
| 16 | #include <linux/i2c.h> | ||
| 17 | |||
| 18 | #define MP5416_REG_CTL0 0x00 | ||
| 19 | #define MP5416_REG_CTL1 0x01 | ||
| 20 | #define MP5416_REG_CTL2 0x02 | ||
| 21 | #define MP5416_REG_ILIM 0x03 | ||
| 22 | #define MP5416_REG_BUCK1 0x04 | ||
| 23 | #define MP5416_REG_BUCK2 0x05 | ||
| 24 | #define MP5416_REG_BUCK3 0x06 | ||
| 25 | #define MP5416_REG_BUCK4 0x07 | ||
| 26 | #define MP5416_REG_LDO1 0x08 | ||
| 27 | #define MP5416_REG_LDO2 0x09 | ||
| 28 | #define MP5416_REG_LDO3 0x0a | ||
| 29 | #define MP5416_REG_LDO4 0x0b | ||
| 30 | |||
| 31 | #define MP5416_REGULATOR_EN BIT(7) | ||
| 32 | #define MP5416_MASK_VSET 0x7f | ||
| 33 | #define MP5416_MASK_BUCK1_ILIM 0xc0 | ||
| 34 | #define MP5416_MASK_BUCK2_ILIM 0x0c | ||
| 35 | #define MP5416_MASK_BUCK3_ILIM 0x30 | ||
| 36 | #define MP5416_MASK_BUCK4_ILIM 0x03 | ||
| 37 | #define MP5416_MASK_DVS_SLEWRATE 0xc0 | ||
| 38 | |||
| 39 | /* values in uV */ | ||
| 40 | #define MP5416_VOLT1_MIN 600000 | ||
| 41 | #define MP5416_VOLT1_MAX 2187500 | ||
| 42 | #define MP5416_VOLT1_STEP 12500 | ||
| 43 | #define MP5416_VOLT2_MIN 800000 | ||
| 44 | #define MP5416_VOLT2_MAX 3975000 | ||
| 45 | #define MP5416_VOLT2_STEP 25000 | ||
| 46 | |||
| 47 | #define MP5416_VOLT1_RANGE \ | ||
| 48 | ((MP5416_VOLT1_MAX - MP5416_VOLT1_MIN)/MP5416_VOLT1_STEP + 1) | ||
| 49 | #define MP5416_VOLT2_RANGE \ | ||
| 50 | ((MP5416_VOLT2_MAX - MP5416_VOLT2_MIN)/MP5416_VOLT2_STEP + 1) | ||
| 51 | |||
| 52 | #define MP5416BUCK(_name, _id, _ilim, _dreg, _dval, _vsel) \ | ||
| 53 | [MP5416_BUCK ## _id] = { \ | ||
| 54 | .id = MP5416_BUCK ## _id, \ | ||
| 55 | .name = _name, \ | ||
| 56 | .of_match = _name, \ | ||
| 57 | .regulators_node = "regulators", \ | ||
| 58 | .ops = &mp5416_buck_ops, \ | ||
| 59 | .min_uV = MP5416_VOLT ##_vsel## _MIN, \ | ||
| 60 | .uV_step = MP5416_VOLT ##_vsel## _STEP, \ | ||
| 61 | .n_voltages = MP5416_VOLT ##_vsel## _RANGE, \ | ||
| 62 | .curr_table = _ilim, \ | ||
| 63 | .n_current_limits = ARRAY_SIZE(_ilim), \ | ||
| 64 | .csel_reg = MP5416_REG_ILIM, \ | ||
| 65 | .csel_mask = MP5416_MASK_BUCK ## _id ##_ILIM, \ | ||
| 66 | .vsel_reg = MP5416_REG_BUCK ## _id, \ | ||
| 67 | .vsel_mask = MP5416_MASK_VSET, \ | ||
| 68 | .enable_reg = MP5416_REG_BUCK ## _id, \ | ||
| 69 | .enable_mask = MP5416_REGULATOR_EN, \ | ||
| 70 | .active_discharge_on = _dval, \ | ||
| 71 | .active_discharge_reg = _dreg, \ | ||
| 72 | .active_discharge_mask = _dval, \ | ||
| 73 | .owner = THIS_MODULE, \ | ||
| 74 | } | ||
| 75 | |||
| 76 | #define MP5416LDO(_name, _id, _dval) \ | ||
| 77 | [MP5416_LDO ## _id] = { \ | ||
| 78 | .id = MP5416_LDO ## _id, \ | ||
| 79 | .name = _name, \ | ||
| 80 | .of_match = _name, \ | ||
| 81 | .regulators_node = "regulators", \ | ||
| 82 | .ops = &mp5416_ldo_ops, \ | ||
| 83 | .min_uV = MP5416_VOLT2_MIN, \ | ||
| 84 | .uV_step = MP5416_VOLT2_STEP, \ | ||
| 85 | .n_voltages = MP5416_VOLT2_RANGE, \ | ||
| 86 | .vsel_reg = MP5416_REG_LDO ##_id, \ | ||
| 87 | .vsel_mask = MP5416_MASK_VSET, \ | ||
| 88 | .enable_reg = MP5416_REG_LDO ##_id, \ | ||
| 89 | .enable_mask = MP5416_REGULATOR_EN, \ | ||
| 90 | .active_discharge_on = _dval, \ | ||
| 91 | .active_discharge_reg = MP5416_REG_CTL2, \ | ||
| 92 | .active_discharge_mask = _dval, \ | ||
| 93 | .owner = THIS_MODULE, \ | ||
| 94 | } | ||
| 95 | |||
| 96 | enum mp5416_regulators { | ||
| 97 | MP5416_BUCK1, | ||
| 98 | MP5416_BUCK2, | ||
| 99 | MP5416_BUCK3, | ||
| 100 | MP5416_BUCK4, | ||
| 101 | MP5416_LDO1, | ||
| 102 | MP5416_LDO2, | ||
| 103 | MP5416_LDO3, | ||
| 104 | MP5416_LDO4, | ||
| 105 | MP5416_MAX_REGULATORS, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static const struct regmap_config mp5416_regmap_config = { | ||
| 109 | .reg_bits = 8, | ||
| 110 | .val_bits = 8, | ||
| 111 | .max_register = 0x0d, | ||
| 112 | }; | ||
| 113 | |||
| 114 | /* Current limits array (in uA) | ||
| 115 | * ILIM1 & ILIM3 | ||
| 116 | */ | ||
| 117 | static const unsigned int mp5416_I_limits1[] = { | ||
| 118 | 3800000, 4600000, 5600000, 6800000 | ||
| 119 | }; | ||
| 120 | |||
| 121 | /* ILIM2 & ILIM4 */ | ||
| 122 | static const unsigned int mp5416_I_limits2[] = { | ||
| 123 | 2200000, 3200000, 4200000, 5200000 | ||
| 124 | }; | ||
| 125 | |||
| 126 | static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay); | ||
| 127 | |||
| 128 | static const struct regulator_ops mp5416_ldo_ops = { | ||
| 129 | .enable = regulator_enable_regmap, | ||
| 130 | .disable = regulator_disable_regmap, | ||
| 131 | .is_enabled = regulator_is_enabled_regmap, | ||
| 132 | .list_voltage = regulator_list_voltage_linear, | ||
| 133 | .map_voltage = regulator_map_voltage_linear, | ||
| 134 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 135 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 136 | .set_active_discharge = regulator_set_active_discharge_regmap, | ||
| 137 | }; | ||
| 138 | |||
| 139 | static const struct regulator_ops mp5416_buck_ops = { | ||
| 140 | .enable = regulator_enable_regmap, | ||
| 141 | .disable = regulator_disable_regmap, | ||
| 142 | .is_enabled = regulator_is_enabled_regmap, | ||
| 143 | .list_voltage = regulator_list_voltage_linear, | ||
| 144 | .map_voltage = regulator_map_voltage_linear, | ||
| 145 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
| 146 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 147 | .set_active_discharge = regulator_set_active_discharge_regmap, | ||
| 148 | .get_current_limit = regulator_get_current_limit_regmap, | ||
| 149 | .set_current_limit = regulator_set_current_limit_regmap, | ||
| 150 | .set_ramp_delay = mp5416_set_ramp_delay, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static struct regulator_desc mp5416_regulators_desc[MP5416_MAX_REGULATORS] = { | ||
| 154 | MP5416BUCK("buck1", 1, mp5416_I_limits1, MP5416_REG_CTL1, BIT(0), 1), | ||
| 155 | MP5416BUCK("buck2", 2, mp5416_I_limits2, MP5416_REG_CTL1, BIT(1), 2), | ||
| 156 | MP5416BUCK("buck3", 3, mp5416_I_limits1, MP5416_REG_CTL1, BIT(2), 1), | ||
| 157 | MP5416BUCK("buck4", 4, mp5416_I_limits2, MP5416_REG_CTL2, BIT(5), 2), | ||
| 158 | MP5416LDO("ldo1", 1, BIT(4)), | ||
| 159 | MP5416LDO("ldo2", 2, BIT(3)), | ||
| 160 | MP5416LDO("ldo3", 3, BIT(2)), | ||
| 161 | MP5416LDO("ldo4", 4, BIT(1)), | ||
| 162 | }; | ||
| 163 | |||
| 164 | /* | ||
| 165 | * DVS ramp rate BUCK1 to BUCK4 | ||
| 166 | * 00: 32mV/us | ||
| 167 | * 01: 16mV/us | ||
| 168 | * 10: 8mV/us | ||
| 169 | * 11: 4mV/us | ||
| 170 | */ | ||
| 171 | static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
| 172 | { | ||
| 173 | unsigned int ramp_val; | ||
| 174 | |||
| 175 | if (ramp_delay > 32000 || ramp_delay < 0) | ||
| 176 | return -EINVAL; | ||
| 177 | |||
| 178 | if (ramp_delay <= 4000) | ||
| 179 | ramp_val = 3; | ||
| 180 | else if (ramp_delay <= 8000) | ||
| 181 | ramp_val = 2; | ||
| 182 | else if (ramp_delay <= 16000) | ||
| 183 | ramp_val = 1; | ||
| 184 | else | ||
| 185 | ramp_val = 0; | ||
| 186 | |||
| 187 | return regmap_update_bits(rdev->regmap, MP5416_REG_CTL2, | ||
| 188 | MP5416_MASK_DVS_SLEWRATE, ramp_val << 6); | ||
| 189 | } | ||
| 190 | |||
| 191 | static int mp5416_i2c_probe(struct i2c_client *client) | ||
| 192 | { | ||
| 193 | struct device *dev = &client->dev; | ||
| 194 | struct regulator_config config = { NULL, }; | ||
| 195 | struct regulator_dev *rdev; | ||
| 196 | struct regmap *regmap; | ||
| 197 | int i; | ||
| 198 | |||
| 199 | regmap = devm_regmap_init_i2c(client, &mp5416_regmap_config); | ||
| 200 | if (IS_ERR(regmap)) { | ||
| 201 | dev_err(dev, "Failed to allocate regmap!\n"); | ||
| 202 | return PTR_ERR(regmap); | ||
| 203 | } | ||
| 204 | |||
| 205 | config.dev = dev; | ||
| 206 | config.regmap = regmap; | ||
| 207 | |||
| 208 | for (i = 0; i < MP5416_MAX_REGULATORS; i++) { | ||
| 209 | rdev = devm_regulator_register(dev, | ||
| 210 | &mp5416_regulators_desc[i], | ||
| 211 | &config); | ||
| 212 | if (IS_ERR(rdev)) { | ||
| 213 | dev_err(dev, "Failed to register regulator!\n"); | ||
| 214 | return PTR_ERR(rdev); | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static const struct of_device_id mp5416_of_match[] = { | ||
| 222 | { .compatible = "mps,mp5416" }, | ||
| 223 | {}, | ||
| 224 | }; | ||
| 225 | MODULE_DEVICE_TABLE(of, mp5416_of_match); | ||
| 226 | |||
| 227 | static const struct i2c_device_id mp5416_id[] = { | ||
| 228 | { "mp5416", }, | ||
| 229 | { }, | ||
| 230 | }; | ||
| 231 | MODULE_DEVICE_TABLE(i2c, mp5416_id); | ||
| 232 | |||
| 233 | static struct i2c_driver mp5416_regulator_driver = { | ||
| 234 | .driver = { | ||
| 235 | .name = "mp5416", | ||
| 236 | .of_match_table = of_match_ptr(mp5416_of_match), | ||
| 237 | }, | ||
| 238 | .probe_new = mp5416_i2c_probe, | ||
| 239 | .id_table = mp5416_id, | ||
| 240 | }; | ||
| 241 | module_i2c_driver(mp5416_regulator_driver); | ||
| 242 | |||
| 243 | MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>"); | ||
| 244 | MODULE_DESCRIPTION("MP5416 PMIC regulator driver"); | ||
| 245 | MODULE_LICENSE("GPL"); | ||
| @@ -95,6 +95,7 @@ static const struct regulator_desc mp8859_regulators[] = { · 94 unmodified lines | |||
| 95 | .id = 0, | 95 | .id = 0, |
| 96 | .type = REGULATOR_VOLTAGE, | 96 | .type = REGULATOR_VOLTAGE, |
| 97 | .name = "mp8859_dcdc", | 97 | .name = "mp8859_dcdc", |
| 98 | .supply_name = "vin", | ||
| 98 | .of_match = of_match_ptr("mp8859_dcdc"), | 99 | .of_match = of_match_ptr("mp8859_dcdc"), |
| 99 | .n_voltages = VOL_MAX_IDX + 1, | 100 | .n_voltages = VOL_MAX_IDX + 1, |
| 100 | .linear_ranges = mp8859_dcdc_ranges, | 101 | .linear_ranges = mp8859_dcdc_ranges, |
| @@ -354,7 +354,11 @@ static int pwm_regulator_probe(struct platform_device *pdev) · 353 unmodified lines | |||
| 354 | drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); | 354 | drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); |
| 355 | if (IS_ERR(drvdata->pwm)) { | 355 | if (IS_ERR(drvdata->pwm)) { |
| 356 | ret = PTR_ERR(drvdata->pwm); | 356 | ret = PTR_ERR(drvdata->pwm); |
| 357 | dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret); | 357 | if (ret == -EPROBE_DEFER) |
| 358 | dev_dbg(&pdev->dev, | ||
| 359 | "Failed to get PWM, deferring probe\n"); | ||
| 360 | else | ||
| 361 | dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret); | ||
| 358 | return ret; | 362 | return ret; |
| 359 | } | 363 | } |
| 360 | 364 | ||
| @@ -925,12 +925,21 @@ static const struct rpm_regulator_data rpm_pm8921_regulators[] = { · 924 unmodified lines | |||
| 925 | { } | 925 | { } |
| 926 | }; | 926 | }; |
| 927 | 927 | ||
| 928 | static const struct rpm_regulator_data rpm_smb208_regulators[] = { | ||
| 929 | { "s1a", QCOM_RPM_SMB208_S1a, &smb208_smps, "vin_s1a" }, | ||
| 930 | { "s1b", QCOM_RPM_SMB208_S1b, &smb208_smps, "vin_s1b" }, | ||
| 931 | { "s2a", QCOM_RPM_SMB208_S2a, &smb208_smps, "vin_s2a" }, | ||
| 932 | { "s2b", QCOM_RPM_SMB208_S2b, &smb208_smps, "vin_s2b" }, | ||
| 933 | { } | ||
| 934 | }; | ||
| 935 | |||
| 928 | static const struct of_device_id rpm_of_match[] = { | 936 | static const struct of_device_id rpm_of_match[] = { |
| 929 | { .compatible = "qcom,rpm-pm8018-regulators", | 937 | { .compatible = "qcom,rpm-pm8018-regulators", |
| 930 | .data = &rpm_pm8018_regulators }, | 938 | .data = &rpm_pm8018_regulators }, |
| 931 | { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, | 939 | { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, |
| 932 | { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, | 940 | { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, |
| 933 | { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators }, | 941 | { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators }, |
| 942 | { .compatible = "qcom,rpm-smb208-regulators", .data = &rpm_smb208_regulators }, | ||
| 934 | { } | 943 | { } |
| 935 | }; | 944 | }; |
| 936 | MODULE_DEVICE_TABLE(of, rpm_of_match); | 945 | MODULE_DEVICE_TABLE(of, rpm_of_match); |
| @@ -62,6 +62,13 @@ config SPI_ALTERA · 61 unmodified lines | |||
| 62 | help | 62 | help |
| 63 | This is the driver for the Altera SPI Controller. | 63 | This is the driver for the Altera SPI Controller. |
| 64 | 64 | ||
| 65 | config SPI_AR934X | ||
| 66 | tristate "Qualcomm Atheros AR934X/QCA95XX SPI controller driver" | ||
| 67 | depends on ATH79 || COMPILE_TEST | ||
| 68 | help | ||
| 69 | This enables support for the SPI controller present on the | ||
| 70 | Qualcomm Atheros AR934X/QCA95XX SoCs. | ||
| 71 | |||
| 65 | config SPI_ATH79 | 72 | config SPI_ATH79 |
| 66 | tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" | 73 | tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" |
| 67 | depends on ATH79 || COMPILE_TEST | 74 | depends on ATH79 || COMPILE_TEST |
| @@ -264,6 +271,13 @@ config SPI_FALCON · 196 unmodified lines | |||
| 264 | has only been tested with m25p80 type chips. The hardware has no | 271 | has only been tested with m25p80 type chips. The hardware has no |
| 265 | support for other types of SPI peripherals. | 272 | support for other types of SPI peripherals. |
| 266 | 273 | ||
| 274 | config SPI_FSI | ||
| 275 | tristate "FSI SPI driver" | ||
| 276 | depends on FSI | ||
| 277 | help | ||
| 278 | This enables support for the driver for FSI bus attached SPI | ||
| 279 | controllers. | ||
| 280 | |||
| 267 | config SPI_FSL_LPSPI | 281 | config SPI_FSL_LPSPI |
| 268 | tristate "Freescale i.MX LPSPI controller" | 282 | tristate "Freescale i.MX LPSPI controller" |
| 269 | depends on ARCH_MXC || COMPILE_TEST | 283 | depends on ARCH_MXC || COMPILE_TEST |
| @@ -285,7 +299,6 @@ config SPI_HISI_SFC_V3XX · 15 unmodified lines | |||
| 285 | tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets" | 299 | tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets" |
| 286 | depends on (ARM64 && ACPI) || COMPILE_TEST | 300 | depends on (ARM64 && ACPI) || COMPILE_TEST |
| 287 | depends on HAS_IOMEM | 301 | depends on HAS_IOMEM |
| 288 | select CONFIG_MTD_SPI_NOR | ||
| 289 | help | 302 | help |
| 290 | This enables support for HiSilicon v3xx SPI-NOR flash controller | 303 | This enables support for HiSilicon v3xx SPI-NOR flash controller |
| 291 | found in hi16xx chipsets. | 304 | found in hi16xx chipsets. |
| @@ -415,6 +428,7 @@ config SPI_FSL_ESPI · 123 unmodified lines | |||
| 415 | 428 | ||
| 416 | config SPI_MESON_SPICC | 429 | config SPI_MESON_SPICC |
| 417 | tristate "Amlogic Meson SPICC controller" | 430 | tristate "Amlogic Meson SPICC controller" |
| 431 | depends on COMMON_CLK | ||
| 418 | depends on ARCH_MESON || COMPILE_TEST | 432 | depends on ARCH_MESON || COMPILE_TEST |
| 419 | help | 433 | help |
| 420 | This enables master mode support for the SPICC (SPI communication | 434 | This enables master mode support for the SPICC (SPI communication |
| @@ -443,6 +457,16 @@ config SPI_MT7621 · 22 unmodified lines | |||
| 443 | help | 457 | help |
| 444 | This selects a driver for the MediaTek MT7621 SPI Controller. | 458 | This selects a driver for the MediaTek MT7621 SPI Controller. |
| 445 | 459 | ||
| 460 | config SPI_MTK_NOR | ||
| 461 | tristate "MediaTek SPI NOR controller" | ||
| 462 | depends on ARCH_MEDIATEK || COMPILE_TEST | ||
| 463 | help | ||
| 464 | This enables support for SPI NOR controller found on MediaTek | ||
| 465 | ARM SoCs. This is a controller specifically for SPI-NOR flash. | ||
| 466 | It can perform generic SPI transfers up to 6 bytes via generic | ||
| 467 | SPI interface as well as several SPI-NOR specific instructions | ||
| 468 | via SPI MEM interface. | ||
| 469 | |||
| 446 | config SPI_NPCM_FIU | 470 | config SPI_NPCM_FIU |
| 447 | tristate "Nuvoton NPCM FLASH Interface Unit" | 471 | tristate "Nuvoton NPCM FLASH Interface Unit" |
| 448 | depends on ARCH_NPCM || COMPILE_TEST | 472 | depends on ARCH_NPCM || COMPILE_TEST |
| @@ -890,6 +914,17 @@ config SPI_ZYNQMP_GQSPI · 441 unmodified lines | |||
| 890 | # Add new SPI master controllers in alphabetical order above this line | 914 | # Add new SPI master controllers in alphabetical order above this line |
| 891 | # | 915 | # |
| 892 | 916 | ||
| 917 | comment "SPI Multiplexer support" | ||
| 918 | |||
| 919 | config SPI_MUX | ||
| 920 | tristate "SPI multiplexer support" | ||
| 921 | select MULTIPLEXER | ||
| 922 | help | ||
| 923 | This adds support for SPI multiplexers. Each SPI mux will be | ||
| 924 | accessible as a SPI controller, the devices behind the mux will appear | ||
| 925 | to be chip selects on this controller. It is still necessary to | ||
| 926 | select one or more specific mux-controller drivers. | ||
| 927 | |||
| 893 | # | 928 | # |
| 894 | # There are lots of SPI device types, with sensors and memory | 929 | # There are lots of SPI device types, with sensors and memory |
| 895 | # being probably the most widely used ones. | 930 | # being probably the most widely used ones. |
| @@ -9,11 +9,13 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG · 8 unmodified lines | |||
| 9 | # config declarations into driver model code | 9 | # config declarations into driver model code |
| 10 | obj-$(CONFIG_SPI_MASTER) += spi.o | 10 | obj-$(CONFIG_SPI_MASTER) += spi.o |
| 11 | obj-$(CONFIG_SPI_MEM) += spi-mem.o | 11 | obj-$(CONFIG_SPI_MEM) += spi-mem.o |
| 12 | obj-$(CONFIG_SPI_MUX) += spi-mux.o | ||
| 12 | obj-$(CONFIG_SPI_SPIDEV) += spidev.o | 13 | obj-$(CONFIG_SPI_SPIDEV) += spidev.o |
| 13 | obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o | 14 | obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o |
| 14 | 15 | ||
| 15 | # SPI master controller drivers (bus) | 16 | # SPI master controller drivers (bus) |
| 16 | obj-$(CONFIG_SPI_ALTERA) += spi-altera.o | 17 | obj-$(CONFIG_SPI_ALTERA) += spi-altera.o |
| 18 | obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o | ||
| 17 | obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o | 19 | obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o |
| 18 | obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o | 20 | obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o |
| 19 | obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o | 21 | obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o |
| @@ -40,6 +42,7 @@ spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o · 20 unmodified lines | |||
| 40 | obj-$(CONFIG_SPI_EFM32) += spi-efm32.o | 42 | obj-$(CONFIG_SPI_EFM32) += spi-efm32.o |
| 41 | obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o | 43 | obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o |
| 42 | obj-$(CONFIG_SPI_FALCON) += spi-falcon.o | 44 | obj-$(CONFIG_SPI_FALCON) += spi-falcon.o |
| 45 | obj-$(CONFIG_SPI_FSI) += spi-fsi.o | ||
| 43 | obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o | 46 | obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o |
| 44 | obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o | 47 | obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o |
| 45 | obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o | 48 | obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o |
| @@ -62,6 +65,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o · 16 unmodified lines | |||
| 62 | obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o | 65 | obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o |
| 63 | obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o | 66 | obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o |
| 64 | obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o | 67 | obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o |
| 68 | obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o | ||
| 65 | obj-$(CONFIG_SPI_MXIC) += spi-mxic.o | 69 | obj-$(CONFIG_SPI_MXIC) += spi-mxic.o |
| 66 | obj-$(CONFIG_SPI_MXS) += spi-mxs.o | 70 | obj-$(CONFIG_SPI_MXS) += spi-mxs.o |
| 67 | obj-$(CONFIG_SPI_NPCM_FIU) += spi-npcm-fiu.o | 71 | obj-$(CONFIG_SPI_NPCM_FIU) += spi-npcm-fiu.o |
| @@ -173,6 +173,81 @@ static const struct atmel_qspi_mode atmel_qspi_modes[] = { · 172 unmodified lines | |||
| 173 | { 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD }, | 173 | { 4, 4, 4, QSPI_IFR_WIDTH_QUAD_CMD }, |
| 174 | }; | 174 | }; |
| 175 | 175 | ||
| 176 | #ifdef VERBOSE_DEBUG | ||
| 177 | static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz) | ||
| 178 | { | ||
| 179 | switch (offset) { | ||
| 180 | case QSPI_CR: | ||
| 181 | return "CR"; | ||
| 182 | case QSPI_MR: | ||
| 183 | return "MR"; | ||
| 184 | case QSPI_RD: | ||
| 185 | return "MR"; | ||
| 186 | case QSPI_TD: | ||
| 187 | return "TD"; | ||
| 188 | case QSPI_SR: | ||
| 189 | return "SR"; | ||
| 190 | case QSPI_IER: | ||
| 191 | return "IER"; | ||
| 192 | case QSPI_IDR: | ||
| 193 | return "IDR"; | ||
| 194 | case QSPI_IMR: | ||
| 195 | return "IMR"; | ||
| 196 | case QSPI_SCR: | ||
| 197 | return "SCR"; | ||
| 198 | case QSPI_IAR: | ||
| 199 | return "IAR"; | ||
| 200 | case QSPI_ICR: | ||
| 201 | return "ICR/WICR"; | ||
| 202 | case QSPI_IFR: | ||
| 203 | return "IFR"; | ||
| 204 | case QSPI_RICR: | ||
| 205 | return "RICR"; | ||
| 206 | case QSPI_SMR: | ||
| 207 | return "SMR"; | ||
| 208 | case QSPI_SKR: | ||
| 209 | return "SKR"; | ||
| 210 | case QSPI_WPMR: | ||
| 211 | return "WPMR"; | ||
| 212 | case QSPI_WPSR: | ||
| 213 | return "WPSR"; | ||
| 214 | case QSPI_VERSION: | ||
| 215 | return "VERSION"; | ||
| 216 | default: | ||
| 217 | snprintf(tmp, sz, "0x%02x", offset); | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | |||
| 221 | return tmp; | ||
| 222 | } | ||
| 223 | #endif /* VERBOSE_DEBUG */ | ||
| 224 | |||
| 225 | static u32 atmel_qspi_read(struct atmel_qspi *aq, u32 offset) | ||
| 226 | { | ||
| 227 | u32 value = readl_relaxed(aq->regs + offset); | ||
| 228 | |||
| 229 | #ifdef VERBOSE_DEBUG | ||
| 230 | char tmp[8]; | ||
| 231 | |||
| 232 | dev_vdbg(&aq->pdev->dev, "read 0x%08x from %s\n", value, | ||
| 233 | atmel_qspi_reg_name(offset, tmp, sizeof(tmp))); | ||
| 234 | #endif /* VERBOSE_DEBUG */ | ||
| 235 | |||
| 236 | return value; | ||
| 237 | } | ||
| 238 | |||
| 239 | static void atmel_qspi_write(u32 value, struct atmel_qspi *aq, u32 offset) | ||
| 240 | { | ||
| 241 | #ifdef VERBOSE_DEBUG | ||
| 242 | char tmp[8]; | ||
| 243 | |||
| 244 | dev_vdbg(&aq->pdev->dev, "write 0x%08x into %s\n", value, | ||
| 245 | atmel_qspi_reg_name(offset, tmp, sizeof(tmp))); | ||
| 246 | #endif /* VERBOSE_DEBUG */ | ||
| 247 | |||
| 248 | writel_relaxed(value, aq->regs + offset); | ||
| 249 | } | ||
| 250 | |||
| 176 | static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op, | 251 | static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op, |
| 177 | const struct atmel_qspi_mode *mode) | 252 | const struct atmel_qspi_mode *mode) |
| 178 | { | 253 | { |
| @@ -293,32 +368,32 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, · 114 unmodified lines | |||
| 293 | * Serial Memory Mode (SMM). | 368 | * Serial Memory Mode (SMM). |
| 294 | */ | 369 | */ |
| 295 | if (aq->mr != QSPI_MR_SMM) { | 370 | if (aq->mr != QSPI_MR_SMM) { |
| 296 | writel_relaxed(QSPI_MR_SMM, aq->regs + QSPI_MR); | 371 | atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); |
| 297 | aq->mr = QSPI_MR_SMM; | 372 | aq->mr = QSPI_MR_SMM; |
| 298 | } | 373 | } |
| 299 | 374 | ||
| 300 | /* Clear pending interrupts */ | 375 | /* Clear pending interrupts */ |
| 301 | (void)readl_relaxed(aq->regs + QSPI_SR); | 376 | (void)atmel_qspi_read(aq, QSPI_SR); |
| 302 | 377 | ||
| 303 | if (aq->caps->has_ricr) { | 378 | if (aq->caps->has_ricr) { |
| 304 | if (!op->addr.nbytes && op->data.dir == SPI_MEM_DATA_IN) | 379 | if (!op->addr.nbytes && op->data.dir == SPI_MEM_DATA_IN) |
| 305 | ifr |= QSPI_IFR_APBTFRTYP_READ; | 380 | ifr |= QSPI_IFR_APBTFRTYP_READ; |
| 306 | 381 | ||
| 307 | /* Set QSPI Instruction Frame registers */ | 382 | /* Set QSPI Instruction Frame registers */ |
| 308 | writel_relaxed(iar, aq->regs + QSPI_IAR); | 383 | atmel_qspi_write(iar, aq, QSPI_IAR); |
| 309 | if (op->data.dir == SPI_MEM_DATA_IN) | 384 | if (op->data.dir == SPI_MEM_DATA_IN) |
| 310 | writel_relaxed(icr, aq->regs + QSPI_RICR); | 385 | atmel_qspi_write(icr, aq, QSPI_RICR); |
| 311 | else | 386 | else |
| 312 | writel_relaxed(icr, aq->regs + QSPI_WICR); | 387 | atmel_qspi_write(icr, aq, QSPI_WICR); |
| 313 | writel_relaxed(ifr, aq->regs + QSPI_IFR); | 388 | atmel_qspi_write(ifr, aq, QSPI_IFR); |
| 314 | } else { | 389 | } else { |
| 315 | if (op->data.dir == SPI_MEM_DATA_OUT) | 390 | if (op->data.dir == SPI_MEM_DATA_OUT) |
| 316 | ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR; | 391 | ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR; |
| 317 | 392 | ||
| 318 | /* Set QSPI Instruction Frame registers */ | 393 | /* Set QSPI Instruction Frame registers */ |
| 319 | writel_relaxed(iar, aq->regs + QSPI_IAR); | 394 | atmel_qspi_write(iar, aq, QSPI_IAR); |
| 320 | writel_relaxed(icr, aq->regs + QSPI_ICR); | 395 | atmel_qspi_write(icr, aq, QSPI_ICR); |
| 321 | writel_relaxed(ifr, aq->regs + QSPI_IFR); | 396 | atmel_qspi_write(ifr, aq, QSPI_IFR); |
| 322 | } | 397 | } |
| 323 | 398 | ||
| 324 | return 0; | 399 | return 0; |
| @@ -345,7 +420,7 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) · 20 unmodified lines | |||
| 345 | /* Skip to the final steps if there is no data */ | 420 | /* Skip to the final steps if there is no data */ |
| 346 | if (op->data.nbytes) { | 421 | if (op->data.nbytes) { |
| 347 | /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ | 422 | /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */ |
| 348 | (void)readl_relaxed(aq->regs + QSPI_IFR); | 423 | (void)atmel_qspi_read(aq, QSPI_IFR); |
| 349 | 424 | ||
| 350 | /* Send/Receive data */ | 425 | /* Send/Receive data */ |
| 351 | if (op->data.dir == SPI_MEM_DATA_IN) | 426 | if (op->data.dir == SPI_MEM_DATA_IN) |
| @@ -356,22 +431,22 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) · 4 unmodified lines | |||
| 356 | op->data.nbytes); | 431 | op->data.nbytes); |
| 357 | 432 | ||
| 358 | /* Release the chip-select */ | 433 | /* Release the chip-select */ |
| 359 | writel_relaxed(QSPI_CR_LASTXFER, aq->regs + QSPI_CR); | 434 | atmel_qspi_write(QSPI_CR_LASTXFER, aq, QSPI_CR); |
| 360 | } | 435 | } |
| 361 | 436 | ||
| 362 | /* Poll INSTRuction End status */ | 437 | /* Poll INSTRuction End status */ |
| 363 | sr = readl_relaxed(aq->regs + QSPI_SR); | 438 | sr = atmel_qspi_read(aq, QSPI_SR); |
| 364 | if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) | 439 | if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED) |
| 365 | return err; | 440 | return err; |
| 366 | 441 | ||
| 367 | /* Wait for INSTRuction End interrupt */ | 442 | /* Wait for INSTRuction End interrupt */ |
| 368 | reinit_completion(&aq->cmd_completion); | 443 | reinit_completion(&aq->cmd_completion); |
| 369 | aq->pending = sr & QSPI_SR_CMD_COMPLETED; | 444 | aq->pending = sr & QSPI_SR_CMD_COMPLETED; |
| 370 | writel_relaxed(QSPI_SR_CMD_COMPLETED, aq->regs + QSPI_IER); | 445 | atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IER); |
| 371 | if (!wait_for_completion_timeout(&aq->cmd_completion, | 446 | if (!wait_for_completion_timeout(&aq->cmd_completion, |
| 372 | msecs_to_jiffies(1000))) | 447 | msecs_to_jiffies(1000))) |
| 373 | err = -ETIMEDOUT; | 448 | err = -ETIMEDOUT; |
| 374 | writel_relaxed(QSPI_SR_CMD_COMPLETED, aq->regs + QSPI_IDR); | 449 | atmel_qspi_write(QSPI_SR_CMD_COMPLETED, aq, QSPI_IDR); |
| 375 | 450 | ||
| 376 | return err; | 451 | return err; |
| 377 | } | 452 | } |
| @@ -410,7 +485,7 @@ static int atmel_qspi_setup(struct spi_device *spi) · 32 unmodified lines | |||
| 410 | scbr--; | 485 | scbr--; |
| 411 | 486 | ||
| 412 | aq->scr = QSPI_SCR_SCBR(scbr); | 487 | aq->scr = QSPI_SCR_SCBR(scbr); |
| 413 | writel_relaxed(aq->scr, aq->regs + QSPI_SCR); | 488 | atmel_qspi_write(aq->scr, aq, QSPI_SCR); |
| 414 | 489 | ||
| 415 | return 0; | 490 | return 0; |
| 416 | } | 491 | } |
| @@ -418,14 +493,14 @@ static int atmel_qspi_setup(struct spi_device *spi) · 1 unmodified line | |||
| 418 | static void atmel_qspi_init(struct atmel_qspi *aq) | 493 | static void atmel_qspi_init(struct atmel_qspi *aq) |
| 419 | { | 494 | { |
| 420 | /* Reset the QSPI controller */ | 495 | /* Reset the QSPI controller */ |
| 421 | writel_relaxed(QSPI_CR_SWRST, aq->regs + QSPI_CR); | 496 | atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR); |
| 422 | 497 | ||
| 423 | /* Set the QSPI controller by default in Serial Memory Mode */ | 498 | /* Set the QSPI controller by default in Serial Memory Mode */ |
| 424 | writel_relaxed(QSPI_MR_SMM, aq->regs + QSPI_MR); | 499 | atmel_qspi_write(QSPI_MR_SMM, aq, QSPI_MR); |
| 425 | aq->mr = QSPI_MR_SMM; | 500 | aq->mr = QSPI_MR_SMM; |
| 426 | 501 | ||
| 427 | /* Enable the QSPI controller */ | 502 | /* Enable the QSPI controller */ |
| 428 | writel_relaxed(QSPI_CR_QSPIEN, aq->regs + QSPI_CR); | 503 | atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR); |
| 429 | } | 504 | } |
| 430 | 505 | ||
| 431 | static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id) | 506 | static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id) |
| @@ -433,8 +508,8 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id) · 1 unmodified line | |||
| 433 | struct atmel_qspi *aq = dev_id; | 508 | struct atmel_qspi *aq = dev_id; |
| 434 | u32 status, mask, pending; | 509 | u32 status, mask, pending; |
| 435 | 510 | ||
| 436 | status = readl_relaxed(aq->regs + QSPI_SR); | 511 | status = atmel_qspi_read(aq, QSPI_SR); |
| 437 | mask = readl_relaxed(aq->regs + QSPI_IMR); | 512 | mask = atmel_qspi_read(aq, QSPI_IMR); |
| 438 | pending = status & mask; | 513 | pending = status & mask; |
| 439 | 514 | ||
| 440 | if (!pending) | 515 | if (!pending) |
| @@ -569,7 +644,7 @@ static int atmel_qspi_remove(struct platform_device *pdev) · 128 unmodified lines | |||
| 569 | struct atmel_qspi *aq = spi_controller_get_devdata(ctrl); | 644 | struct atmel_qspi *aq = spi_controller_get_devdata(ctrl); |
| 570 | 645 | ||
| 571 | spi_unregister_controller(ctrl); | 646 | spi_unregister_controller(ctrl); |
| 572 | writel_relaxed(QSPI_CR_QSPIDIS, aq->regs + QSPI_CR); | 647 | atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR); |
| 573 | clk_disable_unprepare(aq->qspick); | 648 | clk_disable_unprepare(aq->qspick); |
| 574 | clk_disable_unprepare(aq->pclk); | 649 | clk_disable_unprepare(aq->pclk); |
| 575 | return 0; | 650 | return 0; |
| @@ -596,7 +671,7 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev) · 20 unmodified lines | |||
| 596 | 671 | ||
| 597 | atmel_qspi_init(aq); | 672 | atmel_qspi_init(aq); |
| 598 | 673 | ||
| 599 | writel_relaxed(aq->scr, aq->regs + QSPI_SCR); | 674 | atmel_qspi_write(aq->scr, aq, QSPI_SCR); |
| 600 | 675 | ||
| 601 | return 0; | 676 | return 0; |
| 602 | } | 677 | } |
| @@ -0,0 +1,235 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // | ||
| 3 | // SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs | ||
| 4 | // | ||
| 5 | // Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com> | ||
| 6 | // | ||
| 7 | // Based on spi-mt7621.c: | ||
| 8 | // Copyright (C) 2011 Sergiy <piratfm@gmail.com> | ||
| 9 | // Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org> | ||
| 10 | // Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name> | ||
| 11 | |||
| 12 | #include <linux/clk.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/iopoll.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of_device.h> | ||
| 18 | #include <linux/spi/spi.h> | ||
| 19 | |||
| 20 | #define DRIVER_NAME "spi-ar934x" | ||
| 21 | |||
| 22 | #define AR934X_SPI_REG_FS 0x00 | ||
| 23 | #define AR934X_SPI_ENABLE BIT(0) | ||
| 24 | |||
| 25 | #define AR934X_SPI_REG_IOC 0x08 | ||
| 26 | #define AR934X_SPI_IOC_INITVAL 0x70000 | ||
| 27 | |||
| 28 | #define AR934X_SPI_REG_CTRL 0x04 | ||
| 29 | #define AR934X_SPI_CLK_MASK GENMASK(5, 0) | ||
| 30 | |||
| 31 | #define AR934X_SPI_DATAOUT 0x10 | ||
| 32 | |||
| 33 | #define AR934X_SPI_REG_SHIFT_CTRL 0x14 | ||
| 34 | #define AR934X_SPI_SHIFT_EN BIT(31) | ||
| 35 | #define AR934X_SPI_SHIFT_CS(n) BIT(28 + (n)) | ||
| 36 | #define AR934X_SPI_SHIFT_TERM 26 | ||
| 37 | #define AR934X_SPI_SHIFT_VAL(cs, term, count) \ | ||
| 38 | (AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) | \ | ||
| 39 | (term) << AR934X_SPI_SHIFT_TERM | (count)) | ||
| 40 | |||
| 41 | #define AR934X_SPI_DATAIN 0x18 | ||
| 42 | |||
| 43 | struct ar934x_spi { | ||
| 44 | struct spi_controller *ctlr; | ||
| 45 | void __iomem *base; | ||
| 46 | struct clk *clk; | ||
| 47 | unsigned int clk_freq; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq) | ||
| 51 | { | ||
| 52 | int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1; | ||
| 53 | |||
| 54 | if (div < 0) | ||
| 55 | return 0; | ||
| 56 | else if (div > AR934X_SPI_CLK_MASK) | ||
| 57 | return -EINVAL; | ||
| 58 | else | ||
| 59 | return div; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int ar934x_spi_setup(struct spi_device *spi) | ||
| 63 | { | ||
| 64 | struct ar934x_spi *sp = spi_controller_get_devdata(spi->master); | ||
| 65 | |||
| 66 | if ((spi->max_speed_hz == 0) || | ||
| 67 | (spi->max_speed_hz > (sp->clk_freq / 2))) { | ||
| 68 | spi->max_speed_hz = sp->clk_freq / 2; | ||
| 69 | } else if (spi->max_speed_hz < (sp->clk_freq / 128)) { | ||
| 70 | dev_err(&spi->dev, "spi clock is too low\n"); | ||
| 71 | return -EINVAL; | ||
| 72 | } | ||
| 73 | |||
| 74 | return 0; | ||
| 75 | } | ||
| 76 | |||
| 77 | static int ar934x_spi_transfer_one_message(struct spi_controller *master, | ||
| 78 | struct spi_message *m) | ||
| 79 | { | ||
| 80 | struct ar934x_spi *sp = spi_controller_get_devdata(master); | ||
| 81 | struct spi_transfer *t = NULL; | ||
| 82 | struct spi_device *spi = m->spi; | ||
| 83 | unsigned long trx_done, trx_cur; | ||
| 84 | int stat = 0; | ||
| 85 | u8 term = 0; | ||
| 86 | int div, i; | ||
| 87 | u32 reg; | ||
| 88 | const u8 *tx_buf; | ||
| 89 | u8 *buf; | ||
| 90 | |||
| 91 | m->actual_length = 0; | ||
| 92 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 93 | if (t->speed_hz) | ||
| 94 | div = ar934x_spi_clk_div(sp, t->speed_hz); | ||
| 95 | else | ||
| 96 | div = ar934x_spi_clk_div(sp, spi->max_speed_hz); | ||
| 97 | if (div < 0) { | ||
| 98 | stat = -EIO; | ||
| 99 | goto msg_done; | ||
| 100 | } | ||
| 101 | |||
| 102 | reg = ioread32(sp->base + AR934X_SPI_REG_CTRL); | ||
| 103 | reg &= ~AR934X_SPI_CLK_MASK; | ||
| 104 | reg |= div; | ||
| 105 | iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL); | ||
| 106 | iowrite32(0, sp->base + AR934X_SPI_DATAOUT); | ||
| 107 | |||
| 108 | for (trx_done = 0; trx_done < t->len; trx_done += 4) { | ||
| 109 | trx_cur = t->len - trx_done; | ||
| 110 | if (trx_cur > 4) | ||
| 111 | trx_cur = 4; | ||
| 112 | else if (list_is_last(&t->transfer_list, &m->transfers)) | ||
| 113 | term = 1; | ||
| 114 | |||
| 115 | if (t->tx_buf) { | ||
| 116 | tx_buf = t->tx_buf + trx_done; | ||
| 117 | reg = tx_buf[0]; | ||
| 118 | for (i = 1; i < trx_cur; i++) | ||
| 119 | reg = reg << 8 | tx_buf[i]; | ||
| 120 | iowrite32(reg, sp->base + AR934X_SPI_DATAOUT); | ||
| 121 | } | ||
| 122 | |||
| 123 | reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term, | ||
| 124 | trx_cur * 8); | ||
| 125 | iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL); | ||
| 126 | stat = readl_poll_timeout( | ||
| 127 | sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg, | ||
| 128 | !(reg & AR934X_SPI_SHIFT_EN), 0, 5); | ||
| 129 | if (stat < 0) | ||
| 130 | goto msg_done; | ||
| 131 | |||
| 132 | if (t->rx_buf) { | ||
| 133 | reg = ioread32(sp->base + AR934X_SPI_DATAIN); | ||
| 134 | buf = t->rx_buf + trx_done; | ||
| 135 | for (i = 0; i < trx_cur; i++) { | ||
| 136 | buf[trx_cur - i - 1] = reg & 0xff; | ||
| 137 | reg >>= 8; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | m->actual_length += t->len; | ||
| 142 | } | ||
| 143 | |||
| 144 | msg_done: | ||
| 145 | m->status = stat; | ||
| 146 | spi_finalize_current_message(master); | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static const struct of_device_id ar934x_spi_match[] = { | ||
| 152 | { .compatible = "qca,ar934x-spi" }, | ||
| 153 | {}, | ||
| 154 | }; | ||
| 155 | MODULE_DEVICE_TABLE(of, ar934x_spi_match); | ||
| 156 | |||
| 157 | static int ar934x_spi_probe(struct platform_device *pdev) | ||
| 158 | { | ||
| 159 | struct spi_controller *ctlr; | ||
| 160 | struct ar934x_spi *sp; | ||
| 161 | void __iomem *base; | ||
| 162 | struct clk *clk; | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 166 | if (IS_ERR(base)) | ||
| 167 | return PTR_ERR(base); | ||
| 168 | |||
| 169 | clk = devm_clk_get(&pdev->dev, NULL); | ||
| 170 | if (IS_ERR(clk)) { | ||
| 171 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 172 | return PTR_ERR(clk); | ||
| 173 | } | ||
| 174 | |||
| 175 | ret = clk_prepare_enable(clk); | ||
| 176 | if (ret) | ||
| 177 | return ret; | ||
| 178 | |||
| 179 | ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp)); | ||
| 180 | if (!ctlr) { | ||
| 181 | dev_info(&pdev->dev, "failed to allocate spi controller\n"); | ||
| 182 | return -ENOMEM; | ||
| 183 | } | ||
| 184 | |||
| 185 | /* disable flash mapping and expose spi controller registers */ | ||
| 186 | iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS); | ||
| 187 | /* restore pins to default state: CSn=1 DO=CLK=0 */ | ||
| 188 | iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC); | ||
| 189 | |||
| 190 | ctlr->mode_bits = SPI_LSB_FIRST; | ||
| 191 | ctlr->setup = ar934x_spi_setup; | ||
| 192 | ctlr->transfer_one_message = ar934x_spi_transfer_one_message; | ||
| 193 | ctlr->bits_per_word_mask = SPI_BPW_MASK(8); | ||
| 194 | ctlr->dev.of_node = pdev->dev.of_node; | ||
| 195 | ctlr->num_chipselect = 3; | ||
| 196 | |||
| 197 | dev_set_drvdata(&pdev->dev, ctlr); | ||
| 198 | |||
| 199 | sp = spi_controller_get_devdata(ctlr); | ||
| 200 | sp->base = base; | ||
| 201 | sp->clk = clk; | ||
| 202 | sp->clk_freq = clk_get_rate(clk); | ||
| 203 | sp->ctlr = ctlr; | ||
| 204 | |||
| 205 | return devm_spi_register_controller(&pdev->dev, ctlr); | ||
| 206 | } | ||
| 207 | |||
| 208 | static int ar934x_spi_remove(struct platform_device *pdev) | ||
| 209 | { | ||
| 210 | struct spi_controller *ctlr; | ||
| 211 | struct ar934x_spi *sp; | ||
| 212 | |||
| 213 | ctlr = dev_get_drvdata(&pdev->dev); | ||
| 214 | sp = spi_controller_get_devdata(ctlr); | ||
| 215 | |||
| 216 | clk_disable_unprepare(sp->clk); | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static struct platform_driver ar934x_spi_driver = { | ||
| 222 | .driver = { | ||
| 223 | .name = DRIVER_NAME, | ||
| 224 | .of_match_table = ar934x_spi_match, | ||
| 225 | }, | ||
| 226 | .probe = ar934x_spi_probe, | ||
| 227 | .remove = ar934x_spi_remove, | ||
| 228 | }; | ||
| 229 | |||
| 230 | module_platform_driver(ar934x_spi_driver); | ||
| 231 | |||
| 232 | MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx"); | ||
| 233 | MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>"); | ||
| 234 | MODULE_LICENSE("GPL v2"); | ||
| 235 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
| @@ -6,14 +6,13 @@ · 5 unmodified lines | |||
| 6 | #include <linux/io.h> | 6 | #include <linux/io.h> |
| 7 | #include <linux/spi/spi.h> | 7 | #include <linux/spi/spi.h> |
| 8 | #include <linux/spi/spi_bitbang.h> | 8 | #include <linux/spi/spi_bitbang.h> |
| 9 | #include <linux/gpio.h> | ||
| 10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 11 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 12 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 13 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| 14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 15 | #include <linux/of_gpio.h> | ||
| 16 | #include <linux/platform_data/efm32-spi.h> | 14 | #include <linux/platform_data/efm32-spi.h> |
| 15 | #include <linux/of.h> | ||
| 17 | 16 | ||
| 18 | #define DRIVER_NAME "efm32-spi" | 17 | #define DRIVER_NAME "efm32-spi" |
| 19 | 18 | ||
| @@ -82,9 +81,6 @@ struct efm32_spi_ddata { · 62 unmodified lines | |||
| 82 | const u8 *tx_buf; | 81 | const u8 *tx_buf; |
| 83 | u8 *rx_buf; | 82 | u8 *rx_buf; |
| 84 | unsigned tx_len, rx_len; | 83 | unsigned tx_len, rx_len; |
| 85 | |||
| 86 | /* chip selects */ | ||
| 87 | unsigned csgpio[]; | ||
| 88 | }; | 84 | }; |
| 89 | 85 | ||
| 90 | #define ddata_to_dev(ddata) (&(ddata->bitbang.master->dev)) | 86 | #define ddata_to_dev(ddata) (&(ddata->bitbang.master->dev)) |
| @@ -102,14 +98,6 @@ static u32 efm32_spi_read32(struct efm32_spi_ddata *ddata, unsigned offset) · 11 unmodified lines | |||
| 102 | return readl_relaxed(ddata->base + offset); | 98 | return readl_relaxed(ddata->base + offset); |
| 103 | } | 99 | } |
| 104 | 100 | ||
| 105 | static void efm32_spi_chipselect(struct spi_device *spi, int is_on) | ||
| 106 | { | ||
| 107 | struct efm32_spi_ddata *ddata = spi_master_get_devdata(spi->master); | ||
| 108 | int value = !(spi->mode & SPI_CS_HIGH) == !(is_on == BITBANG_CS_ACTIVE); | ||
| 109 | |||
| 110 | gpio_set_value(ddata->csgpio[spi->chip_select], value); | ||
| 111 | } | ||
| 112 | |||
| 113 | static int efm32_spi_setup_transfer(struct spi_device *spi, | 101 | static int efm32_spi_setup_transfer(struct spi_device *spi, |
| 114 | struct spi_transfer *t) | 102 | struct spi_transfer *t) |
| 115 | { | 103 | { |
| @@ -320,17 +308,11 @@ static int efm32_spi_probe(struct platform_device *pdev) · 204 unmodified lines | |||
| 320 | int ret; | 308 | int ret; |
| 321 | struct spi_master *master; | 309 | struct spi_master *master; |
| 322 | struct device_node *np = pdev->dev.of_node; | 310 | struct device_node *np = pdev->dev.of_node; |
| 323 | int num_cs, i; | ||
| 324 | 311 | ||
| 325 | if (!np) | 312 | if (!np) |
| 326 | return -EINVAL; | 313 | return -EINVAL; |
| 327 | 314 | ||
| 328 | num_cs = of_gpio_named_count(np, "cs-gpios"); | 315 | master = spi_alloc_master(&pdev->dev, sizeof(*ddata)); |
| 329 | if (num_cs < 0) | ||
| 330 | return num_cs; | ||
| 331 | |||
| 332 | master = spi_alloc_master(&pdev->dev, | ||
| 333 | sizeof(*ddata) + num_cs * sizeof(unsigned)); | ||
| 334 | if (!master) { | 316 | if (!master) { |
| 335 | dev_dbg(&pdev->dev, | 317 | dev_dbg(&pdev->dev, |
| 336 | "failed to allocate spi master controller\n"); | 318 | "failed to allocate spi master controller\n"); |
| @@ -340,14 +322,13 @@ static int efm32_spi_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 340 | 322 | ||
| 341 | master->dev.of_node = pdev->dev.of_node; | 323 | master->dev.of_node = pdev->dev.of_node; |
| 342 | 324 | ||
| 343 | master->num_chipselect = num_cs; | ||
| 344 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 325 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 345 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | 326 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
| 327 | master->use_gpio_descriptors = true; | ||
| 346 | 328 | ||
| 347 | ddata = spi_master_get_devdata(master); | 329 | ddata = spi_master_get_devdata(master); |
| 348 | 330 | ||
| 349 | ddata->bitbang.master = master; | 331 | ddata->bitbang.master = master; |
| 350 | ddata->bitbang.chipselect = efm32_spi_chipselect; | ||
| 351 | ddata->bitbang.setup_transfer = efm32_spi_setup_transfer; | 332 | ddata->bitbang.setup_transfer = efm32_spi_setup_transfer; |
| 352 | ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; | 333 | ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; |
| 353 | 334 | ||
| @@ -361,25 +342,6 @@ static int efm32_spi_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 361 | goto err; | 342 | goto err; |
| 362 | } | 343 | } |
| 363 | 344 | ||
| 364 | for (i = 0; i < num_cs; ++i) { | ||
| 365 | ret = of_get_named_gpio(np, "cs-gpios", i); | ||
| 366 | if (ret < 0) { | ||
| 367 | dev_err(&pdev->dev, "failed to get csgpio#%u (%d)\n", | ||
| 368 | i, ret); | ||
| 369 | goto err; | ||
| 370 | } | ||
| 371 | ddata->csgpio[i] = ret; | ||
| 372 | dev_dbg(&pdev->dev, "csgpio#%u = %u\n", i, ddata->csgpio[i]); | ||
| 373 | ret = devm_gpio_request_one(&pdev->dev, ddata->csgpio[i], | ||
| 374 | GPIOF_OUT_INIT_LOW, DRIVER_NAME); | ||
| 375 | if (ret < 0) { | ||
| 376 | dev_err(&pdev->dev, | ||
| 377 | "failed to configure csgpio#%u (%d)\n", | ||
| 378 | i, ret); | ||
| 379 | goto err; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 345 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 384 | if (!res) { | 346 | if (!res) { |
| 385 | ret = -ENODEV; | 347 | ret = -ENODEV; |
| @@ -0,0 +1,558 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | // Copyright (C) IBM Corporation 2020 | ||
| 3 | |||
| 4 | #include <linux/bitfield.h> | ||
| 5 | #include <linux/bits.h> | ||
| 6 | #include <linux/fsi.h> | ||
| 7 | #include <linux/jiffies.h> | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/of.h> | ||
| 11 | #include <linux/spi/spi.h> | ||
| 12 | |||
| 13 | #define FSI_ENGID_SPI 0x23 | ||
| 14 | #define FSI_MBOX_ROOT_CTRL_8 0x2860 | ||
| 15 | |||
| 16 | #define FSI2SPI_DATA0 0x00 | ||
| 17 | #define FSI2SPI_DATA1 0x04 | ||
| 18 | #define FSI2SPI_CMD 0x08 | ||
| 19 | #define FSI2SPI_CMD_WRITE BIT(31) | ||
| 20 | #define FSI2SPI_RESET 0x18 | ||
| 21 | #define FSI2SPI_STATUS 0x1c | ||
| 22 | #define FSI2SPI_STATUS_ANY_ERROR BIT(31) | ||
| 23 | #define FSI2SPI_IRQ 0x20 | ||
| 24 | |||
| 25 | #define SPI_FSI_BASE 0x70000 | ||
| 26 | #define SPI_FSI_INIT_TIMEOUT_MS 1000 | ||
| 27 | #define SPI_FSI_MAX_TRANSFER_SIZE 2048 | ||
| 28 | |||
| 29 | #define SPI_FSI_ERROR 0x0 | ||
| 30 | #define SPI_FSI_COUNTER_CFG 0x1 | ||
| 31 | #define SPI_FSI_COUNTER_CFG_LOOPS(x) (((u64)(x) & 0xffULL) << 32) | ||
| 32 | #define SPI_FSI_CFG1 0x2 | ||
| 33 | #define SPI_FSI_CLOCK_CFG 0x3 | ||
| 34 | #define SPI_FSI_CLOCK_CFG_MM_ENABLE BIT_ULL(32) | ||
| 35 | #define SPI_FSI_CLOCK_CFG_ECC_DISABLE (BIT_ULL(35) | BIT_ULL(33)) | ||
| 36 | #define SPI_FSI_CLOCK_CFG_RESET1 (BIT_ULL(36) | BIT_ULL(38)) | ||
| 37 | #define SPI_FSI_CLOCK_CFG_RESET2 (BIT_ULL(37) | BIT_ULL(39)) | ||
| 38 | #define SPI_FSI_CLOCK_CFG_MODE (BIT_ULL(41) | BIT_ULL(42)) | ||
| 39 | #define SPI_FSI_CLOCK_CFG_SCK_RECV_DEL GENMASK_ULL(51, 44) | ||
| 40 | #define SPI_FSI_CLOCK_CFG_SCK_NO_DEL BIT_ULL(51) | ||
| 41 | #define SPI_FSI_CLOCK_CFG_SCK_DIV GENMASK_ULL(63, 52) | ||
| 42 | #define SPI_FSI_MMAP 0x4 | ||
| 43 | #define SPI_FSI_DATA_TX 0x5 | ||
| 44 | #define SPI_FSI_DATA_RX 0x6 | ||
| 45 | #define SPI_FSI_SEQUENCE 0x7 | ||
| 46 | #define SPI_FSI_SEQUENCE_STOP 0x00 | ||
| 47 | #define SPI_FSI_SEQUENCE_SEL_SLAVE(x) (0x10 | ((x) & 0xf)) | ||
| 48 | #define SPI_FSI_SEQUENCE_SHIFT_OUT(x) (0x30 | ((x) & 0xf)) | ||
| 49 | #define SPI_FSI_SEQUENCE_SHIFT_IN(x) (0x40 | ((x) & 0xf)) | ||
| 50 | #define SPI_FSI_SEQUENCE_COPY_DATA_TX 0xc0 | ||
| 51 | #define SPI_FSI_SEQUENCE_BRANCH(x) (0xe0 | ((x) & 0xf)) | ||
| 52 | #define SPI_FSI_STATUS 0x8 | ||
| 53 | #define SPI_FSI_STATUS_ERROR \ | ||
| 54 | (GENMASK_ULL(31, 21) | GENMASK_ULL(15, 12)) | ||
| 55 | #define SPI_FSI_STATUS_SEQ_STATE GENMASK_ULL(55, 48) | ||
| 56 | #define SPI_FSI_STATUS_SEQ_STATE_IDLE BIT_ULL(48) | ||
| 57 | #define SPI_FSI_STATUS_TDR_UNDERRUN BIT_ULL(57) | ||
| 58 | #define SPI_FSI_STATUS_TDR_OVERRUN BIT_ULL(58) | ||
| 59 | #define SPI_FSI_STATUS_TDR_FULL BIT_ULL(59) | ||
| 60 | #define SPI_FSI_STATUS_RDR_UNDERRUN BIT_ULL(61) | ||
| 61 | #define SPI_FSI_STATUS_RDR_OVERRUN BIT_ULL(62) | ||
| 62 | #define SPI_FSI_STATUS_RDR_FULL BIT_ULL(63) | ||
| 63 | #define SPI_FSI_STATUS_ANY_ERROR \ | ||
| 64 | (SPI_FSI_STATUS_ERROR | SPI_FSI_STATUS_TDR_UNDERRUN | \ | ||
| 65 | SPI_FSI_STATUS_TDR_OVERRUN | SPI_FSI_STATUS_RDR_UNDERRUN | \ | ||
| 66 | SPI_FSI_STATUS_RDR_OVERRUN) | ||
| 67 | #define SPI_FSI_PORT_CTRL 0x9 | ||
| 68 | |||
| 69 | struct fsi_spi { | ||
| 70 | struct device *dev; /* SPI controller device */ | ||
| 71 | struct fsi_device *fsi; /* FSI2SPI CFAM engine device */ | ||
| 72 | u32 base; | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct fsi_spi_sequence { | ||
| 76 | int bit; | ||
| 77 | u64 data; | ||
| 78 | }; | ||
| 79 | |||
| 80 | static int fsi_spi_check_status(struct fsi_spi *ctx) | ||
| 81 | { | ||
| 82 | int rc; | ||
| 83 | u32 sts; | ||
| 84 | __be32 sts_be; | ||
| 85 | |||
| 86 | rc = fsi_device_read(ctx->fsi, FSI2SPI_STATUS, &sts_be, | ||
| 87 | sizeof(sts_be)); | ||
| 88 | if (rc) | ||
| 89 | return rc; | ||
| 90 | |||
| 91 | sts = be32_to_cpu(sts_be); | ||
| 92 | if (sts & FSI2SPI_STATUS_ANY_ERROR) { | ||
| 93 | dev_err(ctx->dev, "Error with FSI2SPI interface: %08x.\n", sts); | ||
| 94 | return -EIO; | ||
| 95 | } | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value) | ||
| 101 | { | ||
| 102 | int rc; | ||
| 103 | __be32 cmd_be; | ||
| 104 | __be32 data_be; | ||
| 105 | u32 cmd = offset + ctx->base; | ||
| 106 | |||
| 107 | *value = 0ULL; | ||
| 108 | |||
| 109 | if (cmd & FSI2SPI_CMD_WRITE) | ||
| 110 | return -EINVAL; | ||
| 111 | |||
| 112 | cmd_be = cpu_to_be32(cmd); | ||
| 113 | rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be)); | ||
| 114 | if (rc) | ||
| 115 | return rc; | ||
| 116 | |||
| 117 | rc = fsi_spi_check_status(ctx); | ||
| 118 | if (rc) | ||
| 119 | return rc; | ||
| 120 | |||
| 121 | rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA0, &data_be, | ||
| 122 | sizeof(data_be)); | ||
| 123 | if (rc) | ||
| 124 | return rc; | ||
| 125 | |||
| 126 | *value |= (u64)be32_to_cpu(data_be) << 32; | ||
| 127 | |||
| 128 | rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA1, &data_be, | ||
| 129 | sizeof(data_be)); | ||
| 130 | if (rc) | ||
| 131 | return rc; | ||
| 132 | |||
| 133 | *value |= (u64)be32_to_cpu(data_be); | ||
| 134 | dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value); | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int fsi_spi_write_reg(struct fsi_spi *ctx, u32 offset, u64 value) | ||
| 140 | { | ||
| 141 | int rc; | ||
| 142 | __be32 cmd_be; | ||
| 143 | __be32 data_be; | ||
| 144 | u32 cmd = offset + ctx->base; | ||
| 145 | |||
| 146 | if (cmd & FSI2SPI_CMD_WRITE) | ||
| 147 | return -EINVAL; | ||
| 148 | |||
| 149 | dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value); | ||
| 150 | |||
| 151 | data_be = cpu_to_be32(upper_32_bits(value)); | ||
| 152 | rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA0, &data_be, | ||
| 153 | sizeof(data_be)); | ||
| 154 | if (rc) | ||
| 155 | return rc; | ||
| 156 | |||
| 157 | data_be = cpu_to_be32(lower_32_bits(value)); | ||
| 158 | rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA1, &data_be, | ||
| 159 | sizeof(data_be)); | ||
| 160 | if (rc) | ||
| 161 | return rc; | ||
| 162 | |||
| 163 | cmd_be = cpu_to_be32(cmd | FSI2SPI_CMD_WRITE); | ||
| 164 | rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be)); | ||
| 165 | if (rc) | ||
| 166 | return rc; | ||
| 167 | |||
| 168 | return fsi_spi_check_status(ctx); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int fsi_spi_data_in(u64 in, u8 *rx, int len) | ||
| 172 | { | ||
| 173 | int i; | ||
| 174 | int num_bytes = min(len, 8); | ||
| 175 | |||
| 176 | for (i = 0; i < num_bytes; ++i) | ||
| 177 | rx[i] = (u8)(in >> (8 * ((num_bytes - 1) - i))); | ||
| 178 | |||
| 179 | return num_bytes; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int fsi_spi_data_out(u64 *out, const u8 *tx, int len) | ||
| 183 | { | ||
| 184 | int i; | ||
| 185 | int num_bytes = min(len, 8); | ||
| 186 | u8 *out_bytes = (u8 *)out; | ||
| 187 | |||
| 188 | /* Unused bytes of the tx data should be 0. */ | ||
| 189 | *out = 0ULL; | ||
| 190 | |||
| 191 | for (i = 0; i < num_bytes; ++i) | ||
| 192 | out_bytes[8 - (i + 1)] = tx[i]; | ||
| 193 | |||
| 194 | return num_bytes; | ||
| 195 | } | ||
| 196 | |||
| 197 | static int fsi_spi_reset(struct fsi_spi *ctx) | ||
| 198 | { | ||
| 199 | int rc; | ||
| 200 | |||
| 201 | dev_dbg(ctx->dev, "Resetting SPI controller.\n"); | ||
| 202 | |||
| 203 | rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG, | ||
| 204 | SPI_FSI_CLOCK_CFG_RESET1); | ||
| 205 | if (rc) | ||
| 206 | return rc; | ||
| 207 | |||
| 208 | return fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG, | ||
| 209 | SPI_FSI_CLOCK_CFG_RESET2); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val) | ||
| 213 | { | ||
| 214 | /* | ||
| 215 | * Add the next byte of instruction to the 8-byte sequence register. | ||
| 216 | * Then decrement the counter so that the next instruction will go in | ||
| 217 | * the right place. Return the number of "slots" left in the sequence | ||
| 218 | * register. | ||
| 219 | */ | ||
| 220 | seq->data |= (u64)val << seq->bit; | ||
| 221 | seq->bit -= 8; | ||
| 222 | |||
| 223 | return ((64 - seq->bit) / 8) - 2; | ||
| 224 | } | ||
| 225 | |||
| 226 | static void fsi_spi_sequence_init(struct fsi_spi_sequence *seq) | ||
| 227 | { | ||
| 228 | seq->bit = 56; | ||
| 229 | seq->data = 0ULL; | ||
| 230 | } | ||
| 231 | |||
| 232 | static int fsi_spi_sequence_transfer(struct fsi_spi *ctx, | ||
| 233 | struct fsi_spi_sequence *seq, | ||
| 234 | struct spi_transfer *transfer) | ||
| 235 | { | ||
| 236 | int loops; | ||
| 237 | int idx; | ||
| 238 | int rc; | ||
| 239 | u8 len = min(transfer->len, 8U); | ||
| 240 | u8 rem = transfer->len % len; | ||
| 241 | |||
| 242 | loops = transfer->len / len; | ||
| 243 | |||
| 244 | if (transfer->tx_buf) { | ||
| 245 | idx = fsi_spi_sequence_add(seq, | ||
| 246 | SPI_FSI_SEQUENCE_SHIFT_OUT(len)); | ||
| 247 | if (rem) | ||
| 248 | rem = SPI_FSI_SEQUENCE_SHIFT_OUT(rem); | ||
| 249 | } else if (transfer->rx_buf) { | ||
| 250 | idx = fsi_spi_sequence_add(seq, | ||
| 251 | SPI_FSI_SEQUENCE_SHIFT_IN(len)); | ||
| 252 | if (rem) | ||
| 253 | rem = SPI_FSI_SEQUENCE_SHIFT_IN(rem); | ||
| 254 | } else { | ||
| 255 | return -EINVAL; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (loops > 1) { | ||
| 259 | fsi_spi_sequence_add(seq, SPI_FSI_SEQUENCE_BRANCH(idx)); | ||
| 260 | |||
| 261 | if (rem) | ||
| 262 | fsi_spi_sequence_add(seq, rem); | ||
| 263 | |||
| 264 | rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, | ||
| 265 | SPI_FSI_COUNTER_CFG_LOOPS(loops - 1)); | ||
| 266 | if (rc) | ||
| 267 | return rc; | ||
| 268 | } | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | static int fsi_spi_transfer_data(struct fsi_spi *ctx, | ||
| 274 | struct spi_transfer *transfer) | ||
| 275 | { | ||
| 276 | int rc = 0; | ||
| 277 | u64 status = 0ULL; | ||
| 278 | |||
| 279 | if (transfer->tx_buf) { | ||
| 280 | int nb; | ||
| 281 | int sent = 0; | ||
| 282 | u64 out = 0ULL; | ||
| 283 | const u8 *tx = transfer->tx_buf; | ||
| 284 | |||
| 285 | while (transfer->len > sent) { | ||
| 286 | nb = fsi_spi_data_out(&out, &tx[sent], | ||
| 287 | (int)transfer->len - sent); | ||
| 288 | |||
| 289 | rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, out); | ||
| 290 | if (rc) | ||
| 291 | return rc; | ||
| 292 | |||
| 293 | do { | ||
| 294 | rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, | ||
| 295 | &status); | ||
| 296 | if (rc) | ||
| 297 | return rc; | ||
| 298 | |||
| 299 | if (status & SPI_FSI_STATUS_ANY_ERROR) { | ||
| 300 | rc = fsi_spi_reset(ctx); | ||
| 301 | if (rc) | ||
| 302 | return rc; | ||
| 303 | |||
| 304 | return -EREMOTEIO; | ||
| 305 | } | ||
| 306 | } while (status & SPI_FSI_STATUS_TDR_FULL); | ||
| 307 | |||
| 308 | sent += nb; | ||
| 309 | } | ||
| 310 | } else if (transfer->rx_buf) { | ||
| 311 | int recv = 0; | ||
| 312 | u64 in = 0ULL; | ||
| 313 | u8 *rx = transfer->rx_buf; | ||
| 314 | |||
| 315 | while (transfer->len > recv) { | ||
| 316 | do { | ||
| 317 | rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, | ||
| 318 | &status); | ||
| 319 | if (rc) | ||
| 320 | return rc; | ||
| 321 | |||
| 322 | if (status & SPI_FSI_STATUS_ANY_ERROR) { | ||
| 323 | rc = fsi_spi_reset(ctx); | ||
| 324 | if (rc) | ||
| 325 | return rc; | ||
| 326 | |||
| 327 | return -EREMOTEIO; | ||
| 328 | } | ||
| 329 | } while (!(status & SPI_FSI_STATUS_RDR_FULL)); | ||
| 330 | |||
| 331 | rc = fsi_spi_read_reg(ctx, SPI_FSI_DATA_RX, &in); | ||
| 332 | if (rc) | ||
| 333 | return rc; | ||
| 334 | |||
| 335 | recv += fsi_spi_data_in(in, &rx[recv], | ||
| 336 | (int)transfer->len - recv); | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | static int fsi_spi_transfer_init(struct fsi_spi *ctx) | ||
| 344 | { | ||
| 345 | int rc; | ||
| 346 | bool reset = false; | ||
| 347 | unsigned long end; | ||
| 348 | u64 seq_state; | ||
| 349 | u64 clock_cfg = 0ULL; | ||
| 350 | u64 status = 0ULL; | ||
| 351 | u64 wanted_clock_cfg = SPI_FSI_CLOCK_CFG_ECC_DISABLE | | ||
| 352 | SPI_FSI_CLOCK_CFG_SCK_NO_DEL | | ||
| 353 | FIELD_PREP(SPI_FSI_CLOCK_CFG_SCK_DIV, 4); | ||
| 354 | |||
| 355 | end = jiffies + msecs_to_jiffies(SPI_FSI_INIT_TIMEOUT_MS); | ||
| 356 | do { | ||
| 357 | if (time_after(jiffies, end)) | ||
| 358 | return -ETIMEDOUT; | ||
| 359 | |||
| 360 | rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, &status); | ||
| 361 | if (rc) | ||
| 362 | return rc; | ||
| 363 | |||
| 364 | seq_state = status & SPI_FSI_STATUS_SEQ_STATE; | ||
| 365 | |||
| 366 | if (status & (SPI_FSI_STATUS_ANY_ERROR | | ||
| 367 | SPI_FSI_STATUS_TDR_FULL | | ||
| 368 | SPI_FSI_STATUS_RDR_FULL)) { | ||
| 369 | if (reset) | ||
| 370 | return -EIO; | ||
| 371 | |||
| 372 | rc = fsi_spi_reset(ctx); | ||
| 373 | if (rc) | ||
| 374 | return rc; | ||
| 375 | |||
| 376 | reset = true; | ||
| 377 | continue; | ||
| 378 | } | ||
| 379 | } while (seq_state && (seq_state != SPI_FSI_STATUS_SEQ_STATE_IDLE)); | ||
| 380 | |||
| 381 | rc = fsi_spi_read_reg(ctx, SPI_FSI_CLOCK_CFG, &clock_cfg); | ||
| 382 | if (rc) | ||
| 383 | return rc; | ||
| 384 | |||
| 385 | if ((clock_cfg & (SPI_FSI_CLOCK_CFG_MM_ENABLE | | ||
| 386 | SPI_FSI_CLOCK_CFG_ECC_DISABLE | | ||
| 387 | SPI_FSI_CLOCK_CFG_MODE | | ||
| 388 | SPI_FSI_CLOCK_CFG_SCK_RECV_DEL | | ||
| 389 | SPI_FSI_CLOCK_CFG_SCK_DIV)) != wanted_clock_cfg) | ||
| 390 | rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG, | ||
| 391 | wanted_clock_cfg); | ||
| 392 | |||
| 393 | return rc; | ||
| 394 | } | ||
| 395 | |||
| 396 | static int fsi_spi_transfer_one_message(struct spi_controller *ctlr, | ||
| 397 | struct spi_message *mesg) | ||
| 398 | { | ||
| 399 | int rc = 0; | ||
| 400 | u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(mesg->spi->chip_select + 1); | ||
| 401 | struct spi_transfer *transfer; | ||
| 402 | struct fsi_spi *ctx = spi_controller_get_devdata(ctlr); | ||
| 403 | |||
| 404 | list_for_each_entry(transfer, &mesg->transfers, transfer_list) { | ||
| 405 | struct fsi_spi_sequence seq; | ||
| 406 | struct spi_transfer *next = NULL; | ||
| 407 | |||
| 408 | /* Sequencer must do shift out (tx) first. */ | ||
| 409 | if (!transfer->tx_buf || | ||
| 410 | transfer->len > SPI_FSI_MAX_TRANSFER_SIZE) { | ||
| 411 | rc = -EINVAL; | ||
| 412 | goto error; | ||
| 413 | } | ||
| 414 | |||
| 415 | dev_dbg(ctx->dev, "Start tx of %d bytes.\n", transfer->len); | ||
| 416 | |||
| 417 | rc = fsi_spi_transfer_init(ctx); | ||
| 418 | if (rc < 0) | ||
| 419 | goto error; | ||
| 420 | |||
| 421 | fsi_spi_sequence_init(&seq); | ||
| 422 | fsi_spi_sequence_add(&seq, seq_slave); | ||
| 423 | |||
| 424 | rc = fsi_spi_sequence_transfer(ctx, &seq, transfer); | ||
| 425 | if (rc) | ||
| 426 | goto error; | ||
| 427 | |||
| 428 | if (!list_is_last(&transfer->transfer_list, | ||
| 429 | &mesg->transfers)) { | ||
| 430 | next = list_next_entry(transfer, transfer_list); | ||
| 431 | |||
| 432 | /* Sequencer can only do shift in (rx) after tx. */ | ||
| 433 | if (next->rx_buf) { | ||
| 434 | if (next->len > SPI_FSI_MAX_TRANSFER_SIZE) { | ||
| 435 | rc = -EINVAL; | ||
| 436 | goto error; | ||
| 437 | } | ||
| 438 | |||
| 439 | dev_dbg(ctx->dev, "Sequence rx of %d bytes.\n", | ||
| 440 | next->len); | ||
| 441 | |||
| 442 | rc = fsi_spi_sequence_transfer(ctx, &seq, | ||
| 443 | next); | ||
| 444 | if (rc) | ||
| 445 | goto error; | ||
| 446 | } else { | ||
| 447 | next = NULL; | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | fsi_spi_sequence_add(&seq, SPI_FSI_SEQUENCE_SEL_SLAVE(0)); | ||
| 452 | |||
| 453 | rc = fsi_spi_write_reg(ctx, SPI_FSI_SEQUENCE, seq.data); | ||
| 454 | if (rc) | ||
| 455 | goto error; | ||
| 456 | |||
| 457 | rc = fsi_spi_transfer_data(ctx, transfer); | ||
| 458 | if (rc) | ||
| 459 | goto error; | ||
| 460 | |||
| 461 | if (next) { | ||
| 462 | rc = fsi_spi_transfer_data(ctx, next); | ||
| 463 | if (rc) | ||
| 464 | goto error; | ||
| 465 | |||
| 466 | transfer = next; | ||
| 467 | } | ||
| 468 | } | ||
| 469 | |||
| 470 | error: | ||
| 471 | mesg->status = rc; | ||
| 472 | spi_finalize_current_message(ctlr); | ||
| 473 | |||
| 474 | return rc; | ||
| 475 | } | ||
| 476 | |||
| 477 | static size_t fsi_spi_max_transfer_size(struct spi_device *spi) | ||
| 478 | { | ||
| 479 | return SPI_FSI_MAX_TRANSFER_SIZE; | ||
| 480 | } | ||
| 481 | |||
| 482 | static int fsi_spi_probe(struct device *dev) | ||
| 483 | { | ||
| 484 | int rc; | ||
| 485 | u32 root_ctrl_8; | ||
| 486 | struct device_node *np; | ||
| 487 | int num_controllers_registered = 0; | ||
| 488 | struct fsi_device *fsi = to_fsi_dev(dev); | ||
| 489 | |||
| 490 | /* | ||
| 491 | * Check the SPI mux before attempting to probe. If the mux isn't set | ||
| 492 | * then the SPI controllers can't access their slave devices. | ||
| 493 | */ | ||
| 494 | rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8, | ||
| 495 | sizeof(root_ctrl_8)); | ||
| 496 | if (rc) | ||
| 497 | return rc; | ||
| 498 | |||
| 499 | if (!root_ctrl_8) { | ||
| 500 | dev_dbg(dev, "SPI mux not set, aborting probe.\n"); | ||
| 501 | return -ENODEV; | ||
| 502 | } | ||
| 503 | |||
| 504 | for_each_available_child_of_node(dev->of_node, np) { | ||
| 505 | u32 base; | ||
| 506 | struct fsi_spi *ctx; | ||
| 507 | struct spi_controller *ctlr; | ||
| 508 | |||
| 509 | if (of_property_read_u32(np, "reg", &base)) | ||
| 510 | continue; | ||
| 511 | |||
| 512 | ctlr = spi_alloc_master(dev, sizeof(*ctx)); | ||
| 513 | if (!ctlr) | ||
| 514 | break; | ||
| 515 | |||
| 516 | ctlr->dev.of_node = np; | ||
| 517 | ctlr->num_chipselect = of_get_available_child_count(np) ?: 1; | ||
| 518 | ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX; | ||
| 519 | ctlr->max_transfer_size = fsi_spi_max_transfer_size; | ||
| 520 | ctlr->transfer_one_message = fsi_spi_transfer_one_message; | ||
| 521 | |||
| 522 | ctx = spi_controller_get_devdata(ctlr); | ||
| 523 | ctx->dev = &ctlr->dev; | ||
| 524 | ctx->fsi = fsi; | ||
| 525 | ctx->base = base + SPI_FSI_BASE; | ||
| 526 | |||
| 527 | rc = devm_spi_register_controller(dev, ctlr); | ||
| 528 | if (rc) | ||
| 529 | spi_controller_put(ctlr); | ||
| 530 | else | ||
| 531 | num_controllers_registered++; | ||
| 532 | } | ||
| 533 | |||
| 534 | if (!num_controllers_registered) | ||
| 535 | return -ENODEV; | ||
| 536 | |||
| 537 | return 0; | ||
| 538 | } | ||
| 539 | |||
| 540 | static const struct fsi_device_id fsi_spi_ids[] = { | ||
| 541 | { FSI_ENGID_SPI, FSI_VERSION_ANY }, | ||
| 542 | { } | ||
| 543 | }; | ||
| 544 | MODULE_DEVICE_TABLE(fsi, fsi_spi_ids); | ||
| 545 | |||
| 546 | static struct fsi_driver fsi_spi_driver = { | ||
| 547 | .id_table = fsi_spi_ids, | ||
| 548 | .drv = { | ||
| 549 | .name = "spi-fsi", | ||
| 550 | .bus = &fsi_bus_type, | ||
| 551 | .probe = fsi_spi_probe, | ||
| 552 | }, | ||
| 553 | }; | ||
| 554 | module_fsi_driver(fsi_spi_driver); | ||
| 555 | |||
| 556 | MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>"); | ||
| 557 | MODULE_DESCRIPTION("FSI attached SPI controller"); | ||
| 558 | MODULE_LICENSE("GPL"); | ||
| @@ -20,16 +20,9 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | #define DRIVER_NAME "fsl-dspi" | 21 | #define DRIVER_NAME "fsl-dspi" |
| 22 | 22 | ||
| 23 | #ifdef CONFIG_M5441x | ||
| 24 | #define DSPI_FIFO_SIZE 16 | ||
| 25 | #else | ||
| 26 | #define DSPI_FIFO_SIZE 4 | ||
| 27 | #endif | ||
| 28 | #define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024) | ||
| 29 | |||
| 30 | #define SPI_MCR 0x00 | 23 | #define SPI_MCR 0x00 |
| 31 | #define SPI_MCR_MASTER BIT(31) | 24 | #define SPI_MCR_MASTER BIT(31) |
| 32 | #define SPI_MCR_PCSIS (0x3F << 16) | 25 | #define SPI_MCR_PCSIS(x) ((x) << 16) |
| 33 | #define SPI_MCR_CLR_TXF BIT(11) | 26 | #define SPI_MCR_CLR_TXF BIT(11) |
| 34 | #define SPI_MCR_CLR_RXF BIT(10) | 27 | #define SPI_MCR_CLR_RXF BIT(10) |
| 35 | #define SPI_MCR_XSPI BIT(3) | 28 | #define SPI_MCR_XSPI BIT(3) |
| @@ -79,6 +72,7 @@ · 43 unmodified lines | |||
| 79 | #define SPI_RSER 0x30 | 72 | #define SPI_RSER 0x30 |
| 80 | #define SPI_RSER_TCFQE BIT(31) | 73 | #define SPI_RSER_TCFQE BIT(31) |
| 81 | #define SPI_RSER_EOQFE BIT(28) | 74 | #define SPI_RSER_EOQFE BIT(28) |
| 75 | #define SPI_RSER_CMDTCFE BIT(23) | ||
| 82 | 76 | ||
| 83 | #define SPI_PUSHR 0x34 | 77 | #define SPI_PUSHR 0x34 |
| 84 | #define SPI_PUSHR_CMD_CONT BIT(15) | 78 | #define SPI_PUSHR_CMD_CONT BIT(15) |
| @@ -109,57 +103,95 @@ · 24 unmodified lines | |||
| 109 | #define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1) | 103 | #define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1) |
| 110 | #define SPI_FRAME_EBITS(bits) SPI_CTARE_FMSZE(((bits) - 1) >> 4) | 104 | #define SPI_FRAME_EBITS(bits) SPI_CTARE_FMSZE(((bits) - 1) >> 4) |
| 111 | 105 | ||
| 112 | /* Register offsets for regmap_pushr */ | ||
| 113 | #define PUSHR_CMD 0x0 | ||
| 114 | #define PUSHR_TX 0x2 | ||
| 115 | |||
| 116 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) | 106 | #define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000) |
| 117 | 107 | ||
| 118 | struct chip_data { | 108 | struct chip_data { |
| 119 | u32 ctar_val; | 109 | u32 ctar_val; |
| 120 | u16 void_write_data; | ||
| 121 | }; | 110 | }; |
| 122 | 111 | ||
| 123 | enum dspi_trans_mode { | 112 | enum dspi_trans_mode { |
| 124 | DSPI_EOQ_MODE = 0, | 113 | DSPI_EOQ_MODE = 0, |
| 125 | DSPI_TCFQ_MODE, | 114 | DSPI_XSPI_MODE, |
| 126 | DSPI_DMA_MODE, | 115 | DSPI_DMA_MODE, |
| 127 | }; | 116 | }; |
| 128 | 117 | ||
| 129 | struct fsl_dspi_devtype_data { | 118 | struct fsl_dspi_devtype_data { |
| 130 | enum dspi_trans_mode trans_mode; | 119 | enum dspi_trans_mode trans_mode; |
| 131 | u8 max_clock_factor; | 120 | u8 max_clock_factor; |
| 132 | bool ptp_sts_supported; | 121 | int fifo_size; |
| 133 | bool xspi_mode; | ||
| 134 | }; | ||
| 135 | |||
| 136 | static const struct fsl_dspi_devtype_data vf610_data = { | ||
| 137 | .trans_mode = DSPI_DMA_MODE, | ||
| 138 | .max_clock_factor = 2, | ||
| 139 | }; | ||
| 140 | |||
| 141 | static const struct fsl_dspi_devtype_data ls1021a_v1_data = { | ||
| 142 | .trans_mode = DSPI_TCFQ_MODE, | ||
| 143 | .max_clock_factor = 8, | ||
| 144 | .ptp_sts_supported = true, | ||
| 145 | .xspi_mode = true, | ||
| 146 | }; | 122 | }; |
| 147 | 123 | ||
| 148 | static const struct fsl_dspi_devtype_data ls2085a_data = { | 124 | enum { |
| 149 | .trans_mode = DSPI_TCFQ_MODE, | 125 | LS1021A, |
| 150 | .max_clock_factor = 8, | 126 | LS1012A, |
| 151 | .ptp_sts_supported = true, | 127 | LS1028A, |
| 128 | LS1043A, | ||
| 129 | LS1046A, | ||
| 130 | LS2080A, | ||
| 131 | LS2085A, | ||
| 132 | LX2160A, | ||
| 133 | MCF5441X, | ||
| 134 | VF610, | ||
| 152 | }; | 135 | }; |
| 153 | 136 | ||
| 154 | static const struct fsl_dspi_devtype_data coldfire_data = { | 137 | static const struct fsl_dspi_devtype_data devtype_data[] = { |
| 155 | .trans_mode = DSPI_EOQ_MODE, | 138 | [VF610] = { |
| 156 | .max_clock_factor = 8, | 139 | .trans_mode = DSPI_DMA_MODE, |
| 140 | .max_clock_factor = 2, | ||
| 141 | .fifo_size = 4, | ||
| 142 | }, | ||
| 143 | [LS1021A] = { | ||
| 144 | /* Has A-011218 DMA erratum */ | ||
| 145 | .trans_mode = DSPI_XSPI_MODE, | ||
| 146 | .max_clock_factor = 8, | ||
| 147 | .fifo_size = 4, | ||
| 148 | }, | ||
| 149 | [LS1012A] = { | ||
| 150 | /* Has A-011218 DMA erratum */ | ||
| 151 | .trans_mode = DSPI_XSPI_MODE, | ||
| 152 | .max_clock_factor = 8, | ||
| 153 | .fifo_size = 16, | ||
| 154 | }, | ||
| 155 | [LS1028A] = { | ||
| 156 | .trans_mode = DSPI_XSPI_MODE, | ||
| 157 | .max_clock_factor = 8, | ||
| 158 | .fifo_size = 4, | ||
| 159 | }, | ||
| 160 | [LS1043A] = { | ||
| 161 | /* Has A-011218 DMA erratum */ | ||
| 162 | .trans_mode = DSPI_XSPI_MODE, | ||
| 163 | .max_clock_factor = 8, | ||
| 164 | .fifo_size = 16, | ||
| 165 | }, | ||
| 166 | [LS1046A] = { | ||
| 167 | /* Has A-011218 DMA erratum */ | ||
| 168 | .trans_mode = DSPI_XSPI_MODE, | ||
| 169 | .max_clock_factor = 8, | ||
| 170 | .fifo_size = 16, | ||
| 171 | }, | ||
| 172 | [LS2080A] = { | ||
| 173 | .trans_mode = DSPI_DMA_MODE, | ||
| 174 | .max_clock_factor = 8, | ||
| 175 | .fifo_size = 4, | ||
| 176 | }, | ||
| 177 | [LS2085A] = { | ||
| 178 | .trans_mode = DSPI_DMA_MODE, | ||
| 179 | .max_clock_factor = 8, | ||
| 180 | .fifo_size = 4, | ||
| 181 | }, | ||
| 182 | [LX2160A] = { | ||
| 183 | .trans_mode = DSPI_DMA_MODE, | ||
| 184 | .max_clock_factor = 8, | ||
| 185 | .fifo_size = 4, | ||
| 186 | }, | ||
| 187 | [MCF5441X] = { | ||
| 188 | .trans_mode = DSPI_EOQ_MODE, | ||
| 189 | .max_clock_factor = 8, | ||
| 190 | .fifo_size = 16, | ||
| 191 | }, | ||
| 157 | }; | 192 | }; |
| 158 | 193 | ||
| 159 | struct fsl_dspi_dma { | 194 | struct fsl_dspi_dma { |
| 160 | /* Length of transfer in words of DSPI_FIFO_SIZE */ | ||
| 161 | u32 curr_xfer_len; | ||
| 162 | |||
| 163 | u32 *tx_dma_buf; | 195 | u32 *tx_dma_buf; |
| 164 | struct dma_chan *chan_tx; | 196 | struct dma_chan *chan_tx; |
| 165 | dma_addr_t tx_dma_phys; | 197 | dma_addr_t tx_dma_phys; |
| @@ -189,36 +221,99 @@ struct fsl_dspi { · 23 unmodified lines | |||
| 189 | size_t len; | 221 | size_t len; |
| 190 | const void *tx; | 222 | const void *tx; |
| 191 | void *rx; | 223 | void *rx; |
| 192 | void *rx_end; | ||
| 193 | u16 void_write_data; | ||
| 194 | u16 tx_cmd; | 224 | u16 tx_cmd; |
| 195 | u8 bits_per_word; | ||
| 196 | u8 bytes_per_word; | ||
| 197 | const struct fsl_dspi_devtype_data *devtype_data; | 225 | const struct fsl_dspi_devtype_data *devtype_data; |
| 198 | 226 | ||
| 199 | wait_queue_head_t waitq; | 227 | struct completion xfer_done; |
| 200 | u32 waitflags; | ||
| 201 | 228 | ||
| 202 | struct fsl_dspi_dma *dma; | 229 | struct fsl_dspi_dma *dma; |
| 230 | |||
| 231 | int oper_word_size; | ||
| 232 | int oper_bits_per_word; | ||
| 233 | |||
| 234 | int words_in_flight; | ||
| 235 | |||
| 236 | /* | ||
| 237 | * Offsets for CMD and TXDATA within SPI_PUSHR when accessed | ||
| 238 | * individually (in XSPI mode) | ||
| 239 | */ | ||
| 240 | int pushr_cmd; | ||
| 241 | int pushr_tx; | ||
| 242 | |||
| 243 | void (*host_to_dev)(struct fsl_dspi *dspi, u32 *txdata); | ||
| 244 | void (*dev_to_host)(struct fsl_dspi *dspi, u32 rxdata); | ||
| 203 | }; | 245 | }; |
| 204 | 246 | ||
| 247 | static void dspi_native_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | ||
| 248 | { | ||
| 249 | memcpy(txdata, dspi->tx, dspi->oper_word_size); | ||
| 250 | dspi->tx += dspi->oper_word_size; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void dspi_native_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | ||
| 254 | { | ||
| 255 | memcpy(dspi->rx, &rxdata, dspi->oper_word_size); | ||
| 256 | dspi->rx += dspi->oper_word_size; | ||
| 257 | } | ||
| 258 | |||
| 259 | static void dspi_8on32_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | ||
| 260 | { | ||
| 261 | *txdata = cpu_to_be32(*(u32 *)dspi->tx); | ||
| 262 | dspi->tx += sizeof(u32); | ||
| 263 | } | ||
| 264 | |||
| 265 | static void dspi_8on32_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | ||
| 266 | { | ||
| 267 | *(u32 *)dspi->rx = be32_to_cpu(rxdata); | ||
| 268 | dspi->rx += sizeof(u32); | ||
| 269 | } | ||
| 270 | |||
| 271 | static void dspi_8on16_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | ||
| 272 | { | ||
| 273 | *txdata = cpu_to_be16(*(u16 *)dspi->tx); | ||
| 274 | dspi->tx += sizeof(u16); | ||
| 275 | } | ||
| 276 | |||
| 277 | static void dspi_8on16_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | ||
| 278 | { | ||
| 279 | *(u16 *)dspi->rx = be16_to_cpu(rxdata); | ||
| 280 | dspi->rx += sizeof(u16); | ||
| 281 | } | ||
| 282 | |||
| 283 | static void dspi_16on32_host_to_dev(struct fsl_dspi *dspi, u32 *txdata) | ||
| 284 | { | ||
| 285 | u16 hi = *(u16 *)dspi->tx; | ||
| 286 | u16 lo = *(u16 *)(dspi->tx + 2); | ||
| 287 | |||
| 288 | *txdata = (u32)hi << 16 | lo; | ||
| 289 | dspi->tx += sizeof(u32); | ||
| 290 | } | ||
| 291 | |||
| 292 | static void dspi_16on32_dev_to_host(struct fsl_dspi *dspi, u32 rxdata) | ||
| 293 | { | ||
| 294 | u16 hi = rxdata & 0xffff; | ||
| 295 | u16 lo = rxdata >> 16; | ||
| 296 | |||
| 297 | *(u16 *)dspi->rx = lo; | ||
| 298 | *(u16 *)(dspi->rx + 2) = hi; | ||
| 299 | dspi->rx += sizeof(u32); | ||
| 300 | } | ||
| 301 | |||
| 302 | /* | ||
| 303 | * Pop one word from the TX buffer for pushing into the | ||
| 304 | * PUSHR register (TX FIFO) | ||
| 305 | */ | ||
| 205 | static u32 dspi_pop_tx(struct fsl_dspi *dspi) | 306 | static u32 dspi_pop_tx(struct fsl_dspi *dspi) |
| 206 | { | 307 | { |
| 207 | u32 txdata = 0; | 308 | u32 txdata = 0; |
| 208 | 309 | ||
| 209 | if (dspi->tx) { | 310 | if (dspi->tx) |
| 210 | if (dspi->bytes_per_word == 1) | 311 | dspi->host_to_dev(dspi, &txdata); |
| 211 | txdata = *(u8 *)dspi->tx; | 312 | dspi->len -= dspi->oper_word_size; |
| 212 | else if (dspi->bytes_per_word == 2) | ||
| 213 | txdata = *(u16 *)dspi->tx; | ||
| 214 | else /* dspi->bytes_per_word == 4 */ | ||
| 215 | txdata = *(u32 *)dspi->tx; | ||
| 216 | dspi->tx += dspi->bytes_per_word; | ||
| 217 | } | ||
| 218 | dspi->len -= dspi->bytes_per_word; | ||
| 219 | return txdata; | 313 | return txdata; |
| 220 | } | 314 | } |
| 221 | 315 | ||
| 316 | /* Prepare one TX FIFO entry (txdata plus cmd) */ | ||
| 222 | static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi) | 317 | static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi) |
| 223 | { | 318 | { |
| 224 | u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi); | 319 | u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi); |
| @@ -231,21 +326,12 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi) · 6 unmodified lines | |||
| 231 | return cmd << 16 | data; | 326 | return cmd << 16 | data; |
| 232 | } | 327 | } |
| 233 | 328 | ||
| 329 | /* Push one word to the RX buffer from the POPR register (RX FIFO) */ | ||
| 234 | static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata) | 330 | static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata) |
| 235 | { | 331 | { |
| 236 | if (!dspi->rx) | 332 | if (!dspi->rx) |
| 237 | return; | 333 | return; |
| 238 | 334 | dspi->dev_to_host(dspi, rxdata); | |
| 239 | /* Mask off undefined bits */ | ||
| 240 | rxdata &= (1 << dspi->bits_per_word) - 1; | ||
| 241 | |||
| 242 | if (dspi->bytes_per_word == 1) | ||
| 243 | *(u8 *)dspi->rx = rxdata; | ||
| 244 | else if (dspi->bytes_per_word == 2) | ||
| 245 | *(u16 *)dspi->rx = rxdata; | ||
| 246 | else /* dspi->bytes_per_word == 4 */ | ||
| 247 | *(u32 *)dspi->rx = rxdata; | ||
| 248 | dspi->rx += dspi->bytes_per_word; | ||
| 249 | } | 335 | } |
| 250 | 336 | ||
| 251 | static void dspi_tx_dma_callback(void *arg) | 337 | static void dspi_tx_dma_callback(void *arg) |
| @@ -263,7 +349,7 @@ static void dspi_rx_dma_callback(void *arg) · 11 unmodified lines | |||
| 263 | int i; | 349 | int i; |
| 264 | 350 | ||
| 265 | if (dspi->rx) { | 351 | if (dspi->rx) { |
| 266 | for (i = 0; i < dma->curr_xfer_len; i++) | 352 | for (i = 0; i < dspi->words_in_flight; i++) |
| 267 | dspi_push_rx(dspi, dspi->dma->rx_dma_buf[i]); | 353 | dspi_push_rx(dspi, dspi->dma->rx_dma_buf[i]); |
| 268 | } | 354 | } |
| 269 | 355 | ||
| @@ -277,12 +363,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) · 7 unmodified lines | |||
| 277 | int time_left; | 363 | int time_left; |
| 278 | int i; | 364 | int i; |
| 279 | 365 | ||
| 280 | for (i = 0; i < dma->curr_xfer_len; i++) | 366 | for (i = 0; i < dspi->words_in_flight; i++) |
| 281 | dspi->dma->tx_dma_buf[i] = dspi_pop_tx_pushr(dspi); | 367 | dspi->dma->tx_dma_buf[i] = dspi_pop_tx_pushr(dspi); |
| 282 | 368 | ||
| 283 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, | 369 | dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, |
| 284 | dma->tx_dma_phys, | 370 | dma->tx_dma_phys, |
| 285 | dma->curr_xfer_len * | 371 | dspi->words_in_flight * |
| 286 | DMA_SLAVE_BUSWIDTH_4_BYTES, | 372 | DMA_SLAVE_BUSWIDTH_4_BYTES, |
| 287 | DMA_MEM_TO_DEV, | 373 | DMA_MEM_TO_DEV, |
| 288 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 374 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| @@ -300,7 +386,7 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) · 11 unmodified lines | |||
| 300 | 386 | ||
| 301 | dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx, | 387 | dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx, |
| 302 | dma->rx_dma_phys, | 388 | dma->rx_dma_phys, |
| 303 | dma->curr_xfer_len * | 389 | dspi->words_in_flight * |
| 304 | DMA_SLAVE_BUSWIDTH_4_BYTES, | 390 | DMA_SLAVE_BUSWIDTH_4_BYTES, |
| 305 | DMA_DEV_TO_MEM, | 391 | DMA_DEV_TO_MEM, |
| 306 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 392 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| @@ -348,45 +434,42 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) · 41 unmodified lines | |||
| 348 | return 0; | 434 | return 0; |
| 349 | } | 435 | } |
| 350 | 436 | ||
| 437 | static void dspi_setup_accel(struct fsl_dspi *dspi); | ||
| 438 | |||
| 351 | static int dspi_dma_xfer(struct fsl_dspi *dspi) | 439 | static int dspi_dma_xfer(struct fsl_dspi *dspi) |
| 352 | { | 440 | { |
| 353 | struct spi_message *message = dspi->cur_msg; | 441 | struct spi_message *message = dspi->cur_msg; |
| 354 | struct device *dev = &dspi->pdev->dev; | 442 | struct device *dev = &dspi->pdev->dev; |
| 355 | struct fsl_dspi_dma *dma = dspi->dma; | ||
| 356 | int curr_remaining_bytes; | ||
| 357 | int bytes_per_buffer; | ||
| 358 | int ret = 0; | 443 | int ret = 0; |
| 359 | 444 | ||
| 360 | curr_remaining_bytes = dspi->len; | 445 | /* |
| 361 | bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; | 446 | * dspi->len gets decremented by dspi_pop_tx_pushr in |
| 362 | while (curr_remaining_bytes) { | 447 | * dspi_next_xfer_dma_submit |
| 363 | /* Check if current transfer fits the DMA buffer */ | 448 | */ |
| 364 | dma->curr_xfer_len = curr_remaining_bytes | 449 | while (dspi->len) { |
| 365 | / dspi->bytes_per_word; | 450 | /* Figure out operational bits-per-word for this chunk */ |
| 366 | if (dma->curr_xfer_len > bytes_per_buffer) | 451 | dspi_setup_accel(dspi); |
| 367 | dma->curr_xfer_len = bytes_per_buffer; | 452 | |
| 453 | dspi->words_in_flight = dspi->len / dspi->oper_word_size; | ||
| 454 | if (dspi->words_in_flight > dspi->devtype_data->fifo_size) | ||
| 455 | dspi->words_in_flight = dspi->devtype_data->fifo_size; | ||
| 456 | |||
| 457 | message->actual_length += dspi->words_in_flight * | ||
| 458 | dspi->oper_word_size; | ||
| 368 | 459 | ||
| 369 | ret = dspi_next_xfer_dma_submit(dspi); | 460 | ret = dspi_next_xfer_dma_submit(dspi); |
| 370 | if (ret) { | 461 | if (ret) { |
| 371 | dev_err(dev, "DMA transfer failed\n"); | 462 | dev_err(dev, "DMA transfer failed\n"); |
| 372 | goto exit; | 463 | break; |
| 373 | |||
| 374 | } else { | ||
| 375 | const int len = | ||
| 376 | dma->curr_xfer_len * dspi->bytes_per_word; | ||
| 377 | curr_remaining_bytes -= len; | ||
| 378 | message->actual_length += len; | ||
| 379 | if (curr_remaining_bytes < 0) | ||
| 380 | curr_remaining_bytes = 0; | ||
| 381 | } | 464 | } |
| 382 | } | 465 | } |
| 383 | 466 | ||
| 384 | exit: | ||
| 385 | return ret; | 467 | return ret; |
| 386 | } | 468 | } |
| 387 | 469 | ||
| 388 | static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) | 470 | static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) |
| 389 | { | 471 | { |
| 472 | int dma_bufsize = dspi->devtype_data->fifo_size * 2; | ||
| 390 | struct device *dev = &dspi->pdev->dev; | 473 | struct device *dev = &dspi->pdev->dev; |
| 391 | struct dma_slave_config cfg; | 474 | struct dma_slave_config cfg; |
| 392 | struct fsl_dspi_dma *dma; | 475 | struct fsl_dspi_dma *dma; |
| @@ -410,15 +493,17 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) · 17 unmodified lines | |||
| 410 | goto err_tx_channel; | 493 | goto err_tx_channel; |
| 411 | } | 494 | } |
| 412 | 495 | ||
| 413 | dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, | 496 | dma->tx_dma_buf = dma_alloc_coherent(dma->chan_tx->device->dev, |
| 414 | &dma->tx_dma_phys, GFP_KERNEL); | 497 | dma_bufsize, &dma->tx_dma_phys, |
| 498 | GFP_KERNEL); | ||
| 415 | if (!dma->tx_dma_buf) { | 499 | if (!dma->tx_dma_buf) { |
| 416 | ret = -ENOMEM; | 500 | ret = -ENOMEM; |
| 417 | goto err_tx_dma_buf; | 501 | goto err_tx_dma_buf; |
| 418 | } | 502 | } |
| 419 | 503 | ||
| 420 | dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, | 504 | dma->rx_dma_buf = dma_alloc_coherent(dma->chan_rx->device->dev, |
| 421 | &dma->rx_dma_phys, GFP_KERNEL); | 505 | dma_bufsize, &dma->rx_dma_phys, |
| 506 | GFP_KERNEL); | ||
| 422 | if (!dma->rx_dma_buf) { | 507 | if (!dma->rx_dma_buf) { |
| 423 | ret = -ENOMEM; | 508 | ret = -ENOMEM; |
| 424 | goto err_rx_dma_buf; | 509 | goto err_rx_dma_buf; |
| @@ -454,11 +539,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) · 29 unmodified lines | |||
| 454 | return 0; | 539 | return 0; |
| 455 | 540 | ||
| 456 | err_slave_config: | 541 | err_slave_config: |
| 457 | dma_free_coherent(dev, DSPI_DMA_BUFSIZE, | 542 | dma_free_coherent(dma->chan_rx->device->dev, |
| 458 | dma->rx_dma_buf, dma->rx_dma_phys); | 543 | dma_bufsize, dma->rx_dma_buf, dma->rx_dma_phys); |
| 459 | err_rx_dma_buf: | 544 | err_rx_dma_buf: |
| 460 | dma_free_coherent(dev, DSPI_DMA_BUFSIZE, | 545 | dma_free_coherent(dma->chan_tx->device->dev, |
| 461 | dma->tx_dma_buf, dma->tx_dma_phys); | 546 | dma_bufsize, dma->tx_dma_buf, dma->tx_dma_phys); |
| 462 | err_tx_dma_buf: | 547 | err_tx_dma_buf: |
| 463 | dma_release_channel(dma->chan_tx); | 548 | dma_release_channel(dma->chan_tx); |
| 464 | err_tx_channel: | 549 | err_tx_channel: |
| @@ -472,21 +557,21 @@ err_tx_channel: · 7 unmodified lines | |||
| 472 | 557 | ||
| 473 | static void dspi_release_dma(struct fsl_dspi *dspi) | 558 | static void dspi_release_dma(struct fsl_dspi *dspi) |
| 474 | { | 559 | { |
| 560 | int dma_bufsize = dspi->devtype_data->fifo_size * 2; | ||
| 475 | struct fsl_dspi_dma *dma = dspi->dma; | 561 | struct fsl_dspi_dma *dma = dspi->dma; |
| 476 | struct device *dev = &dspi->pdev->dev; | ||
| 477 | 562 | ||
| 478 | if (!dma) | 563 | if (!dma) |
| 479 | return; | 564 | return; |
| 480 | 565 | ||
| 481 | if (dma->chan_tx) { | 566 | if (dma->chan_tx) { |
| 482 | dma_unmap_single(dev, dma->tx_dma_phys, | 567 | dma_unmap_single(dma->chan_tx->device->dev, dma->tx_dma_phys, |
| 483 | DSPI_DMA_BUFSIZE, DMA_TO_DEVICE); | 568 | dma_bufsize, DMA_TO_DEVICE); |
| 484 | dma_release_channel(dma->chan_tx); | 569 | dma_release_channel(dma->chan_tx); |
| 485 | } | 570 | } |
| 486 | 571 | ||
| 487 | if (dma->chan_rx) { | 572 | if (dma->chan_rx) { |
| 488 | dma_unmap_single(dev, dma->rx_dma_phys, | 573 | dma_unmap_single(dma->chan_rx->device->dev, dma->rx_dma_phys, |
| 489 | DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE); | 574 | dma_bufsize, DMA_FROM_DEVICE); |
| 490 | dma_release_channel(dma->chan_rx); | 575 | dma_release_channel(dma->chan_rx); |
| 491 | } | 576 | } |
| 492 | } | 577 | } |
| @@ -562,124 +647,220 @@ static void ns_delay_scale(char *psc, char *sc, int delay_ns, · 69 unmodified lines | |||
| 562 | } | 647 | } |
| 563 | } | 648 | } |
| 564 | 649 | ||
| 565 | static void fifo_write(struct fsl_dspi *dspi) | 650 | static void dspi_pushr_write(struct fsl_dspi *dspi) |
| 566 | { | 651 | { |
| 567 | regmap_write(dspi->regmap, SPI_PUSHR, dspi_pop_tx_pushr(dspi)); | 652 | regmap_write(dspi->regmap, SPI_PUSHR, dspi_pop_tx_pushr(dspi)); |
| 568 | } | 653 | } |
| 569 | 654 | ||
| 570 | static void cmd_fifo_write(struct fsl_dspi *dspi) | 655 | static void dspi_pushr_cmd_write(struct fsl_dspi *dspi, u16 cmd) |
| 571 | { | 656 | { |
| 572 | u16 cmd = dspi->tx_cmd; | 657 | /* |
| 573 | 658 | * The only time when the PCS doesn't need continuation after this word | |
| 574 | if (dspi->len > 0) | 659 | * is when it's last. We need to look ahead, because we actually call |
| 660 | * dspi_pop_tx (the function that decrements dspi->len) _after_ | ||
| 661 | * dspi_pushr_cmd_write with XSPI mode. As for how much in advance? One | ||
| 662 | * word is enough. If there's more to transmit than that, | ||
| 663 | * dspi_xspi_write will know to split the FIFO writes in 2, and | ||
| 664 | * generate a new PUSHR command with the final word that will have PCS | ||
| 665 | * deasserted (not continued) here. | ||
| 666 | */ | ||
| 667 | if (dspi->len > dspi->oper_word_size) | ||
| 575 | cmd |= SPI_PUSHR_CMD_CONT; | 668 | cmd |= SPI_PUSHR_CMD_CONT; |
| 576 | regmap_write(dspi->regmap_pushr, PUSHR_CMD, cmd); | 669 | regmap_write(dspi->regmap_pushr, dspi->pushr_cmd, cmd); |
| 577 | } | 670 | } |
| 578 | 671 | ||
| 579 | static void tx_fifo_write(struct fsl_dspi *dspi, u16 txdata) | 672 | static void dspi_pushr_txdata_write(struct fsl_dspi *dspi, u16 txdata) |
| 580 | { | 673 | { |
| 581 | regmap_write(dspi->regmap_pushr, PUSHR_TX, txdata); | 674 | regmap_write(dspi->regmap_pushr, dspi->pushr_tx, txdata); |
| 582 | } | 675 | } |
| 583 | 676 | ||
| 584 | static void dspi_tcfq_write(struct fsl_dspi *dspi) | 677 | static void dspi_xspi_fifo_write(struct fsl_dspi *dspi, int num_words) |
| 585 | { | 678 | { |
| 586 | /* Clear transfer count */ | 679 | int num_bytes = num_words * dspi->oper_word_size; |
| 587 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; | 680 | u16 tx_cmd = dspi->tx_cmd; |
| 588 | 681 | ||
| 589 | if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { | 682 | /* |
| 590 | /* Write the CMD FIFO entry first, and then the two | 683 | * If the PCS needs to de-assert (i.e. we're at the end of the buffer |
| 591 | * corresponding TX FIFO entries. | 684 | * and cs_change does not want the PCS to stay on), then we need a new |
| 592 | */ | 685 | * PUSHR command, since this one (for the body of the buffer) |
| 593 | u32 data = dspi_pop_tx(dspi); | 686 | * necessarily has the CONT bit set. |
| 687 | * So send one word less during this go, to force a split and a command | ||
| 688 | * with a single word next time, when CONT will be unset. | ||
| 689 | */ | ||
| 690 | if (!(dspi->tx_cmd & SPI_PUSHR_CMD_CONT) && num_bytes == dspi->len) | ||
| 691 | tx_cmd |= SPI_PUSHR_CMD_EOQ; | ||
| 594 | 692 | ||
| 595 | cmd_fifo_write(dspi); | 693 | /* Update CTARE */ |
| 596 | tx_fifo_write(dspi, data & 0xFFFF); | 694 | regmap_write(dspi->regmap, SPI_CTARE(0), |
| 597 | tx_fifo_write(dspi, data >> 16); | 695 | SPI_FRAME_EBITS(dspi->oper_bits_per_word) | |
| 598 | } else { | 696 | SPI_CTARE_DTCP(num_words)); |
| 599 | /* Write one entry to both TX FIFO and CMD FIFO | ||
| 600 | * simultaneously. | ||
| 601 | */ | ||
| 602 | fifo_write(dspi); | ||
| 603 | } | ||
| 604 | } | ||
| 605 | 697 | ||
| 606 | static u32 fifo_read(struct fsl_dspi *dspi) | 698 | /* |
| 607 | { | 699 | * Write the CMD FIFO entry first, and then the two |
| 608 | u32 rxdata = 0; | 700 | * corresponding TX FIFO entries (or one...). |
| 701 | */ | ||
| 702 | dspi_pushr_cmd_write(dspi, tx_cmd); | ||
| 609 | 703 | ||
| 610 | regmap_read(dspi->regmap, SPI_POPR, &rxdata); | 704 | /* Fill TX FIFO with as many transfers as possible */ |
| 611 | return rxdata; | 705 | while (num_words--) { |
| 612 | } | 706 | u32 data = dspi_pop_tx(dspi); |
| 613 | 707 | ||
| 614 | static void dspi_tcfq_read(struct fsl_dspi *dspi) | 708 | dspi_pushr_txdata_write(dspi, data & 0xFFFF); |
| 615 | { | 709 | if (dspi->oper_bits_per_word > 16) |
| 616 | dspi_push_rx(dspi, fifo_read(dspi)); | 710 | dspi_pushr_txdata_write(dspi, data >> 16); |
| 711 | } | ||
| 617 | } | 712 | } |
| 618 | 713 | ||
| 619 | static void dspi_eoq_write(struct fsl_dspi *dspi) | 714 | static void dspi_eoq_fifo_write(struct fsl_dspi *dspi, int num_words) |
| 620 | { | 715 | { |
| 621 | int fifo_size = DSPI_FIFO_SIZE; | ||
| 622 | u16 xfer_cmd = dspi->tx_cmd; | 716 | u16 xfer_cmd = dspi->tx_cmd; |
| 623 | 717 | ||
| 624 | /* Fill TX FIFO with as many transfers as possible */ | 718 | /* Fill TX FIFO with as many transfers as possible */ |
| 625 | while (dspi->len && fifo_size--) { | 719 | while (num_words--) { |
| 626 | dspi->tx_cmd = xfer_cmd; | 720 | dspi->tx_cmd = xfer_cmd; |
| 627 | /* Request EOQF for last transfer in FIFO */ | 721 | /* Request EOQF for last transfer in FIFO */ |
| 628 | if (dspi->len == dspi->bytes_per_word || fifo_size == 0) | 722 | if (num_words == 0) |
| 629 | dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ; | 723 | dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ; |
| 630 | /* Clear transfer count for first transfer in FIFO */ | ||
| 631 | if (fifo_size == (DSPI_FIFO_SIZE - 1)) | ||
| 632 | dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; | ||
| 633 | /* Write combined TX FIFO and CMD FIFO entry */ | 724 | /* Write combined TX FIFO and CMD FIFO entry */ |
| 634 | fifo_write(dspi); | 725 | dspi_pushr_write(dspi); |
| 635 | } | 726 | } |
| 636 | } | 727 | } |
| 637 | 728 | ||
| 638 | static void dspi_eoq_read(struct fsl_dspi *dspi) | 729 | static u32 dspi_popr_read(struct fsl_dspi *dspi) |
| 639 | { | 730 | { |
| 640 | int fifo_size = DSPI_FIFO_SIZE; | 731 | u32 rxdata = 0; |
| 732 | |||
| 733 | regmap_read(dspi->regmap, SPI_POPR, &rxdata); | ||
| 734 | return rxdata; | ||
| 735 | } | ||
| 736 | |||
| 737 | static void dspi_fifo_read(struct fsl_dspi *dspi) | ||
| 738 | { | ||
| 739 | int num_fifo_entries = dspi->words_in_flight; | ||
| 641 | 740 | ||
| 642 | /* Read one FIFO entry and push to rx buffer */ | 741 | /* Read one FIFO entry and push to rx buffer */ |
| 643 | while ((dspi->rx < dspi->rx_end) && fifo_size--) | 742 | while (num_fifo_entries--) |
| 644 | dspi_push_rx(dspi, fifo_read(dspi)); | 743 | dspi_push_rx(dspi, dspi_popr_read(dspi)); |
| 645 | } | 744 | } |
| 646 | 745 | ||
| 647 | static int dspi_rxtx(struct fsl_dspi *dspi) | 746 | static void dspi_setup_accel(struct fsl_dspi *dspi) |
| 648 | { | 747 | { |
| 748 | struct spi_transfer *xfer = dspi->cur_transfer; | ||
| 749 | bool odd = !!(dspi->len & 1); | ||
| 750 | |||
| 751 | /* No accel for frames not multiple of 8 bits at the moment */ | ||
| 752 | if (xfer->bits_per_word % 8) | ||
| 753 | goto no_accel; | ||
| 754 | |||
| 755 | if (!odd && dspi->len <= dspi->devtype_data->fifo_size * 2) { | ||
| 756 | dspi->oper_bits_per_word = 16; | ||
| 757 | } else if (odd && dspi->len <= dspi->devtype_data->fifo_size) { | ||
| 758 | dspi->oper_bits_per_word = 8; | ||
| 759 | } else { | ||
| 760 | /* Start off with maximum supported by hardware */ | ||
| 761 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) | ||
| 762 | dspi->oper_bits_per_word = 32; | ||
| 763 | else | ||
| 764 | dspi->oper_bits_per_word = 16; | ||
| 765 | |||
| 766 | /* | ||
| 767 | * And go down only if the buffer can't be sent with | ||
| 768 | * words this big | ||
| 769 | */ | ||
| 770 | do { | ||
| 771 | if (dspi->len >= DIV_ROUND_UP(dspi->oper_bits_per_word, 8)) | ||
| 772 | break; | ||
| 773 | |||
| 774 | dspi->oper_bits_per_word /= 2; | ||
| 775 | } while (dspi->oper_bits_per_word > 8); | ||
| 776 | } | ||
| 777 | |||
| 778 | if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 32) { | ||
| 779 | dspi->dev_to_host = dspi_8on32_dev_to_host; | ||
| 780 | dspi->host_to_dev = dspi_8on32_host_to_dev; | ||
| 781 | } else if (xfer->bits_per_word == 8 && dspi->oper_bits_per_word == 16) { | ||
| 782 | dspi->dev_to_host = dspi_8on16_dev_to_host; | ||
| 783 | dspi->host_to_dev = dspi_8on16_host_to_dev; | ||
| 784 | } else if (xfer->bits_per_word == 16 && dspi->oper_bits_per_word == 32) { | ||
| 785 | dspi->dev_to_host = dspi_16on32_dev_to_host; | ||
| 786 | dspi->host_to_dev = dspi_16on32_host_to_dev; | ||
| 787 | } else { | ||
| 788 | no_accel: | ||
| 789 | dspi->dev_to_host = dspi_native_dev_to_host; | ||
| 790 | dspi->host_to_dev = dspi_native_host_to_dev; | ||
| 791 | dspi->oper_bits_per_word = xfer->bits_per_word; | ||
| 792 | } | ||
| 793 | |||
| 794 | dspi->oper_word_size = DIV_ROUND_UP(dspi->oper_bits_per_word, 8); | ||
| 795 | |||
| 796 | /* | ||
| 797 | * Update CTAR here (code is common for EOQ, XSPI and DMA modes). | ||
| 798 | * We will update CTARE in the portion specific to XSPI, when we | ||
| 799 | * also know the preload value (DTCP). | ||
| 800 | */ | ||
| 801 | regmap_write(dspi->regmap, SPI_CTAR(0), | ||
| 802 | dspi->cur_chip->ctar_val | | ||
| 803 | SPI_FRAME_BITS(dspi->oper_bits_per_word)); | ||
| 804 | } | ||
| 805 | |||
| 806 | static void dspi_fifo_write(struct fsl_dspi *dspi) | ||
| 807 | { | ||
| 808 | int num_fifo_entries = dspi->devtype_data->fifo_size; | ||
| 809 | struct spi_transfer *xfer = dspi->cur_transfer; | ||
| 649 | struct spi_message *msg = dspi->cur_msg; | 810 | struct spi_message *msg = dspi->cur_msg; |
| 650 | enum dspi_trans_mode trans_mode; | 811 | int num_words, num_bytes; |
| 651 | u16 spi_tcnt; | ||
| 652 | u32 spi_tcr; | ||
| 653 | 812 | ||
| 654 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, | 813 | dspi_setup_accel(dspi); |
| 655 | dspi->progress, !dspi->irq); | 814 | |
| 815 | /* In XSPI mode each 32-bit word occupies 2 TX FIFO entries */ | ||
| 816 | if (dspi->oper_word_size == 4) | ||
| 817 | num_fifo_entries /= 2; | ||
| 656 | 818 | ||
| 657 | /* Get transfer counter (in number of SPI transfers). It was | 819 | /* |
| 658 | * reset to 0 when transfer(s) were started. | 820 | * Integer division intentionally trims off odd (or non-multiple of 4) |
| 821 | * numbers of bytes at the end of the buffer, which will be sent next | ||
| 822 | * time using a smaller oper_word_size. | ||
| 659 | */ | 823 | */ |
| 660 | regmap_read(dspi->regmap, SPI_TCR, &spi_tcr); | 824 | num_words = dspi->len / dspi->oper_word_size; |
| 661 | spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr); | 825 | if (num_words > num_fifo_entries) |
| 826 | num_words = num_fifo_entries; | ||
| 827 | |||
| 662 | /* Update total number of bytes that were transferred */ | 828 | /* Update total number of bytes that were transferred */ |
| 663 | msg->actual_length += spi_tcnt * dspi->bytes_per_word; | 829 | num_bytes = num_words * dspi->oper_word_size; |
| 664 | dspi->progress += spi_tcnt; | 830 | msg->actual_length += num_bytes; |
| 831 | dspi->progress += num_bytes / DIV_ROUND_UP(xfer->bits_per_word, 8); | ||
| 665 | 832 | ||
| 666 | trans_mode = dspi->devtype_data->trans_mode; | 833 | /* |
| 667 | if (trans_mode == DSPI_EOQ_MODE) | 834 | * Update shared variable for use in the next interrupt (both in |
| 668 | dspi_eoq_read(dspi); | 835 | * dspi_fifo_read and in dspi_fifo_write). |
| 669 | else if (trans_mode == DSPI_TCFQ_MODE) | 836 | */ |
| 670 | dspi_tcfq_read(dspi); | 837 | dspi->words_in_flight = num_words; |
| 838 | |||
| 839 | spi_take_timestamp_pre(dspi->ctlr, xfer, dspi->progress, !dspi->irq); | ||
| 840 | |||
| 841 | if (dspi->devtype_data->trans_mode == DSPI_EOQ_MODE) | ||
| 842 | dspi_eoq_fifo_write(dspi, num_words); | ||
| 843 | else | ||
| 844 | dspi_xspi_fifo_write(dspi, num_words); | ||
| 845 | /* | ||
| 846 | * Everything after this point is in a potential race with the next | ||
| 847 | * interrupt, so we must never use dspi->words_in_flight again since it | ||
| 848 | * might already be modified by the next dspi_fifo_write. | ||
| 849 | */ | ||
| 850 | |||
| 851 | spi_take_timestamp_post(dspi->ctlr, dspi->cur_transfer, | ||
| 852 | dspi->progress, !dspi->irq); | ||
| 853 | } | ||
| 854 | |||
| 855 | static int dspi_rxtx(struct fsl_dspi *dspi) | ||
| 856 | { | ||
| 857 | dspi_fifo_read(dspi); | ||
| 671 | 858 | ||
| 672 | if (!dspi->len) | 859 | if (!dspi->len) |
| 673 | /* Success! */ | 860 | /* Success! */ |
| 674 | return 0; | 861 | return 0; |
| 675 | 862 | ||
| 676 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, | 863 | dspi_fifo_write(dspi); |
| 677 | dspi->progress, !dspi->irq); | ||
| 678 | |||
| 679 | if (trans_mode == DSPI_EOQ_MODE) | ||
| 680 | dspi_eoq_write(dspi); | ||
| 681 | else if (trans_mode == DSPI_TCFQ_MODE) | ||
| 682 | dspi_tcfq_write(dspi); | ||
| 683 | 864 | ||
| 684 | return -EINPROGRESS; | 865 | return -EINPROGRESS; |
| 685 | } | 866 | } |
| @@ -693,7 +874,7 @@ static int dspi_poll(struct fsl_dspi *dspi) · 7 unmodified lines | |||
| 693 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | 874 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); |
| 694 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | 875 | regmap_write(dspi->regmap, SPI_SR, spi_sr); |
| 695 | 876 | ||
| 696 | if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) | 877 | if (spi_sr & (SPI_SR_EOQF | SPI_SR_CMDTCF)) |
| 697 | break; | 878 | break; |
| 698 | } while (--tries); | 879 | } while (--tries); |
| 699 | 880 | ||
| @@ -711,13 +892,11 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) · 11 unmodified lines | |||
| 711 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); | 892 | regmap_read(dspi->regmap, SPI_SR, &spi_sr); |
| 712 | regmap_write(dspi->regmap, SPI_SR, spi_sr); | 893 | regmap_write(dspi->regmap, SPI_SR, spi_sr); |
| 713 | 894 | ||
| 714 | if (!(spi_sr & SPI_SR_EOQF)) | 895 | if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_CMDTCF))) |
| 715 | return IRQ_NONE; | 896 | return IRQ_NONE; |
| 716 | 897 | ||
| 717 | if (dspi_rxtx(dspi) == 0) { | 898 | if (dspi_rxtx(dspi) == 0) |
| 718 | dspi->waitflags = 1; | 899 | complete(&dspi->xfer_done); |
| 719 | wake_up_interruptible(&dspi->waitq); | ||
| 720 | } | ||
| 721 | 900 | ||
| 722 | return IRQ_HANDLED; | 901 | return IRQ_HANDLED; |
| 723 | } | 902 | } |
| @@ -727,7 +906,6 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 3 unmodified lines | |||
| 727 | { | 906 | { |
| 728 | struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); | 907 | struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); |
| 729 | struct spi_device *spi = message->spi; | 908 | struct spi_device *spi = message->spi; |
| 730 | enum dspi_trans_mode trans_mode; | ||
| 731 | struct spi_transfer *transfer; | 909 | struct spi_transfer *transfer; |
| 732 | int status = 0; | 910 | int status = 0; |
| 733 | 911 | ||
| @@ -757,76 +935,38 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr, · 23 unmodified lines | |||
| 757 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; | 935 | dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; |
| 758 | } | 936 | } |
| 759 | 937 | ||
| 760 | dspi->void_write_data = dspi->cur_chip->void_write_data; | ||
| 761 | |||
| 762 | dspi->tx = transfer->tx_buf; | 938 | dspi->tx = transfer->tx_buf; |
| 763 | dspi->rx = transfer->rx_buf; | 939 | dspi->rx = transfer->rx_buf; |
| 764 | dspi->rx_end = dspi->rx + transfer->len; | ||
| 765 | dspi->len = transfer->len; | 940 | dspi->len = transfer->len; |
| 766 | dspi->progress = 0; | 941 | dspi->progress = 0; |
| 767 | /* Validated transfer specific frame size (defaults applied) */ | ||
| 768 | dspi->bits_per_word = transfer->bits_per_word; | ||
| 769 | if (transfer->bits_per_word <= 8) | ||
| 770 | dspi->bytes_per_word = 1; | ||
| 771 | else if (transfer->bits_per_word <= 16) | ||
| 772 | dspi->bytes_per_word = 2; | ||
| 773 | else | ||
| 774 | dspi->bytes_per_word = 4; | ||
| 775 | 942 | ||
| 776 | regmap_update_bits(dspi->regmap, SPI_MCR, | 943 | regmap_update_bits(dspi->regmap, SPI_MCR, |
| 777 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, | 944 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, |
| 778 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | 945 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); |
| 779 | regmap_write(dspi->regmap, SPI_CTAR(0), | ||
| 780 | dspi->cur_chip->ctar_val | | ||
| 781 | SPI_FRAME_BITS(transfer->bits_per_word)); | ||
| 782 | if (dspi->devtype_data->xspi_mode) | ||
| 783 | regmap_write(dspi->regmap, SPI_CTARE(0), | ||
| 784 | SPI_FRAME_EBITS(transfer->bits_per_word) | | ||
| 785 | SPI_CTARE_DTCP(1)); | ||
| 786 | 946 | ||
| 787 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, | 947 | spi_take_timestamp_pre(dspi->ctlr, dspi->cur_transfer, |
| 788 | dspi->progress, !dspi->irq); | 948 | dspi->progress, !dspi->irq); |
| 789 | 949 | ||
| 790 | trans_mode = dspi->devtype_data->trans_mode; | 950 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
| 791 | switch (trans_mode) { | ||
| 792 | case DSPI_EOQ_MODE: | ||
| 793 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); | ||
| 794 | dspi_eoq_write(dspi); | ||
| 795 | break; | ||
| 796 | case DSPI_TCFQ_MODE: | ||
| 797 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE); | ||
| 798 | dspi_tcfq_write(dspi); | ||
| 799 | break; | ||
| 800 | case DSPI_DMA_MODE: | ||
| 801 | regmap_write(dspi->regmap, SPI_RSER, | ||
| 802 | SPI_RSER_TFFFE | SPI_RSER_TFFFD | | ||
| 803 | SPI_RSER_RFDFE | SPI_RSER_RFDFD); | ||
| 804 | status = dspi_dma_xfer(dspi); | 951 | status = dspi_dma_xfer(dspi); |
| 805 | break; | 952 | } else { |
| 806 | default: | 953 | dspi_fifo_write(dspi); |
| 807 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", | 954 | |
| 808 | trans_mode); | 955 | if (dspi->irq) { |
| 809 | status = -EINVAL; | 956 | wait_for_completion(&dspi->xfer_done); |
| 810 | goto out; | 957 | reinit_completion(&dspi->xfer_done); |
| 811 | } | 958 | } else { |
| 812 | 959 | do { | |
| 813 | if (!dspi->irq) { | 960 | status = dspi_poll(dspi); |
| 814 | do { | 961 | } while (status == -EINPROGRESS); |
| 815 | status = dspi_poll(dspi); | 962 | } |
| 816 | } while (status == -EINPROGRESS); | ||
| 817 | } else if (trans_mode != DSPI_DMA_MODE) { | ||
| 818 | status = wait_event_interruptible(dspi->waitq, | ||
| 819 | dspi->waitflags); | ||
| 820 | dspi->waitflags = 0; | ||
| 821 | } | 963 | } |
| 822 | if (status) | 964 | if (status) |
| 823 | dev_err(&dspi->pdev->dev, | 965 | break; |
| 824 | "Waiting for transfer to complete failed!\n"); | ||
| 825 | 966 | ||
| 826 | spi_transfer_delay_exec(transfer); | 967 | spi_transfer_delay_exec(transfer); |
| 827 | } | 968 | } |
| 828 | 969 | ||
| 829 | out: | ||
| 830 | message->status = status; | 970 | message->status = status; |
| 831 | spi_finalize_current_message(ctlr); | 971 | spi_finalize_current_message(ctlr); |
| 832 | 972 | ||
| @@ -864,8 +1004,6 @@ static int dspi_setup(struct spi_device *spi) · 31 unmodified lines | |||
| 864 | sck_cs_delay = pdata->sck_cs_delay; | 1004 | sck_cs_delay = pdata->sck_cs_delay; |
| 865 | } | 1005 | } |
| 866 | 1006 | ||
| 867 | chip->void_write_data = 0; | ||
| 868 | |||
| 869 | clkrate = clk_get_rate(dspi->clk); | 1007 | clkrate = clk_get_rate(dspi->clk); |
| 870 | hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); | 1008 | hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); |
| 871 | 1009 | ||
| @@ -909,9 +1047,34 @@ static void dspi_cleanup(struct spi_device *spi) · 37 unmodified lines | |||
| 909 | } | 1047 | } |
| 910 | 1048 | ||
| 911 | static const struct of_device_id fsl_dspi_dt_ids[] = { | 1049 | static const struct of_device_id fsl_dspi_dt_ids[] = { |
| 912 | { .compatible = "fsl,vf610-dspi", .data = &vf610_data, }, | 1050 | { |
| 913 | { .compatible = "fsl,ls1021a-v1.0-dspi", .data = &ls1021a_v1_data, }, | 1051 | .compatible = "fsl,vf610-dspi", |
| 914 | { .compatible = "fsl,ls2085a-dspi", .data = &ls2085a_data, }, | 1052 | .data = &devtype_data[VF610], |
| 1053 | }, { | ||
| 1054 | .compatible = "fsl,ls1021a-v1.0-dspi", | ||
| 1055 | .data = &devtype_data[LS1021A], | ||
| 1056 | }, { | ||
| 1057 | .compatible = "fsl,ls1012a-dspi", | ||
| 1058 | .data = &devtype_data[LS1012A], | ||
| 1059 | }, { | ||
| 1060 | .compatible = "fsl,ls1028a-dspi", | ||
| 1061 | .data = &devtype_data[LS1028A], | ||
| 1062 | }, { | ||
| 1063 | .compatible = "fsl,ls1043a-dspi", | ||
| 1064 | .data = &devtype_data[LS1043A], | ||
| 1065 | }, { | ||
| 1066 | .compatible = "fsl,ls1046a-dspi", | ||
| 1067 | .data = &devtype_data[LS1046A], | ||
| 1068 | }, { | ||
| 1069 | .compatible = "fsl,ls2080a-dspi", | ||
| 1070 | .data = &devtype_data[LS2080A], | ||
| 1071 | }, { | ||
| 1072 | .compatible = "fsl,ls2085a-dspi", | ||
| 1073 | .data = &devtype_data[LS2085A], | ||
| 1074 | }, { | ||
| 1075 | .compatible = "fsl,lx2160a-dspi", | ||
| 1076 | .data = &devtype_data[LX2160A], | ||
| 1077 | }, | ||
| 915 | { /* sentinel */ } | 1078 | { /* sentinel */ } |
| 916 | }; | 1079 | }; |
| 917 | MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); | 1080 | MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); |
| @@ -997,20 +1160,40 @@ static const struct regmap_config dspi_xspi_regmap_config[] = { · 79 unmodified lines | |||
| 997 | }, | 1160 | }, |
| 998 | }; | 1161 | }; |
| 999 | 1162 | ||
| 1000 | static void dspi_init(struct fsl_dspi *dspi) | 1163 | static int dspi_init(struct fsl_dspi *dspi) |
| 1001 | { | 1164 | { |
| 1002 | unsigned int mcr = SPI_MCR_PCSIS; | 1165 | unsigned int mcr; |
| 1166 | |||
| 1167 | /* Set idle states for all chip select signals to high */ | ||
| 1168 | mcr = SPI_MCR_PCSIS(GENMASK(dspi->ctlr->num_chipselect - 1, 0)); | ||
| 1003 | 1169 | ||
| 1004 | if (dspi->devtype_data->xspi_mode) | 1170 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
| 1005 | mcr |= SPI_MCR_XSPI; | 1171 | mcr |= SPI_MCR_XSPI; |
| 1006 | if (!spi_controller_is_slave(dspi->ctlr)) | 1172 | if (!spi_controller_is_slave(dspi->ctlr)) |
| 1007 | mcr |= SPI_MCR_MASTER; | 1173 | mcr |= SPI_MCR_MASTER; |
| 1008 | 1174 | ||
| 1009 | regmap_write(dspi->regmap, SPI_MCR, mcr); | 1175 | regmap_write(dspi->regmap, SPI_MCR, mcr); |
| 1010 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); | 1176 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR); |
| 1011 | if (dspi->devtype_data->xspi_mode) | 1177 | |
| 1012 | regmap_write(dspi->regmap, SPI_CTARE(0), | 1178 | switch (dspi->devtype_data->trans_mode) { |
| 1013 | SPI_CTARE_FMSZE(0) | SPI_CTARE_DTCP(1)); | 1179 | case DSPI_EOQ_MODE: |
| 1180 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); | ||
| 1181 | break; | ||
| 1182 | case DSPI_XSPI_MODE: | ||
| 1183 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_CMDTCFE); | ||
| 1184 | break; | ||
| 1185 | case DSPI_DMA_MODE: | ||
| 1186 | regmap_write(dspi->regmap, SPI_RSER, | ||
| 1187 | SPI_RSER_TFFFE | SPI_RSER_TFFFD | | ||
| 1188 | SPI_RSER_RFDFE | SPI_RSER_RFDFD); | ||
| 1189 | break; | ||
| 1190 | default: | ||
| 1191 | dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n", | ||
| 1192 | dspi->devtype_data->trans_mode); | ||
| 1193 | return -EINVAL; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | return 0; | ||
| 1014 | } | 1197 | } |
| 1015 | 1198 | ||
| 1016 | static int dspi_slave_abort(struct spi_master *master) | 1199 | static int dspi_slave_abort(struct spi_master *master) |
| @@ -1021,8 +1204,10 @@ static int dspi_slave_abort(struct spi_master *master) · 4 unmodified lines | |||
| 1021 | * Terminate all pending DMA transactions for the SPI working | 1204 | * Terminate all pending DMA transactions for the SPI working |
| 1022 | * in SLAVE mode. | 1205 | * in SLAVE mode. |
| 1023 | */ | 1206 | */ |
| 1024 | dmaengine_terminate_sync(dspi->dma->chan_rx); | 1207 | if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { |
| 1025 | dmaengine_terminate_sync(dspi->dma->chan_tx); | 1208 | dmaengine_terminate_sync(dspi->dma->chan_rx); |
| 1209 | dmaengine_terminate_sync(dspi->dma->chan_tx); | ||
| 1210 | } | ||
| 1026 | 1211 | ||
| 1027 | /* Clear the internal DSPI RX and TX FIFO buffers */ | 1212 | /* Clear the internal DSPI RX and TX FIFO buffers */ |
| 1028 | regmap_update_bits(dspi->regmap, SPI_MCR, | 1213 | regmap_update_bits(dspi->regmap, SPI_MCR, |
| @@ -1032,16 +1217,33 @@ static int dspi_slave_abort(struct spi_master *master) · 3 unmodified lines | |||
| 1032 | return 0; | 1217 | return 0; |
| 1033 | } | 1218 | } |
| 1034 | 1219 | ||
| 1220 | /* | ||
| 1221 | * EOQ mode will inevitably deassert its PCS signal on last word in a queue | ||
| 1222 | * (hardware limitation), so we need to inform the spi_device that larger | ||
| 1223 | * buffers than the FIFO size are going to have the chip select randomly | ||
| 1224 | * toggling, so it has a chance to adapt its message sizes. | ||
| 1225 | */ | ||
| 1226 | static size_t dspi_max_message_size(struct spi_device *spi) | ||
| 1227 | { | ||
| 1228 | struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller); | ||
| 1229 | |||
| 1230 | if (dspi->devtype_data->trans_mode == DSPI_EOQ_MODE) | ||
| 1231 | return dspi->devtype_data->fifo_size; | ||
| 1232 | |||
| 1233 | return SIZE_MAX; | ||
| 1234 | } | ||
| 1235 | |||
| 1035 | static int dspi_probe(struct platform_device *pdev) | 1236 | static int dspi_probe(struct platform_device *pdev) |
| 1036 | { | 1237 | { |
| 1037 | struct device_node *np = pdev->dev.of_node; | 1238 | struct device_node *np = pdev->dev.of_node; |
| 1038 | const struct regmap_config *regmap_config; | 1239 | const struct regmap_config *regmap_config; |
| 1039 | struct fsl_dspi_platform_data *pdata; | 1240 | struct fsl_dspi_platform_data *pdata; |
| 1040 | struct spi_controller *ctlr; | 1241 | struct spi_controller *ctlr; |
| 1041 | int ret, cs_num, bus_num; | 1242 | int ret, cs_num, bus_num = -1; |
| 1042 | struct fsl_dspi *dspi; | 1243 | struct fsl_dspi *dspi; |
| 1043 | struct resource *res; | 1244 | struct resource *res; |
| 1044 | void __iomem *base; | 1245 | void __iomem *base; |
| 1246 | bool big_endian; | ||
| 1045 | 1247 | ||
| 1046 | ctlr = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); | 1248 | ctlr = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); |
| 1047 | if (!ctlr) | 1249 | if (!ctlr) |
| @@ -1053,6 +1255,7 @@ static int dspi_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 1053 | 1255 | ||
| 1054 | ctlr->setup = dspi_setup; | 1256 | ctlr->setup = dspi_setup; |
| 1055 | ctlr->transfer_one_message = dspi_transfer_one_message; | 1257 | ctlr->transfer_one_message = dspi_transfer_one_message; |
| 1258 | ctlr->max_message_size = dspi_max_message_size; | ||
| 1056 | ctlr->dev.of_node = pdev->dev.of_node; | 1259 | ctlr->dev.of_node = pdev->dev.of_node; |
| 1057 | 1260 | ||
| 1058 | ctlr->cleanup = dspi_cleanup; | 1261 | ctlr->cleanup = dspi_cleanup; |
| @@ -1064,7 +1267,9 @@ static int dspi_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 1064 | ctlr->num_chipselect = pdata->cs_num; | 1267 | ctlr->num_chipselect = pdata->cs_num; |
| 1065 | ctlr->bus_num = pdata->bus_num; | 1268 | ctlr->bus_num = pdata->bus_num; |
| 1066 | 1269 | ||
| 1067 | dspi->devtype_data = &coldfire_data; | 1270 | /* Only Coldfire uses platform data */ |
| 1271 | dspi->devtype_data = &devtype_data[MCF5441X]; | ||
| 1272 | big_endian = true; | ||
| 1068 | } else { | 1273 | } else { |
| 1069 | 1274 | ||
| 1070 | ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); | 1275 | ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); |
| @@ -1074,11 +1279,7 @@ static int dspi_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 1074 | } | 1279 | } |
| 1075 | ctlr->num_chipselect = cs_num; | 1280 | ctlr->num_chipselect = cs_num; |
| 1076 | 1281 | ||
| 1077 | ret = of_property_read_u32(np, "bus-num", &bus_num); | 1282 | of_property_read_u32(np, "bus-num", &bus_num); |
| 1078 | if (ret < 0) { | ||
| 1079 | dev_err(&pdev->dev, "can't get bus-num\n"); | ||
| 1080 | goto out_ctlr_put; | ||
| 1081 | } | ||
| 1082 | ctlr->bus_num = bus_num; | 1283 | ctlr->bus_num = bus_num; |
| 1083 | 1284 | ||
| 1084 | if (of_property_read_bool(np, "spi-slave")) | 1285 | if (of_property_read_bool(np, "spi-slave")) |
| @@ -1090,9 +1291,18 @@ static int dspi_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 1090 | ret = -EFAULT; | 1291 | ret = -EFAULT; |
| 1091 | goto out_ctlr_put; | 1292 | goto out_ctlr_put; |
| 1092 | } | 1293 | } |
| 1294 | |||
| 1295 | big_endian = of_device_is_big_endian(np); | ||
| 1296 | } | ||
| 1297 | if (big_endian) { | ||
| 1298 | dspi->pushr_cmd = 0; | ||
| 1299 | dspi->pushr_tx = 2; | ||
| 1300 | } else { | ||
| 1301 | dspi->pushr_cmd = 2; | ||
| 1302 | dspi->pushr_tx = 0; | ||
| 1093 | } | 1303 | } |
| 1094 | 1304 | ||
| 1095 | if (dspi->devtype_data->xspi_mode) | 1305 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
| 1096 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | 1306 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
| 1097 | else | 1307 | else |
| 1098 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | 1308 | ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
| @@ -1104,7 +1314,7 @@ static int dspi_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 1104 | goto out_ctlr_put; | 1314 | goto out_ctlr_put; |
| 1105 | } | 1315 | } |
| 1106 | 1316 | ||
| 1107 | if (dspi->devtype_data->xspi_mode) | 1317 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) |
| 1108 | regmap_config = &dspi_xspi_regmap_config[0]; | 1318 | regmap_config = &dspi_xspi_regmap_config[0]; |
| 1109 | else | 1319 | else |
| 1110 | regmap_config = &dspi_regmap_config; | 1320 | regmap_config = &dspi_regmap_config; |
| @@ -1116,7 +1326,7 @@ static int dspi_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 1116 | goto out_ctlr_put; | 1326 | goto out_ctlr_put; |
| 1117 | } | 1327 | } |
| 1118 | 1328 | ||
| 1119 | if (dspi->devtype_data->xspi_mode) { | 1329 | if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE) { |
| 1120 | dspi->regmap_pushr = devm_regmap_init_mmio( | 1330 | dspi->regmap_pushr = devm_regmap_init_mmio( |
| 1121 | &pdev->dev, base + SPI_PUSHR, | 1331 | &pdev->dev, base + SPI_PUSHR, |
| 1122 | &dspi_xspi_regmap_config[1]); | 1332 | &dspi_xspi_regmap_config[1]); |
| @@ -1139,10 +1349,9 @@ static int dspi_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 1139 | if (ret) | 1349 | if (ret) |
| 1140 | goto out_ctlr_put; | 1350 | goto out_ctlr_put; |
| 1141 | 1351 | ||
| 1142 | dspi_init(dspi); | 1352 | ret = dspi_init(dspi); |
| 1143 | 1353 | if (ret) | |
| 1144 | if (dspi->devtype_data->trans_mode == DSPI_TCFQ_MODE) | 1354 | goto out_clk_put; |
| 1145 | goto poll_mode; | ||
| 1146 | 1355 | ||
| 1147 | dspi->irq = platform_get_irq(pdev, 0); | 1356 | dspi->irq = platform_get_irq(pdev, 0); |
| 1148 | if (dspi->irq <= 0) { | 1357 | if (dspi->irq <= 0) { |
| @@ -1159,7 +1368,7 @@ static int dspi_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 1159 | goto out_clk_put; | 1368 | goto out_clk_put; |
| 1160 | } | 1369 | } |
| 1161 | 1370 | ||
| 1162 | init_waitqueue_head(&dspi->waitq); | 1371 | init_completion(&dspi->xfer_done); |
| 1163 | 1372 | ||
| 1164 | poll_mode: | 1373 | poll_mode: |
| 1165 | 1374 | ||
| @@ -1174,7 +1383,8 @@ poll_mode: · 8 unmodified lines | |||
| 1174 | ctlr->max_speed_hz = | 1383 | ctlr->max_speed_hz = |
| 1175 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; | 1384 | clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; |
| 1176 | 1385 | ||
| 1177 | ctlr->ptp_sts_supported = dspi->devtype_data->ptp_sts_supported; | 1386 | if (dspi->devtype_data->trans_mode != DSPI_DMA_MODE) |
| 1387 | ctlr->ptp_sts_supported = true; | ||
| 1178 | 1388 | ||
| 1179 | platform_set_drvdata(pdev, ctlr); | 1389 | platform_set_drvdata(pdev, ctlr); |
| 1180 | 1390 | ||
| @@ -86,8 +86,6 @@ · 85 unmodified lines | |||
| 86 | #define TCR_RXMSK BIT(19) | 86 | #define TCR_RXMSK BIT(19) |
| 87 | #define TCR_TXMSK BIT(18) | 87 | #define TCR_TXMSK BIT(18) |
| 88 | 88 | ||
| 89 | static int clkdivs[] = {1, 2, 4, 8, 16, 32, 64, 128}; | ||
| 90 | |||
| 91 | struct lpspi_config { | 89 | struct lpspi_config { |
| 92 | u8 bpw; | 90 | u8 bpw; |
| 93 | u8 chip_select; | 91 | u8 chip_select; |
| @@ -125,7 +123,7 @@ struct fsl_lpspi_data { · 31 unmodified lines | |||
| 125 | struct completion dma_rx_completion; | 123 | struct completion dma_rx_completion; |
| 126 | struct completion dma_tx_completion; | 124 | struct completion dma_tx_completion; |
| 127 | 125 | ||
| 128 | int chipselect[0]; | 126 | int chipselect[]; |
| 129 | }; | 127 | }; |
| 130 | 128 | ||
| 131 | static const struct of_device_id fsl_lpspi_dt_ids[] = { | 129 | static const struct of_device_id fsl_lpspi_dt_ids[] = { |
| @@ -331,15 +329,14 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) · 199 unmodified lines | |||
| 331 | } | 329 | } |
| 332 | 330 | ||
| 333 | for (prescale = 0; prescale < 8; prescale++) { | 331 | for (prescale = 0; prescale < 8; prescale++) { |
| 334 | scldiv = perclk_rate / | 332 | scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2; |
| 335 | (clkdivs[prescale] * config.speed_hz) - 2; | ||
| 336 | if (scldiv < 256) { | 333 | if (scldiv < 256) { |
| 337 | fsl_lpspi->config.prescale = prescale; | 334 | fsl_lpspi->config.prescale = prescale; |
| 338 | break; | 335 | break; |
| 339 | } | 336 | } |
| 340 | } | 337 | } |
| 341 | 338 | ||
| 342 | if (prescale == 8 && scldiv >= 256) | 339 | if (scldiv >= 256) |
| 343 | return -EINVAL; | 340 | return -EINVAL; |
| 344 | 341 | ||
| 345 | writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16), | 342 | writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16), |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | |||
| 6 | #include <linux/io.h> | 6 | #include <linux/io.h> |
| 7 | #include <linux/log2.h> | 7 | #include <linux/log2.h> |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/of.h> | ||
| 10 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
| 11 | #include <linux/pm_runtime.h> | 10 | #include <linux/pm_runtime.h> |
| 12 | #include <linux/qcom-geni-se.h> | 11 | #include <linux/qcom-geni-se.h> |
| @@ -536,6 +535,7 @@ static int spi_geni_probe(struct platform_device *pdev) · 523 unmodified lines | |||
| 536 | struct spi_geni_master *mas; | 535 | struct spi_geni_master *mas; |
| 537 | void __iomem *base; | 536 | void __iomem *base; |
| 538 | struct clk *clk; | 537 | struct clk *clk; |
| 538 | struct device *dev = &pdev->dev; | ||
| 539 | 539 | ||
| 540 | irq = platform_get_irq(pdev, 0); | 540 | irq = platform_get_irq(pdev, 0); |
| 541 | if (irq < 0) | 541 | if (irq < 0) |
| @@ -545,28 +545,25 @@ static int spi_geni_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 545 | if (IS_ERR(base)) | 545 | if (IS_ERR(base)) |
| 546 | return PTR_ERR(base); | 546 | return PTR_ERR(base); |
| 547 | 547 | ||
| 548 | clk = devm_clk_get(&pdev->dev, "se"); | 548 | clk = devm_clk_get(dev, "se"); |
| 549 | if (IS_ERR(clk)) { | 549 | if (IS_ERR(clk)) |
| 550 | dev_err(&pdev->dev, "Err getting SE Core clk %ld\n", | ||
| 551 | PTR_ERR(clk)); | ||
| 552 | return PTR_ERR(clk); | 550 | return PTR_ERR(clk); |
| 553 | } | ||
| 554 | 551 | ||
| 555 | spi = spi_alloc_master(&pdev->dev, sizeof(*mas)); | 552 | spi = spi_alloc_master(dev, sizeof(*mas)); |
| 556 | if (!spi) | 553 | if (!spi) |
| 557 | return -ENOMEM; | 554 | return -ENOMEM; |
| 558 | 555 | ||
| 559 | platform_set_drvdata(pdev, spi); | 556 | platform_set_drvdata(pdev, spi); |
| 560 | mas = spi_master_get_devdata(spi); | 557 | mas = spi_master_get_devdata(spi); |
| 561 | mas->irq = irq; | 558 | mas->irq = irq; |
| 562 | mas->dev = &pdev->dev; | 559 | mas->dev = dev; |
| 563 | mas->se.dev = &pdev->dev; | 560 | mas->se.dev = dev; |
| 564 | mas->se.wrapper = dev_get_drvdata(pdev->dev.parent); | 561 | mas->se.wrapper = dev_get_drvdata(dev->parent); |
| 565 | mas->se.base = base; | 562 | mas->se.base = base; |
| 566 | mas->se.clk = clk; | 563 | mas->se.clk = clk; |
| 567 | 564 | ||
| 568 | spi->bus_num = -1; | 565 | spi->bus_num = -1; |
| 569 | spi->dev.of_node = pdev->dev.of_node; | 566 | spi->dev.of_node = dev->of_node; |
| 570 | spi->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH; | 567 | spi->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH; |
| 571 | spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | 568 | spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
| 572 | spi->num_chipselect = 4; | 569 | spi->num_chipselect = 4; |
| @@ -579,14 +576,13 @@ static int spi_geni_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 579 | 576 | ||
| 580 | init_completion(&mas->xfer_done); | 577 | init_completion(&mas->xfer_done); |
| 581 | spin_lock_init(&mas->lock); | 578 | spin_lock_init(&mas->lock); |
| 582 | pm_runtime_enable(&pdev->dev); | 579 | pm_runtime_enable(dev); |
| 583 | 580 | ||
| 584 | ret = spi_geni_init(mas); | 581 | ret = spi_geni_init(mas); |
| 585 | if (ret) | 582 | if (ret) |
| 586 | goto spi_geni_probe_runtime_disable; | 583 | goto spi_geni_probe_runtime_disable; |
| 587 | 584 | ||
| 588 | ret = request_irq(mas->irq, geni_spi_isr, | 585 | ret = request_irq(mas->irq, geni_spi_isr, 0, dev_name(dev), spi); |
| 589 | IRQF_TRIGGER_HIGH, "spi_geni", spi); | ||
| 590 | if (ret) | 586 | if (ret) |
| 591 | goto spi_geni_probe_runtime_disable; | 587 | goto spi_geni_probe_runtime_disable; |
| 592 | 588 | ||
| @@ -598,7 +594,7 @@ static int spi_geni_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 598 | spi_geni_probe_free_irq: | 594 | spi_geni_probe_free_irq: |
| 599 | free_irq(mas->irq, spi); | 595 | free_irq(mas->irq, spi); |
| 600 | spi_geni_probe_runtime_disable: | 596 | spi_geni_probe_runtime_disable: |
| 601 | pm_runtime_disable(&pdev->dev); | 597 | pm_runtime_disable(dev); |
| 602 | spi_master_put(spi); | 598 | spi_master_put(spi); |
| 603 | return ret; | 599 | return ret; |
| 604 | } | 600 | } |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <linux/acpi.h> | 8 | #include <linux/acpi.h> |
| 9 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
| 10 | #include <linux/dmi.h> | ||
| 10 | #include <linux/iopoll.h> | 11 | #include <linux/iopoll.h> |
| 11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
| @@ -17,6 +18,12 @@ · 4 unmodified lines | |||
| 17 | #define HISI_SFC_V3XX_VERSION (0x1f8) | 18 | #define HISI_SFC_V3XX_VERSION (0x1f8) |
| 18 | 19 | ||
| 19 | #define HISI_SFC_V3XX_CMD_CFG (0x300) | 20 | #define HISI_SFC_V3XX_CMD_CFG (0x300) |
| 21 | #define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17) | ||
| 22 | #define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17) | ||
| 23 | #define HISI_SFC_V3XX_CMD_CFG_FULL_DIO (3 << 17) | ||
| 24 | #define HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT (5 << 17) | ||
| 25 | #define HISI_SFC_V3XX_CMD_CFG_QUAD_IO (6 << 17) | ||
| 26 | #define HISI_SFC_V3XX_CMD_CFG_FULL_QIO (7 << 17) | ||
| 20 | #define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9 | 27 | #define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9 |
| 21 | #define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8) | 28 | #define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8) |
| 22 | #define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7) | 29 | #define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7) |
| @@ -161,6 +168,43 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host, · 138 unmodified lines | |||
| 161 | if (op->addr.nbytes) | 168 | if (op->addr.nbytes) |
| 162 | config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK; | 169 | config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK; |
| 163 | 170 | ||
| 171 | switch (op->data.buswidth) { | ||
| 172 | case 0 ... 1: | ||
| 173 | break; | ||
| 174 | case 2: | ||
| 175 | if (op->addr.buswidth <= 1) { | ||
| 176 | config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT; | ||
| 177 | } else if (op->addr.buswidth == 2) { | ||
| 178 | if (op->cmd.buswidth <= 1) { | ||
| 179 | config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IO; | ||
| 180 | } else if (op->cmd.buswidth == 2) { | ||
| 181 | config |= HISI_SFC_V3XX_CMD_CFG_FULL_DIO; | ||
| 182 | } else { | ||
| 183 | return -EIO; | ||
| 184 | } | ||
| 185 | } else { | ||
| 186 | return -EIO; | ||
| 187 | } | ||
| 188 | break; | ||
| 189 | case 4: | ||
| 190 | if (op->addr.buswidth <= 1) { | ||
| 191 | config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT; | ||
| 192 | } else if (op->addr.buswidth == 4) { | ||
| 193 | if (op->cmd.buswidth <= 1) { | ||
| 194 | config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IO; | ||
| 195 | } else if (op->cmd.buswidth == 4) { | ||
| 196 | config |= HISI_SFC_V3XX_CMD_CFG_FULL_QIO; | ||
| 197 | } else { | ||
| 198 | return -EIO; | ||
| 199 | } | ||
| 200 | } else { | ||
| 201 | return -EIO; | ||
| 202 | } | ||
| 203 | break; | ||
| 204 | default: | ||
| 205 | return -EOPNOTSUPP; | ||
| 206 | } | ||
| 207 | |||
| 164 | if (op->data.dir != SPI_MEM_NO_DATA) { | 208 | if (op->data.dir != SPI_MEM_NO_DATA) { |
| 165 | config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF; | 209 | config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF; |
| 166 | config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK; | 210 | config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK; |
| @@ -207,6 +251,44 @@ static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = { · 40 unmodified lines | |||
| 207 | .exec_op = hisi_sfc_v3xx_exec_op, | 251 | .exec_op = hisi_sfc_v3xx_exec_op, |
| 208 | }; | 252 | }; |
| 209 | 253 | ||
| 254 | static int hisi_sfc_v3xx_buswidth_override_bits; | ||
| 255 | |||
| 256 | /* | ||
| 257 | * ACPI FW does not allow us to currently set the device buswidth, so quirk it | ||
| 258 | * depending on the board. | ||
| 259 | */ | ||
| 260 | static int __init hisi_sfc_v3xx_dmi_quirk(const struct dmi_system_id *d) | ||
| 261 | { | ||
| 262 | hisi_sfc_v3xx_buswidth_override_bits = SPI_RX_QUAD | SPI_TX_QUAD; | ||
| 263 | |||
| 264 | return 0; | ||
| 265 | } | ||
| 266 | |||
| 267 | static const struct dmi_system_id hisi_sfc_v3xx_dmi_quirk_table[] = { | ||
| 268 | { | ||
| 269 | .callback = hisi_sfc_v3xx_dmi_quirk, | ||
| 270 | .matches = { | ||
| 271 | DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), | ||
| 272 | DMI_MATCH(DMI_PRODUCT_NAME, "D06"), | ||
| 273 | }, | ||
| 274 | }, | ||
| 275 | { | ||
| 276 | .callback = hisi_sfc_v3xx_dmi_quirk, | ||
| 277 | .matches = { | ||
| 278 | DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), | ||
| 279 | DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 2280 V2"), | ||
| 280 | }, | ||
| 281 | }, | ||
| 282 | { | ||
| 283 | .callback = hisi_sfc_v3xx_dmi_quirk, | ||
| 284 | .matches = { | ||
| 285 | DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), | ||
| 286 | DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 200 (Model 2280)"), | ||
| 287 | }, | ||
| 288 | }, | ||
| 289 | {} | ||
| 290 | }; | ||
| 291 | |||
| 210 | static int hisi_sfc_v3xx_probe(struct platform_device *pdev) | 292 | static int hisi_sfc_v3xx_probe(struct platform_device *pdev) |
| 211 | { | 293 | { |
| 212 | struct device *dev = &pdev->dev; | 294 | struct device *dev = &pdev->dev; |
| @@ -222,6 +304,8 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 222 | ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | | 304 | ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | |
| 223 | SPI_TX_DUAL | SPI_TX_QUAD; | 305 | SPI_TX_DUAL | SPI_TX_QUAD; |
| 224 | 306 | ||
| 307 | ctlr->buswidth_override_bits = hisi_sfc_v3xx_buswidth_override_bits; | ||
| 308 | |||
| 225 | host = spi_controller_get_devdata(ctlr); | 309 | host = spi_controller_get_devdata(ctlr); |
| 226 | host->dev = dev; | 310 | host->dev = dev; |
| 227 | 311 | ||
| @@ -277,7 +361,20 @@ static struct platform_driver hisi_sfc_v3xx_spi_driver = { · 49 unmodified lines | |||
| 277 | .probe = hisi_sfc_v3xx_probe, | 361 | .probe = hisi_sfc_v3xx_probe, |
| 278 | }; | 362 | }; |
| 279 | 363 | ||
| 280 | module_platform_driver(hisi_sfc_v3xx_spi_driver); | 364 | static int __init hisi_sfc_v3xx_spi_init(void) |
| 365 | { | ||
| 366 | dmi_check_system(hisi_sfc_v3xx_dmi_quirk_table); | ||
| 367 | |||
| 368 | return platform_driver_register(&hisi_sfc_v3xx_spi_driver); | ||
| 369 | } | ||
| 370 | |||
| 371 | static void __exit hisi_sfc_v3xx_spi_exit(void) | ||
| 372 | { | ||
| 373 | platform_driver_unregister(&hisi_sfc_v3xx_spi_driver); | ||
| 374 | } | ||
| 375 | |||
| 376 | module_init(hisi_sfc_v3xx_spi_init); | ||
| 377 | module_exit(hisi_sfc_v3xx_spi_exit); | ||
| 281 | 378 | ||
| 282 | MODULE_LICENSE("GPL"); | 379 | MODULE_LICENSE("GPL"); |
| 283 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); | 380 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); |
| @@ -418,12 +418,13 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) · 417 unmodified lines | |||
| 418 | struct spi_controller *ctlr = mem->spi->controller; | 418 | struct spi_controller *ctlr = mem->spi->controller; |
| 419 | size_t len; | 419 | size_t len; |
| 420 | 420 | ||
| 421 | len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; | ||
| 422 | |||
| 423 | if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size) | 421 | if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size) |
| 424 | return ctlr->mem_ops->adjust_op_size(mem, op); | 422 | return ctlr->mem_ops->adjust_op_size(mem, op); |
| 425 | 423 | ||
| 426 | if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) { | 424 | if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) { |
| 425 | len = sizeof(op->cmd.opcode) + op->addr.nbytes + | ||
| 426 | op->dummy.nbytes; | ||
| 427 | |||
| 427 | if (len > spi_max_transfer_size(mem->spi)) | 428 | if (len > spi_max_transfer_size(mem->spi)) |
| 428 | return -EINVAL; | 429 | return -EINVAL; |
| 429 | 430 | ||
| @@ -487,7 +488,7 @@ static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc, · 57 unmodified lines | |||
| 487 | * This function is creating a direct mapping descriptor which can then be used | 488 | * This function is creating a direct mapping descriptor which can then be used |
| 488 | * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write(). | 489 | * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write(). |
| 489 | * If the SPI controller driver does not support direct mapping, this function | 490 | * If the SPI controller driver does not support direct mapping, this function |
| 490 | * fallback to an implementation using spi_mem_exec_op(), so that the caller | 491 | * falls back to an implementation using spi_mem_exec_op(), so that the caller |
| 491 | * doesn't have to bother implementing a fallback on his own. | 492 | * doesn't have to bother implementing a fallback on his own. |
| 492 | * | 493 | * |
| 493 | * Return: a valid pointer in case of success, and ERR_PTR() otherwise. | 494 | * Return: a valid pointer in case of success, and ERR_PTR() otherwise. |
| @@ -9,11 +9,13 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/bitfield.h> | 10 | #include <linux/bitfield.h> |
| 11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 12 | #include <linux/clk-provider.h> | ||
| 12 | #include <linux/device.h> | 13 | #include <linux/device.h> |
| 13 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 16 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/of_device.h> | ||
| 17 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 18 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
| 19 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| @@ -33,7 +35,6 @@ · 13 unmodified lines | |||
| 33 | * to have a CS go down over the full transfer | 35 | * to have a CS go down over the full transfer |
| 34 | */ | 36 | */ |
| 35 | 37 | ||
| 36 | #define SPICC_MAX_FREQ 30000000 | ||
| 37 | #define SPICC_MAX_BURST 128 | 38 | #define SPICC_MAX_BURST 128 |
| 38 | 39 | ||
| 39 | /* Register Map */ | 40 | /* Register Map */ |
| @@ -105,7 +106,21 @@ · 65 unmodified lines | |||
| 105 | #define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */ | 106 | #define SPICC_SWAP_RO BIT(14) /* RX FIFO Data Swap Read-Only */ |
| 106 | #define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */ | 107 | #define SPICC_SWAP_W1 BIT(15) /* RX FIFO Data Swap Write-Only */ |
| 107 | #define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */ | 108 | #define SPICC_DLYCTL_RO_MASK GENMASK(20, 15) /* Delay Control Read-Only */ |
| 108 | #define SPICC_DLYCTL_W1_MASK GENMASK(21, 16) /* Delay Control Write-Only */ | 109 | #define SPICC_MO_DELAY_MASK GENMASK(17, 16) /* Master Output Delay */ |
| 110 | #define SPICC_MO_NO_DELAY 0 | ||
| 111 | #define SPICC_MO_DELAY_1_CYCLE 1 | ||
| 112 | #define SPICC_MO_DELAY_2_CYCLE 2 | ||
| 113 | #define SPICC_MO_DELAY_3_CYCLE 3 | ||
| 114 | #define SPICC_MI_DELAY_MASK GENMASK(19, 18) /* Master Input Delay */ | ||
| 115 | #define SPICC_MI_NO_DELAY 0 | ||
| 116 | #define SPICC_MI_DELAY_1_CYCLE 1 | ||
| 117 | #define SPICC_MI_DELAY_2_CYCLE 2 | ||
| 118 | #define SPICC_MI_DELAY_3_CYCLE 3 | ||
| 119 | #define SPICC_MI_CAP_DELAY_MASK GENMASK(21, 20) /* Master Capture Delay */ | ||
| 120 | #define SPICC_CAP_AHEAD_2_CYCLE 0 | ||
| 121 | #define SPICC_CAP_AHEAD_1_CYCLE 1 | ||
| 122 | #define SPICC_CAP_NO_DELAY 2 | ||
| 123 | #define SPICC_CAP_DELAY_1_CYCLE 3 | ||
| 109 | #define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */ | 124 | #define SPICC_FIFORST_RO_MASK GENMASK(22, 21) /* FIFO Softreset Read-Only */ |
| 110 | #define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */ | 125 | #define SPICC_FIFORST_W1_MASK GENMASK(23, 22) /* FIFO Softreset Write-Only */ |
| 111 | 126 | ||
| @@ -113,31 +128,59 @@ · 1 unmodified line | |||
| 113 | 128 | ||
| 114 | #define SPICC_DWADDR 0x24 /* Write Address of DMA */ | 129 | #define SPICC_DWADDR 0x24 /* Write Address of DMA */ |
| 115 | 130 | ||
| 131 | #define SPICC_ENH_CTL0 0x38 /* Enhanced Feature */ | ||
| 132 | #define SPICC_ENH_CLK_CS_DELAY_MASK GENMASK(15, 0) | ||
| 133 | #define SPICC_ENH_DATARATE_MASK GENMASK(23, 16) | ||
| 134 | #define SPICC_ENH_DATARATE_EN BIT(24) | ||
| 135 | #define SPICC_ENH_MOSI_OEN BIT(25) | ||
| 136 | #define SPICC_ENH_CLK_OEN BIT(26) | ||
| 137 | #define SPICC_ENH_CS_OEN BIT(27) | ||
| 138 | #define SPICC_ENH_CLK_CS_DELAY_EN BIT(28) | ||
| 139 | #define SPICC_ENH_MAIN_CLK_AO BIT(29) | ||
| 140 | |||
| 116 | #define writel_bits_relaxed(mask, val, addr) \ | 141 | #define writel_bits_relaxed(mask, val, addr) \ |
| 117 | writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) | 142 | writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) |
| 118 | 143 | ||
| 119 | #define SPICC_BURST_MAX 16 | 144 | struct meson_spicc_data { |
| 120 | #define SPICC_FIFO_HALF 10 | 145 | unsigned int max_speed_hz; |
| 146 | unsigned int min_speed_hz; | ||
| 147 | unsigned int fifo_size; | ||
| 148 | bool has_oen; | ||
| 149 | bool has_enhance_clk_div; | ||
| 150 | bool has_pclk; | ||
| 151 | }; | ||
| 121 | 152 | ||
| 122 | struct meson_spicc_device { | 153 | struct meson_spicc_device { |
| 123 | struct spi_master *master; | 154 | struct spi_master *master; |
| 124 | struct platform_device *pdev; | 155 | struct platform_device *pdev; |
| 125 | void __iomem *base; | 156 | void __iomem *base; |
| 126 | struct clk *core; | 157 | struct clk *core; |
| 158 | struct clk *pclk; | ||
| 159 | struct clk *clk; | ||
| 127 | struct spi_message *message; | 160 | struct spi_message *message; |
| 128 | struct spi_transfer *xfer; | 161 | struct spi_transfer *xfer; |
| 162 | const struct meson_spicc_data *data; | ||
| 129 | u8 *tx_buf; | 163 | u8 *tx_buf; |
| 130 | u8 *rx_buf; | 164 | u8 *rx_buf; |
| 131 | unsigned int bytes_per_word; | 165 | unsigned int bytes_per_word; |
| 132 | unsigned long tx_remain; | 166 | unsigned long tx_remain; |
| 133 | unsigned long txb_remain; | ||
| 134 | unsigned long rx_remain; | 167 | unsigned long rx_remain; |
| 135 | unsigned long rxb_remain; | ||
| 136 | unsigned long xfer_remain; | 168 | unsigned long xfer_remain; |
| 137 | bool is_burst_end; | ||
| 138 | bool is_last_burst; | ||
| 139 | }; | 169 | }; |
| 140 | 170 | ||
| 171 | static void meson_spicc_oen_enable(struct meson_spicc_device *spicc) | ||
| 172 | { | ||
| 173 | u32 conf; | ||
| 174 | |||
| 175 | if (!spicc->data->has_oen) | ||
| 176 | return; | ||
| 177 | |||
| 178 | conf = readl_relaxed(spicc->base + SPICC_ENH_CTL0) | | ||
| 179 | SPICC_ENH_MOSI_OEN | SPICC_ENH_CLK_OEN | SPICC_ENH_CS_OEN; | ||
| 180 | |||
| 181 | writel_relaxed(conf, spicc->base + SPICC_ENH_CTL0); | ||
| 182 | } | ||
| 183 | |||
| 141 | static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc) | 184 | static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc) |
| 142 | { | 185 | { |
| 143 | return !!FIELD_GET(SPICC_TF, | 186 | return !!FIELD_GET(SPICC_TF, |
| @@ -146,7 +189,7 @@ static inline bool meson_spicc_txfull(struct meson_spicc_device *spicc) · 2 unmodified lines | |||
| 146 | 189 | ||
| 147 | static inline bool meson_spicc_rxready(struct meson_spicc_device *spicc) | 190 | static inline bool meson_spicc_rxready(struct meson_spicc_device *spicc) |
| 148 | { | 191 | { |
| 149 | return FIELD_GET(SPICC_RH | SPICC_RR | SPICC_RF_EN, | 192 | return FIELD_GET(SPICC_RH | SPICC_RR | SPICC_RF, |
| 150 | readl_relaxed(spicc->base + SPICC_STATREG)); | 193 | readl_relaxed(spicc->base + SPICC_STATREG)); |
| 151 | } | 194 | } |
| 152 | 195 | ||
| @@ -201,34 +244,22 @@ static inline void meson_spicc_tx(struct meson_spicc_device *spicc) · 48 unmodified lines | |||
| 201 | spicc->base + SPICC_TXDATA); | 244 | spicc->base + SPICC_TXDATA); |
| 202 | } | 245 | } |
| 203 | 246 | ||
| 204 | static inline u32 meson_spicc_setup_rx_irq(struct meson_spicc_device *spicc, | 247 | static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc) |
| 205 | u32 irq_ctrl) | ||
| 206 | { | 248 | { |
| 207 | if (spicc->rx_remain > SPICC_FIFO_HALF) | ||
| 208 | irq_ctrl |= SPICC_RH_EN; | ||
| 209 | else | ||
| 210 | irq_ctrl |= SPICC_RR_EN; | ||
| 211 | |||
| 212 | return irq_ctrl; | ||
| 213 | } | ||
| 214 | 249 | ||
| 215 | static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc, | 250 | unsigned int burst_len = min_t(unsigned int, |
| 216 | unsigned int burst_len) | 251 | spicc->xfer_remain / |
| 217 | { | 252 | spicc->bytes_per_word, |
| 253 | spicc->data->fifo_size); | ||
| 218 | /* Setup Xfer variables */ | 254 | /* Setup Xfer variables */ |
| 219 | spicc->tx_remain = burst_len; | 255 | spicc->tx_remain = burst_len; |
| 220 | spicc->rx_remain = burst_len; | 256 | spicc->rx_remain = burst_len; |
| 221 | spicc->xfer_remain -= burst_len * spicc->bytes_per_word; | 257 | spicc->xfer_remain -= burst_len * spicc->bytes_per_word; |
| 222 | spicc->is_burst_end = false; | ||
| 223 | if (burst_len < SPICC_BURST_MAX || !spicc->xfer_remain) | ||
| 224 | spicc->is_last_burst = true; | ||
| 225 | else | ||
| 226 | spicc->is_last_burst = false; | ||
| 227 | 258 | ||
| 228 | /* Setup burst length */ | 259 | /* Setup burst length */ |
| 229 | writel_bits_relaxed(SPICC_BURSTLENGTH_MASK, | 260 | writel_bits_relaxed(SPICC_BURSTLENGTH_MASK, |
| 230 | FIELD_PREP(SPICC_BURSTLENGTH_MASK, | 261 | FIELD_PREP(SPICC_BURSTLENGTH_MASK, |
| 231 | burst_len), | 262 | burst_len - 1), |
| 232 | spicc->base + SPICC_CONREG); | 263 | spicc->base + SPICC_CONREG); |
| 233 | 264 | ||
| 234 | /* Fill TX FIFO */ | 265 | /* Fill TX FIFO */ |
| @@ -238,97 +269,71 @@ static inline void meson_spicc_setup_burst(struct meson_spicc_device *spicc, · 3 unmodified lines | |||
| 238 | static irqreturn_t meson_spicc_irq(int irq, void *data) | 269 | static irqreturn_t meson_spicc_irq(int irq, void *data) |
| 239 | { | 270 | { |
| 240 | struct meson_spicc_device *spicc = (void *) data; | 271 | struct meson_spicc_device *spicc = (void *) data; |
| 241 | u32 ctrl = readl_relaxed(spicc->base + SPICC_INTREG); | ||
| 242 | u32 stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl; | ||
| 243 | 272 | ||
| 244 | ctrl &= ~(SPICC_RH_EN | SPICC_RR_EN); | 273 | writel_bits_relaxed(SPICC_TC, SPICC_TC, spicc->base + SPICC_STATREG); |
| 245 | 274 | ||
| 246 | /* Empty RX FIFO */ | 275 | /* Empty RX FIFO */ |
| 247 | meson_spicc_rx(spicc); | 276 | meson_spicc_rx(spicc); |
| 248 | 277 | ||
| 249 | /* Enable TC interrupt since we transferred everything */ | 278 | if (!spicc->xfer_remain) { |
| 250 | if (!spicc->tx_remain && !spicc->rx_remain) { | 279 | /* Disable all IRQs */ |
| 251 | spicc->is_burst_end = true; | 280 | writel(0, spicc->base + SPICC_INTREG); |
| 252 | |||
| 253 | /* Enable TC interrupt */ | ||
| 254 | ctrl |= SPICC_TC_EN; | ||
| 255 | 281 | ||
| 256 | /* Reload IRQ status */ | 282 | spi_finalize_current_transfer(spicc->master); |
| 257 | stat = readl_relaxed(spicc->base + SPICC_STATREG) & ctrl; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* Check transfer complete */ | ||
| 261 | if ((stat & SPICC_TC) && spicc->is_burst_end) { | ||
| 262 | unsigned int burst_len; | ||
| 263 | |||
| 264 | /* Clear TC bit */ | ||
| 265 | writel_relaxed(SPICC_TC, spicc->base + SPICC_STATREG); | ||
| 266 | |||
| 267 | /* Disable TC interrupt */ | ||
| 268 | ctrl &= ~SPICC_TC_EN; | ||
| 269 | |||
| 270 | if (spicc->is_last_burst) { | ||
| 271 | /* Disable all IRQs */ | ||
| 272 | writel(0, spicc->base + SPICC_INTREG); | ||
| 273 | |||
| 274 | spi_finalize_current_transfer(spicc->master); | ||
| 275 | |||
| 276 | return IRQ_HANDLED; | ||
| 277 | } | ||
| 278 | |||
| 279 | burst_len = min_t(unsigned int, | ||
| 280 | spicc->xfer_remain / spicc->bytes_per_word, | ||
| 281 | SPICC_BURST_MAX); | ||
| 282 | 283 | ||
| 283 | /* Setup burst */ | 284 | return IRQ_HANDLED; |
| 284 | meson_spicc_setup_burst(spicc, burst_len); | ||
| 285 | |||
| 286 | /* Restart burst */ | ||
| 287 | writel_bits_relaxed(SPICC_XCH, SPICC_XCH, | ||
| 288 | spicc->base + SPICC_CONREG); | ||
| 289 | } | 285 | } |
| 290 | 286 | ||
| 291 | /* Setup RX interrupt trigger */ | 287 | /* Setup burst */ |
| 292 | ctrl = meson_spicc_setup_rx_irq(spicc, ctrl); | 288 | meson_spicc_setup_burst(spicc); |
| 293 | 289 | ||
| 294 | /* Reconfigure interrupts */ | 290 | /* Start burst */ |
| 295 | writel(ctrl, spicc->base + SPICC_INTREG); | 291 | writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); |
| 296 | 292 | ||
| 297 | return IRQ_HANDLED; | 293 | return IRQ_HANDLED; |
| 298 | } | 294 | } |
| 299 | 295 | ||
| 300 | static u32 meson_spicc_setup_speed(struct meson_spicc_device *spicc, u32 conf, | 296 | static void meson_spicc_auto_io_delay(struct meson_spicc_device *spicc) |
| 301 | u32 speed) | ||
| 302 | { | 297 | { |
| 303 | unsigned long parent, value; | 298 | u32 div, hz; |
| 304 | unsigned int i, div; | 299 | u32 mi_delay, cap_delay; |
| 305 | 300 | u32 conf; | |
| 306 | parent = clk_get_rate(spicc->core); | 301 | |
| 307 | 302 | if (spicc->data->has_enhance_clk_div) { | |
| 308 | /* Find closest inferior/equal possible speed */ | 303 | div = FIELD_GET(SPICC_ENH_DATARATE_MASK, |
| 309 | for (i = 0 ; i < 7 ; ++i) { | 304 | readl_relaxed(spicc->base + SPICC_ENH_CTL0)); |
| 310 | /* 2^(data_rate+2) */ | 305 | div++; |
| 311 | value = parent >> (i + 2); | 306 | div <<= 1; |
| 312 | 307 | } else { | |
| 313 | if (value <= speed) | 308 | div = FIELD_GET(SPICC_DATARATE_MASK, |
| 314 | break; | 309 | readl_relaxed(spicc->base + SPICC_CONREG)); |
| 310 | div += 2; | ||
| 311 | div = 1 << div; | ||
| 315 | } | 312 | } |
| 316 | 313 | ||
| 317 | /* If provided speed it lower than max divider, use max divider */ | 314 | mi_delay = SPICC_MI_NO_DELAY; |
| 318 | if (i > 7) { | 315 | cap_delay = SPICC_CAP_AHEAD_2_CYCLE; |
| 319 | div = 7; | 316 | hz = clk_get_rate(spicc->clk); |
| 320 | dev_warn_once(&spicc->pdev->dev, "unable to get close to speed %u\n", | 317 | |
| 321 | speed); | 318 | if (hz >= 100000000) |
| 322 | } else | 319 | cap_delay = SPICC_CAP_DELAY_1_CYCLE; |
| 323 | div = i; | 320 | else if (hz >= 80000000) |
| 324 | 321 | cap_delay = SPICC_CAP_NO_DELAY; | |
| 325 | dev_dbg(&spicc->pdev->dev, "parent %lu, speed %u -> %lu (%u)\n", | 322 | else if (hz >= 40000000) |
| 326 | parent, speed, value, div); | 323 | cap_delay = SPICC_CAP_AHEAD_1_CYCLE; |
| 327 | 324 | else if (div >= 16) | |
| 328 | conf &= ~SPICC_DATARATE_MASK; | 325 | mi_delay = SPICC_MI_DELAY_3_CYCLE; |
| 329 | conf |= FIELD_PREP(SPICC_DATARATE_MASK, div); | 326 | else if (div >= 8) |
| 330 | 327 | mi_delay = SPICC_MI_DELAY_2_CYCLE; | |
| 331 | return conf; | 328 | else if (div >= 6) |
| 329 | mi_delay = SPICC_MI_DELAY_1_CYCLE; | ||
| 330 | |||
| 331 | conf = readl_relaxed(spicc->base + SPICC_TESTREG); | ||
| 332 | conf &= ~(SPICC_MO_DELAY_MASK | SPICC_MI_DELAY_MASK | ||
| 333 | | SPICC_MI_CAP_DELAY_MASK); | ||
| 334 | conf |= FIELD_PREP(SPICC_MI_DELAY_MASK, mi_delay); | ||
| 335 | conf |= FIELD_PREP(SPICC_MI_CAP_DELAY_MASK, cap_delay); | ||
| 336 | writel_relaxed(conf, spicc->base + SPICC_TESTREG); | ||
| 332 | } | 337 | } |
| 333 | 338 | ||
| 334 | static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, | 339 | static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, |
| @@ -339,9 +344,6 @@ static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, · 4 unmodified lines | |||
| 339 | /* Read original configuration */ | 344 | /* Read original configuration */ |
| 340 | conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG); | 345 | conf = conf_orig = readl_relaxed(spicc->base + SPICC_CONREG); |
| 341 | 346 | ||
| 342 | /* Select closest divider */ | ||
| 343 | conf = meson_spicc_setup_speed(spicc, conf, xfer->speed_hz); | ||
| 344 | |||
| 345 | /* Setup word width */ | 347 | /* Setup word width */ |
| 346 | conf &= ~SPICC_BITLENGTH_MASK; | 348 | conf &= ~SPICC_BITLENGTH_MASK; |
| 347 | conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, | 349 | conf |= FIELD_PREP(SPICC_BITLENGTH_MASK, |
| @@ -350,6 +352,32 @@ static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc, · 2 unmodified lines | |||
| 350 | /* Ignore if unchanged */ | 352 | /* Ignore if unchanged */ |
| 351 | if (conf != conf_orig) | 353 | if (conf != conf_orig) |
| 352 | writel_relaxed(conf, spicc->base + SPICC_CONREG); | 354 | writel_relaxed(conf, spicc->base + SPICC_CONREG); |
| 355 | |||
| 356 | clk_set_rate(spicc->clk, xfer->speed_hz); | ||
| 357 | |||
| 358 | meson_spicc_auto_io_delay(spicc); | ||
| 359 | |||
| 360 | writel_relaxed(0, spicc->base + SPICC_DMAREG); | ||
| 361 | } | ||
| 362 | |||
| 363 | static void meson_spicc_reset_fifo(struct meson_spicc_device *spicc) | ||
| 364 | { | ||
| 365 | u32 data; | ||
| 366 | |||
| 367 | if (spicc->data->has_oen) | ||
| 368 | writel_bits_relaxed(SPICC_ENH_MAIN_CLK_AO, | ||
| 369 | SPICC_ENH_MAIN_CLK_AO, | ||
| 370 | spicc->base + SPICC_ENH_CTL0); | ||
| 371 | |||
| 372 | writel_bits_relaxed(SPICC_FIFORST_W1_MASK, SPICC_FIFORST_W1_MASK, | ||
| 373 | spicc->base + SPICC_TESTREG); | ||
| 374 | |||
| 375 | while (meson_spicc_rxready(spicc)) | ||
| 376 | data = readl_relaxed(spicc->base + SPICC_RXDATA); | ||
| 377 | |||
| 378 | if (spicc->data->has_oen) | ||
| 379 | writel_bits_relaxed(SPICC_ENH_MAIN_CLK_AO, 0, | ||
| 380 | spicc->base + SPICC_ENH_CTL0); | ||
| 353 | } | 381 | } |
| 354 | 382 | ||
| 355 | static int meson_spicc_transfer_one(struct spi_master *master, | 383 | static int meson_spicc_transfer_one(struct spi_master *master, |
| @@ -357,8 +385,6 @@ static int meson_spicc_transfer_one(struct spi_master *master, · 1 unmodified line | |||
| 357 | struct spi_transfer *xfer) | 385 | struct spi_transfer *xfer) |
| 358 | { | 386 | { |
| 359 | struct meson_spicc_device *spicc = spi_master_get_devdata(master); | 387 | struct meson_spicc_device *spicc = spi_master_get_devdata(master); |
| 360 | unsigned int burst_len; | ||
| 361 | u32 irq = 0; | ||
| 362 | 388 | ||
| 363 | /* Store current transfer */ | 389 | /* Store current transfer */ |
| 364 | spicc->xfer = xfer; | 390 | spicc->xfer = xfer; |
| @@ -372,22 +398,22 @@ static int meson_spicc_transfer_one(struct spi_master *master, · 7 unmodified lines | |||
| 372 | spicc->bytes_per_word = | 398 | spicc->bytes_per_word = |
| 373 | DIV_ROUND_UP(spicc->xfer->bits_per_word, 8); | 399 | DIV_ROUND_UP(spicc->xfer->bits_per_word, 8); |
| 374 | 400 | ||
| 401 | if (xfer->len % spicc->bytes_per_word) | ||
| 402 | return -EINVAL; | ||
| 403 | |||
| 375 | /* Setup transfer parameters */ | 404 | /* Setup transfer parameters */ |
| 376 | meson_spicc_setup_xfer(spicc, xfer); | 405 | meson_spicc_setup_xfer(spicc, xfer); |
| 377 | 406 | ||
| 378 | burst_len = min_t(unsigned int, | 407 | meson_spicc_reset_fifo(spicc); |
| 379 | spicc->xfer_remain / spicc->bytes_per_word, | ||
| 380 | SPICC_BURST_MAX); | ||
| 381 | 408 | ||
| 382 | meson_spicc_setup_burst(spicc, burst_len); | 409 | /* Setup burst */ |
| 383 | 410 | meson_spicc_setup_burst(spicc); | |
| 384 | irq = meson_spicc_setup_rx_irq(spicc, irq); | ||
| 385 | 411 | ||
| 386 | /* Start burst */ | 412 | /* Start burst */ |
| 387 | writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); | 413 | writel_bits_relaxed(SPICC_XCH, SPICC_XCH, spicc->base + SPICC_CONREG); |
| 388 | 414 | ||
| 389 | /* Enable interrupts */ | 415 | /* Enable interrupts */ |
| 390 | writel_relaxed(irq, spicc->base + SPICC_INTREG); | 416 | writel_relaxed(SPICC_TC_EN, spicc->base + SPICC_INTREG); |
| 391 | 417 | ||
| 392 | return 1; | 418 | return 1; |
| 393 | } | 419 | } |
| @@ -444,7 +470,7 @@ static int meson_spicc_prepare_message(struct spi_master *master, · 50 unmodified lines | |||
| 444 | /* Setup no wait cycles by default */ | 470 | /* Setup no wait cycles by default */ |
| 445 | writel_relaxed(0, spicc->base + SPICC_PERIODREG); | 471 | writel_relaxed(0, spicc->base + SPICC_PERIODREG); |
| 446 | 472 | ||
| 447 | writel_bits_relaxed(BIT(24), BIT(24), spicc->base + SPICC_TESTREG); | 473 | writel_bits_relaxed(SPICC_LBC_W1, 0, spicc->base + SPICC_TESTREG); |
| 448 | 474 | ||
| 449 | return 0; | 475 | return 0; |
| 450 | } | 476 | } |
| @@ -456,9 +482,6 @@ static int meson_spicc_unprepare_transfer(struct spi_master *master) · 5 unmodified lines | |||
| 456 | /* Disable all IRQs */ | 482 | /* Disable all IRQs */ |
| 457 | writel(0, spicc->base + SPICC_INTREG); | 483 | writel(0, spicc->base + SPICC_INTREG); |
| 458 | 484 | ||
| 459 | /* Disable controller */ | ||
| 460 | writel_bits_relaxed(SPICC_ENABLE, 0, spicc->base + SPICC_CONREG); | ||
| 461 | |||
| 462 | device_reset_optional(&spicc->pdev->dev); | 485 | device_reset_optional(&spicc->pdev->dev); |
| 463 | 486 | ||
| 464 | return 0; | 487 | return 0; |
| @@ -477,11 +500,167 @@ static void meson_spicc_cleanup(struct spi_device *spi) · 12 unmodified lines | |||
| 477 | spi->controller_state = NULL; | 500 | spi->controller_state = NULL; |
| 478 | } | 501 | } |
| 479 | 502 | ||
| 503 | /* | ||
| 504 | * The Clock Mux | ||
| 505 | * x-----------------x x------------x x------\ | ||
| 506 | * |---| pow2 fixed div |---| pow2 div |----| | | ||
| 507 | * | x-----------------x x------------x | | | ||
| 508 | * src ---| | mux |-- out | ||
| 509 | * | x-----------------x x------------x | | | ||
| 510 | * |---| enh fixed div |---| enh div |0---| | | ||
| 511 | * x-----------------x x------------x x------/ | ||
| 512 | * | ||
| 513 | * Clk path for GX series: | ||
| 514 | * src -> pow2 fixed div -> pow2 div -> out | ||
| 515 | * | ||
| 516 | * Clk path for AXG series: | ||
| 517 | * src -> pow2 fixed div -> pow2 div -> mux -> out | ||
| 518 | * src -> enh fixed div -> enh div -> mux -> out | ||
| 519 | * | ||
| 520 | * Clk path for G12A series: | ||
| 521 | * pclk -> pow2 fixed div -> pow2 div -> mux -> out | ||
| 522 | * pclk -> enh fixed div -> enh div -> mux -> out | ||
| 523 | */ | ||
| 524 | |||
| 525 | static int meson_spicc_clk_init(struct meson_spicc_device *spicc) | ||
| 526 | { | ||
| 527 | struct device *dev = &spicc->pdev->dev; | ||
| 528 | struct clk_fixed_factor *pow2_fixed_div, *enh_fixed_div; | ||
| 529 | struct clk_divider *pow2_div, *enh_div; | ||
| 530 | struct clk_mux *mux; | ||
| 531 | struct clk_init_data init; | ||
| 532 | struct clk *clk; | ||
| 533 | struct clk_parent_data parent_data[2]; | ||
| 534 | char name[64]; | ||
| 535 | |||
| 536 | memset(&init, 0, sizeof(init)); | ||
| 537 | memset(&parent_data, 0, sizeof(parent_data)); | ||
| 538 | |||
| 539 | init.parent_data = parent_data; | ||
| 540 | |||
| 541 | /* algorithm for pow2 div: rate = freq / 4 / (2 ^ N) */ | ||
| 542 | |||
| 543 | pow2_fixed_div = devm_kzalloc(dev, sizeof(*pow2_fixed_div), GFP_KERNEL); | ||
| 544 | if (!pow2_fixed_div) | ||
| 545 | return -ENOMEM; | ||
| 546 | |||
| 547 | snprintf(name, sizeof(name), "%s#pow2_fixed_div", dev_name(dev)); | ||
| 548 | init.name = name; | ||
| 549 | init.ops = &clk_fixed_factor_ops; | ||
| 550 | init.flags = 0; | ||
| 551 | if (spicc->data->has_pclk) | ||
| 552 | parent_data[0].hw = __clk_get_hw(spicc->pclk); | ||
| 553 | else | ||
| 554 | parent_data[0].hw = __clk_get_hw(spicc->core); | ||
| 555 | init.num_parents = 1; | ||
| 556 | |||
| 557 | pow2_fixed_div->mult = 1, | ||
| 558 | pow2_fixed_div->div = 4, | ||
| 559 | pow2_fixed_div->hw.init = &init; | ||
| 560 | |||
| 561 | clk = devm_clk_register(dev, &pow2_fixed_div->hw); | ||
| 562 | if (WARN_ON(IS_ERR(clk))) | ||
| 563 | return PTR_ERR(clk); | ||
| 564 | |||
| 565 | pow2_div = devm_kzalloc(dev, sizeof(*pow2_div), GFP_KERNEL); | ||
| 566 | if (!pow2_div) | ||
| 567 | return -ENOMEM; | ||
| 568 | |||
| 569 | snprintf(name, sizeof(name), "%s#pow2_div", dev_name(dev)); | ||
| 570 | init.name = name; | ||
| 571 | init.ops = &clk_divider_ops; | ||
| 572 | init.flags = CLK_SET_RATE_PARENT; | ||
| 573 | parent_data[0].hw = &pow2_fixed_div->hw; | ||
| 574 | init.num_parents = 1; | ||
| 575 | |||
| 576 | pow2_div->shift = 16, | ||
| 577 | pow2_div->width = 3, | ||
| 578 | pow2_div->flags = CLK_DIVIDER_POWER_OF_TWO, | ||
| 579 | pow2_div->reg = spicc->base + SPICC_CONREG; | ||
| 580 | pow2_div->hw.init = &init; | ||
| 581 | |||
| 582 | clk = devm_clk_register(dev, &pow2_div->hw); | ||
| 583 | if (WARN_ON(IS_ERR(clk))) | ||
| 584 | return PTR_ERR(clk); | ||
| 585 | |||
| 586 | if (!spicc->data->has_enhance_clk_div) { | ||
| 587 | spicc->clk = clk; | ||
| 588 | return 0; | ||
| 589 | } | ||
| 590 | |||
| 591 | /* algorithm for enh div: rate = freq / 2 / (N + 1) */ | ||
| 592 | |||
| 593 | enh_fixed_div = devm_kzalloc(dev, sizeof(*enh_fixed_div), GFP_KERNEL); | ||
| 594 | if (!enh_fixed_div) | ||
| 595 | return -ENOMEM; | ||
| 596 | |||
| 597 | snprintf(name, sizeof(name), "%s#enh_fixed_div", dev_name(dev)); | ||
| 598 | init.name = name; | ||
| 599 | init.ops = &clk_fixed_factor_ops; | ||
| 600 | init.flags = 0; | ||
| 601 | if (spicc->data->has_pclk) | ||
| 602 | parent_data[0].hw = __clk_get_hw(spicc->pclk); | ||
| 603 | else | ||
| 604 | parent_data[0].hw = __clk_get_hw(spicc->core); | ||
| 605 | init.num_parents = 1; | ||
| 606 | |||
| 607 | enh_fixed_div->mult = 1, | ||
| 608 | enh_fixed_div->div = 2, | ||
| 609 | enh_fixed_div->hw.init = &init; | ||
| 610 | |||
| 611 | clk = devm_clk_register(dev, &enh_fixed_div->hw); | ||
| 612 | if (WARN_ON(IS_ERR(clk))) | ||
| 613 | return PTR_ERR(clk); | ||
| 614 | |||
| 615 | enh_div = devm_kzalloc(dev, sizeof(*enh_div), GFP_KERNEL); | ||
| 616 | if (!enh_div) | ||
| 617 | return -ENOMEM; | ||
| 618 | |||
| 619 | snprintf(name, sizeof(name), "%s#enh_div", dev_name(dev)); | ||
| 620 | init.name = name; | ||
| 621 | init.ops = &clk_divider_ops; | ||
| 622 | init.flags = CLK_SET_RATE_PARENT; | ||
| 623 | parent_data[0].hw = &enh_fixed_div->hw; | ||
| 624 | init.num_parents = 1; | ||
| 625 | |||
| 626 | enh_div->shift = 16, | ||
| 627 | enh_div->width = 8, | ||
| 628 | enh_div->reg = spicc->base + SPICC_ENH_CTL0; | ||
| 629 | enh_div->hw.init = &init; | ||
| 630 | |||
| 631 | clk = devm_clk_register(dev, &enh_div->hw); | ||
| 632 | if (WARN_ON(IS_ERR(clk))) | ||
| 633 | return PTR_ERR(clk); | ||
| 634 | |||
| 635 | mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); | ||
| 636 | if (!mux) | ||
| 637 | return -ENOMEM; | ||
| 638 | |||
| 639 | snprintf(name, sizeof(name), "%s#sel", dev_name(dev)); | ||
| 640 | init.name = name; | ||
| 641 | init.ops = &clk_mux_ops; | ||
| 642 | parent_data[0].hw = &pow2_div->hw; | ||
| 643 | parent_data[1].hw = &enh_div->hw; | ||
| 644 | init.num_parents = 2; | ||
| 645 | init.flags = CLK_SET_RATE_PARENT; | ||
| 646 | |||
| 647 | mux->mask = 0x1, | ||
| 648 | mux->shift = 24, | ||
| 649 | mux->reg = spicc->base + SPICC_ENH_CTL0; | ||
| 650 | mux->hw.init = &init; | ||
| 651 | |||
| 652 | spicc->clk = devm_clk_register(dev, &mux->hw); | ||
| 653 | if (WARN_ON(IS_ERR(spicc->clk))) | ||
| 654 | return PTR_ERR(spicc->clk); | ||
| 655 | |||
| 656 | return 0; | ||
| 657 | } | ||
| 658 | |||
| 480 | static int meson_spicc_probe(struct platform_device *pdev) | 659 | static int meson_spicc_probe(struct platform_device *pdev) |
| 481 | { | 660 | { |
| 482 | struct spi_master *master; | 661 | struct spi_master *master; |
| 483 | struct meson_spicc_device *spicc; | 662 | struct meson_spicc_device *spicc; |
| 484 | int ret, irq, rate; | 663 | int ret, irq; |
| 485 | 664 | ||
| 486 | master = spi_alloc_master(&pdev->dev, sizeof(*spicc)); | 665 | master = spi_alloc_master(&pdev->dev, sizeof(*spicc)); |
| 487 | if (!master) { | 666 | if (!master) { |
| @@ -491,6 +670,13 @@ static int meson_spicc_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 491 | spicc = spi_master_get_devdata(master); | 670 | spicc = spi_master_get_devdata(master); |
| 492 | spicc->master = master; | 671 | spicc->master = master; |
| 493 | 672 | ||
| 673 | spicc->data = of_device_get_match_data(&pdev->dev); | ||
| 674 | if (!spicc->data) { | ||
| 675 | dev_err(&pdev->dev, "failed to get match data\n"); | ||
| 676 | ret = -EINVAL; | ||
| 677 | goto out_master; | ||
| 678 | } | ||
| 679 | |||
| 494 | spicc->pdev = pdev; | 680 | spicc->pdev = pdev; |
| 495 | platform_set_drvdata(pdev, spicc); | 681 | platform_set_drvdata(pdev, spicc); |
| 496 | 682 | ||
| @@ -501,6 +687,10 @@ static int meson_spicc_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 501 | goto out_master; | 687 | goto out_master; |
| 502 | } | 688 | } |
| 503 | 689 | ||
| 690 | /* Set master mode and enable controller */ | ||
| 691 | writel_relaxed(SPICC_ENABLE | SPICC_MODE_MASTER, | ||
| 692 | spicc->base + SPICC_CONREG); | ||
| 693 | |||
| 504 | /* Disable all IRQs */ | 694 | /* Disable all IRQs */ |
| 505 | writel_relaxed(0, spicc->base + SPICC_INTREG); | 695 | writel_relaxed(0, spicc->base + SPICC_INTREG); |
| 506 | 696 | ||
| @@ -519,12 +709,26 @@ static int meson_spicc_probe(struct platform_device *pdev) · 12 unmodified lines | |||
| 519 | goto out_master; | 709 | goto out_master; |
| 520 | } | 710 | } |
| 521 | 711 | ||
| 712 | if (spicc->data->has_pclk) { | ||
| 713 | spicc->pclk = devm_clk_get(&pdev->dev, "pclk"); | ||
| 714 | if (IS_ERR(spicc->pclk)) { | ||
| 715 | dev_err(&pdev->dev, "pclk clock request failed\n"); | ||
| 716 | ret = PTR_ERR(spicc->pclk); | ||
| 717 | goto out_master; | ||
| 718 | } | ||
| 719 | } | ||
| 720 | |||
| 522 | ret = clk_prepare_enable(spicc->core); | 721 | ret = clk_prepare_enable(spicc->core); |
| 523 | if (ret) { | 722 | if (ret) { |
| 524 | dev_err(&pdev->dev, "core clock enable failed\n"); | 723 | dev_err(&pdev->dev, "core clock enable failed\n"); |
| 525 | goto out_master; | 724 | goto out_master; |
| 526 | } | 725 | } |
| 527 | rate = clk_get_rate(spicc->core); | 726 | |
| 727 | ret = clk_prepare_enable(spicc->pclk); | ||
| 728 | if (ret) { | ||
| 729 | dev_err(&pdev->dev, "pclk clock enable failed\n"); | ||
| 730 | goto out_master; | ||
| 731 | } | ||
| 528 | 732 | ||
| 529 | device_reset_optional(&pdev->dev); | 733 | device_reset_optional(&pdev->dev); |
| 530 | 734 | ||
| @@ -536,7 +740,8 @@ static int meson_spicc_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 536 | SPI_BPW_MASK(16) | | 740 | SPI_BPW_MASK(16) | |
| 537 | SPI_BPW_MASK(8); | 741 | SPI_BPW_MASK(8); |
| 538 | master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); | 742 | master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX); |
| 539 | master->min_speed_hz = rate >> 9; | 743 | master->min_speed_hz = spicc->data->min_speed_hz; |
| 744 | master->max_speed_hz = spicc->data->max_speed_hz; | ||
| 540 | master->setup = meson_spicc_setup; | 745 | master->setup = meson_spicc_setup; |
| 541 | master->cleanup = meson_spicc_cleanup; | 746 | master->cleanup = meson_spicc_cleanup; |
| 542 | master->prepare_message = meson_spicc_prepare_message; | 747 | master->prepare_message = meson_spicc_prepare_message; |
| @@ -544,11 +749,13 @@ static int meson_spicc_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 544 | master->transfer_one = meson_spicc_transfer_one; | 749 | master->transfer_one = meson_spicc_transfer_one; |
| 545 | master->use_gpio_descriptors = true; | 750 | master->use_gpio_descriptors = true; |
| 546 | 751 | ||
| 547 | /* Setup max rate according to the Meson GX datasheet */ | 752 | meson_spicc_oen_enable(spicc); |
| 548 | if ((rate >> 2) > SPICC_MAX_FREQ) | 753 | |
| 549 | master->max_speed_hz = SPICC_MAX_FREQ; | 754 | ret = meson_spicc_clk_init(spicc); |
| 550 | else | 755 | if (ret) { |
| 551 | master->max_speed_hz = rate >> 2; | 756 | dev_err(&pdev->dev, "clock registration failed\n"); |
| 757 | goto out_master; | ||
| 758 | } | ||
| 552 | 759 | ||
| 553 | ret = devm_spi_register_master(&pdev->dev, master); | 760 | ret = devm_spi_register_master(&pdev->dev, master); |
| 554 | if (ret) { | 761 | if (ret) { |
| @@ -560,6 +767,7 @@ static int meson_spicc_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 560 | 767 | ||
| 561 | out_clk: | 768 | out_clk: |
| 562 | clk_disable_unprepare(spicc->core); | 769 | clk_disable_unprepare(spicc->core); |
| 770 | clk_disable_unprepare(spicc->pclk); | ||
| 563 | 771 | ||
| 564 | out_master: | 772 | out_master: |
| 565 | spi_master_put(master); | 773 | spi_master_put(master); |
| @@ -575,13 +783,47 @@ static int meson_spicc_remove(struct platform_device *pdev) · 9 unmodified lines | |||
| 575 | writel(0, spicc->base + SPICC_CONREG); | 783 | writel(0, spicc->base + SPICC_CONREG); |
| 576 | 784 | ||
| 577 | clk_disable_unprepare(spicc->core); | 785 | clk_disable_unprepare(spicc->core); |
| 786 | clk_disable_unprepare(spicc->pclk); | ||
| 578 | 787 | ||
| 579 | return 0; | 788 | return 0; |
| 580 | } | 789 | } |
| 581 | 790 | ||
| 791 | static const struct meson_spicc_data meson_spicc_gx_data = { | ||
| 792 | .max_speed_hz = 30000000, | ||
| 793 | .min_speed_hz = 325000, | ||
| 794 | .fifo_size = 16, | ||
| 795 | }; | ||
| 796 | |||
| 797 | static const struct meson_spicc_data meson_spicc_axg_data = { | ||
| 798 | .max_speed_hz = 80000000, | ||
| 799 | .min_speed_hz = 325000, | ||
| 800 | .fifo_size = 16, | ||
| 801 | .has_oen = true, | ||
| 802 | .has_enhance_clk_div = true, | ||
| 803 | }; | ||
| 804 | |||
| 805 | static const struct meson_spicc_data meson_spicc_g12a_data = { | ||
| 806 | .max_speed_hz = 166666666, | ||
| 807 | .min_speed_hz = 50000, | ||
| 808 | .fifo_size = 15, | ||
| 809 | .has_oen = true, | ||
| 810 | .has_enhance_clk_div = true, | ||
| 811 | .has_pclk = true, | ||
| 812 | }; | ||
| 813 | |||
| 582 | static const struct of_device_id meson_spicc_of_match[] = { | 814 | static const struct of_device_id meson_spicc_of_match[] = { |
| 583 | { .compatible = "amlogic,meson-gx-spicc", }, | 815 | { |
| 584 | { .compatible = "amlogic,meson-axg-spicc", }, | 816 | .compatible = "amlogic,meson-gx-spicc", |
| 817 | .data = &meson_spicc_gx_data, | ||
| 818 | }, | ||
| 819 | { | ||
| 820 | .compatible = "amlogic,meson-axg-spicc", | ||
| 821 | .data = &meson_spicc_axg_data, | ||
| 822 | }, | ||
| 823 | { | ||
| 824 | .compatible = "amlogic,meson-g12a-spicc", | ||
| 825 | .data = &meson_spicc_g12a_data, | ||
| 826 | }, | ||
| 585 | { /* sentinel */ } | 827 | { /* sentinel */ } |
| 586 | }; | 828 | }; |
| 587 | MODULE_DEVICE_TABLE(of, meson_spicc_of_match); | 829 | MODULE_DEVICE_TABLE(of, meson_spicc_of_match); |
| @@ -0,0 +1,689 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // | ||
| 3 | // Mediatek SPI NOR controller driver | ||
| 4 | // | ||
| 5 | // Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com> | ||
| 6 | |||
| 7 | #include <linux/bits.h> | ||
| 8 | #include <linux/clk.h> | ||
| 9 | #include <linux/completion.h> | ||
| 10 | #include <linux/dma-mapping.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <linux/io.h> | ||
| 13 | #include <linux/iopoll.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/of_device.h> | ||
| 17 | #include <linux/spi/spi.h> | ||
| 18 | #include <linux/spi/spi-mem.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | |||
| 21 | #define DRIVER_NAME "mtk-spi-nor" | ||
| 22 | |||
| 23 | #define MTK_NOR_REG_CMD 0x00 | ||
| 24 | #define MTK_NOR_CMD_WRITE BIT(4) | ||
| 25 | #define MTK_NOR_CMD_PROGRAM BIT(2) | ||
| 26 | #define MTK_NOR_CMD_READ BIT(0) | ||
| 27 | #define MTK_NOR_CMD_MASK GENMASK(5, 0) | ||
| 28 | |||
| 29 | #define MTK_NOR_REG_PRG_CNT 0x04 | ||
| 30 | #define MTK_NOR_REG_RDATA 0x0c | ||
| 31 | |||
| 32 | #define MTK_NOR_REG_RADR0 0x10 | ||
| 33 | #define MTK_NOR_REG_RADR(n) (MTK_NOR_REG_RADR0 + 4 * (n)) | ||
| 34 | #define MTK_NOR_REG_RADR3 0xc8 | ||
| 35 | |||
| 36 | #define MTK_NOR_REG_WDATA 0x1c | ||
| 37 | |||
| 38 | #define MTK_NOR_REG_PRGDATA0 0x20 | ||
| 39 | #define MTK_NOR_REG_PRGDATA(n) (MTK_NOR_REG_PRGDATA0 + 4 * (n)) | ||
| 40 | #define MTK_NOR_REG_PRGDATA_MAX 5 | ||
| 41 | |||
| 42 | #define MTK_NOR_REG_SHIFT0 0x38 | ||
| 43 | #define MTK_NOR_REG_SHIFT(n) (MTK_NOR_REG_SHIFT0 + 4 * (n)) | ||
| 44 | #define MTK_NOR_REG_SHIFT_MAX 9 | ||
| 45 | |||
| 46 | #define MTK_NOR_REG_CFG1 0x60 | ||
| 47 | #define MTK_NOR_FAST_READ BIT(0) | ||
| 48 | |||
| 49 | #define MTK_NOR_REG_CFG2 0x64 | ||
| 50 | #define MTK_NOR_WR_CUSTOM_OP_EN BIT(4) | ||
| 51 | #define MTK_NOR_WR_BUF_EN BIT(0) | ||
| 52 | |||
| 53 | #define MTK_NOR_REG_PP_DATA 0x98 | ||
| 54 | |||
| 55 | #define MTK_NOR_REG_IRQ_STAT 0xa8 | ||
| 56 | #define MTK_NOR_REG_IRQ_EN 0xac | ||
| 57 | #define MTK_NOR_IRQ_DMA BIT(7) | ||
| 58 | #define MTK_NOR_IRQ_MASK GENMASK(7, 0) | ||
| 59 | |||
| 60 | #define MTK_NOR_REG_CFG3 0xb4 | ||
| 61 | #define MTK_NOR_DISABLE_WREN BIT(7) | ||
| 62 | #define MTK_NOR_DISABLE_SR_POLL BIT(5) | ||
| 63 | |||
| 64 | #define MTK_NOR_REG_WP 0xc4 | ||
| 65 | #define MTK_NOR_ENABLE_SF_CMD 0x30 | ||
| 66 | |||
| 67 | #define MTK_NOR_REG_BUSCFG 0xcc | ||
| 68 | #define MTK_NOR_4B_ADDR BIT(4) | ||
| 69 | #define MTK_NOR_QUAD_ADDR BIT(3) | ||
| 70 | #define MTK_NOR_QUAD_READ BIT(2) | ||
| 71 | #define MTK_NOR_DUAL_ADDR BIT(1) | ||
| 72 | #define MTK_NOR_DUAL_READ BIT(0) | ||
| 73 | #define MTK_NOR_BUS_MODE_MASK GENMASK(4, 0) | ||
| 74 | |||
| 75 | #define MTK_NOR_REG_DMA_CTL 0x718 | ||
| 76 | #define MTK_NOR_DMA_START BIT(0) | ||
| 77 | |||
| 78 | #define MTK_NOR_REG_DMA_FADR 0x71c | ||
| 79 | #define MTK_NOR_REG_DMA_DADR 0x720 | ||
| 80 | #define MTK_NOR_REG_DMA_END_DADR 0x724 | ||
| 81 | |||
| 82 | #define MTK_NOR_PRG_MAX_SIZE 6 | ||
| 83 | // Reading DMA src/dst addresses have to be 16-byte aligned | ||
| 84 | #define MTK_NOR_DMA_ALIGN 16 | ||
| 85 | #define MTK_NOR_DMA_ALIGN_MASK (MTK_NOR_DMA_ALIGN - 1) | ||
| 86 | // and we allocate a bounce buffer if destination address isn't aligned. | ||
| 87 | #define MTK_NOR_BOUNCE_BUF_SIZE PAGE_SIZE | ||
| 88 | |||
| 89 | // Buffered page program can do one 128-byte transfer | ||
| 90 | #define MTK_NOR_PP_SIZE 128 | ||
| 91 | |||
| 92 | #define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq) | ||
| 93 | |||
| 94 | struct mtk_nor { | ||
| 95 | struct spi_controller *ctlr; | ||
| 96 | struct device *dev; | ||
| 97 | void __iomem *base; | ||
| 98 | u8 *buffer; | ||
| 99 | struct clk *spi_clk; | ||
| 100 | struct clk *ctlr_clk; | ||
| 101 | unsigned int spi_freq; | ||
| 102 | bool wbuf_en; | ||
| 103 | bool has_irq; | ||
| 104 | struct completion op_done; | ||
| 105 | }; | ||
| 106 | |||
| 107 | static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr) | ||
| 108 | { | ||
| 109 | u32 val = readl(sp->base + reg); | ||
| 110 | |||
| 111 | val &= ~clr; | ||
| 112 | val |= set; | ||
| 113 | writel(val, sp->base + reg); | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk) | ||
| 117 | { | ||
| 118 | ulong delay = CLK_TO_US(sp, clk); | ||
| 119 | u32 reg; | ||
| 120 | int ret; | ||
| 121 | |||
| 122 | writel(cmd, sp->base + MTK_NOR_REG_CMD); | ||
| 123 | ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CMD, reg, !(reg & cmd), | ||
| 124 | delay / 3, (delay + 1) * 200); | ||
| 125 | if (ret < 0) | ||
| 126 | dev_err(sp->dev, "command %u timeout.\n", cmd); | ||
| 127 | return ret; | ||
| 128 | } | ||
| 129 | |||
| 130 | static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op) | ||
| 131 | { | ||
| 132 | u32 addr = op->addr.val; | ||
| 133 | int i; | ||
| 134 | |||
| 135 | for (i = 0; i < 3; i++) { | ||
| 136 | writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR(i)); | ||
| 137 | addr >>= 8; | ||
| 138 | } | ||
| 139 | if (op->addr.nbytes == 4) { | ||
| 140 | writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR3); | ||
| 141 | mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, MTK_NOR_4B_ADDR, 0); | ||
| 142 | } else { | ||
| 143 | mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, 0, MTK_NOR_4B_ADDR); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static bool mtk_nor_match_read(const struct spi_mem_op *op) | ||
| 148 | { | ||
| 149 | int dummy = 0; | ||
| 150 | |||
| 151 | if (op->dummy.buswidth) | ||
| 152 | dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth; | ||
| 153 | |||
| 154 | if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) { | ||
| 155 | if (op->addr.buswidth == 1) | ||
| 156 | return dummy == 8; | ||
| 157 | else if (op->addr.buswidth == 2) | ||
| 158 | return dummy == 4; | ||
| 159 | else if (op->addr.buswidth == 4) | ||
| 160 | return dummy == 6; | ||
| 161 | } else if ((op->addr.buswidth == 1) && (op->data.buswidth == 1)) { | ||
| 162 | if (op->cmd.opcode == 0x03) | ||
| 163 | return dummy == 0; | ||
| 164 | else if (op->cmd.opcode == 0x0b) | ||
| 165 | return dummy == 8; | ||
| 166 | } | ||
| 167 | return false; | ||
| 168 | } | ||
| 169 | |||
| 170 | static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) | ||
| 171 | { | ||
| 172 | size_t len; | ||
| 173 | |||
| 174 | if (!op->data.nbytes) | ||
| 175 | return 0; | ||
| 176 | |||
| 177 | if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { | ||
| 178 | if ((op->data.dir == SPI_MEM_DATA_IN) && | ||
| 179 | mtk_nor_match_read(op)) { | ||
| 180 | if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) || | ||
| 181 | (op->data.nbytes < MTK_NOR_DMA_ALIGN)) | ||
| 182 | op->data.nbytes = 1; | ||
| 183 | else if (!((ulong)(op->data.buf.in) & | ||
| 184 | MTK_NOR_DMA_ALIGN_MASK)) | ||
| 185 | op->data.nbytes &= ~MTK_NOR_DMA_ALIGN_MASK; | ||
| 186 | else if (op->data.nbytes > MTK_NOR_BOUNCE_BUF_SIZE) | ||
| 187 | op->data.nbytes = MTK_NOR_BOUNCE_BUF_SIZE; | ||
| 188 | return 0; | ||
| 189 | } else if (op->data.dir == SPI_MEM_DATA_OUT) { | ||
| 190 | if (op->data.nbytes >= MTK_NOR_PP_SIZE) | ||
| 191 | op->data.nbytes = MTK_NOR_PP_SIZE; | ||
| 192 | else | ||
| 193 | op->data.nbytes = 1; | ||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | len = MTK_NOR_PRG_MAX_SIZE - sizeof(op->cmd.opcode) - op->addr.nbytes - | ||
| 199 | op->dummy.nbytes; | ||
| 200 | if (op->data.nbytes > len) | ||
| 201 | op->data.nbytes = len; | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static bool mtk_nor_supports_op(struct spi_mem *mem, | ||
| 207 | const struct spi_mem_op *op) | ||
| 208 | { | ||
| 209 | size_t len; | ||
| 210 | |||
| 211 | if (op->cmd.buswidth != 1) | ||
| 212 | return false; | ||
| 213 | |||
| 214 | if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { | ||
| 215 | if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) | ||
| 216 | return true; | ||
| 217 | else if (op->data.dir == SPI_MEM_DATA_OUT) | ||
| 218 | return (op->addr.buswidth == 1) && | ||
| 219 | (op->dummy.buswidth == 0) && | ||
| 220 | (op->data.buswidth == 1); | ||
| 221 | } | ||
| 222 | len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes; | ||
| 223 | if ((len > MTK_NOR_PRG_MAX_SIZE) || | ||
| 224 | ((op->data.nbytes) && (len == MTK_NOR_PRG_MAX_SIZE))) | ||
| 225 | return false; | ||
| 226 | return true; | ||
| 227 | } | ||
| 228 | |||
| 229 | static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op) | ||
| 230 | { | ||
| 231 | u32 reg = 0; | ||
| 232 | |||
| 233 | if (op->addr.nbytes == 4) | ||
| 234 | reg |= MTK_NOR_4B_ADDR; | ||
| 235 | |||
| 236 | if (op->data.buswidth == 4) { | ||
| 237 | reg |= MTK_NOR_QUAD_READ; | ||
| 238 | writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4)); | ||
| 239 | if (op->addr.buswidth == 4) | ||
| 240 | reg |= MTK_NOR_QUAD_ADDR; | ||
| 241 | } else if (op->data.buswidth == 2) { | ||
| 242 | reg |= MTK_NOR_DUAL_READ; | ||
| 243 | writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3)); | ||
| 244 | if (op->addr.buswidth == 2) | ||
| 245 | reg |= MTK_NOR_DUAL_ADDR; | ||
| 246 | } else { | ||
| 247 | if (op->cmd.opcode == 0x0b) | ||
| 248 | mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, MTK_NOR_FAST_READ, 0); | ||
| 249 | else | ||
| 250 | mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, 0, MTK_NOR_FAST_READ); | ||
| 251 | } | ||
| 252 | mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, reg, MTK_NOR_BUS_MODE_MASK); | ||
| 253 | } | ||
| 254 | |||
| 255 | static int mtk_nor_read_dma(struct mtk_nor *sp, u32 from, unsigned int length, | ||
| 256 | u8 *buffer) | ||
| 257 | { | ||
| 258 | int ret = 0; | ||
| 259 | ulong delay; | ||
| 260 | u32 reg; | ||
| 261 | dma_addr_t dma_addr; | ||
| 262 | |||
| 263 | dma_addr = dma_map_single(sp->dev, buffer, length, DMA_FROM_DEVICE); | ||
| 264 | if (dma_mapping_error(sp->dev, dma_addr)) { | ||
| 265 | dev_err(sp->dev, "failed to map dma buffer.\n"); | ||
| 266 | return -EINVAL; | ||
| 267 | } | ||
| 268 | |||
| 269 | writel(from, sp->base + MTK_NOR_REG_DMA_FADR); | ||
| 270 | writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR); | ||
| 271 | writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR); | ||
| 272 | |||
| 273 | if (sp->has_irq) { | ||
| 274 | reinit_completion(&sp->op_done); | ||
| 275 | mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0); | ||
| 276 | } | ||
| 277 | |||
| 278 | mtk_nor_rmw(sp, MTK_NOR_REG_DMA_CTL, MTK_NOR_DMA_START, 0); | ||
| 279 | |||
| 280 | delay = CLK_TO_US(sp, (length + 5) * BITS_PER_BYTE); | ||
| 281 | |||
| 282 | if (sp->has_irq) { | ||
| 283 | if (!wait_for_completion_timeout(&sp->op_done, | ||
| 284 | (delay + 1) * 100)) | ||
| 285 | ret = -ETIMEDOUT; | ||
| 286 | } else { | ||
| 287 | ret = readl_poll_timeout(sp->base + MTK_NOR_REG_DMA_CTL, reg, | ||
| 288 | !(reg & MTK_NOR_DMA_START), delay / 3, | ||
| 289 | (delay + 1) * 100); | ||
| 290 | } | ||
| 291 | |||
| 292 | dma_unmap_single(sp->dev, dma_addr, length, DMA_FROM_DEVICE); | ||
| 293 | if (ret < 0) | ||
| 294 | dev_err(sp->dev, "dma read timeout.\n"); | ||
| 295 | |||
| 296 | return ret; | ||
| 297 | } | ||
| 298 | |||
| 299 | static int mtk_nor_read_bounce(struct mtk_nor *sp, u32 from, | ||
| 300 | unsigned int length, u8 *buffer) | ||
| 301 | { | ||
| 302 | unsigned int rdlen; | ||
| 303 | int ret; | ||
| 304 | |||
| 305 | if (length & MTK_NOR_DMA_ALIGN_MASK) | ||
| 306 | rdlen = (length + MTK_NOR_DMA_ALIGN) & ~MTK_NOR_DMA_ALIGN_MASK; | ||
| 307 | else | ||
| 308 | rdlen = length; | ||
| 309 | |||
| 310 | ret = mtk_nor_read_dma(sp, from, rdlen, sp->buffer); | ||
| 311 | if (ret) | ||
| 312 | return ret; | ||
| 313 | |||
| 314 | memcpy(buffer, sp->buffer, length); | ||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op) | ||
| 319 | { | ||
| 320 | u8 *buf = op->data.buf.in; | ||
| 321 | int ret; | ||
| 322 | |||
| 323 | ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_READ, 6 * BITS_PER_BYTE); | ||
| 324 | if (!ret) | ||
| 325 | buf[0] = readb(sp->base + MTK_NOR_REG_RDATA); | ||
| 326 | return ret; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int mtk_nor_write_buffer_enable(struct mtk_nor *sp) | ||
| 330 | { | ||
| 331 | int ret; | ||
| 332 | u32 val; | ||
| 333 | |||
| 334 | if (sp->wbuf_en) | ||
| 335 | return 0; | ||
| 336 | |||
| 337 | val = readl(sp->base + MTK_NOR_REG_CFG2); | ||
| 338 | writel(val | MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); | ||
| 339 | ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, | ||
| 340 | val & MTK_NOR_WR_BUF_EN, 0, 10000); | ||
| 341 | if (!ret) | ||
| 342 | sp->wbuf_en = true; | ||
| 343 | return ret; | ||
| 344 | } | ||
| 345 | |||
| 346 | static int mtk_nor_write_buffer_disable(struct mtk_nor *sp) | ||
| 347 | { | ||
| 348 | int ret; | ||
| 349 | u32 val; | ||
| 350 | |||
| 351 | if (!sp->wbuf_en) | ||
| 352 | return 0; | ||
| 353 | val = readl(sp->base + MTK_NOR_REG_CFG2); | ||
| 354 | writel(val & ~MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); | ||
| 355 | ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, | ||
| 356 | !(val & MTK_NOR_WR_BUF_EN), 0, 10000); | ||
| 357 | if (!ret) | ||
| 358 | sp->wbuf_en = false; | ||
| 359 | return ret; | ||
| 360 | } | ||
| 361 | |||
| 362 | static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op) | ||
| 363 | { | ||
| 364 | const u8 *buf = op->data.buf.out; | ||
| 365 | u32 val; | ||
| 366 | int ret, i; | ||
| 367 | |||
| 368 | ret = mtk_nor_write_buffer_enable(sp); | ||
| 369 | if (ret < 0) | ||
| 370 | return ret; | ||
| 371 | |||
| 372 | for (i = 0; i < op->data.nbytes; i += 4) { | ||
| 373 | val = buf[i + 3] << 24 | buf[i + 2] << 16 | buf[i + 1] << 8 | | ||
| 374 | buf[i]; | ||
| 375 | writel(val, sp->base + MTK_NOR_REG_PP_DATA); | ||
| 376 | } | ||
| 377 | return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, | ||
| 378 | (op->data.nbytes + 5) * BITS_PER_BYTE); | ||
| 379 | } | ||
| 380 | |||
| 381 | static int mtk_nor_pp_unbuffered(struct mtk_nor *sp, | ||
| 382 | const struct spi_mem_op *op) | ||
| 383 | { | ||
| 384 | const u8 *buf = op->data.buf.out; | ||
| 385 | int ret; | ||
| 386 | |||
| 387 | ret = mtk_nor_write_buffer_disable(sp); | ||
| 388 | if (ret < 0) | ||
| 389 | return ret; | ||
| 390 | writeb(buf[0], sp->base + MTK_NOR_REG_WDATA); | ||
| 391 | return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE); | ||
| 392 | } | ||
| 393 | |||
| 394 | int mtk_nor_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) | ||
| 395 | { | ||
| 396 | struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master); | ||
| 397 | int ret; | ||
| 398 | |||
| 399 | if ((op->data.nbytes == 0) || | ||
| 400 | ((op->addr.nbytes != 3) && (op->addr.nbytes != 4))) | ||
| 401 | return -ENOTSUPP; | ||
| 402 | |||
| 403 | if (op->data.dir == SPI_MEM_DATA_OUT) { | ||
| 404 | mtk_nor_set_addr(sp, op); | ||
| 405 | writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0); | ||
| 406 | if (op->data.nbytes == MTK_NOR_PP_SIZE) | ||
| 407 | return mtk_nor_pp_buffered(sp, op); | ||
| 408 | return mtk_nor_pp_unbuffered(sp, op); | ||
| 409 | } | ||
| 410 | |||
| 411 | if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) { | ||
| 412 | ret = mtk_nor_write_buffer_disable(sp); | ||
| 413 | if (ret < 0) | ||
| 414 | return ret; | ||
| 415 | mtk_nor_setup_bus(sp, op); | ||
| 416 | if (op->data.nbytes == 1) { | ||
| 417 | mtk_nor_set_addr(sp, op); | ||
| 418 | return mtk_nor_read_pio(sp, op); | ||
| 419 | } else if (((ulong)(op->data.buf.in) & | ||
| 420 | MTK_NOR_DMA_ALIGN_MASK)) { | ||
| 421 | return mtk_nor_read_bounce(sp, op->addr.val, | ||
| 422 | op->data.nbytes, | ||
| 423 | op->data.buf.in); | ||
| 424 | } else { | ||
| 425 | return mtk_nor_read_dma(sp, op->addr.val, | ||
| 426 | op->data.nbytes, | ||
| 427 | op->data.buf.in); | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | return -ENOTSUPP; | ||
| 432 | } | ||
| 433 | |||
| 434 | static int mtk_nor_setup(struct spi_device *spi) | ||
| 435 | { | ||
| 436 | struct mtk_nor *sp = spi_controller_get_devdata(spi->master); | ||
| 437 | |||
| 438 | if (spi->max_speed_hz && (spi->max_speed_hz < sp->spi_freq)) { | ||
| 439 | dev_err(&spi->dev, "spi clock should be %u Hz.\n", | ||
| 440 | sp->spi_freq); | ||
| 441 | return -EINVAL; | ||
| 442 | } | ||
| 443 | spi->max_speed_hz = sp->spi_freq; | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static int mtk_nor_transfer_one_message(struct spi_controller *master, | ||
| 449 | struct spi_message *m) | ||
| 450 | { | ||
| 451 | struct mtk_nor *sp = spi_controller_get_devdata(master); | ||
| 452 | struct spi_transfer *t = NULL; | ||
| 453 | unsigned long trx_len = 0; | ||
| 454 | int stat = 0; | ||
| 455 | int reg_offset = MTK_NOR_REG_PRGDATA_MAX; | ||
| 456 | void __iomem *reg; | ||
| 457 | const u8 *txbuf; | ||
| 458 | u8 *rxbuf; | ||
| 459 | int i; | ||
| 460 | |||
| 461 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 462 | txbuf = t->tx_buf; | ||
| 463 | for (i = 0; i < t->len; i++, reg_offset--) { | ||
| 464 | reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); | ||
| 465 | if (txbuf) | ||
| 466 | writeb(txbuf[i], reg); | ||
| 467 | else | ||
| 468 | writeb(0, reg); | ||
| 469 | } | ||
| 470 | trx_len += t->len; | ||
| 471 | } | ||
| 472 | |||
| 473 | writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); | ||
| 474 | |||
| 475 | stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, | ||
| 476 | trx_len * BITS_PER_BYTE); | ||
| 477 | if (stat < 0) | ||
| 478 | goto msg_done; | ||
| 479 | |||
| 480 | reg_offset = trx_len - 1; | ||
| 481 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
| 482 | rxbuf = t->rx_buf; | ||
| 483 | for (i = 0; i < t->len; i++, reg_offset--) { | ||
| 484 | reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); | ||
| 485 | if (rxbuf) | ||
| 486 | rxbuf[i] = readb(reg); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | m->actual_length = trx_len; | ||
| 491 | msg_done: | ||
| 492 | m->status = stat; | ||
| 493 | spi_finalize_current_message(master); | ||
| 494 | |||
| 495 | return 0; | ||
| 496 | } | ||
| 497 | |||
| 498 | static void mtk_nor_disable_clk(struct mtk_nor *sp) | ||
| 499 | { | ||
| 500 | clk_disable_unprepare(sp->spi_clk); | ||
| 501 | clk_disable_unprepare(sp->ctlr_clk); | ||
| 502 | } | ||
| 503 | |||
| 504 | static int mtk_nor_enable_clk(struct mtk_nor *sp) | ||
| 505 | { | ||
| 506 | int ret; | ||
| 507 | |||
| 508 | ret = clk_prepare_enable(sp->spi_clk); | ||
| 509 | if (ret) | ||
| 510 | return ret; | ||
| 511 | |||
| 512 | ret = clk_prepare_enable(sp->ctlr_clk); | ||
| 513 | if (ret) { | ||
| 514 | clk_disable_unprepare(sp->spi_clk); | ||
| 515 | return ret; | ||
| 516 | } | ||
| 517 | |||
| 518 | return 0; | ||
| 519 | } | ||
| 520 | |||
| 521 | static int mtk_nor_init(struct mtk_nor *sp) | ||
| 522 | { | ||
| 523 | int ret; | ||
| 524 | |||
| 525 | ret = mtk_nor_enable_clk(sp); | ||
| 526 | if (ret) | ||
| 527 | return ret; | ||
| 528 | |||
| 529 | sp->spi_freq = clk_get_rate(sp->spi_clk); | ||
| 530 | |||
| 531 | writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); | ||
| 532 | mtk_nor_rmw(sp, MTK_NOR_REG_CFG2, MTK_NOR_WR_CUSTOM_OP_EN, 0); | ||
| 533 | mtk_nor_rmw(sp, MTK_NOR_REG_CFG3, | ||
| 534 | MTK_NOR_DISABLE_WREN | MTK_NOR_DISABLE_SR_POLL, 0); | ||
| 535 | |||
| 536 | return ret; | ||
| 537 | } | ||
| 538 | |||
| 539 | static irqreturn_t mtk_nor_irq_handler(int irq, void *data) | ||
| 540 | { | ||
| 541 | struct mtk_nor *sp = data; | ||
| 542 | u32 irq_status, irq_enabled; | ||
| 543 | |||
| 544 | irq_status = readl(sp->base + MTK_NOR_REG_IRQ_STAT); | ||
| 545 | irq_enabled = readl(sp->base + MTK_NOR_REG_IRQ_EN); | ||
| 546 | // write status back to clear interrupt | ||
| 547 | writel(irq_status, sp->base + MTK_NOR_REG_IRQ_STAT); | ||
| 548 | |||
| 549 | if (!(irq_status & irq_enabled)) | ||
| 550 | return IRQ_NONE; | ||
| 551 | |||
| 552 | if (irq_status & MTK_NOR_IRQ_DMA) { | ||
| 553 | complete(&sp->op_done); | ||
| 554 | writel(0, sp->base + MTK_NOR_REG_IRQ_EN); | ||
| 555 | } | ||
| 556 | |||
| 557 | return IRQ_HANDLED; | ||
| 558 | } | ||
| 559 | |||
| 560 | static size_t mtk_max_msg_size(struct spi_device *spi) | ||
| 561 | { | ||
| 562 | return MTK_NOR_PRG_MAX_SIZE; | ||
| 563 | } | ||
| 564 | |||
| 565 | static const struct spi_controller_mem_ops mtk_nor_mem_ops = { | ||
| 566 | .adjust_op_size = mtk_nor_adjust_op_size, | ||
| 567 | .supports_op = mtk_nor_supports_op, | ||
| 568 | .exec_op = mtk_nor_exec_op | ||
| 569 | }; | ||
| 570 | |||
| 571 | static const struct of_device_id mtk_nor_match[] = { | ||
| 572 | { .compatible = "mediatek,mt8173-nor" }, | ||
| 573 | { /* sentinel */ } | ||
| 574 | }; | ||
| 575 | MODULE_DEVICE_TABLE(of, mtk_nor_match); | ||
| 576 | |||
| 577 | static int mtk_nor_probe(struct platform_device *pdev) | ||
| 578 | { | ||
| 579 | struct spi_controller *ctlr; | ||
| 580 | struct mtk_nor *sp; | ||
| 581 | void __iomem *base; | ||
| 582 | u8 *buffer; | ||
| 583 | struct clk *spi_clk, *ctlr_clk; | ||
| 584 | int ret, irq; | ||
| 585 | |||
| 586 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 587 | if (IS_ERR(base)) | ||
| 588 | return PTR_ERR(base); | ||
| 589 | |||
| 590 | spi_clk = devm_clk_get(&pdev->dev, "spi"); | ||
| 591 | if (IS_ERR(spi_clk)) | ||
| 592 | return PTR_ERR(spi_clk); | ||
| 593 | |||
| 594 | ctlr_clk = devm_clk_get(&pdev->dev, "sf"); | ||
| 595 | if (IS_ERR(ctlr_clk)) | ||
| 596 | return PTR_ERR(ctlr_clk); | ||
| 597 | |||
| 598 | buffer = devm_kmalloc(&pdev->dev, | ||
| 599 | MTK_NOR_BOUNCE_BUF_SIZE + MTK_NOR_DMA_ALIGN, | ||
| 600 | GFP_KERNEL); | ||
| 601 | if (!buffer) | ||
| 602 | return -ENOMEM; | ||
| 603 | |||
| 604 | if ((ulong)buffer & MTK_NOR_DMA_ALIGN_MASK) | ||
| 605 | buffer = (u8 *)(((ulong)buffer + MTK_NOR_DMA_ALIGN) & | ||
| 606 | ~MTK_NOR_DMA_ALIGN_MASK); | ||
| 607 | |||
| 608 | ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp)); | ||
| 609 | if (!ctlr) { | ||
| 610 | dev_err(&pdev->dev, "failed to allocate spi controller\n"); | ||
| 611 | return -ENOMEM; | ||
| 612 | } | ||
| 613 | |||
| 614 | ctlr->bits_per_word_mask = SPI_BPW_MASK(8); | ||
| 615 | ctlr->dev.of_node = pdev->dev.of_node; | ||
| 616 | ctlr->max_message_size = mtk_max_msg_size; | ||
| 617 | ctlr->mem_ops = &mtk_nor_mem_ops; | ||
| 618 | ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; | ||
| 619 | ctlr->num_chipselect = 1; | ||
| 620 | ctlr->setup = mtk_nor_setup; | ||
| 621 | ctlr->transfer_one_message = mtk_nor_transfer_one_message; | ||
| 622 | |||
| 623 | dev_set_drvdata(&pdev->dev, ctlr); | ||
| 624 | |||
| 625 | sp = spi_controller_get_devdata(ctlr); | ||
| 626 | sp->base = base; | ||
| 627 | sp->buffer = buffer; | ||
| 628 | sp->has_irq = false; | ||
| 629 | sp->wbuf_en = false; | ||
| 630 | sp->ctlr = ctlr; | ||
| 631 | sp->dev = &pdev->dev; | ||
| 632 | sp->spi_clk = spi_clk; | ||
| 633 | sp->ctlr_clk = ctlr_clk; | ||
| 634 | |||
| 635 | irq = platform_get_irq_optional(pdev, 0); | ||
| 636 | if (irq < 0) { | ||
| 637 | dev_warn(sp->dev, "IRQ not available."); | ||
| 638 | } else { | ||
| 639 | writel(MTK_NOR_IRQ_MASK, base + MTK_NOR_REG_IRQ_STAT); | ||
| 640 | writel(0, base + MTK_NOR_REG_IRQ_EN); | ||
| 641 | ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0, | ||
| 642 | pdev->name, sp); | ||
| 643 | if (ret < 0) { | ||
| 644 | dev_warn(sp->dev, "failed to request IRQ."); | ||
| 645 | } else { | ||
| 646 | init_completion(&sp->op_done); | ||
| 647 | sp->has_irq = true; | ||
| 648 | } | ||
| 649 | } | ||
| 650 | |||
| 651 | ret = mtk_nor_init(sp); | ||
| 652 | if (ret < 0) { | ||
| 653 | kfree(ctlr); | ||
| 654 | return ret; | ||
| 655 | } | ||
| 656 | |||
| 657 | dev_info(&pdev->dev, "spi frequency: %d Hz\n", sp->spi_freq); | ||
| 658 | |||
| 659 | return devm_spi_register_controller(&pdev->dev, ctlr); | ||
| 660 | } | ||
| 661 | |||
| 662 | static int mtk_nor_remove(struct platform_device *pdev) | ||
| 663 | { | ||
| 664 | struct spi_controller *ctlr; | ||
| 665 | struct mtk_nor *sp; | ||
| 666 | |||
| 667 | ctlr = dev_get_drvdata(&pdev->dev); | ||
| 668 | sp = spi_controller_get_devdata(ctlr); | ||
| 669 | |||
| 670 | mtk_nor_disable_clk(sp); | ||
| 671 | |||
| 672 | return 0; | ||
| 673 | } | ||
| 674 | |||
| 675 | static struct platform_driver mtk_nor_driver = { | ||
| 676 | .driver = { | ||
| 677 | .name = DRIVER_NAME, | ||
| 678 | .of_match_table = mtk_nor_match, | ||
| 679 | }, | ||
| 680 | .probe = mtk_nor_probe, | ||
| 681 | .remove = mtk_nor_remove, | ||
| 682 | }; | ||
| 683 | |||
| 684 | module_platform_driver(mtk_nor_driver); | ||
| 685 | |||
| 686 | MODULE_DESCRIPTION("Mediatek SPI NOR controller driver"); | ||
| 687 | MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>"); | ||
| 688 | MODULE_LICENSE("GPL v2"); | ||
| 689 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
| @@ -0,0 +1,187 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // | ||
| 3 | // General Purpose SPI multiplexer | ||
| 4 | |||
| 5 | #include <linux/err.h> | ||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <linux/mux/consumer.h> | ||
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/spi/spi.h> | ||
| 11 | |||
| 12 | #define SPI_MUX_NO_CS ((unsigned int)-1) | ||
| 13 | |||
| 14 | /** | ||
| 15 | * DOC: Driver description | ||
| 16 | * | ||
| 17 | * This driver supports a MUX on an SPI bus. This can be useful when you need | ||
| 18 | * more chip selects than the hardware peripherals support, or than are | ||
| 19 | * available in a particular board setup. | ||
| 20 | * | ||
| 21 | * The driver will create an additional SPI controller. Devices added under the | ||
| 22 | * mux will be handled as 'chip selects' on this controller. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /** | ||
| 26 | * struct spi_mux_priv - the basic spi_mux structure | ||
| 27 | * @spi: pointer to the device struct attached to the parent | ||
| 28 | * spi controller | ||
| 29 | * @current_cs: The current chip select set in the mux | ||
| 30 | * @child_msg_complete: The mux replaces the complete callback in the child's | ||
| 31 | * message to its own callback; this field is used by the | ||
| 32 | * driver to store the child's callback during a transfer | ||
| 33 | * @child_msg_context: Used to store the child's context to the callback | ||
| 34 | * @child_msg_dev: Used to store the spi_device pointer to the child | ||
| 35 | * @mux: mux_control structure used to provide chip selects for | ||
| 36 | * downstream spi devices | ||
| 37 | */ | ||
| 38 | struct spi_mux_priv { | ||
| 39 | struct spi_device *spi; | ||
| 40 | unsigned int current_cs; | ||
| 41 | |||
| 42 | void (*child_msg_complete)(void *context); | ||
| 43 | void *child_msg_context; | ||
| 44 | struct spi_device *child_msg_dev; | ||
| 45 | struct mux_control *mux; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* should not get called when the parent controller is doing a transfer */ | ||
| 49 | static int spi_mux_select(struct spi_device *spi) | ||
| 50 | { | ||
| 51 | struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller); | ||
| 52 | int ret; | ||
| 53 | |||
| 54 | if (priv->current_cs == spi->chip_select) | ||
| 55 | return 0; | ||
| 56 | |||
| 57 | dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n", | ||
| 58 | spi->chip_select); | ||
| 59 | |||
| 60 | /* copy the child device's settings except for the cs */ | ||
| 61 | priv->spi->max_speed_hz = spi->max_speed_hz; | ||
| 62 | priv->spi->mode = spi->mode; | ||
| 63 | priv->spi->bits_per_word = spi->bits_per_word; | ||
| 64 | |||
| 65 | ret = mux_control_select(priv->mux, spi->chip_select); | ||
| 66 | if (ret) | ||
| 67 | return ret; | ||
| 68 | |||
| 69 | priv->current_cs = spi->chip_select; | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int spi_mux_setup(struct spi_device *spi) | ||
| 75 | { | ||
| 76 | struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller); | ||
| 77 | |||
| 78 | /* | ||
| 79 | * can be called multiple times, won't do a valid setup now but we will | ||
| 80 | * change the settings when we do a transfer (necessary because we | ||
| 81 | * can't predict from which device it will be anyway) | ||
| 82 | */ | ||
| 83 | return spi_setup(priv->spi); | ||
| 84 | } | ||
| 85 | |||
| 86 | static void spi_mux_complete_cb(void *context) | ||
| 87 | { | ||
| 88 | struct spi_mux_priv *priv = (struct spi_mux_priv *)context; | ||
| 89 | struct spi_controller *ctlr = spi_get_drvdata(priv->spi); | ||
| 90 | struct spi_message *m = ctlr->cur_msg; | ||
| 91 | |||
| 92 | m->complete = priv->child_msg_complete; | ||
| 93 | m->context = priv->child_msg_context; | ||
| 94 | m->spi = priv->child_msg_dev; | ||
| 95 | spi_finalize_current_message(ctlr); | ||
| 96 | mux_control_deselect(priv->mux); | ||
| 97 | } | ||
| 98 | |||
| 99 | static int spi_mux_transfer_one_message(struct spi_controller *ctlr, | ||
| 100 | struct spi_message *m) | ||
| 101 | { | ||
| 102 | struct spi_mux_priv *priv = spi_controller_get_devdata(ctlr); | ||
| 103 | struct spi_device *spi = m->spi; | ||
| 104 | int ret; | ||
| 105 | |||
| 106 | ret = spi_mux_select(spi); | ||
| 107 | if (ret) | ||
| 108 | return ret; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Replace the complete callback, context and spi_device with our own | ||
| 112 | * pointers. Save originals | ||
| 113 | */ | ||
| 114 | priv->child_msg_complete = m->complete; | ||
| 115 | priv->child_msg_context = m->context; | ||
| 116 | priv->child_msg_dev = m->spi; | ||
| 117 | |||
| 118 | m->complete = spi_mux_complete_cb; | ||
| 119 | m->context = priv; | ||
| 120 | m->spi = priv->spi; | ||
| 121 | |||
| 122 | /* do the transfer */ | ||
| 123 | return spi_async(priv->spi, m); | ||
| 124 | } | ||
| 125 | |||
| 126 | static int spi_mux_probe(struct spi_device *spi) | ||
| 127 | { | ||
| 128 | struct spi_controller *ctlr; | ||
| 129 | struct spi_mux_priv *priv; | ||
| 130 | int ret; | ||
| 131 | |||
| 132 | ctlr = spi_alloc_master(&spi->dev, sizeof(*priv)); | ||
| 133 | if (!ctlr) | ||
| 134 | return -ENOMEM; | ||
| 135 | |||
| 136 | spi_set_drvdata(spi, ctlr); | ||
| 137 | priv = spi_controller_get_devdata(ctlr); | ||
| 138 | priv->spi = spi; | ||
| 139 | |||
| 140 | priv->mux = devm_mux_control_get(&spi->dev, NULL); | ||
| 141 | if (IS_ERR(priv->mux)) { | ||
| 142 | ret = PTR_ERR(priv->mux); | ||
| 143 | if (ret != -EPROBE_DEFER) | ||
| 144 | dev_err(&spi->dev, "failed to get control-mux\n"); | ||
| 145 | goto err_put_ctlr; | ||
| 146 | } | ||
| 147 | |||
| 148 | priv->current_cs = SPI_MUX_NO_CS; | ||
| 149 | |||
| 150 | /* supported modes are the same as our parent's */ | ||
| 151 | ctlr->mode_bits = spi->controller->mode_bits; | ||
| 152 | ctlr->flags = spi->controller->flags; | ||
| 153 | ctlr->transfer_one_message = spi_mux_transfer_one_message; | ||
| 154 | ctlr->setup = spi_mux_setup; | ||
| 155 | ctlr->num_chipselect = mux_control_states(priv->mux); | ||
| 156 | ctlr->bus_num = -1; | ||
| 157 | ctlr->dev.of_node = spi->dev.of_node; | ||
| 158 | |||
| 159 | ret = devm_spi_register_controller(&spi->dev, ctlr); | ||
| 160 | if (ret) | ||
| 161 | goto err_put_ctlr; | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | |||
| 165 | err_put_ctlr: | ||
| 166 | spi_controller_put(ctlr); | ||
| 167 | |||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static const struct of_device_id spi_mux_of_match[] = { | ||
| 172 | { .compatible = "spi-mux" }, | ||
| 173 | { } | ||
| 174 | }; | ||
| 175 | |||
| 176 | static struct spi_driver spi_mux_driver = { | ||
| 177 | .probe = spi_mux_probe, | ||
| 178 | .driver = { | ||
| 179 | .name = "spi-mux", | ||
| 180 | .of_match_table = spi_mux_of_match, | ||
| 181 | }, | ||
| 182 | }; | ||
| 183 | |||
| 184 | module_spi_driver(spi_mux_driver); | ||
| 185 | |||
| 186 | MODULE_DESCRIPTION("SPI multiplexer"); | ||
| 187 | MODULE_LICENSE("GPL"); | ||
| @@ -22,7 +22,6 @@ · 21 unmodified lines | |||
| 22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
| 23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 24 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
| 25 | #include <linux/of_gpio.h> | ||
| 26 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 28 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| @@ -32,7 +31,7 @@ · 3 unmodified lines | |||
| 32 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
| 33 | #include <linux/err.h> | 32 | #include <linux/err.h> |
| 34 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
| 35 | #include <linux/gpio.h> | 34 | #include <linux/pinctrl/consumer.h> |
| 36 | #include <linux/regulator/consumer.h> | 35 | #include <linux/regulator/consumer.h> |
| 37 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
| 38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
| @@ -307,6 +307,7 @@ · 306 unmodified lines | |||
| 307 | 307 | ||
| 308 | #define POLL_TOUT 5000 | 308 | #define POLL_TOUT 5000 |
| 309 | #define NXP_FSPI_MAX_CHIPSELECT 4 | 309 | #define NXP_FSPI_MAX_CHIPSELECT 4 |
| 310 | #define NXP_FSPI_MIN_IOMAP SZ_4M | ||
| 310 | 311 | ||
| 311 | struct nxp_fspi_devtype_data { | 312 | struct nxp_fspi_devtype_data { |
| 312 | unsigned int rxfifo; | 313 | unsigned int rxfifo; |
| @@ -324,11 +325,29 @@ static const struct nxp_fspi_devtype_data lx2160a_data = { · 11 unmodified lines | |||
| 324 | .little_endian = true, /* little-endian */ | 325 | .little_endian = true, /* little-endian */ |
| 325 | }; | 326 | }; |
| 326 | 327 | ||
| 328 | static const struct nxp_fspi_devtype_data imx8mm_data = { | ||
| 329 | .rxfifo = SZ_512, /* (64 * 64 bits) */ | ||
| 330 | .txfifo = SZ_1K, /* (128 * 64 bits) */ | ||
| 331 | .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ | ||
| 332 | .quirks = 0, | ||
| 333 | .little_endian = true, /* little-endian */ | ||
| 334 | }; | ||
| 335 | |||
| 336 | static const struct nxp_fspi_devtype_data imx8qxp_data = { | ||
| 337 | .rxfifo = SZ_512, /* (64 * 64 bits) */ | ||
| 338 | .txfifo = SZ_1K, /* (128 * 64 bits) */ | ||
| 339 | .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ | ||
| 340 | .quirks = 0, | ||
| 341 | .little_endian = true, /* little-endian */ | ||
| 342 | }; | ||
| 343 | |||
| 327 | struct nxp_fspi { | 344 | struct nxp_fspi { |
| 328 | void __iomem *iobase; | 345 | void __iomem *iobase; |
| 329 | void __iomem *ahb_addr; | 346 | void __iomem *ahb_addr; |
| 330 | u32 memmap_phy; | 347 | u32 memmap_phy; |
| 331 | u32 memmap_phy_size; | 348 | u32 memmap_phy_size; |
| 349 | u32 memmap_start; | ||
| 350 | u32 memmap_len; | ||
| 332 | struct clk *clk, *clk_en; | 351 | struct clk *clk, *clk_en; |
| 333 | struct device *dev; | 352 | struct device *dev; |
| 334 | struct completion c; | 353 | struct completion c; |
| @@ -641,12 +660,35 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi) · 306 unmodified lines | |||
| 641 | f->selected = spi->chip_select; | 660 | f->selected = spi->chip_select; |
| 642 | } | 661 | } |
| 643 | 662 | ||
| 644 | static void nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) | 663 | static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) |
| 645 | { | 664 | { |
| 665 | u32 start = op->addr.val; | ||
| 646 | u32 len = op->data.nbytes; | 666 | u32 len = op->data.nbytes; |
| 647 | 667 | ||
| 668 | /* if necessary, ioremap before AHB read */ | ||
| 669 | if ((!f->ahb_addr) || start < f->memmap_start || | ||
| 670 | start + len > f->memmap_start + f->memmap_len) { | ||
| 671 | if (f->ahb_addr) | ||
| 672 | iounmap(f->ahb_addr); | ||
| 673 | |||
| 674 | f->memmap_start = start; | ||
| 675 | f->memmap_len = len > NXP_FSPI_MIN_IOMAP ? | ||
| 676 | len : NXP_FSPI_MIN_IOMAP; | ||
| 677 | |||
| 678 | f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start, | ||
| 679 | f->memmap_len); | ||
| 680 | |||
| 681 | if (!f->ahb_addr) { | ||
| 682 | dev_err(f->dev, "failed to alloc memory\n"); | ||
| 683 | return -ENOMEM; | ||
| 684 | } | ||
| 685 | } | ||
| 686 | |||
| 648 | /* Read out the data directly from the AHB buffer. */ | 687 | /* Read out the data directly from the AHB buffer. */ |
| 649 | memcpy_fromio(op->data.buf.in, (f->ahb_addr + op->addr.val), len); | 688 | memcpy_fromio(op->data.buf.in, |
| 689 | f->ahb_addr + start - f->memmap_start, len); | ||
| 690 | |||
| 691 | return 0; | ||
| 650 | } | 692 | } |
| 651 | 693 | ||
| 652 | static void nxp_fspi_fill_txfifo(struct nxp_fspi *f, | 694 | static void nxp_fspi_fill_txfifo(struct nxp_fspi *f, |
| @@ -806,7 +848,7 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) · 153 unmodified lines | |||
| 806 | */ | 848 | */ |
| 807 | if (op->data.nbytes > (f->devtype_data->rxfifo - 4) && | 849 | if (op->data.nbytes > (f->devtype_data->rxfifo - 4) && |
| 808 | op->data.dir == SPI_MEM_DATA_IN) { | 850 | op->data.dir == SPI_MEM_DATA_IN) { |
| 809 | nxp_fspi_read_ahb(f, op); | 851 | err = nxp_fspi_read_ahb(f, op); |
| 810 | } else { | 852 | } else { |
| 811 | if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) | 853 | if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) |
| 812 | nxp_fspi_fill_txfifo(f, op); | 854 | nxp_fspi_fill_txfifo(f, op); |
| @@ -871,8 +913,9 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) · 58 unmodified lines | |||
| 871 | fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR); | 913 | fspi_writel(f, FSPI_DLLBCR_OVRDEN, base + FSPI_DLLBCR); |
| 872 | 914 | ||
| 873 | /* enable module */ | 915 | /* enable module */ |
| 874 | fspi_writel(f, FSPI_MCR0_AHB_TIMEOUT(0xFF) | FSPI_MCR0_IP_TIMEOUT(0xFF), | 916 | fspi_writel(f, FSPI_MCR0_AHB_TIMEOUT(0xFF) | |
| 875 | base + FSPI_MCR0); | 917 | FSPI_MCR0_IP_TIMEOUT(0xFF) | (u32) FSPI_MCR0_OCTCOMB_EN, |
| 918 | base + FSPI_MCR0); | ||
| 876 | 919 | ||
| 877 | /* | 920 | /* |
| 878 | * Disable same device enable bit and configure all slave devices | 921 | * Disable same device enable bit and configure all slave devices |
| @@ -976,9 +1019,8 @@ static int nxp_fspi_probe(struct platform_device *pdev) · 97 unmodified lines | |||
| 976 | 1019 | ||
| 977 | /* find the resources - controller memory mapped space */ | 1020 | /* find the resources - controller memory mapped space */ |
| 978 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap"); | 1021 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap"); |
| 979 | f->ahb_addr = devm_ioremap_resource(dev, res); | 1022 | if (!res) { |
| 980 | if (IS_ERR(f->ahb_addr)) { | 1023 | ret = -ENODEV; |
| 981 | ret = PTR_ERR(f->ahb_addr); | ||
| 982 | goto err_put_ctrl; | 1024 | goto err_put_ctrl; |
| 983 | } | 1025 | } |
| 984 | 1026 | ||
| @@ -1057,6 +1099,9 @@ static int nxp_fspi_remove(struct platform_device *pdev) · 72 unmodified lines | |||
| 1057 | 1099 | ||
| 1058 | mutex_destroy(&f->lock); | 1100 | mutex_destroy(&f->lock); |
| 1059 | 1101 | ||
| 1102 | if (f->ahb_addr) | ||
| 1103 | iounmap(f->ahb_addr); | ||
| 1104 | |||
| 1060 | return 0; | 1105 | return 0; |
| 1061 | } | 1106 | } |
| 1062 | 1107 | ||
| @@ -1076,6 +1121,8 @@ static int nxp_fspi_resume(struct device *dev) · 13 unmodified lines | |||
| 1076 | 1121 | ||
| 1077 | static const struct of_device_id nxp_fspi_dt_ids[] = { | 1122 | static const struct of_device_id nxp_fspi_dt_ids[] = { |
| 1078 | { .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, }, | 1123 | { .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, }, |
| 1124 | { .compatible = "nxp,imx8mm-fspi", .data = (void *)&imx8mm_data, }, | ||
| 1125 | { .compatible = "nxp,imx8qxp-fspi", .data = (void *)&imx8qxp_data, }, | ||
| 1079 | { /* sentinel */ } | 1126 | { /* sentinel */ } |
| 1080 | }; | 1127 | }; |
| 1081 | MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids); | 1128 | MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids); |
| @@ -192,6 +192,11 @@ static bool is_quark_x1000_ssp(const struct driver_data *drv_data) · 191 unmodified lines | |||
| 192 | return drv_data->ssp_type == QUARK_X1000_SSP; | 192 | return drv_data->ssp_type == QUARK_X1000_SSP; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static bool is_mmp2_ssp(const struct driver_data *drv_data) | ||
| 196 | { | ||
| 197 | return drv_data->ssp_type == MMP2_SSP; | ||
| 198 | } | ||
| 199 | |||
| 195 | static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) | 200 | static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data) |
| 196 | { | 201 | { |
| 197 | switch (drv_data->ssp_type) { | 202 | switch (drv_data->ssp_type) { |
| @@ -486,8 +491,8 @@ int pxa2xx_spi_flush(struct driver_data *drv_data) · 288 unmodified lines | |||
| 486 | 491 | ||
| 487 | static void pxa2xx_spi_off(struct driver_data *drv_data) | 492 | static void pxa2xx_spi_off(struct driver_data *drv_data) |
| 488 | { | 493 | { |
| 489 | /* On MMP, disabling SSE seems to corrupt the rx fifo */ | 494 | /* On MMP, disabling SSE seems to corrupt the Rx FIFO */ |
| 490 | if (drv_data->ssp_type == MMP2_SSP) | 495 | if (is_mmp2_ssp(drv_data)) |
| 491 | return; | 496 | return; |
| 492 | 497 | ||
| 493 | pxa2xx_spi_write(drv_data, SSCR0, | 498 | pxa2xx_spi_write(drv_data, SSCR0, |
| @@ -1093,7 +1098,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, · 599 unmodified lines | |||
| 1093 | || (pxa2xx_spi_read(drv_data, SSCR1) & change_mask) | 1098 | || (pxa2xx_spi_read(drv_data, SSCR1) & change_mask) |
| 1094 | != (cr1 & change_mask)) { | 1099 | != (cr1 & change_mask)) { |
| 1095 | /* stop the SSP, and update the other bits */ | 1100 | /* stop the SSP, and update the other bits */ |
| 1096 | if (drv_data->ssp_type != MMP2_SSP) | 1101 | if (!is_mmp2_ssp(drv_data)) |
| 1097 | pxa2xx_spi_write(drv_data, SSCR0, cr0 & ~SSCR0_SSE); | 1102 | pxa2xx_spi_write(drv_data, SSCR0, cr0 & ~SSCR0_SSE); |
| 1098 | if (!pxa25x_ssp_comp(drv_data)) | 1103 | if (!pxa25x_ssp_comp(drv_data)) |
| 1099 | pxa2xx_spi_write(drv_data, SSTO, chip->timeout); | 1104 | pxa2xx_spi_write(drv_data, SSTO, chip->timeout); |
| @@ -1107,7 +1112,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, · 7 unmodified lines | |||
| 1107 | pxa2xx_spi_write(drv_data, SSTO, chip->timeout); | 1112 | pxa2xx_spi_write(drv_data, SSTO, chip->timeout); |
| 1108 | } | 1113 | } |
| 1109 | 1114 | ||
| 1110 | if (drv_data->ssp_type == MMP2_SSP) { | 1115 | if (is_mmp2_ssp(drv_data)) { |
| 1111 | u8 tx_level = (pxa2xx_spi_read(drv_data, SSSR) | 1116 | u8 tx_level = (pxa2xx_spi_read(drv_data, SSSR) |
| 1112 | & SSSR_TFL_MASK) >> 8; | 1117 | & SSSR_TFL_MASK) >> 8; |
| 1113 | 1118 | ||
| @@ -1571,18 +1576,18 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) · 457 unmodified lines | |||
| 1571 | else if (pcidev_id) | 1576 | else if (pcidev_id) |
| 1572 | type = (enum pxa_ssp_type)pcidev_id->driver_data; | 1577 | type = (enum pxa_ssp_type)pcidev_id->driver_data; |
| 1573 | else | 1578 | else |
| 1574 | return NULL; | 1579 | return ERR_PTR(-EINVAL); |
| 1575 | 1580 | ||
| 1576 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 1581 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
| 1577 | if (!pdata) | 1582 | if (!pdata) |
| 1578 | return NULL; | 1583 | return ERR_PTR(-ENOMEM); |
| 1579 | 1584 | ||
| 1580 | ssp = &pdata->ssp; | 1585 | ssp = &pdata->ssp; |
| 1581 | 1586 | ||
| 1582 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1587 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1583 | ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res); | 1588 | ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res); |
| 1584 | if (IS_ERR(ssp->mmio_base)) | 1589 | if (IS_ERR(ssp->mmio_base)) |
| 1585 | return NULL; | 1590 | return ERR_CAST(ssp->mmio_base); |
| 1586 | 1591 | ||
| 1587 | ssp->phys_base = res->start; | 1592 | ssp->phys_base = res->start; |
| 1588 | 1593 | ||
| @@ -1596,11 +1601,11 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) · 7 unmodified lines | |||
| 1596 | 1601 | ||
| 1597 | ssp->clk = devm_clk_get(&pdev->dev, NULL); | 1602 | ssp->clk = devm_clk_get(&pdev->dev, NULL); |
| 1598 | if (IS_ERR(ssp->clk)) | 1603 | if (IS_ERR(ssp->clk)) |
| 1599 | return NULL; | 1604 | return ERR_CAST(ssp->clk); |
| 1600 | 1605 | ||
| 1601 | ssp->irq = platform_get_irq(pdev, 0); | 1606 | ssp->irq = platform_get_irq(pdev, 0); |
| 1602 | if (ssp->irq < 0) | 1607 | if (ssp->irq < 0) |
| 1603 | return NULL; | 1608 | return ERR_PTR(ssp->irq); |
| 1604 | 1609 | ||
| 1605 | ssp->type = type; | 1610 | ssp->type = type; |
| 1606 | ssp->dev = &pdev->dev; | 1611 | ssp->dev = &pdev->dev; |
| @@ -1657,9 +1662,9 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) · 50 unmodified lines | |||
| 1657 | platform_info = dev_get_platdata(dev); | 1662 | platform_info = dev_get_platdata(dev); |
| 1658 | if (!platform_info) { | 1663 | if (!platform_info) { |
| 1659 | platform_info = pxa2xx_spi_init_pdata(pdev); | 1664 | platform_info = pxa2xx_spi_init_pdata(pdev); |
| 1660 | if (!platform_info) { | 1665 | if (IS_ERR(platform_info)) { |
| 1661 | dev_err(&pdev->dev, "missing platform data\n"); | 1666 | dev_err(&pdev->dev, "missing platform data\n"); |
| 1662 | return -ENODEV; | 1667 | return PTR_ERR(platform_info); |
| 1663 | } | 1668 | } |
| 1664 | } | 1669 | } |
| 1665 | 1670 | ||
| @@ -1907,11 +1912,7 @@ out_error_controller_alloc: · 241 unmodified lines | |||
| 1907 | static int pxa2xx_spi_remove(struct platform_device *pdev) | 1912 | static int pxa2xx_spi_remove(struct platform_device *pdev) |
| 1908 | { | 1913 | { |
| 1909 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1914 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
| 1910 | struct ssp_device *ssp; | 1915 | struct ssp_device *ssp = drv_data->ssp; |
| 1911 | |||
| 1912 | if (!drv_data) | ||
| 1913 | return 0; | ||
| 1914 | ssp = drv_data->ssp; | ||
| 1915 | 1916 | ||
| 1916 | pm_runtime_get_sync(&pdev->dev); | 1917 | pm_runtime_get_sync(&pdev->dev); |
| 1917 | 1918 | ||
| @@ -843,14 +843,17 @@ static const struct dev_pm_ops rockchip_spi_pm = { · 842 unmodified lines | |||
| 843 | }; | 843 | }; |
| 844 | 844 | ||
| 845 | static const struct of_device_id rockchip_spi_dt_match[] = { | 845 | static const struct of_device_id rockchip_spi_dt_match[] = { |
| 846 | { .compatible = "rockchip,rv1108-spi", }, | 846 | { .compatible = "rockchip,px30-spi", }, |
| 847 | { .compatible = "rockchip,rk3036-spi", }, | 847 | { .compatible = "rockchip,rk3036-spi", }, |
| 848 | { .compatible = "rockchip,rk3066-spi", }, | 848 | { .compatible = "rockchip,rk3066-spi", }, |
| 849 | { .compatible = "rockchip,rk3188-spi", }, | 849 | { .compatible = "rockchip,rk3188-spi", }, |
| 850 | { .compatible = "rockchip,rk3228-spi", }, | 850 | { .compatible = "rockchip,rk3228-spi", }, |
| 851 | { .compatible = "rockchip,rk3288-spi", }, | 851 | { .compatible = "rockchip,rk3288-spi", }, |
| 852 | { .compatible = "rockchip,rk3308-spi", }, | ||
| 853 | { .compatible = "rockchip,rk3328-spi", }, | ||
| 852 | { .compatible = "rockchip,rk3368-spi", }, | 854 | { .compatible = "rockchip,rk3368-spi", }, |
| 853 | { .compatible = "rockchip,rk3399-spi", }, | 855 | { .compatible = "rockchip,rk3399-spi", }, |
| 856 | { .compatible = "rockchip,rv1108-spi", }, | ||
| 854 | { }, | 857 | { }, |
| 855 | }; | 858 | }; |
| 856 | MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match); | 859 | MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match); |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #include <linux/sh_dma.h> | 24 | #include <linux/sh_dma.h> |
| 25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| 26 | #include <linux/spi/rspi.h> | 26 | #include <linux/spi/rspi.h> |
| 27 | #include <linux/spinlock.h> | ||
| 27 | 28 | ||
| 28 | #define RSPI_SPCR 0x00 /* Control Register */ | 29 | #define RSPI_SPCR 0x00 /* Control Register */ |
| 29 | #define RSPI_SSLP 0x01 /* Slave Select Polarity Register */ | 30 | #define RSPI_SSLP 0x01 /* Slave Select Polarity Register */ |
| @@ -79,8 +80,7 @@ · 49 unmodified lines | |||
| 79 | #define SPCR_BSWAP 0x01 /* Byte Swap of read-data for DMAC */ | 80 | #define SPCR_BSWAP 0x01 /* Byte Swap of read-data for DMAC */ |
| 80 | 81 | ||
| 81 | /* SSLP - Slave Select Polarity Register */ | 82 | /* SSLP - Slave Select Polarity Register */ |
| 82 | #define SSLP_SSL1P 0x02 /* SSL1 Signal Polarity Setting */ | 83 | #define SSLP_SSLP(i) BIT(i) /* SSLi Signal Polarity Setting */ |
| 83 | #define SSLP_SSL0P 0x01 /* SSL0 Signal Polarity Setting */ | ||
| 84 | 84 | ||
| 85 | /* SPPCR - Pin Control Register */ | 85 | /* SPPCR - Pin Control Register */ |
| 86 | #define SPPCR_MOIFE 0x20 /* MOSI Idle Value Fixing Enable */ | 86 | #define SPPCR_MOIFE 0x20 /* MOSI Idle Value Fixing Enable */ |
| @@ -181,7 +181,9 @@ struct rspi_data { · 94 unmodified lines | |||
| 181 | void __iomem *addr; | 181 | void __iomem *addr; |
| 182 | u32 max_speed_hz; | 182 | u32 max_speed_hz; |
| 183 | struct spi_controller *ctlr; | 183 | struct spi_controller *ctlr; |
| 184 | struct platform_device *pdev; | ||
| 184 | wait_queue_head_t wait; | 185 | wait_queue_head_t wait; |
| 186 | spinlock_t lock; /* Protects RMW-access to RSPI_SSLP */ | ||
| 185 | struct clk *clk; | 187 | struct clk *clk; |
| 186 | u16 spcmd; | 188 | u16 spcmd; |
| 187 | u8 spsr; | 189 | u8 spsr; |
| @@ -239,7 +241,7 @@ struct spi_ops { · 51 unmodified lines | |||
| 239 | int (*set_config_register)(struct rspi_data *rspi, int access_size); | 241 | int (*set_config_register)(struct rspi_data *rspi, int access_size); |
| 240 | int (*transfer_one)(struct spi_controller *ctlr, | 242 | int (*transfer_one)(struct spi_controller *ctlr, |
| 241 | struct spi_device *spi, struct spi_transfer *xfer); | 243 | struct spi_device *spi, struct spi_transfer *xfer); |
| 242 | u16 mode_bits; | 244 | u16 extra_mode_bits; |
| 243 | u16 flags; | 245 | u16 flags; |
| 244 | u16 fifo_size; | 246 | u16 fifo_size; |
| 245 | u8 num_hw_ss; | 247 | u8 num_hw_ss; |
| @@ -919,6 +921,29 @@ static int qspi_setup_sequencer(struct rspi_data *rspi, · 673 unmodified lines | |||
| 919 | return 0; | 921 | return 0; |
| 920 | } | 922 | } |
| 921 | 923 | ||
| 924 | static int rspi_setup(struct spi_device *spi) | ||
| 925 | { | ||
| 926 | struct rspi_data *rspi = spi_controller_get_devdata(spi->controller); | ||
| 927 | u8 sslp; | ||
| 928 | |||
| 929 | if (spi->cs_gpiod) | ||
| 930 | return 0; | ||
| 931 | |||
| 932 | pm_runtime_get_sync(&rspi->pdev->dev); | ||
| 933 | spin_lock_irq(&rspi->lock); | ||
| 934 | |||
| 935 | sslp = rspi_read8(rspi, RSPI_SSLP); | ||
| 936 | if (spi->mode & SPI_CS_HIGH) | ||
| 937 | sslp |= SSLP_SSLP(spi->chip_select); | ||
| 938 | else | ||
| 939 | sslp &= ~SSLP_SSLP(spi->chip_select); | ||
| 940 | rspi_write8(rspi, sslp, RSPI_SSLP); | ||
| 941 | |||
| 942 | spin_unlock_irq(&rspi->lock); | ||
| 943 | pm_runtime_put(&rspi->pdev->dev); | ||
| 944 | return 0; | ||
| 945 | } | ||
| 946 | |||
| 922 | static int rspi_prepare_message(struct spi_controller *ctlr, | 947 | static int rspi_prepare_message(struct spi_controller *ctlr, |
| 923 | struct spi_message *msg) | 948 | struct spi_message *msg) |
| 924 | { | 949 | { |
| @@ -933,6 +958,8 @@ static int rspi_prepare_message(struct spi_controller *ctlr, · 8 unmodified lines | |||
| 933 | rspi->spcmd |= SPCMD_CPOL; | 958 | rspi->spcmd |= SPCMD_CPOL; |
| 934 | if (spi->mode & SPI_CPHA) | 959 | if (spi->mode & SPI_CPHA) |
| 935 | rspi->spcmd |= SPCMD_CPHA; | 960 | rspi->spcmd |= SPCMD_CPHA; |
| 961 | if (spi->mode & SPI_LSB_FIRST) | ||
| 962 | rspi->spcmd |= SPCMD_LSBF; | ||
| 936 | 963 | ||
| 937 | /* Configure slave signal to assert */ | 964 | /* Configure slave signal to assert */ |
| 938 | rspi->spcmd |= SPCMD_SSLA(spi->cs_gpiod ? rspi->ctlr->unused_native_cs | 965 | rspi->spcmd |= SPCMD_SSLA(spi->cs_gpiod ? rspi->ctlr->unused_native_cs |
| @@ -1122,7 +1149,6 @@ static int rspi_remove(struct platform_device *pdev) · 183 unmodified lines | |||
| 1122 | static const struct spi_ops rspi_ops = { | 1149 | static const struct spi_ops rspi_ops = { |
| 1123 | .set_config_register = rspi_set_config_register, | 1150 | .set_config_register = rspi_set_config_register, |
| 1124 | .transfer_one = rspi_transfer_one, | 1151 | .transfer_one = rspi_transfer_one, |
| 1125 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, | ||
| 1126 | .flags = SPI_CONTROLLER_MUST_TX, | 1152 | .flags = SPI_CONTROLLER_MUST_TX, |
| 1127 | .fifo_size = 8, | 1153 | .fifo_size = 8, |
| 1128 | .num_hw_ss = 2, | 1154 | .num_hw_ss = 2, |
| @@ -1131,7 +1157,6 @@ static const struct spi_ops rspi_ops = { · 2 unmodified lines | |||
| 1131 | static const struct spi_ops rspi_rz_ops = { | 1157 | static const struct spi_ops rspi_rz_ops = { |
| 1132 | .set_config_register = rspi_rz_set_config_register, | 1158 | .set_config_register = rspi_rz_set_config_register, |
| 1133 | .transfer_one = rspi_rz_transfer_one, | 1159 | .transfer_one = rspi_rz_transfer_one, |
| 1134 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, | ||
| 1135 | .flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX, | 1160 | .flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX, |
| 1136 | .fifo_size = 8, /* 8 for TX, 32 for RX */ | 1161 | .fifo_size = 8, /* 8 for TX, 32 for RX */ |
| 1137 | .num_hw_ss = 1, | 1162 | .num_hw_ss = 1, |
| @@ -1140,8 +1165,7 @@ static const struct spi_ops rspi_rz_ops = { · 2 unmodified lines | |||
| 1140 | static const struct spi_ops qspi_ops = { | 1165 | static const struct spi_ops qspi_ops = { |
| 1141 | .set_config_register = qspi_set_config_register, | 1166 | .set_config_register = qspi_set_config_register, |
| 1142 | .transfer_one = qspi_transfer_one, | 1167 | .transfer_one = qspi_transfer_one, |
| 1143 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP | | 1168 | .extra_mode_bits = SPI_TX_DUAL | SPI_TX_QUAD | |
| 1144 | SPI_TX_DUAL | SPI_TX_QUAD | | ||
| 1145 | SPI_RX_DUAL | SPI_RX_QUAD, | 1169 | SPI_RX_DUAL | SPI_RX_QUAD, |
| 1146 | .flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX, | 1170 | .flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX, |
| 1147 | .fifo_size = 32, | 1171 | .fifo_size = 32, |
| @@ -1249,16 +1273,20 @@ static int rspi_probe(struct platform_device *pdev) · 101 unmodified lines | |||
| 1249 | goto error1; | 1273 | goto error1; |
| 1250 | } | 1274 | } |
| 1251 | 1275 | ||
| 1276 | rspi->pdev = pdev; | ||
| 1252 | pm_runtime_enable(&pdev->dev); | 1277 | pm_runtime_enable(&pdev->dev); |
| 1253 | 1278 | ||
| 1254 | init_waitqueue_head(&rspi->wait); | 1279 | init_waitqueue_head(&rspi->wait); |
| 1280 | spin_lock_init(&rspi->lock); | ||
| 1255 | 1281 | ||
| 1256 | ctlr->bus_num = pdev->id; | 1282 | ctlr->bus_num = pdev->id; |
| 1283 | ctlr->setup = rspi_setup; | ||
| 1257 | ctlr->auto_runtime_pm = true; | 1284 | ctlr->auto_runtime_pm = true; |
| 1258 | ctlr->transfer_one = ops->transfer_one; | 1285 | ctlr->transfer_one = ops->transfer_one; |
| 1259 | ctlr->prepare_message = rspi_prepare_message; | 1286 | ctlr->prepare_message = rspi_prepare_message; |
| 1260 | ctlr->unprepare_message = rspi_unprepare_message; | 1287 | ctlr->unprepare_message = rspi_unprepare_message; |
| 1261 | ctlr->mode_bits = ops->mode_bits; | 1288 | ctlr->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST | |
| 1289 | SPI_LOOP | ops->extra_mode_bits; | ||
| 1262 | ctlr->flags = ops->flags; | 1290 | ctlr->flags = ops->flags; |
| 1263 | ctlr->dev.of_node = pdev->dev.of_node; | 1291 | ctlr->dev.of_node = pdev->dev.of_node; |
| 1264 | ctlr->use_gpio_descriptors = true; | 1292 | ctlr->use_gpio_descriptors = true; |
| @@ -227,7 +227,7 @@ static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) · 226 unmodified lines | |||
| 227 | struct spi_fiq_code { | 227 | struct spi_fiq_code { |
| 228 | u32 length; | 228 | u32 length; |
| 229 | u32 ack_offset; | 229 | u32 ack_offset; |
| 230 | u8 data[0]; | 230 | u8 data[]; |
| 231 | }; | 231 | }; |
| 232 | 232 | ||
| 233 | extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; | 233 | extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; |
| @@ -565,7 +565,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) · 564 unmodified lines | |||
| 565 | qspi->io_base = devm_ioremap_resource(dev, res); | 565 | qspi->io_base = devm_ioremap_resource(dev, res); |
| 566 | if (IS_ERR(qspi->io_base)) { | 566 | if (IS_ERR(qspi->io_base)) { |
| 567 | ret = PTR_ERR(qspi->io_base); | 567 | ret = PTR_ERR(qspi->io_base); |
| 568 | goto err; | 568 | goto err_master_put; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | qspi->phys_base = res->start; | 571 | qspi->phys_base = res->start; |
| @@ -574,24 +574,26 @@ static int stm32_qspi_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 574 | qspi->mm_base = devm_ioremap_resource(dev, res); | 574 | qspi->mm_base = devm_ioremap_resource(dev, res); |
| 575 | if (IS_ERR(qspi->mm_base)) { | 575 | if (IS_ERR(qspi->mm_base)) { |
| 576 | ret = PTR_ERR(qspi->mm_base); | 576 | ret = PTR_ERR(qspi->mm_base); |
| 577 | goto err; | 577 | goto err_master_put; |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | qspi->mm_size = resource_size(res); | 580 | qspi->mm_size = resource_size(res); |
| 581 | if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) { | 581 | if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) { |
| 582 | ret = -EINVAL; | 582 | ret = -EINVAL; |
| 583 | goto err; | 583 | goto err_master_put; |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | irq = platform_get_irq(pdev, 0); | 586 | irq = platform_get_irq(pdev, 0); |
| 587 | if (irq < 0) | 587 | if (irq < 0) { |
| 588 | return irq; | 588 | ret = irq; |
| 589 | goto err_master_put; | ||
| 590 | } | ||
| 589 | 591 | ||
| 590 | ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0, | 592 | ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0, |
| 591 | dev_name(dev), qspi); | 593 | dev_name(dev), qspi); |
| 592 | if (ret) { | 594 | if (ret) { |
| 593 | dev_err(dev, "failed to request irq\n"); | 595 | dev_err(dev, "failed to request irq\n"); |
| 594 | goto err; | 596 | goto err_master_put; |
| 595 | } | 597 | } |
| 596 | 598 | ||
| 597 | init_completion(&qspi->data_completion); | 599 | init_completion(&qspi->data_completion); |
| @@ -599,23 +601,27 @@ static int stm32_qspi_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 599 | qspi->clk = devm_clk_get(dev, NULL); | 601 | qspi->clk = devm_clk_get(dev, NULL); |
| 600 | if (IS_ERR(qspi->clk)) { | 602 | if (IS_ERR(qspi->clk)) { |
| 601 | ret = PTR_ERR(qspi->clk); | 603 | ret = PTR_ERR(qspi->clk); |
| 602 | goto err; | 604 | goto err_master_put; |
| 603 | } | 605 | } |
| 604 | 606 | ||
| 605 | qspi->clk_rate = clk_get_rate(qspi->clk); | 607 | qspi->clk_rate = clk_get_rate(qspi->clk); |
| 606 | if (!qspi->clk_rate) { | 608 | if (!qspi->clk_rate) { |
| 607 | ret = -EINVAL; | 609 | ret = -EINVAL; |
| 608 | goto err; | 610 | goto err_master_put; |
| 609 | } | 611 | } |
| 610 | 612 | ||
| 611 | ret = clk_prepare_enable(qspi->clk); | 613 | ret = clk_prepare_enable(qspi->clk); |
| 612 | if (ret) { | 614 | if (ret) { |
| 613 | dev_err(dev, "can not enable the clock\n"); | 615 | dev_err(dev, "can not enable the clock\n"); |
| 614 | goto err; | 616 | goto err_master_put; |
| 615 | } | 617 | } |
| 616 | 618 | ||
| 617 | rstc = devm_reset_control_get_exclusive(dev, NULL); | 619 | rstc = devm_reset_control_get_exclusive(dev, NULL); |
| 618 | if (!IS_ERR(rstc)) { | 620 | if (IS_ERR(rstc)) { |
| 621 | ret = PTR_ERR(rstc); | ||
| 622 | if (ret == -EPROBE_DEFER) | ||
| 623 | goto err_qspi_release; | ||
| 624 | } else { | ||
| 619 | reset_control_assert(rstc); | 625 | reset_control_assert(rstc); |
| 620 | udelay(2); | 626 | udelay(2); |
| 621 | reset_control_deassert(rstc); | 627 | reset_control_deassert(rstc); |
| @@ -625,7 +631,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 625 | platform_set_drvdata(pdev, qspi); | 631 | platform_set_drvdata(pdev, qspi); |
| 626 | ret = stm32_qspi_dma_setup(qspi); | 632 | ret = stm32_qspi_dma_setup(qspi); |
| 627 | if (ret) | 633 | if (ret) |
| 628 | goto err; | 634 | goto err_qspi_release; |
| 629 | 635 | ||
| 630 | mutex_init(&qspi->lock); | 636 | mutex_init(&qspi->lock); |
| 631 | 637 | ||
| @@ -641,8 +647,9 @@ static int stm32_qspi_probe(struct platform_device *pdev) · 9 unmodified lines | |||
| 641 | if (!ret) | 647 | if (!ret) |
| 642 | return 0; | 648 | return 0; |
| 643 | 649 | ||
| 644 | err: | 650 | err_qspi_release: |
| 645 | stm32_qspi_release(qspi); | 651 | stm32_qspi_release(qspi); |
| 652 | err_master_put: | ||
| 646 | spi_master_put(qspi->ctrl); | 653 | spi_master_put(qspi->ctrl); |
| 647 | 654 | ||
| 648 | return ret; | 655 | return ret; |
| @@ -175,7 +175,7 @@ · 174 unmodified lines | |||
| 175 | #define SPI_DMA_MIN_BYTES 16 | 175 | #define SPI_DMA_MIN_BYTES 16 |
| 176 | 176 | ||
| 177 | /** | 177 | /** |
| 178 | * stm32_spi_reg - stm32 SPI register & bitfield desc | 178 | * struct stm32_spi_reg - stm32 SPI register & bitfield desc |
| 179 | * @reg: register offset | 179 | * @reg: register offset |
| 180 | * @mask: bitfield mask | 180 | * @mask: bitfield mask |
| 181 | * @shift: left shift | 181 | * @shift: left shift |
| @@ -187,16 +187,16 @@ struct stm32_spi_reg { · 5 unmodified lines | |||
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | /** | 189 | /** |
| 190 | * stm32_spi_regspec - stm32 registers definition, compatible dependent data | 190 | * struct stm32_spi_regspec - stm32 registers definition, compatible dependent data |
| 191 | * en: enable register and SPI enable bit | 191 | * @en: enable register and SPI enable bit |
| 192 | * dma_rx_en: SPI DMA RX enable register end SPI DMA RX enable bit | 192 | * @dma_rx_en: SPI DMA RX enable register end SPI DMA RX enable bit |
| 193 | * dma_tx_en: SPI DMA TX enable register end SPI DMA TX enable bit | 193 | * @dma_tx_en: SPI DMA TX enable register end SPI DMA TX enable bit |
| 194 | * cpol: clock polarity register and polarity bit | 194 | * @cpol: clock polarity register and polarity bit |
| 195 | * cpha: clock phase register and phase bit | 195 | * @cpha: clock phase register and phase bit |
| 196 | * lsb_first: LSB transmitted first register and bit | 196 | * @lsb_first: LSB transmitted first register and bit |
| 197 | * br: baud rate register and bitfields | 197 | * @br: baud rate register and bitfields |
| 198 | * rx: SPI RX data register | 198 | * @rx: SPI RX data register |
| 199 | * tx: SPI TX data register | 199 | * @tx: SPI TX data register |
| 200 | */ | 200 | */ |
| 201 | struct stm32_spi_regspec { | 201 | struct stm32_spi_regspec { |
| 202 | const struct stm32_spi_reg en; | 202 | const struct stm32_spi_reg en; |
| @@ -213,7 +213,7 @@ struct stm32_spi_regspec { · 10 unmodified lines | |||
| 213 | struct stm32_spi; | 213 | struct stm32_spi; |
| 214 | 214 | ||
| 215 | /** | 215 | /** |
| 216 | * stm32_spi_cfg - stm32 compatible configuration data | 216 | * struct stm32_spi_cfg - stm32 compatible configuration data |
| 217 | * @regs: registers descriptions | 217 | * @regs: registers descriptions |
| 218 | * @get_fifo_size: routine to get fifo size | 218 | * @get_fifo_size: routine to get fifo size |
| 219 | * @get_bpw_mask: routine to get bits per word mask | 219 | * @get_bpw_mask: routine to get bits per word mask |
| @@ -223,13 +223,13 @@ struct stm32_spi; · 3 unmodified lines | |||
| 223 | * @set_mode: routine to configure registers to desired mode | 223 | * @set_mode: routine to configure registers to desired mode |
| 224 | * @set_data_idleness: optional routine to configure registers to desired idle | 224 | * @set_data_idleness: optional routine to configure registers to desired idle |
| 225 | * time between frames (if driver has this functionality) | 225 | * time between frames (if driver has this functionality) |
| 226 | * set_number_of_data: optional routine to configure registers to desired | 226 | * @set_number_of_data: optional routine to configure registers to desired |
| 227 | * number of data (if driver has this functionality) | 227 | * number of data (if driver has this functionality) |
| 228 | * @can_dma: routine to determine if the transfer is eligible for DMA use | 228 | * @can_dma: routine to determine if the transfer is eligible for DMA use |
| 229 | * @transfer_one_dma_start: routine to start transfer a single spi_transfer | 229 | * @transfer_one_dma_start: routine to start transfer a single spi_transfer |
| 230 | * using DMA | 230 | * using DMA |
| 231 | * @dma_rx cb: routine to call after DMA RX channel operation is complete | 231 | * @dma_rx_cb: routine to call after DMA RX channel operation is complete |
| 232 | * @dma_tx cb: routine to call after DMA TX channel operation is complete | 232 | * @dma_tx_cb: routine to call after DMA TX channel operation is complete |
| 233 | * @transfer_one_irq: routine to configure interrupts for driver | 233 | * @transfer_one_irq: routine to configure interrupts for driver |
| 234 | * @irq_handler_event: Interrupt handler for SPI controller events | 234 | * @irq_handler_event: Interrupt handler for SPI controller events |
| 235 | * @irq_handler_thread: thread of interrupt handler for SPI controller | 235 | * @irq_handler_thread: thread of interrupt handler for SPI controller |
| @@ -587,6 +587,7 @@ static void stm32f4_spi_read_rx(struct stm32_spi *spi) · 351 unmodified lines | |||
| 587 | /** | 587 | /** |
| 588 | * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register | 588 | * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register |
| 589 | * @spi: pointer to the spi controller data structure | 589 | * @spi: pointer to the spi controller data structure |
| 590 | * @flush: boolean indicating that FIFO should be flushed | ||
| 590 | * | 591 | * |
| 591 | * Write in rx_buf depends on remaining bytes to avoid to write beyond | 592 | * Write in rx_buf depends on remaining bytes to avoid to write beyond |
| 592 | * rx_buf end. | 593 | * rx_buf end. |
| @@ -756,6 +757,9 @@ static void stm32h7_spi_disable(struct stm32_spi *spi) · 163 unmodified lines | |||
| 756 | 757 | ||
| 757 | /** | 758 | /** |
| 758 | * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use | 759 | * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use |
| 760 | * @master: controller master interface | ||
| 761 | * @spi_dev: pointer to the spi device | ||
| 762 | * @transfer: pointer to spi transfer | ||
| 759 | * | 763 | * |
| 760 | * If driver has fifo and the current transfer size is greater than fifo size, | 764 | * If driver has fifo and the current transfer size is greater than fifo size, |
| 761 | * use DMA. Otherwise use DMA for transfer longer than defined DMA min bytes. | 765 | * use DMA. Otherwise use DMA for transfer longer than defined DMA min bytes. |
| @@ -974,6 +978,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) · 212 unmodified lines | |||
| 974 | 978 | ||
| 975 | /** | 979 | /** |
| 976 | * stm32_spi_prepare_msg - set up the controller to transfer a single message | 980 | * stm32_spi_prepare_msg - set up the controller to transfer a single message |
| 981 | * @master: controller master interface | ||
| 982 | * @msg: pointer to spi message | ||
| 977 | */ | 983 | */ |
| 978 | static int stm32_spi_prepare_msg(struct spi_master *master, | 984 | static int stm32_spi_prepare_msg(struct spi_master *master, |
| 979 | struct spi_message *msg) | 985 | struct spi_message *msg) |
| @@ -1026,6 +1032,7 @@ static int stm32_spi_prepare_msg(struct spi_master *master, · 46 unmodified lines | |||
| 1026 | 1032 | ||
| 1027 | /** | 1033 | /** |
| 1028 | * stm32f4_spi_dma_tx_cb - dma callback | 1034 | * stm32f4_spi_dma_tx_cb - dma callback |
| 1035 | * @data: pointer to the spi controller data structure | ||
| 1029 | * | 1036 | * |
| 1030 | * DMA callback is called when the transfer is complete for DMA TX channel. | 1037 | * DMA callback is called when the transfer is complete for DMA TX channel. |
| 1031 | */ | 1038 | */ |
| @@ -1041,6 +1048,7 @@ static void stm32f4_spi_dma_tx_cb(void *data) · 9 unmodified lines | |||
| 1041 | 1048 | ||
| 1042 | /** | 1049 | /** |
| 1043 | * stm32f4_spi_dma_rx_cb - dma callback | 1050 | * stm32f4_spi_dma_rx_cb - dma callback |
| 1051 | * @data: pointer to the spi controller data structure | ||
| 1044 | * | 1052 | * |
| 1045 | * DMA callback is called when the transfer is complete for DMA RX channel. | 1053 | * DMA callback is called when the transfer is complete for DMA RX channel. |
| 1046 | */ | 1054 | */ |
| @@ -1054,6 +1062,7 @@ static void stm32f4_spi_dma_rx_cb(void *data) · 7 unmodified lines | |||
| 1054 | 1062 | ||
| 1055 | /** | 1063 | /** |
| 1056 | * stm32h7_spi_dma_cb - dma callback | 1064 | * stm32h7_spi_dma_cb - dma callback |
| 1065 | * @data: pointer to the spi controller data structure | ||
| 1057 | * | 1066 | * |
| 1058 | * DMA callback is called when the transfer is complete or when an error | 1067 | * DMA callback is called when the transfer is complete or when an error |
| 1059 | * occurs. If the transfer is complete, EOT flag is raised. | 1068 | * occurs. If the transfer is complete, EOT flag is raised. |
| @@ -1079,6 +1088,9 @@ static void stm32h7_spi_dma_cb(void *data) · 19 unmodified lines | |||
| 1079 | /** | 1088 | /** |
| 1080 | * stm32_spi_dma_config - configure dma slave channel depending on current | 1089 | * stm32_spi_dma_config - configure dma slave channel depending on current |
| 1081 | * transfer bits_per_word. | 1090 | * transfer bits_per_word. |
| 1091 | * @spi: pointer to the spi controller data structure | ||
| 1092 | * @dma_conf: pointer to the dma_slave_config structure | ||
| 1093 | * @dir: direction of the dma transfer | ||
| 1082 | */ | 1094 | */ |
| 1083 | static void stm32_spi_dma_config(struct stm32_spi *spi, | 1095 | static void stm32_spi_dma_config(struct stm32_spi *spi, |
| 1084 | struct dma_slave_config *dma_conf, | 1096 | struct dma_slave_config *dma_conf, |
| @@ -1126,6 +1138,7 @@ static void stm32_spi_dma_config(struct stm32_spi *spi, · 41 unmodified lines | |||
| 1126 | /** | 1138 | /** |
| 1127 | * stm32f4_spi_transfer_one_irq - transfer a single spi_transfer using | 1139 | * stm32f4_spi_transfer_one_irq - transfer a single spi_transfer using |
| 1128 | * interrupts | 1140 | * interrupts |
| 1141 | * @spi: pointer to the spi controller data structure | ||
| 1129 | * | 1142 | * |
| 1130 | * It must returns 0 if the transfer is finished or 1 if the transfer is still | 1143 | * It must returns 0 if the transfer is finished or 1 if the transfer is still |
| 1131 | * in progress. | 1144 | * in progress. |
| @@ -1166,6 +1179,7 @@ static int stm32f4_spi_transfer_one_irq(struct stm32_spi *spi) · 34 unmodified lines | |||
| 1166 | /** | 1179 | /** |
| 1167 | * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using | 1180 | * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using |
| 1168 | * interrupts | 1181 | * interrupts |
| 1182 | * @spi: pointer to the spi controller data structure | ||
| 1169 | * | 1183 | * |
| 1170 | * It must returns 0 if the transfer is finished or 1 if the transfer is still | 1184 | * It must returns 0 if the transfer is finished or 1 if the transfer is still |
| 1171 | * in progress. | 1185 | * in progress. |
| @@ -1207,6 +1221,7 @@ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi) · 35 unmodified lines | |||
| 1207 | /** | 1221 | /** |
| 1208 | * stm32f4_spi_transfer_one_dma_start - Set SPI driver registers to start | 1222 | * stm32f4_spi_transfer_one_dma_start - Set SPI driver registers to start |
| 1209 | * transfer using DMA | 1223 | * transfer using DMA |
| 1224 | * @spi: pointer to the spi controller data structure | ||
| 1210 | */ | 1225 | */ |
| 1211 | static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) | 1226 | static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) |
| 1212 | { | 1227 | { |
| @@ -1227,6 +1242,7 @@ static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi) · 14 unmodified lines | |||
| 1227 | /** | 1242 | /** |
| 1228 | * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start | 1243 | * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start |
| 1229 | * transfer using DMA | 1244 | * transfer using DMA |
| 1245 | * @spi: pointer to the spi controller data structure | ||
| 1230 | */ | 1246 | */ |
| 1231 | static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) | 1247 | static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) |
| 1232 | { | 1248 | { |
| @@ -1243,6 +1259,8 @@ static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi) · 10 unmodified lines | |||
| 1243 | 1259 | ||
| 1244 | /** | 1260 | /** |
| 1245 | * stm32_spi_transfer_one_dma - transfer a single spi_transfer using DMA | 1261 | * stm32_spi_transfer_one_dma - transfer a single spi_transfer using DMA |
| 1262 | * @spi: pointer to the spi controller data structure | ||
| 1263 | * @xfer: pointer to the spi_transfer structure | ||
| 1246 | * | 1264 | * |
| 1247 | * It must returns 0 if the transfer is finished or 1 if the transfer is still | 1265 | * It must returns 0 if the transfer is finished or 1 if the transfer is still |
| 1248 | * in progress. | 1266 | * in progress. |
| @@ -1405,7 +1423,7 @@ static void stm32_spi_set_mbr(struct stm32_spi *spi, u32 mbrdiv) · 156 unmodified lines | |||
| 1405 | /** | 1423 | /** |
| 1406 | * stm32_spi_communication_type - return transfer communication type | 1424 | * stm32_spi_communication_type - return transfer communication type |
| 1407 | * @spi_dev: pointer to the spi device | 1425 | * @spi_dev: pointer to the spi device |
| 1408 | * transfer: pointer to spi transfer | 1426 | * @transfer: pointer to spi transfer |
| 1409 | */ | 1427 | */ |
| 1410 | static unsigned int stm32_spi_communication_type(struct spi_device *spi_dev, | 1428 | static unsigned int stm32_spi_communication_type(struct spi_device *spi_dev, |
| 1411 | struct spi_transfer *transfer) | 1429 | struct spi_transfer *transfer) |
| @@ -1522,7 +1540,7 @@ static void stm32h7_spi_data_idleness(struct stm32_spi *spi, u32 len) · 110 unmodified lines | |||
| 1522 | /** | 1540 | /** |
| 1523 | * stm32h7_spi_number_of_data - configure number of data at current transfer | 1541 | * stm32h7_spi_number_of_data - configure number of data at current transfer |
| 1524 | * @spi: pointer to the spi controller data structure | 1542 | * @spi: pointer to the spi controller data structure |
| 1525 | * @len: transfer length | 1543 | * @nb_words: transfer length (in words) |
| 1526 | */ | 1544 | */ |
| 1527 | static int stm32h7_spi_number_of_data(struct stm32_spi *spi, u32 nb_words) | 1545 | static int stm32h7_spi_number_of_data(struct stm32_spi *spi, u32 nb_words) |
| 1528 | { | 1546 | { |
| @@ -1546,6 +1564,9 @@ static int stm32h7_spi_number_of_data(struct stm32_spi *spi, u32 nb_words) · 17 unmodified lines | |||
| 1546 | * stm32_spi_transfer_one_setup - common setup to transfer a single | 1564 | * stm32_spi_transfer_one_setup - common setup to transfer a single |
| 1547 | * spi_transfer either using DMA or | 1565 | * spi_transfer either using DMA or |
| 1548 | * interrupts. | 1566 | * interrupts. |
| 1567 | * @spi: pointer to the spi controller data structure | ||
| 1568 | * @spi_dev: pointer to the spi device | ||
| 1569 | * @transfer: pointer to spi transfer | ||
| 1549 | */ | 1570 | */ |
| 1550 | static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, | 1571 | static int stm32_spi_transfer_one_setup(struct stm32_spi *spi, |
| 1551 | struct spi_device *spi_dev, | 1572 | struct spi_device *spi_dev, |
| @@ -1625,6 +1646,9 @@ out: · 73 unmodified lines | |||
| 1625 | 1646 | ||
| 1626 | /** | 1647 | /** |
| 1627 | * stm32_spi_transfer_one - transfer a single spi_transfer | 1648 | * stm32_spi_transfer_one - transfer a single spi_transfer |
| 1649 | * @master: controller master interface | ||
| 1650 | * @spi_dev: pointer to the spi device | ||
| 1651 | * @transfer: pointer to spi transfer | ||
| 1628 | * | 1652 | * |
| 1629 | * It must return 0 if the transfer is finished or 1 if the transfer is still | 1653 | * It must return 0 if the transfer is finished or 1 if the transfer is still |
| 1630 | * in progress. | 1654 | * in progress. |
| @@ -1658,6 +1682,8 @@ static int stm32_spi_transfer_one(struct spi_master *master, · 27 unmodified lines | |||
| 1658 | 1682 | ||
| 1659 | /** | 1683 | /** |
| 1660 | * stm32_spi_unprepare_msg - relax the hardware | 1684 | * stm32_spi_unprepare_msg - relax the hardware |
| 1685 | * @master: controller master interface | ||
| 1686 | * @msg: pointer to the spi message | ||
| 1661 | */ | 1687 | */ |
| 1662 | static int stm32_spi_unprepare_msg(struct spi_master *master, | 1688 | static int stm32_spi_unprepare_msg(struct spi_master *master, |
| 1663 | struct spi_message *msg) | 1689 | struct spi_message *msg) |
| @@ -1671,6 +1697,7 @@ static int stm32_spi_unprepare_msg(struct spi_master *master, · 7 unmodified lines | |||
| 1671 | 1697 | ||
| 1672 | /** | 1698 | /** |
| 1673 | * stm32f4_spi_config - Configure SPI controller as SPI master | 1699 | * stm32f4_spi_config - Configure SPI controller as SPI master |
| 1700 | * @spi: pointer to the spi controller data structure | ||
| 1674 | */ | 1701 | */ |
| 1675 | static int stm32f4_spi_config(struct stm32_spi *spi) | 1702 | static int stm32f4_spi_config(struct stm32_spi *spi) |
| 1676 | { | 1703 | { |
| @@ -1701,6 +1728,7 @@ static int stm32f4_spi_config(struct stm32_spi *spi) · 24 unmodified lines | |||
| 1701 | 1728 | ||
| 1702 | /** | 1729 | /** |
| 1703 | * stm32h7_spi_config - Configure SPI controller as SPI master | 1730 | * stm32h7_spi_config - Configure SPI controller as SPI master |
| 1731 | * @spi: pointer to the spi controller data structure | ||
| 1704 | */ | 1732 | */ |
| 1705 | static int stm32h7_spi_config(struct stm32_spi *spi) | 1733 | static int stm32h7_spi_config(struct stm32_spi *spi) |
| 1706 | { | 1734 | { |
| @@ -510,6 +510,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr) · 509 unmodified lines | |||
| 510 | spi->dev.bus = &spi_bus_type; | 510 | spi->dev.bus = &spi_bus_type; |
| 511 | spi->dev.release = spidev_release; | 511 | spi->dev.release = spidev_release; |
| 512 | spi->cs_gpio = -ENOENT; | 512 | spi->cs_gpio = -ENOENT; |
| 513 | spi->mode = ctlr->buswidth_override_bits; | ||
| 513 | 514 | ||
| 514 | spin_lock_init(&spi->statistics.lock); | 515 | spin_lock_init(&spi->statistics.lock); |
| 515 | 516 | ||
| @@ -1514,17 +1515,15 @@ void spi_take_timestamp_pre(struct spi_controller *ctlr, · 998 unmodified lines | |||
| 1514 | if (!xfer->ptp_sts) | 1515 | if (!xfer->ptp_sts) |
| 1515 | return; | 1516 | return; |
| 1516 | 1517 | ||
| 1517 | if (xfer->timestamped_pre) | 1518 | if (xfer->timestamped) |
| 1518 | return; | 1519 | return; |
| 1519 | 1520 | ||
| 1520 | if (progress < xfer->ptp_sts_word_pre) | 1521 | if (progress > xfer->ptp_sts_word_pre) |
| 1521 | return; | 1522 | return; |
| 1522 | 1523 | ||
| 1523 | /* Capture the resolution of the timestamp */ | 1524 | /* Capture the resolution of the timestamp */ |
| 1524 | xfer->ptp_sts_word_pre = progress; | 1525 | xfer->ptp_sts_word_pre = progress; |
| 1525 | 1526 | ||
| 1526 | xfer->timestamped_pre = true; | ||
| 1527 | |||
| 1528 | if (irqs_off) { | 1527 | if (irqs_off) { |
| 1529 | local_irq_save(ctlr->irq_flags); | 1528 | local_irq_save(ctlr->irq_flags); |
| 1530 | preempt_disable(); | 1529 | preempt_disable(); |
| @@ -1553,7 +1552,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, · 22 unmodified lines | |||
| 1553 | if (!xfer->ptp_sts) | 1552 | if (!xfer->ptp_sts) |
| 1554 | return; | 1553 | return; |
| 1555 | 1554 | ||
| 1556 | if (xfer->timestamped_post) | 1555 | if (xfer->timestamped) |
| 1557 | return; | 1556 | return; |
| 1558 | 1557 | ||
| 1559 | if (progress < xfer->ptp_sts_word_post) | 1558 | if (progress < xfer->ptp_sts_word_post) |
| @@ -1569,7 +1568,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, · 9 unmodified lines | |||
| 1569 | /* Capture the resolution of the timestamp */ | 1568 | /* Capture the resolution of the timestamp */ |
| 1570 | xfer->ptp_sts_word_post = progress; | 1569 | xfer->ptp_sts_word_post = progress; |
| 1571 | 1570 | ||
| 1572 | xfer->timestamped_post = true; | 1571 | xfer->timestamped = true; |
| 1573 | } | 1572 | } |
| 1574 | EXPORT_SYMBOL_GPL(spi_take_timestamp_post); | 1573 | EXPORT_SYMBOL_GPL(spi_take_timestamp_post); |
| 1575 | 1574 | ||
| @@ -1674,12 +1673,9 @@ void spi_finalize_current_message(struct spi_controller *ctlr) · 98 unmodified lines | |||
| 1674 | } | 1673 | } |
| 1675 | } | 1674 | } |
| 1676 | 1675 | ||
| 1677 | if (unlikely(ctlr->ptp_sts_supported)) { | 1676 | if (unlikely(ctlr->ptp_sts_supported)) |
| 1678 | list_for_each_entry(xfer, &mesg->transfers, transfer_list) { | 1677 | list_for_each_entry(xfer, &mesg->transfers, transfer_list) |
| 1679 | WARN_ON_ONCE(xfer->ptp_sts && !xfer->timestamped_pre); | 1678 | WARN_ON_ONCE(xfer->ptp_sts && !xfer->timestamped); |
| 1680 | WARN_ON_ONCE(xfer->ptp_sts && !xfer->timestamped_post); | ||
| 1681 | } | ||
| 1682 | } | ||
| 1683 | 1679 | ||
| 1684 | spi_unmap_msg(ctlr, mesg); | 1680 | spi_unmap_msg(ctlr, mesg); |
| 1685 | 1681 | ||
| @@ -1955,13 +1951,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, · 269 unmodified lines | |||
| 1955 | spi->mode |= SPI_CS_HIGH; | 1951 | spi->mode |= SPI_CS_HIGH; |
| 1956 | 1952 | ||
| 1957 | /* Device speed */ | 1953 | /* Device speed */ |
| 1958 | rc = of_property_read_u32(nc, "spi-max-frequency", &value); | 1954 | if (!of_property_read_u32(nc, "spi-max-frequency", &value)) |
| 1959 | if (rc) { | 1955 | spi->max_speed_hz = value; |
| 1960 | dev_err(&ctlr->dev, | ||
| 1961 | "%pOF has no valid 'spi-max-frequency' property (%d)\n", nc, rc); | ||
| 1962 | return rc; | ||
| 1963 | } | ||
| 1964 | spi->max_speed_hz = value; | ||
| 1965 | 1956 | ||
| 1966 | return 0; | 1957 | return 0; |
| 1967 | } | 1958 | } |
| @@ -2181,9 +2172,10 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr, · 213 unmodified lines | |||
| 2181 | return AE_NO_MEMORY; | 2172 | return AE_NO_MEMORY; |
| 2182 | } | 2173 | } |
| 2183 | 2174 | ||
| 2175 | |||
| 2184 | ACPI_COMPANION_SET(&spi->dev, adev); | 2176 | ACPI_COMPANION_SET(&spi->dev, adev); |
| 2185 | spi->max_speed_hz = lookup.max_speed_hz; | 2177 | spi->max_speed_hz = lookup.max_speed_hz; |
| 2186 | spi->mode = lookup.mode; | 2178 | spi->mode |= lookup.mode; |
| 2187 | spi->irq = lookup.irq; | 2179 | spi->irq = lookup.irq; |
| 2188 | spi->bits_per_word = lookup.bits_per_word; | 2180 | spi->bits_per_word = lookup.bits_per_word; |
| 2189 | spi->chip_select = lookup.chip_select; | 2181 | spi->chip_select = lookup.chip_select; |
| @@ -4034,7 +4026,7 @@ static struct spi_device *acpi_spi_find_device_by_adev(struct acpi_device *adev) · 1844 unmodified lines | |||
| 4034 | struct device *dev; | 4026 | struct device *dev; |
| 4035 | 4027 | ||
| 4036 | dev = bus_find_device_by_acpi_dev(&spi_bus_type, adev); | 4028 | dev = bus_find_device_by_acpi_dev(&spi_bus_type, adev); |
| 4037 | return dev ? to_spi_device(dev) : NULL; | 4029 | return to_spi_device(dev); |
| 4038 | } | 4030 | } |
| 4039 | 4031 | ||
| 4040 | static int acpi_spi_notify(struct notifier_block *nb, unsigned long value, | 4032 | static int acpi_spi_notify(struct notifier_block *nb, unsigned long value, |
| @@ -275,14 +275,14 @@ static int spidev_message(struct spidev_data *spidev, · 274 unmodified lines | |||
| 275 | #ifdef VERBOSE | 275 | #ifdef VERBOSE |
| 276 | dev_dbg(&spidev->spi->dev, | 276 | dev_dbg(&spidev->spi->dev, |
| 277 | " xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n", | 277 | " xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n", |
| 278 | u_tmp->len, | 278 | k_tmp->len, |
| 279 | u_tmp->rx_buf ? "rx " : "", | 279 | k_tmp->rx_buf ? "rx " : "", |
| 280 | u_tmp->tx_buf ? "tx " : "", | 280 | k_tmp->tx_buf ? "tx " : "", |
| 281 | u_tmp->cs_change ? "cs " : "", | 281 | k_tmp->cs_change ? "cs " : "", |
| 282 | u_tmp->bits_per_word ? : spidev->spi->bits_per_word, | 282 | k_tmp->bits_per_word ? : spidev->spi->bits_per_word, |
| 283 | u_tmp->delay_usecs, | 283 | k_tmp->delay.value, |
| 284 | u_tmp->word_delay_usecs, | 284 | k_tmp->word_delay.value, |
| 285 | u_tmp->speed_hz ? : spidev->spi->max_speed_hz); | 285 | k_tmp->speed_hz ? : spidev->spi->max_speed_hz); |
| 286 | #endif | 286 | #endif |
| 287 | spi_message_add_tail(k_tmp, &msg); | 287 | spi_message_add_tail(k_tmp, &msg); |
| 288 | } | 288 | } |
| @@ -454,10 +454,11 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 165 unmodified lines | |||
| 454 | 454 | ||
| 455 | spi->max_speed_hz = tmp; | 455 | spi->max_speed_hz = tmp; |
| 456 | retval = spi_setup(spi); | 456 | retval = spi_setup(spi); |
| 457 | if (retval >= 0) | 457 | if (retval == 0) { |
| 458 | spidev->speed_hz = tmp; | 458 | spidev->speed_hz = tmp; |
| 459 | else | 459 | dev_dbg(&spi->dev, "%d Hz (max)\n", |
| 460 | dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); | 460 | spidev->speed_hz); |
| 461 | } | ||
| 461 | spi->max_speed_hz = save; | 462 | spi->max_speed_hz = save; |
| 462 | } | 463 | } |
| 463 | break; | 464 | break; |
| @@ -135,6 +135,8 @@ extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer); · 134 unmodified lines | |||
| 135 | * @modalias: Name of the driver to use with this device, or an alias | 135 | * @modalias: Name of the driver to use with this device, or an alias |
| 136 | * for that name. This appears in the sysfs "modalias" attribute | 136 | * for that name. This appears in the sysfs "modalias" attribute |
| 137 | * for driver coldplugging, and in uevents used for hotplugging | 137 | * for driver coldplugging, and in uevents used for hotplugging |
| 138 | * @driver_override: If the name of a driver is written to this attribute, then | ||
| 139 | * the device will bind to the named driver and only the named driver. | ||
| 138 | * @cs_gpio: LEGACY: gpio number of the chipselect line (optional, -ENOENT when | 140 | * @cs_gpio: LEGACY: gpio number of the chipselect line (optional, -ENOENT when |
| 139 | * not using a GPIO line) use cs_gpiod in new drivers by opting in on | 141 | * not using a GPIO line) use cs_gpiod in new drivers by opting in on |
| 140 | * the spi_master. | 142 | * the spi_master. |
| @@ -443,6 +445,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) · 302 unmodified lines | |||
| 443 | * @spi_transfer->ptp_sts_word_post were transmitted. | 445 | * @spi_transfer->ptp_sts_word_post were transmitted. |
| 444 | * If the driver does not set this, the SPI core takes the snapshot as | 446 | * If the driver does not set this, the SPI core takes the snapshot as |
| 445 | * close to the driver hand-over as possible. | 447 | * close to the driver hand-over as possible. |
| 448 | * @irq_flags: Interrupt enable state during PTP system timestamping | ||
| 446 | * | 449 | * |
| 447 | * Each SPI controller can communicate with one or more @spi_device | 450 | * Each SPI controller can communicate with one or more @spi_device |
| 448 | * children. These make a small bus, sharing MOSI, MISO and SCK signals | 451 | * children. These make a small bus, sharing MOSI, MISO and SCK signals |
| @@ -481,6 +484,9 @@ struct spi_controller { · 32 unmodified lines | |||
| 481 | /* spi_device.mode flags understood by this controller driver */ | 484 | /* spi_device.mode flags understood by this controller driver */ |
| 482 | u32 mode_bits; | 485 | u32 mode_bits; |
| 483 | 486 | ||
| 487 | /* spi_device.mode flags override flags for this controller */ | ||
| 488 | u32 buswidth_override_bits; | ||
| 489 | |||
| 484 | /* bitmask of supported bits_per_word for transfers */ | 490 | /* bitmask of supported bits_per_word for transfers */ |
| 485 | u32 bits_per_word_mask; | 491 | u32 bits_per_word_mask; |
| 486 | #define SPI_BPW_MASK(bits) BIT((bits) - 1) | 492 | #define SPI_BPW_MASK(bits) BIT((bits) - 1) |
| @@ -930,8 +936,7 @@ struct spi_transfer { · 443 unmodified lines | |||
| 930 | 936 | ||
| 931 | struct ptp_system_timestamp *ptp_sts; | 937 | struct ptp_system_timestamp *ptp_sts; |
| 932 | 938 | ||
| 933 | bool timestamped_pre; | 939 | bool timestamped; |
| 934 | bool timestamped_post; | ||
| 935 | 940 | ||
| 936 | struct list_head transfer_list; | 941 | struct list_head transfer_list; |
| 937 | }; | 942 | }; |
| @@ -51,7 +51,7 @@ $(OUTPUT)spidev_fdx: $(SPIDEV_FDX_IN) · 50 unmodified lines | |||
| 51 | 51 | ||
| 52 | clean: | 52 | clean: |
| 53 | rm -f $(ALL_PROGRAMS) | 53 | rm -f $(ALL_PROGRAMS) |
| 54 | rm -f $(OUTPUT)include/linux/spi/spidev.h | 54 | rm -rf $(OUTPUT)include/ |
| 55 | find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete | 55 | find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete |
| 56 | 56 | ||
| 57 | install: $(ALL_PROGRAMS) | 57 | install: $(ALL_PROGRAMS) |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <stdio.h> | 13 | #include <stdio.h> |
| 14 | #include <stdlib.h> | 14 | #include <stdlib.h> |
| 15 | #include <string.h> | 15 | #include <string.h> |
| 16 | #include <errno.h> | ||
| 16 | #include <getopt.h> | 17 | #include <getopt.h> |
| 17 | #include <fcntl.h> | 18 | #include <fcntl.h> |
| 18 | #include <time.h> | 19 | #include <time.h> |
| @@ -26,7 +27,11 @@ · 7 unmodified lines | |||
| 26 | 27 | ||
| 27 | static void pabort(const char *s) | 28 | static void pabort(const char *s) |
| 28 | { | 29 | { |
| 29 | perror(s); | 30 | if (errno != 0) |
| 31 | perror(s); | ||
| 32 | else | ||
| 33 | printf("%s\n", s); | ||
| 34 | |||
| 30 | abort(); | 35 | abort(); |
| 31 | } | 36 | } |
| 32 | 37 | ||
| @@ -283,7 +288,6 @@ static void parse_opts(int argc, char *argv[]) · 250 unmodified lines | |||
| 283 | break; | 288 | break; |
| 284 | default: | 289 | default: |
| 285 | print_usage(argv[0]); | 290 | print_usage(argv[0]); |
| 286 | break; | ||
| 287 | } | 291 | } |
| 288 | } | 292 | } |
| 289 | if (mode & SPI_LOOP) { | 293 | if (mode & SPI_LOOP) { |
| @@ -405,6 +409,9 @@ int main(int argc, char *argv[]) · 115 unmodified lines | |||
| 405 | 409 | ||
| 406 | parse_opts(argc, argv); | 410 | parse_opts(argc, argv); |
| 407 | 411 | ||
| 412 | if (input_tx && input_file) | ||
| 413 | pabort("only one of -p and --input may be selected"); | ||
| 414 | |||
| 408 | fd = open(device, O_RDWR); | 415 | fd = open(device, O_RDWR); |
| 409 | if (fd < 0) | 416 | if (fd < 0) |
| 410 | pabort("can't open device"); | 417 | pabort("can't open device"); |
| @@ -446,9 +453,6 @@ int main(int argc, char *argv[]) · 35 unmodified lines | |||
| 446 | printf("bits per word: %d\n", bits); | 453 | printf("bits per word: %d\n", bits); |
| 447 | printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); | 454 | printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); |
| 448 | 455 | ||
| 449 | if (input_tx && input_file) | ||
| 450 | pabort("only one of -p and --input may be selected"); | ||
| 451 | |||
| 452 | if (input_tx) | 456 | if (input_tx) |
| 453 | transfer_escaped_string(fd, input_tx); | 457 | transfer_escaped_string(fd, input_tx); |
| 454 | else if (input_file) | 458 | else if (input_file) |