Merge tag 'mips_7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux

Pull MIPS updates from Thomas Bogendoerfer:

 - Support for Mobileye EyeQ6Lplus

 - Cleanups and fixes

* tag 'mips_7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (30 commits)
  MIPS/mtd: Handle READY GPIO in generic NAND platform data
  MIPS/input: Move RB532 button to GPIO descriptors
  MIPS: validate DT bootargs before appending them
  MIPS: Alchemy: Remove unused forward declaration
  MAINTAINERS: Mobileye: Add EyeQ6Lplus files
  MIPS: config: add eyeq6lplus_defconfig
  MIPS: Add Mobileye EyeQ6Lplus evaluation board dts
  MIPS: Add Mobileye EyeQ6Lplus SoC dtsi
  clk: eyeq: Add Mobileye EyeQ6Lplus OLB
  clk: eyeq: Adjust PLL accuracy computation
  clk: eyeq: Skip post-divisor when computing PLL frequency
  pinctrl: eyeq5: Add Mobileye EyeQ6Lplus OLB
  pinctrl: eyeq5: Use match data
  reset: eyeq: Add Mobileye EyeQ6Lplus OLB
  MIPS: Add Mobileye EyeQ6Lplus support
  dt-bindings: soc: mobileye: Add EyeQ6Lplus OLB
  dt-bindings: mips: Add Mobileye EyeQ6Lplus SoC
  MIPS: dts: loongson64g-package: Switch to Loongson UART driver
  mips: pci-mt7620: rework initialization procedure
  mips: pci-mt7620: add more register init values
  ...
This commit is contained in:
Linus Torvalds
2026-04-17 08:53:23 -07:00
42 changed files with 1589 additions and 247 deletions

View File

@@ -31,6 +31,11 @@ properties:
- enum:
- mobileye,eyeq6h-epm6
- const: mobileye,eyeq6h
- description: Boards with Mobileye EyeQ6Lplus SoC
items:
- enum:
- mobileye,eyeq6lplus-epm6
- const: mobileye,eyeq6lplus
additionalProperties: true

View File

@@ -51,6 +51,9 @@ properties:
clock-names:
const: ref
'#phy-cells':
const: 1
patternProperties:
'-pins?$':
type: object
@@ -310,7 +313,7 @@ allOf:
properties:
'#reset-cells': false
# Only EyeQ5 has pinctrl in OLB.
# Only EyeQ5 has pinctrl and PHY in OLB.
- if:
not:
properties:
@@ -320,6 +323,8 @@ allOf:
then:
patternProperties:
'-pins?$': false
properties:
'#phy-cells': false
examples:
- |

View File

@@ -0,0 +1,208 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/mobileye/mobileye,eyeq6lplus-olb.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mobileye EyeQ6Lplus SoC system controller
maintainers:
- Benoît Monin <benoit.monin@bootlin.com>
- Grégory Clement <gregory.clement@bootlin.com>
- Théo Lebrun <theo.lebrun@bootlin.com>
- Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
description:
OLB ("Other Logic Block") is a hardware block grouping smaller blocks.
Clocks, resets, pinctrl are being handled from here. EyeQ6Lplus hosts
a single instance providing 22 clocks, two reset domains and one bank
of 32 pins.
properties:
compatible:
items:
- const: mobileye,eyeq6lplus-olb
- const: syscon
reg:
maxItems: 1
'#reset-cells':
description:
First cell is reset domain index.
Second cell is reset index inside that domain.
const: 2
'#clock-cells':
const: 1
clocks:
maxItems: 1
description:
Input parent clock to all PLLs. Expected to be the main crystal.
clock-names:
const: ref
patternProperties:
'-pins?$':
type: object
description: Pin muxing configuration.
$ref: /schemas/pinctrl/pinmux-node.yaml#
additionalProperties: false
properties:
pins: true
function:
enum: [gpio, timer0, timer1, uart_ssi, spi0, uart0, timer2, timer3,
timer_ext0, spi1, timer_ext1, ext_ref_clk, mipi_ref_clk]
bias-disable: true
bias-pull-down: true
bias-pull-up: true
drive-strength: true
required:
- pins
- function
allOf:
- if:
properties:
function:
const: gpio
then:
properties:
pins:
items: # PA0 - PA31
pattern: '^(PA[1,2]?[0-9]|PA3[0,1])$'
- if:
properties:
function:
const: timer0
then:
properties:
pins:
items:
enum: [PA0, PA1]
- if:
properties:
function:
const: timer1
then:
properties:
pins:
items:
enum: [PA2, PA3]
- if:
properties:
function:
const: uart_ssi
then:
properties:
pins:
items:
enum: [PA4, PA5]
- if:
properties:
function:
const: spi0
then:
properties:
pins:
items:
enum: [PA6, PA7, PA8, PA9, PA10]
- if:
properties:
function:
const: uart0
then:
properties:
pins:
items:
enum: [PA11, PA12]
- if:
properties:
function:
const: timer2
then:
properties:
pins:
items:
enum: [PA13, PA14]
- if:
properties:
function:
const: timer3
then:
properties:
pins:
items:
enum: [PA15, PA16]
- if:
properties:
function:
const: timer_ext0
then:
properties:
pins:
items:
enum: [PA17, PA18, PA19, PA20]
- if:
properties:
function:
const: spi1
then:
properties:
pins:
items:
enum: [PA21, PA22, PA23, PA24, PA25]
- if:
properties:
function:
const: timer_ext1
then:
properties:
pins:
items:
enum: [PA26, PA27, PA28, PA29]
- if:
properties:
function:
const: ext_ref_clk
then:
properties:
pins:
items:
enum: [PA30]
- if:
properties:
function:
const: mipi_ref_clk
then:
properties:
pins:
items:
enum: [PA31]
required:
- compatible
- reg
- '#clock-cells'
- clocks
- clock-names
- '#reset-cells'
additionalProperties: false
examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
system-controller@e8400000 {
compatible = "mobileye,eyeq6lplus-olb", "syscon";
reg = <0 0xe8400000 0x0 0x80000>;
#reset-cells = <2>;
#clock-cells = <1>;
clocks = <&xtal>;
clock-names = "ref";
};
};

View File

@@ -17913,6 +17913,7 @@ F: drivers/media/dvb-frontends/mn88473*
MOBILEYE MIPS SOCS
M: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
M: Benoît Monin <benoit.monin@bootlin.com>
M: Gregory CLEMENT <gregory.clement@bootlin.com>
M: Théo Lebrun <theo.lebrun@bootlin.com>
L: linux-mips@vger.kernel.org
@@ -17920,12 +17921,13 @@ S: Maintained
F: Documentation/devicetree/bindings/mips/mobileye.yaml
F: Documentation/devicetree/bindings/soc/mobileye/
F: arch/mips/boot/dts/mobileye/
F: arch/mips/configs/eyeq5_defconfig
F: arch/mips/configs/eyeq*_defconfig
F: arch/mips/mobileye/board-epm5.its.S
F: drivers/clk/clk-eyeq.c
F: drivers/pinctrl/pinctrl-eyeq5.c
F: drivers/reset/reset-eyeq.c
F: include/dt-bindings/clock/mobileye,eyeq5-clk.h
F: include/dt-bindings/clock/mobileye,eyeq6lplus-clk.h
MODULE SUPPORT
M: Luis Chamberlain <mcgrof@kernel.org>

View File

@@ -1,6 +1,8 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;
#include <dt-bindings/clock/econet,en751221-scu.h>
/ {
compatible = "econet,en751221";
#address-cells = <1>;
@@ -30,6 +32,30 @@
#interrupt-cells = <1>;
};
chip_scu: syscon@1fa20000 {
compatible = "econet,en751221-chip-scu", "syscon";
reg = <0x1fa20000 0x388>;
};
pcie_phy1: pcie-phy@1fac0000 {
compatible = "econet,en751221-pcie-gen2";
reg = <0x1fac0000 0x1000>;
#phy-cells = <0>;
};
pcie_phy0: pcie-phy@1faf2000 {
compatible = "econet,en751221-pcie-gen1";
reg = <0x1faf2000 0x1000>;
#phy-cells = <0>;
};
scuclk: clock-controller@1fb00000 {
compatible = "econet,en751221-scu";
reg = <0x1fb00000 0x970>;
#clock-cells = <1>;
#reset-cells = <1>;
};
intc: interrupt-controller@1fb40000 {
compatible = "econet,en751221-intc";
reg = <0x1fb40000 0x100>;
@@ -41,6 +67,94 @@
econet,shadow-interrupts = <7 2>, <8 3>, <13 12>, <30 29>;
};
pciecfg: pciecfg@1fb80000 {
compatible = "mediatek,generic-pciecfg", "syscon";
reg = <0x1fb80000 0x1000>;
};
pcie0: pcie@1fb81000 {
compatible = "econet,en7528-pcie";
device_type = "pci";
reg = <0x1fb81000 0x1000>;
reg-names = "port0";
linux,pci-domain = <0>;
#address-cells = <3>;
#size-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <23>;
interrupt-names = "pcie_irq";
clocks = <&scuclk EN751221_CLK_PCIE>;
clock-names = "sys_ck0";
phys = <&pcie_phy0>;
phy-names = "pcie-phy0";
bus-range = <0x00 0xff>;
ranges = <0x01000000 0 0x00000000 0x1f600000 0 0x00008000>,
<0x82000000 0 0x20000000 0x20000000 0 0x08000000>;
status = "disabled";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc0 0>,
<0 0 0 2 &pcie_intc0 1>,
<0 0 0 3 &pcie_intc0 2>,
<0 0 0 4 &pcie_intc0 3>;
pcie_intc0: interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
};
slot0: pcie@0,0 {
reg = <0x0000 0 0 0 0>;
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
ranges;
};
};
pcie1: pcie@1fb83000 {
compatible = "econet,en7528-pcie";
device_type = "pci";
reg = <0x1fb83000 0x1000>;
reg-names = "port1";
linux,pci-domain = <1>;
#address-cells = <3>;
#size-cells = <2>;
interrupt-parent = <&intc>;
interrupts = <24>;
interrupt-names = "pcie_irq";
clocks = <&scuclk EN751221_CLK_PCIE>;
clock-names = "sys_ck1";
phys = <&pcie_phy1>;
phy-names = "pcie-phy1";
bus-range = <0x00 0xff>;
ranges = <0x81000000 0 0x00000000 0x1f608000 0 0x00008000>,
<0x82000000 0 0x28000000 0x28000000 0 0x08000000>;
status = "disabled";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc1 0>,
<0 0 0 2 &pcie_intc1 1>,
<0 0 0 3 &pcie_intc1 2>,
<0 0 0 4 &pcie_intc1 3>;
pcie_intc1: interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
};
slot1: pcie@1,0 {
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
ranges;
};
};
uart: serial@1fbf0000 {
compatible = "ns16550";
reg = <0x1fbf0000 0x30>;

View File

@@ -17,3 +17,24 @@
linux,usable-memory-range = <0x00020000 0x1bfe0000>;
};
};
&pcie0 {
status = "okay";
};
&slot0 {
wifi@0,0 {
/* MT7612E */
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
};
};
&pcie1 {
status = "okay";
};
&slot1 {
wifi@0,0 {
/* MT7592 */
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
};
};

View File

@@ -40,7 +40,7 @@
};
cpu_uart0: serial@1fe00100 {
compatible = "ns16550a";
compatible = "loongson,ls3a4000-uart", "loongson,ls2k1500-uart", "ns16550a";
reg = <0 0x1fe00100 0x10>;
clock-frequency = <100000000>;
interrupt-parent = <&liointc>;
@@ -50,7 +50,7 @@
cpu_uart1: serial@1fe00110 {
status = "disabled";
compatible = "ns16550a";
compatible = "loongson,ls3a4000-uart", "loongson,ls2k1500-uart", "ns16550a";
reg = <0 0x1fe00110 0x10>;
clock-frequency = <100000000>;
interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;

View File

@@ -3,3 +3,4 @@
dtb-$(CONFIG_MACH_EYEQ5) += eyeq5-epm5.dtb
dtb-$(CONFIG_MACH_EYEQ6H) += eyeq6h-epm6.dtb
dtb-$(CONFIG_MACH_EYEQ6LPLUS) += eyeq6lplus-epm6.dtb

View File

@@ -29,3 +29,29 @@
label = "U60";
};
};
&macb0 {
phy-mode = "sgmii";
phy-handle = <&macb0_phy>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
macb0_phy: ethernet-phy@e {
reg = <0xe>;
};
};
};
&macb1 {
phy-mode = "rgmii-id";
phy-handle = <&macb1_phy>;
mdio {
#address-cells = <1>;
#size-cells = <0>;
macb1_phy: ethernet-phy@e {
reg = <0xe>;
};
};
};

View File

@@ -77,6 +77,8 @@
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
ethernet0 = &macb0;
ethernet1 = &macb1;
};
cpu_intc: interrupt-controller {
@@ -231,6 +233,7 @@
#clock-cells = <1>;
clocks = <&xtal>;
clock-names = "ref";
#phy-cells = <1>;
};
gic: interrupt-controller@140000 {
@@ -305,6 +308,48 @@
#interrupt-cells = <2>;
resets = <&olb 0 26>;
};
iocu-bus {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
dma-coherent;
dma-ranges = <0x10 0x00000000 0x0 0x0 0x10 0>;
macb0: ethernet@2a00000 {
compatible = "mobileye,eyeq5-gem";
reg = <0x0 0x02a00000 0x0 0x4000>;
interrupt-parent = <&gic>;
/* One interrupt per queue */
interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "pclk", "hclk", "tsu_clk";
clocks = <&pclk>, <&pclk>, <&tsu_clk>;
nvmem-cells = <&eth0_mac>;
nvmem-cell-names = "mac-address";
phys = <&olb 0>;
};
macb1: ethernet@2b00000 {
compatible = "mobileye,eyeq5-gem";
reg = <0x0 0x02b00000 0x0 0x4000>;
interrupt-parent = <&gic>;
/* One interrupt per queue */
interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "pclk", "hclk", "tsu_clk";
clocks = <&pclk>, <&pclk>, <&tsu_clk>;
nvmem-cells = <&eth1_mac>;
nvmem-cell-names = "mac-address";
phys = <&olb 1>;
};
};
};
};

View File

@@ -0,0 +1,103 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
* Copyright 2025 Mobileye Vision Technologies Ltd.
*/
/dts-v1/;
#include "eyeq6lplus.dtsi"
/ {
compatible = "mobileye,eyeq6lplus-epm6", "mobileye,eyeq6lplus";
model = "Mobileye EyeQ6Lplus Evaluation board";
aliases {
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:921600n8";
};
memory@0 {
device_type = "memory";
reg = <0x1 0x00000000 0x0 0x80000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
/* These reserved memory regions are also defined in bootmanager
* for configuring inbound translation for BARS, don't change
* these without syncing with bootmanager
*/
mhm_reserved_0: the-mhm-reserved-0 {
reg = <0x1 0x00000000 0x0 0x0000800>;
};
bm_logs_reserved: bm-logs-reserved {
reg = <0x1 0x0000800 0x0 0x000f800>;
};
shmem0_reserved: shmem@804000000 {
reg = <0x1 0x04000000 0x0 0x1000000>;
};
shmem1_reserved: shmem@805000000 {
reg = <0x1 0x05000000 0x0 0x1000000>;
};
mini_coredump0_reserved: mini-coredump0@806200000 {
reg = <0x1 0x06200000 0x0 0x100000>;
};
mailbox_reserved: mailbox-reserved {
reg = <0x1 0x06300000 0x0 0x000300>;
};
sys_logs_reserved: sys-logs-reserved {
reg = <0x1 0x10000000 0x0 0x800000>;
};
csl_policy_logs_reserved: csl-policy-logs-reserved {
reg = <0x1 0x10800000 0x0 0x10000>;
};
};
};
&ospi {
status = "okay";
flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <40000000>;
cdns,read-delay = <0>;
cdns,tshsl-ns = <400>;
cdns,tsd2d-ns = <120>;
cdns,tchsh-ns = <40>;
cdns,tslch-ns = <20>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <8>;
};
};
&spi0 {
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
status = "okay";
};
&spi1 {
pinctrl-0 = <&spi1_pins>;
pinctrl-names = "default";
status = "okay";
};
&uart0 {
pinctrl-0 = <&uart0_pins>;
pinctrl-names = "default";
status = "okay";
};
&i2c0 {
status = "okay";
};
&i2c1 {
status = "okay";
};

View File

@@ -0,0 +1,84 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
&olb {
timer0_pins: timer0-pins {
function = "timer0";
pins = "PA0", "PA1";
};
timer1_pins: timer1-pins {
function = "timer1";
pins = "PA2", "PA3";
};
uart_ssi_pins: uart-ssi-pins {
function = "uart_ssi";
pins = "PA4", "PA5";
};
spi0_pins: spi0-pins {
function = "spi0";
pins = "PA6", "PA7", "PA8", "PA9";
};
uart0_pins: uart0-pins {
function = "uart0";
pins = "PA11", "PA12";
};
timer2_pins: timer2-pins {
function = "timer2";
pins = "PA13", "PA14";
};
timer3_pins: timer3-pins {
function = "timer3";
pins = "PA15", "PA16";
};
timer_ext0_pins: timer-ext0-pins {
function = "timer_ext0";
pins = "PA17", "PA18", "PA19", "PA20";
};
timer_ext0_input_a_pins: timer-ext0-input-a-pins {
function = "timer_ext0";
pins = "PA17";
};
pps0_pins: pps0-pins {
function = "timer_ext0";
pins = "PA17";
};
timer_ext0_input_b_pins: timer-ext0-input-b-pins {
function = "timer_ext0";
pins = "PA18";
};
timer_ext0_output_pins: timer-ext0-output-pins {
function = "timer_ext0";
pins = "PA19", "PA20";
};
spi1_pins: spi1-pins {
function = "spi1";
pins = "PA21", "PA22", "PA23", "PA24";
};
spi1_reduced_pins: spi1-reduced-pins {
function = "spi1";
pins = "PA21", "PA22", "PA23";
};
timer_ext1_pins: timer-ext1-pins {
function = "timer_ext1";
pins = "PA26", "PA27", "PA28", "PA29";
};
timer_ext1_input_a_pins: timer-ext1-input-a-pins {
function = "timer_ext1";
pins = "PA26";
};
timer_ext1_input_b_pins: timer-ext1-input-b-pins {
function = "timer_ext1";
pins = "PA27";
};
timer_ext1_output_pins: timer-ext1-output-pins {
function = "timer_ext1";
pins = "PA28", "PA29";
};
ext_ref_clk_pins: ext-ref-clk-pins {
function = "ext_ref_clk";
pins = "PA30";
};
mipi_ref_clk_pins: mipi-ref-clk-pins {
function = "mipi_ref_clk";
pins = "PA31";
};
};

View File

@@ -0,0 +1,170 @@
// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
/*
* Copyright 2025 Mobileye Vision Technologies Ltd.
*/
#include <dt-bindings/interrupt-controller/mips-gic.h>
#include <dt-bindings/clock/mobileye,eyeq6lplus-clk.h>
/ {
#address-cells = <2>;
#size-cells = <2>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "img,i6500";
reg = <0>;
clocks = <&olb EQ6LPC_CPU_OCC>;
};
};
cpu_intc: interrupt-controller {
compatible = "mti,cpu-interrupt-controller";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
};
coherency-manager {
compatible = "mobileye,eyeq6-cm";
};
xtal: clock-30000000 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <30000000>;
};
soc: soc {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
olb: system-controller@e8400000 {
compatible = "mobileye,eyeq6lplus-olb", "syscon";
reg = <0 0xe8400000 0x0 0x80000>;
#reset-cells = <2>;
#clock-cells = <1>;
clocks = <&xtal>;
clock-names = "ref";
};
ospi: spi@e8800000 {
compatible = "mobileye,eyeq5-ospi", "cdns,qspi-nor";
#address-cells = <1>;
#size-cells = <0>;
reg = <0 0xe8800000 0x0 0x100000>,
<0 0xb0000000 0x0 0x30000000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 10 IRQ_TYPE_LEVEL_HIGH>;
cdns,fifo-depth = <128>;
cdns,fifo-width = <4>;
cdns,trigger-address = <0x00000000>;
clocks = <&olb EQ6LPC_PER_OSPI>;
status = "disabled";
};
spi0: spi@eac0d000 {
compatible = "snps,dw-apb-ssi";
reg = <0 0xeac0d000 0x0 0x1000>;
clocks = <&olb EQ6LPC_PER_SPI>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 11 IRQ_TYPE_LEVEL_HIGH>;
resets = <&olb 0 0>;
reset-names = "spi";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
spi1: spi@eac0e000 {
compatible = "snps,dw-apb-ssi";
reg = <0 0xeac0e000 0x0 0x1000>;
spi-slave;
clocks = <&olb EQ6LPC_PER_SPI>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 12 IRQ_TYPE_LEVEL_HIGH>;
resets = <&olb 0 1>;
reset-names = "spi";
#address-cells = <0>;
#size-cells = <0>;
status = "disabled";
};
uart0: serial@eac10000 {
compatible = "snps,dw-apb-uart";
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&olb EQ6LPC_PER_UART>;
clock-frequency = <15625000>;
reg = <0 0xeac10000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 8 IRQ_TYPE_LEVEL_HIGH>;
resets = <&olb 0 2>;
status = "disabled";
};
i2c0: i2c@eac11000 {
compatible = "mobileye,eyeq6lplus-i2c", "snps,designware-i2c";
reg = <0 0xeac11000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <400000>;
clocks = <&olb EQ6LPC_PER_I2C_SER>;
resets = <&olb 0 3>;
i2c-sda-hold-time-ns = <50>;
status = "disabled";
};
i2c1: i2c@eac12000 {
compatible = "mobileye,eyeq6lplus-i2c", "snps,designware-i2c";
reg = <0 0xeac12000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 7 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <400000>;
clocks = <&olb EQ6LPC_PER_I2C_SER>;
resets = <&olb 0 4>;
i2c-sda-hold-time-ns = <50>;
status = "disabled";
};
gpio: gpio@eac14000 {
compatible = "snps,dw-apb-gpio";
reg = <0x0 0xeac14000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
resets = <&olb 0 13>;
porta: gpio-port@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
snps,nr-gpios = <32>;
gpio-ranges = <&olb 0 0 32>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 13 IRQ_TYPE_LEVEL_HIGH>;
};
};
gic: interrupt-controller@f0920000 {
compatible = "mti,gic";
reg = <0x0 0xf0920000 0x0 0x20000>;
interrupt-controller;
#interrupt-cells = <3>;
interrupt-parent = <&cpu_intc>;
timer {
compatible = "mti,gic-timer";
interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
clocks = <&olb EQ6LPC_CPU_OCC>;
};
};
};
};
#include "eyeq6lplus-pins.dtsi"

View File

@@ -0,0 +1,117 @@
CONFIG_SYSVIPC=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_TASKSTATS=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_EYEQ=y
CONFIG_MACH_EYEQ6LPLUS=y
CONFIG_MIPS_CPS=y
CONFIG_CPU_HAS_MSA=y
CONFIG_NR_CPUS=16
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_JUMP_LABEL=y
CONFIG_PAGE_SIZE_16KB=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_TRIM_UNUSED_KSYMS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_USERFAULTFD=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_NETFILTER=y
CONFIG_CAN=y
CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_ENDPOINT=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_CONNECTOR=y
CONFIG_MTD=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BLOCK=y
CONFIG_SCSI=y
CONFIG_NETDEVICES=y
CONFIG_MACVLAN=y
CONFIG_IPVLAN=y
CONFIG_MACB=y
CONFIG_MARVELL_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_CAN_M_CAN=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DW=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_SPI=y
CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_SPI_DESIGNWARE=y
CONFIG_SPI_DW_MMIO=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_SLAVE=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_PINCTRL=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DWAPB=y
CONFIG_MFD_SYSCON=y
CONFIG_HID_A4TECH=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
CONFIG_HID_ITE=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_REDRAGON=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_CADENCE=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_RESET_CONTROLLER=y
# CONFIG_NVMEM is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UBIFS_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_2=y
CONFIG_ROOT_NFS=y
CONFIG_FRAME_WARN=1024
CONFIG_DEBUG_FS=y
# CONFIG_RCU_TRACE is not set
# CONFIG_FTRACE is not set

View File

@@ -71,7 +71,6 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_WATCHDOG=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_GBE=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y

View File

@@ -136,7 +136,6 @@ CONFIG_FB_SIS_300=y
CONFIG_FB_SIS_315=y
CONFIG_FB_SIMPLE=y
CONFIG_FB_SM712=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y

View File

@@ -128,7 +128,6 @@ CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_G=y
CONFIG_USB=y

View File

@@ -129,7 +129,6 @@ CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_G=y
CONFIG_USB=y

View File

@@ -129,7 +129,6 @@ CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_G=y
CONFIG_USB=y

View File

@@ -132,7 +132,6 @@ CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_G=y
CONFIG_USB=y

View File

@@ -128,7 +128,6 @@ CONFIG_POWER_RESET_PIIX4_POWEROFF=y
CONFIG_POWER_RESET_SYSCON=y
# CONFIG_HWMON is not set
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_G=y
CONFIG_USB=y

View File

@@ -5,12 +5,13 @@
* 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
* 5900/260 (KN05) systems.
*
* Copyright (c) 2003, 2005 Maciej W. Rozycki
* Copyright (c) 2003, 2005, 2026 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/ratelimit.h>
#include <linux/sched.h>
#include <linux/types.h>
@@ -51,6 +52,10 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
static const char overstr[] = "overrun";
static const char eccstr[] = "ECC error";
static DEFINE_RATELIMIT_STATE(rs,
DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
const char *kind, *agent, *cycle, *event;
const char *status = "", *xbit = "", *fmt = "";
unsigned long address;
@@ -70,7 +75,7 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
if (!(erraddr & KN0X_EAR_VALID)) {
/* No idea what happened. */
printk(KERN_ALERT "Unidentified bus error %s\n", kind);
pr_alert_ratelimited("Unidentified bus error %s\n", kind);
return action;
}
@@ -180,12 +185,13 @@ static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
}
}
if (action != MIPS_BE_FIXUP)
if (action != MIPS_BE_FIXUP && __ratelimit(&rs)) {
printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
printk(fmt, " ECC syndrome ", syn, status, xbit, i);
if (erraddr & KN0X_EAR_ECCERR)
printk(fmt, " ECC syndrome ", syn, status, xbit, i);
}
return action;
}

View File

@@ -4,7 +4,7 @@
* and 2100 (KN01) systems equipped with parity error detection
* logic.
*
* Copyright (c) 2005 Maciej W. Rozycki
* Copyright (c) 2005, 2026 Maciej W. Rozycki
*/
#include <linux/init.h>
@@ -134,8 +134,8 @@ static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
action = MIPS_BE_FIXUP;
if (action != MIPS_BE_FIXUP)
printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
pr_alert_ratelimited("Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
return action;
}

View File

@@ -6,12 +6,13 @@
* DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
* (KN04-CA) systems.
*
* Copyright (c) 2005 Maciej W. Rozycki
* Copyright (c) 2005, 2026 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/ratelimit.h>
#include <linux/types.h>
#include <asm/addrspace.h>
@@ -50,6 +51,10 @@ static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
static const char paritystr[] = "parity error";
static const char lanestat[][4] = { " OK", "BAD" };
static DEFINE_RATELIMIT_STATE(rs,
DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
const char *kind, *agent, *cycle, *event;
unsigned long address;
@@ -79,18 +84,19 @@ static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
if (is_fixup)
action = MIPS_BE_FIXUP;
if (action != MIPS_BE_FIXUP)
if (action != MIPS_BE_FIXUP && __ratelimit(&rs)) {
printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
if (action != MIPS_BE_FIXUP && address < 0x10000000)
printk(KERN_ALERT " Byte lane status %#3x -- "
"#3: %s, #2: %s, #1: %s, #0: %s\n",
(mer & KN02XA_MER_BYTERR) >> 8,
lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
if (address < 0x10000000)
printk(KERN_ALERT " Byte lane status %#3x -- "
"#3: %s, #2: %s, #1: %s, #0: %s\n",
(mer & KN02XA_MER_BYTERR) >> 8,
lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
}
return action;
}

View File

@@ -13,7 +13,9 @@ choice
bool "EN751221 family"
select COMMON_CLK
select ECONET_EN751221_INTC
select HAVE_PCI
select IRQ_MIPS_CPU
select PCI_DRIVERS_GENERIC
select SMP
select SMP_UP
select SYS_SUPPORTS_SMP

View File

@@ -40,8 +40,6 @@
#define AU1000_GPIO2_INTENABLE 0x10
#define AU1000_GPIO2_ENABLE 0x14
struct gpio;
static inline int au1000_gpio1_to_irq(int gpio)
{
return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);

View File

@@ -12,7 +12,6 @@
#include <asm/io.h>
#include <asm/mach-au1x00/au1000.h>
struct gpio;
struct gpio_chip;
/* with the current GPIC design, up to 128 GPIOs are possible.

View File

@@ -91,7 +91,7 @@ void mult_sh_align_mod(long *v1, long *v2, long *w,
".set pop"
: "=&r" (lv1), "=r" (lw)
: "r" (m1), "r" (m2), "r" (s), "I" (0)
: "hi", "lo", "$0");
: "hi", "lo");
/* We have to use single integers for m1 and m2 and a double
* one for p to be sure the mulsidi3 gcc's RTL multiplication
* instruction has the workaround applied. Older versions of

View File

@@ -31,6 +31,7 @@
#include <linux/of_fdt.h>
#include <linux/dmi.h>
#include <linux/crash_dump.h>
#include <linux/string.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -541,6 +542,9 @@ static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
p = of_get_flat_dt_prop(node, "bootargs", &l);
if (p != NULL && l > 0) {
if (strnlen(p, l) >= l)
return 1;
bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
*dt_bootargs = true;
}

View File

@@ -12,6 +12,9 @@ choice
config MACH_EYEQ6H
bool "Mobileye EyeQ6H SoC"
config MACH_EYEQ6LPLUS
bool "Mobileye EyeQ6Lplus SoC"
endchoice
config FIT_IMAGE_FDT_EPM5

View File

@@ -10,6 +10,7 @@
load-$(CONFIG_MACH_EYEQ5) = 0xa800000808000000
load-$(CONFIG_MACH_EYEQ6H) = 0xa800000100800000
load-$(CONFIG_MACH_EYEQ6LPLUS) = 0xa800000108800000
all-$(CONFIG_MACH_EYEQ5) += vmlinux.gz.itb
its-y := vmlinux.its.S

View File

@@ -26,8 +26,9 @@
#define RALINK_INT_PCIE0 4
#define RALINK_SYSCFG0 0x10
#define RALINK_SYSCFG0_XTAL40 BIT(6)
#define RALINK_CLKCFG1 0x30
#define RALINK_GPIOMODE 0x60
#define PPLL_CFG1 0x9c
#define PPLL_LD BIT(23)
@@ -62,7 +63,7 @@
#define PCIEPHY0_CFG 0x90
#define RALINK_PCIEPHY_P0_CTL_OFFSET 0x7498
#define RALINK_PCIEPHY_P0_CTL_OFFSET 0x7000
#define RALINK_PCIE0_CLK_EN BIT(26)
#define BUSY 0x80000000
@@ -87,6 +88,15 @@ static inline u32 bridge_r32(unsigned reg)
return ioread32(bridge_base + reg);
}
static inline void bridge_m32(u32 clr, u32 set, unsigned reg)
{
u32 val = bridge_r32(reg);
val &= ~clr;
val |= set;
bridge_w32(val, reg);
}
static inline void pcie_w32(u32 val, unsigned reg)
{
iowrite32(val, pcie_base + reg);
@@ -106,6 +116,14 @@ static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
pcie_w32(val, reg);
}
static inline void
pcie_phyctrl_set(unsigned offset, u32 b_start, u32 bits, u32 val)
{
pcie_m32(GENMASK(b_start + bits - 1, b_start),
val << b_start,
RALINK_PCIEPHY_P0_CTL_OFFSET + offset);
}
static int wait_pciephy_busy(void)
{
unsigned long reg_value = 0x0, retry = 0;
@@ -227,19 +245,6 @@ static int mt7620_pci_hw_init(struct platform_device *pdev)
/* Elastic buffer control */
pcie_phy(0x68, 0xB4);
/* put core into reset */
pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
reset_control_assert(rstpcie0);
/* disable power and all clocks */
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
/* bring core out of reset */
reset_control_deassert(rstpcie0);
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
mdelay(100);
if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) {
dev_err(&pdev->dev, "pcie PLL not locked, aborting init\n");
reset_control_assert(rstpcie0);
@@ -254,27 +259,36 @@ static int mt7620_pci_hw_init(struct platform_device *pdev)
return 0;
}
static int mt7628_pci_hw_init(struct platform_device *pdev)
static void mt7628_pci_hw_init(struct platform_device *pdev)
{
u32 val = 0;
/* bring the core out of reset */
rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
reset_control_deassert(rstpcie0);
/* enable the pci clk */
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
mdelay(100);
/* voodoo from the SDK driver */
pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
pcie_phyctrl_set(0x400, 8, 1, 0x1);
pcie_phyctrl_set(0x400, 9, 2, 0x0);
pcie_phyctrl_set(0x000, 4, 1, 0x1);
pcie_phyctrl_set(0x000, 5, 1, 0x0);
pcie_phyctrl_set(0x4ac, 16, 3, 0x3);
pci_config_read(NULL, 0, 0x70c, 4, &val);
val &= ~(0xff) << 8;
val |= 0x50 << 8;
pci_config_write(NULL, 0, 0x70c, 4, val);
if (rt_sysc_r32(RALINK_SYSCFG0) & RALINK_SYSCFG0_XTAL40) {
pcie_phyctrl_set(0x4bc, 24, 8, 0x7d);
pcie_phyctrl_set(0x490, 12, 4, 0x08);
pcie_phyctrl_set(0x490, 6, 2, 0x01);
pcie_phyctrl_set(0x4c0, 0, 32, 0x1f400000);
pcie_phyctrl_set(0x4a4, 0, 16, 0x013d);
pcie_phyctrl_set(0x4a8, 16, 16, 0x74);
pcie_phyctrl_set(0x4a8, 0, 16, 0x74);
} else {
pcie_phyctrl_set(0x4bc, 24, 8, 0x64);
pcie_phyctrl_set(0x490, 12, 4, 0x0a);
pcie_phyctrl_set(0x490, 6, 2, 0x00);
pcie_phyctrl_set(0x4c0, 0, 32, 0x19000000);
pcie_phyctrl_set(0x4a4, 0, 16, 0x018d);
pcie_phyctrl_set(0x4a8, 16, 16, 0x4a);
pcie_phyctrl_set(0x4a8, 0, 16, 0x4a);
}
return 0;
pcie_phyctrl_set(0x498, 0, 8, 0x5);
pcie_phyctrl_set(0x000, 5, 1, 0x1);
pcie_phyctrl_set(0x000, 4, 1, 0x0);
}
static int mt7620_pci_probe(struct platform_device *pdev)
@@ -298,6 +312,16 @@ static int mt7620_pci_probe(struct platform_device *pdev)
ioport_resource.start = 0;
ioport_resource.end = ~0;
/* reset PCIe controller */
reset_control_assert(rstpcie0);
msleep(100);
reset_control_deassert(rstpcie0);
rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
msleep(100);
/* assert PERST_N pin */
bridge_m32(PCIRST, PCIRST, RALINK_PCI_PCICFG_ADDR);
/* bring up the pci core */
switch (ralink_soc) {
case MT762X_SOC_MT7620A:
@@ -307,19 +331,18 @@ static int mt7620_pci_probe(struct platform_device *pdev)
case MT762X_SOC_MT7628AN:
case MT762X_SOC_MT7688:
if (mt7628_pci_hw_init(pdev))
return -1;
mt7628_pci_hw_init(pdev);
break;
default:
dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
return -1;
}
mdelay(50);
msleep(500);
/* enable write access */
pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
mdelay(100);
/* deassert PERST_N pin and wait PCIe peripheral init */
bridge_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
msleep(1000);
/* check if there is a card present */
if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
@@ -327,6 +350,8 @@ static int mt7620_pci_probe(struct platform_device *pdev)
rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
if (ralink_soc == MT762X_SOC_MT7620A)
rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
else
pcie_phyctrl_set(0x000, 0, 32, 0x10);
dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
return -1;
}
@@ -340,12 +365,17 @@ static int mt7620_pci_probe(struct platform_device *pdev)
pcie_w32(0x06040001, RALINK_PCI0_CLASS);
/* enable interrupts */
pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
bridge_m32(PCIINT2, PCIINT2, RALINK_PCI_PCIENA);
/* voodoo from the SDK driver */
pci_config_read(NULL, 0, 4, 4, &val);
pci_config_write(NULL, 0, 4, 4, val | 0x7);
pci_config_read(NULL, 0, 0x70c, 4, &val);
val &= ~(0xff) << 8;
val |= 0x50 << 8;
pci_config_write(NULL, 0, 0x70c, 4, val);
pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
register_pci_controller(&mt7620_controller);

View File

@@ -14,10 +14,11 @@
#include <linux/platform_device.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/mtd.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/property.h>
#include <linux/serial_8250.h>
#include <asm/bootinfo.h>
@@ -38,6 +39,10 @@ extern unsigned int idt_cpu_freq;
static struct mpmc_device dev3;
static const struct software_node rb532_gpio0_node = {
.name = "gpio0",
};
void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
{
unsigned long flags;
@@ -129,12 +134,6 @@ static struct platform_device cf_slot0 = {
.num_resources = ARRAY_SIZE(cf_slot0_res),
};
/* Resources and device for NAND */
static int rb532_dev_ready(struct nand_chip *chip)
{
return gpio_get_value(GPIO_RDY);
}
static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
{
unsigned char orbits, nandbits;
@@ -160,16 +159,23 @@ static struct resource nand_slot0_res[] = {
};
static struct platform_nand_data rb532_nand_data = {
.ctrl.dev_ready = rb532_dev_ready,
.ctrl.cmd_ctrl = rb532_cmd_ctrl,
};
static struct platform_device nand_slot0 = {
.name = "gen_nand",
.id = -1,
.resource = nand_slot0_res,
.num_resources = ARRAY_SIZE(nand_slot0_res),
.dev.platform_data = &rb532_nand_data,
static const struct property_entry nand0_properties[] = {
PROPERTY_ENTRY_GPIO("ready-gpios", &rb532_gpio0_node,
GPIO_RDY, GPIO_ACTIVE_HIGH),
{ }
};
static const struct platform_device_info nand0_info __initconst = {
.name = "gen_nand",
.id = PLATFORM_DEVID_NONE,
.res = nand_slot0_res,
.num_res = ARRAY_SIZE(nand_slot0_res),
.data = &rb532_nand_data,
.size_data = sizeof(struct platform_nand_data),
.properties = nand0_properties,
};
static struct mtd_partition rb532_partition_info[] = {
@@ -189,11 +195,6 @@ static struct platform_device rb532_led = {
.id = -1,
};
static struct platform_device rb532_button = {
.name = "rb532-button",
.id = -1,
};
static struct resource rb532_wdt_res[] = {
{
.name = "rb532_wdt_res",
@@ -233,14 +234,25 @@ static struct platform_device rb532_uart = {
static struct platform_device *rb532_devs[] = {
&korina_dev0,
&nand_slot0,
&cf_slot0,
&rb532_led,
&rb532_button,
&rb532_uart,
&rb532_wdt
};
static const struct property_entry rb532_button_properties[] = {
PROPERTY_ENTRY_GPIO("button-gpios", &rb532_gpio0_node,
GPIO_BTN_S1, GPIO_ACTIVE_LOW),
{ }
};
static const struct platform_device_info rb532_button_info __initconst = {
.name = "rb532-button",
.id = PLATFORM_DEVID_NONE,
.properties = rb532_button_properties,
};
/* NAND definitions */
#define NAND_CHIP_DELAY 25
@@ -267,6 +279,9 @@ static void __init rb532_nand_setup(void)
static int __init plat_setup_devices(void)
{
struct platform_device *pd;
int ret;
/* Look for the CF card reader */
if (!readl(IDT434_REG_BASE + DEV1MASK))
rb532_devs[2] = NULL; /* disable cf_slot0 at index 2 */
@@ -295,7 +310,31 @@ static int __init plat_setup_devices(void)
rb532_uart_res[0].uartclk = idt_cpu_freq;
gpiod_add_lookup_table(&cf_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
ret = platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
if (ret)
return ret;
/*
* Stack devices using full info and properties here, after we
* register the node for the GPIO chip.
*/
software_node_register(&rb532_gpio0_node);
pd = platform_device_register_full(&nand0_info);
ret = PTR_ERR_OR_ZERO(pd);
if (ret) {
pr_err("failed to create NAND slot0 device: %d\n", ret);
return ret;
}
pd = platform_device_register_full(&rb532_button_info);
ret = PTR_ERR_OR_ZERO(pd);
if (ret) {
pr_err("failed to create RB532 button device: %d\n", ret);
return ret;
}
return 0;
}
#ifdef CONFIG_NET

View File

@@ -236,9 +236,9 @@ config COMMON_CLK_EP93XX
config COMMON_CLK_EYEQ
bool "Clock driver for the Mobileye EyeQ platform"
depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST
depends on EYEQ || COMPILE_TEST
select AUXILIARY_BUS
default MACH_EYEQ5 || MACH_EYEQ6H
default EYEQ
help
This driver provides clocks found on Mobileye EyeQ5, EyeQ6L and Eye6H
SoCs. Controllers live in shared register regions called OLB. Driver

View File

@@ -45,6 +45,7 @@
#include <linux/types.h>
#include <dt-bindings/clock/mobileye,eyeq5-clk.h>
#include <dt-bindings/clock/mobileye,eyeq6lplus-clk.h>
/* In frac mode, it enables fractional noise canceling DAC. Else, no function. */
#define PCSR0_DAC_EN BIT(0)
@@ -163,7 +164,7 @@ static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div)
static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult,
unsigned long *div, unsigned long *acc)
{
u32 spread;
unsigned long spread;
if (r0 & PCSR0_BYPASS) {
*mult = 1;
@@ -177,8 +178,6 @@ static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult,
*mult = FIELD_GET(PCSR0_INTIN, r0);
*div = FIELD_GET(PCSR0_REF_DIV, r0);
if (r0 & PCSR0_FOUTPOSTDIV_EN)
*div *= FIELD_GET(PCSR0_POST_DIV1, r0) * FIELD_GET(PCSR0_POST_DIV2, r0);
/* Fractional mode, in 2^20 (0x100000) parts. */
if (r0 & PCSR0_DSM_EN) {
@@ -197,23 +196,23 @@ static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult,
/*
* Spread spectrum.
*
* Spread is 1/1000 parts of frequency, accuracy is half of
* that. To get accuracy, convert to ppb (parts per billion).
* Spread is in 1/1024 parts of frequency. Clock accuracy
* is half the spread value expressed in parts per billion.
*
* acc = spread * 1e6 / 2
* with acc in parts per billion and,
* spread in parts per thousand.
* accuracy = (spread * 1e9) / (1024 * 2)
*
* Care is taken to avoid overflowing or losing precision.
*/
spread = FIELD_GET(PCSR1_SPREAD, r1);
*acc = spread * 500000;
*acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2);
if (r1 & PCSR1_DOWN_SPREAD) {
/*
* Downspreading: the central frequency is half a
* spread lower.
*/
*mult *= 2000 - spread;
*div *= 2000;
*mult *= 2048 - spread;
*div *= 2048;
/*
* Previous operation might overflow 32 bits. If it
@@ -573,6 +572,68 @@ static const struct eqc_match_data eqc_eyeq6l_match_data = {
.reset_auxdev_name = "reset",
};
static const struct eqc_pll eqc_eyeq6lplus_early_plls[] = {
{ .index = EQ6LPC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x058 },
};
static const struct eqc_pll eqc_eyeq6lplus_plls[] = {
{ .index = EQ6LPC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C },
{ .index = EQ6LPC_PLL_ACC, .name = "pll-acc", .reg64 = 0x034 },
{ .index = EQ6LPC_PLL_PER, .name = "pll-per", .reg64 = 0x03C },
{ .index = EQ6LPC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 },
};
static const struct eqc_fixed_factor eqc_eyeq6lplus_early_fixed_factors[] = {
{ EQ6LPC_CPU_OCC, "occ-cpu", 1, 1, EQ6LPC_PLL_CPU },
};
static const struct eqc_fixed_factor eqc_eyeq6lplus_fixed_factors[] = {
{ EQ6LPC_DDR_OCC, "occ-ddr", 1, 1, EQ6LPC_PLL_DDR },
{ EQ6LPC_ACC_VDI, "vdi-div", 1, 10, EQ6LPC_PLL_ACC },
{ EQ6LPC_ACC_OCC, "occ-acc", 1, 1, EQ6LPC_PLL_ACC },
{ EQ6LPC_ACC_FCMU, "fcmu-a-clk", 1, 10, EQ6LPC_ACC_OCC },
{ EQ6LPC_PER_OCC, "occ-per", 1, 1, EQ6LPC_PLL_PER },
{ EQ6LPC_PER_I2C_SER, "i2c-ser-clk", 1, 10, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_PCLK, "pclk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_TSU, "tsu-clk", 1, 8, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_OSPI, "ospi-ref-clk", 1, 10, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_GPIO, "gpio-clk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_TIMER, "timer-clk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_I2C, "i2c-clk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_UART, "uart-clk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_SPI, "spi-clk", 1, 4, EQ6LPC_PER_OCC },
{ EQ6LPC_PER_PERIPH, "periph-clk", 1, 1, EQ6LPC_PER_OCC },
{ EQ6LPC_VDI_OCC, "occ-vdi", 1, 1, EQ6LPC_PLL_VDI },
};
static const struct eqc_early_match_data eqc_eyeq6lplus_early_match_data __initconst = {
.early_pll_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls),
.early_plls = eqc_eyeq6lplus_early_plls,
.early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors),
.early_fixed_factors = eqc_eyeq6lplus_early_fixed_factors,
.late_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_plls) +
ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors),
};
static const struct eqc_match_data eqc_eyeq6lplus_match_data = {
.pll_count = ARRAY_SIZE(eqc_eyeq6lplus_plls),
.plls = eqc_eyeq6lplus_plls,
.fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors),
.fixed_factors = eqc_eyeq6lplus_fixed_factors,
.reset_auxdev_name = "reset",
.pinctrl_auxdev_name = "pinctrl",
.early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls) +
ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors),
};
static const struct eqc_match_data eqc_eyeq6h_west_match_data = {
.reset_auxdev_name = "reset_west",
};
@@ -674,6 +735,7 @@ static const struct eqc_match_data eqc_eyeq6h_acc_match_data = {
static const struct of_device_id eqc_match_table[] = {
{ .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data },
{ .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data },
{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data },
{ .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data },
{ .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data },
{ .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data },
@@ -857,3 +919,9 @@ static void __init eqc_eyeq6h_west_early_init(struct device_node *np)
}
CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west, "mobileye,eyeq6h-west-olb",
eqc_eyeq6h_west_early_init);
static void __init eqc_eyeq6lplus_early_init(struct device_node *np)
{
eqc_early_init(np, &eqc_eyeq6lplus_early_match_data);
}
CLK_OF_DECLARE_DRIVER(eqc_eyeq6lplus, "mobileye,eyeq6lplus-olb", eqc_eyeq6lplus_early_init);

View File

@@ -8,7 +8,7 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <asm/mach-rc32434/gpio.h>
#include <asm/mach-rc32434/rb.h>
@@ -18,6 +18,14 @@
#define RB532_BTN_RATE 100 /* msec */
#define RB532_BTN_KSYM BTN_0
/**
* struct rb532_button - RB532 button information
* @gpio: GPIO connected to the button
*/
struct rb532_button {
struct gpio_desc *gpio;
};
/* The S1 button state is provided by GPIO pin 1. But as this
* pin is also used for uart input as alternate function, the
* operational modes must be switched first:
@@ -31,35 +39,48 @@
* The GPIO value occurs to be inverted, so pin high means
* button is not pressed.
*/
static bool rb532_button_pressed(void)
static bool rb532_button_pressed(struct rb532_button *button)
{
int val;
set_latch_u5(0, LO_FOFF);
gpio_direction_input(GPIO_BTN_S1);
gpiod_direction_input(button->gpio);
val = gpio_get_value(GPIO_BTN_S1);
val = gpiod_get_value(button->gpio);
rb532_gpio_set_func(GPIO_BTN_S1);
set_latch_u5(LO_FOFF, 0);
return !val;
return val;
}
static void rb532_button_poll(struct input_dev *input)
{
input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed());
struct rb532_button *button = input_get_drvdata(input);
input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed(button));
input_sync(input);
}
static int rb532_button_probe(struct platform_device *pdev)
{
struct rb532_button *button;
struct input_dev *input;
int error;
button = devm_kzalloc(&pdev->dev, sizeof(*button), GFP_KERNEL);
if (!button)
return -ENOMEM;
button->gpio = devm_gpiod_get(&pdev->dev, "button", GPIOD_IN);
if (IS_ERR(button->gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(button->gpio),
"error getting button GPIO\n");
input = devm_input_allocate_device(&pdev->dev);
if (!input)
return -ENOMEM;
input_set_drvdata(input, button);
input->name = "rb532 button";
input->phys = "rb532/button0";
@@ -77,6 +98,8 @@ static int rb532_button_probe(struct platform_device *pdev)
if (error)
return error;
platform_set_drvdata(pdev, button);
return 0;
}

View File

@@ -6,6 +6,7 @@
*/
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -17,6 +18,7 @@ struct plat_nand_data {
struct nand_controller controller;
struct nand_chip chip;
void __iomem *io_base;
struct gpio_desc *ready_gpio;
};
static int plat_nand_attach_chip(struct nand_chip *chip)
@@ -32,6 +34,14 @@ static const struct nand_controller_ops plat_nand_ops = {
.attach_chip = plat_nand_attach_chip,
};
/* Resources and device for NAND */
static int plat_nand_gpio_dev_ready(struct nand_chip *chip)
{
struct plat_nand_data *data = nand_get_controller_data(chip);
return gpiod_get_value(data->ready_gpio);
}
/*
* Probe for the NAND device.
*/
@@ -41,6 +51,7 @@ static int plat_nand_probe(struct platform_device *pdev)
struct plat_nand_data *data;
struct mtd_info *mtd;
const char **part_types;
struct nand_chip *chip;
int err = 0;
if (!pdata) {
@@ -59,9 +70,17 @@ static int plat_nand_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
data->ready_gpio = devm_gpiod_get_optional(&pdev->dev, "ready",
GPIOD_IN);
if (IS_ERR(data->ready_gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(data->ready_gpio),
"could not get READY GPIO\n");
data->controller.ops = &plat_nand_ops;
nand_controller_init(&data->controller);
data->chip.controller = &data->controller;
chip = &data->chip;
nand_set_controller_data(chip, data);
data->io_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->io_base))
@@ -74,7 +93,10 @@ static int plat_nand_probe(struct platform_device *pdev)
data->chip.legacy.IO_ADDR_R = data->io_base;
data->chip.legacy.IO_ADDR_W = data->io_base;
data->chip.legacy.cmd_ctrl = pdata->ctrl.cmd_ctrl;
data->chip.legacy.dev_ready = pdata->ctrl.dev_ready;
if (data->ready_gpio)
data->chip.legacy.dev_ready = plat_nand_gpio_dev_ready;
else
data->chip.legacy.dev_ready = pdata->ctrl.dev_ready;
data->chip.legacy.select_chip = pdata->ctrl.select_chip;
data->chip.legacy.write_buf = pdata->ctrl.write_buf;
data->chip.legacy.read_buf = pdata->ctrl.read_buf;

View File

@@ -254,11 +254,11 @@ config PINCTRL_EQUILIBRIUM
config PINCTRL_EYEQ5
bool "Mobileye EyeQ5 pinctrl driver"
depends on OF
depends on MACH_EYEQ5 || COMPILE_TEST
depends on MACH_EYEQ5 || MACH_EYEQ6LPLUS || COMPILE_TEST
select PINMUX
select GENERIC_PINCONF
select AUXILIARY_BUS
default MACH_EYEQ5
default MACH_EYEQ5 || MACH_EYEQ6LPLUS
help
Pin controller driver for the Mobileye EyeQ5 platform. It does both
pin config & pin muxing. It does not handle GPIO.

View File

@@ -26,6 +26,7 @@
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -38,18 +39,6 @@
#include "core.h"
#include "pinctrl-utils.h"
struct eq5p_pinctrl {
struct pinctrl_desc desc;
void __iomem *base;
};
enum eq5p_bank {
EQ5P_BANK_A,
EQ5P_BANK_B,
EQ5P_BANK_COUNT,
};
enum eq5p_regs {
EQ5P_PD,
EQ5P_PU,
@@ -60,9 +49,24 @@ enum eq5p_regs {
EQ5P_REG_COUNT,
};
static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = {
[EQ5P_BANK_A] = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
[EQ5P_BANK_B] = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},
struct eq5p_bank {
const unsigned int npins;
const unsigned int regs[EQ5P_REG_COUNT];
};
struct eq5p_match_data {
const unsigned int npins;
const unsigned int nfunctions;
const unsigned int nbanks;
const struct pinctrl_pin_desc *pins;
const struct pinfunction *functions;
const struct eq5p_bank *banks;
};
struct eq5p_pinctrl {
struct pinctrl_desc desc;
void __iomem *base;
const struct eq5p_match_data *data;
};
/*
@@ -70,10 +74,18 @@ static const unsigned int eq5p_regs[EQ5P_BANK_COUNT][EQ5P_REG_COUNT] = {
*/
#define EQ5P_DS_MASK GENMASK(1, 0)
/*
* The GPIO function is always the first function
*/
#define EQ5P_GPIO_FUNC_SELECTOR 0
/* Helper to declare pinfunction */
#define EQ5P_PINFUNCTION(func, groups) PINCTRL_PINFUNCTION(func, groups, ARRAY_SIZE(groups))
/*
* Comments to the right of each pin are the "signal name" in the datasheet.
*/
static const struct pinctrl_pin_desc eq5p_pins[] = {
static const struct pinctrl_pin_desc eq5p_eyeq5_pins[] = {
/* Bank A */
PINCTRL_PIN(0, "PA0"), /* A0_TIMER0_CK */
PINCTRL_PIN(1, "PA1"), /* A1_TIMER0_EOC */
@@ -105,35 +117,35 @@ static const struct pinctrl_pin_desc eq5p_pins[] = {
PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */
PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */
#define EQ5P_PIN_OFFSET_BANK_B 29
#define EQ5P_EYEQ5_PIN_OFFSET_BANK_B 29
/* Bank B */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */
PINCTRL_PIN(EQ5P_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 0, "PB0"), /* B0_TIMER3_CK */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 1, "PB1"), /* B1_TIMER3_EOC */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 2, "PB2"), /* B2_TIMER4_CK */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 3, "PB3"), /* B3_TIMER4_EOC */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 4, "PB4"), /* B4_TIMER6_EXT_INCAP1 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 5, "PB5"), /* B5_TIMER6_EXT_INCAP2 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 6, "PB6"), /* B6_TIMER6_EXT_OUTCMP1 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 7, "PB7"), /* B7_TIMER6_EXT_OUTCMP2 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 8, "PB8"), /* B8_UART_2_TX */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 9, "PB9"), /* B9_UART_2_RX */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */
PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */
};
static const char * const gpio_groups[] = {
static const char * const eq5p_eyeq5_gpio_groups[] = {
/* Bank A */
"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
"PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
@@ -147,70 +159,184 @@ static const char * const gpio_groups[] = {
};
/* Groups of functions on bank A */
static const char * const timer0_groups[] = { "PA0", "PA1" };
static const char * const timer1_groups[] = { "PA2", "PA3" };
static const char * const timer2_groups[] = { "PA4", "PA5" };
static const char * const timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };
static const char * const uart0_groups[] = { "PA10", "PA11" };
static const char * const uart1_groups[] = { "PA12", "PA13" };
static const char * const can0_groups[] = { "PA14", "PA15" };
static const char * const can1_groups[] = { "PA16", "PA17" };
static const char * const spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };
static const char * const spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };
static const char * const refclk0_groups[] = { "PA28" };
static const char * const eq5p_eyeq5_timer0_groups[] = { "PA0", "PA1" };
static const char * const eq5p_eyeq5_timer1_groups[] = { "PA2", "PA3" };
static const char * const eq5p_eyeq5_timer2_groups[] = { "PA4", "PA5" };
static const char * const eq5p_eyeq5_timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };
static const char * const eq5p_eyeq5_uart0_groups[] = { "PA10", "PA11" };
static const char * const eq5p_eyeq5_uart1_groups[] = { "PA12", "PA13" };
static const char * const eq5p_eyeq5_can0_groups[] = { "PA14", "PA15" };
static const char * const eq5p_eyeq5_can1_groups[] = { "PA16", "PA17" };
static const char * const eq5p_eyeq5_spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };
static const char * const eq5p_eyeq5_spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };
static const char * const eq5p_eyeq5_refclk0_groups[] = { "PA28" };
/* Groups of functions on bank B */
static const char * const timer3_groups[] = { "PB0", "PB1" };
static const char * const timer4_groups[] = { "PB2", "PB3" };
static const char * const timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };
static const char * const uart2_groups[] = { "PB8", "PB9" };
static const char * const can2_groups[] = { "PB10", "PB11" };
static const char * const spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };
static const char * const spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };
static const char * const mclk0_groups[] = { "PB22" };
static const char * const eq5p_eyeq5_timer3_groups[] = { "PB0", "PB1" };
static const char * const eq5p_eyeq5_timer4_groups[] = { "PB2", "PB3" };
static const char * const eq5p_eyeq5_timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };
static const char * const eq5p_eyeq5_uart2_groups[] = { "PB8", "PB9" };
static const char * const eq5p_eyeq5_can2_groups[] = { "PB10", "PB11" };
static const char * const eq5p_eyeq5_spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };
static const char * const eq5p_eyeq5_spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };
static const char * const eq5p_eyeq5_mclk0_groups[] = { "PB22" };
static const struct pinfunction eq5p_functions[] = {
/* GPIO having a fixed index is depended upon, see GPIO_FUNC_SELECTOR. */
PINCTRL_PINFUNCTION("gpio", gpio_groups, ARRAY_SIZE(gpio_groups)),
#define GPIO_FUNC_SELECTOR 0
static const struct pinfunction eq5p_eyeq5_functions[] = {
/* GPIO having a fixed index is depended upon, see EQ5P_GPIO_FUNC_SELECTOR. */
EQ5P_PINFUNCTION("gpio", eq5p_eyeq5_gpio_groups),
/* Bank A functions */
PINCTRL_PINFUNCTION("timer0", timer0_groups, ARRAY_SIZE(timer0_groups)),
PINCTRL_PINFUNCTION("timer1", timer1_groups, ARRAY_SIZE(timer1_groups)),
PINCTRL_PINFUNCTION("timer2", timer2_groups, ARRAY_SIZE(timer2_groups)),
PINCTRL_PINFUNCTION("timer5", timer5_groups, ARRAY_SIZE(timer5_groups)),
PINCTRL_PINFUNCTION("uart0", uart0_groups, ARRAY_SIZE(uart0_groups)),
PINCTRL_PINFUNCTION("uart1", uart1_groups, ARRAY_SIZE(uart1_groups)),
PINCTRL_PINFUNCTION("can0", can0_groups, ARRAY_SIZE(can0_groups)),
PINCTRL_PINFUNCTION("can1", can1_groups, ARRAY_SIZE(can1_groups)),
PINCTRL_PINFUNCTION("spi0", spi0_groups, ARRAY_SIZE(spi0_groups)),
PINCTRL_PINFUNCTION("spi1", spi1_groups, ARRAY_SIZE(spi1_groups)),
PINCTRL_PINFUNCTION("refclk0", refclk0_groups, ARRAY_SIZE(refclk0_groups)),
EQ5P_PINFUNCTION("timer0", eq5p_eyeq5_timer0_groups),
EQ5P_PINFUNCTION("timer1", eq5p_eyeq5_timer1_groups),
EQ5P_PINFUNCTION("timer2", eq5p_eyeq5_timer2_groups),
EQ5P_PINFUNCTION("timer5", eq5p_eyeq5_timer5_groups),
EQ5P_PINFUNCTION("uart0", eq5p_eyeq5_uart0_groups),
EQ5P_PINFUNCTION("uart1", eq5p_eyeq5_uart1_groups),
EQ5P_PINFUNCTION("can0", eq5p_eyeq5_can0_groups),
EQ5P_PINFUNCTION("can1", eq5p_eyeq5_can1_groups),
EQ5P_PINFUNCTION("spi0", eq5p_eyeq5_spi0_groups),
EQ5P_PINFUNCTION("spi1", eq5p_eyeq5_spi1_groups),
EQ5P_PINFUNCTION("refclk0", eq5p_eyeq5_refclk0_groups),
/* Bank B functions */
PINCTRL_PINFUNCTION("timer3", timer3_groups, ARRAY_SIZE(timer3_groups)),
PINCTRL_PINFUNCTION("timer4", timer4_groups, ARRAY_SIZE(timer4_groups)),
PINCTRL_PINFUNCTION("timer6", timer6_groups, ARRAY_SIZE(timer6_groups)),
PINCTRL_PINFUNCTION("uart2", uart2_groups, ARRAY_SIZE(uart2_groups)),
PINCTRL_PINFUNCTION("can2", can2_groups, ARRAY_SIZE(can2_groups)),
PINCTRL_PINFUNCTION("spi2", spi2_groups, ARRAY_SIZE(spi2_groups)),
PINCTRL_PINFUNCTION("spi3", spi3_groups, ARRAY_SIZE(spi3_groups)),
PINCTRL_PINFUNCTION("mclk0", mclk0_groups, ARRAY_SIZE(mclk0_groups)),
EQ5P_PINFUNCTION("timer3", eq5p_eyeq5_timer3_groups),
EQ5P_PINFUNCTION("timer4", eq5p_eyeq5_timer4_groups),
EQ5P_PINFUNCTION("timer6", eq5p_eyeq5_timer6_groups),
EQ5P_PINFUNCTION("uart2", eq5p_eyeq5_uart2_groups),
EQ5P_PINFUNCTION("can2", eq5p_eyeq5_can2_groups),
EQ5P_PINFUNCTION("spi2", eq5p_eyeq5_spi2_groups),
EQ5P_PINFUNCTION("spi3", eq5p_eyeq5_spi3_groups),
EQ5P_PINFUNCTION("mclk0", eq5p_eyeq5_mclk0_groups),
};
static const struct eq5p_bank eq5p_eyeq5_banks[] = {
{
.npins = EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
.regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
},
{
.npins = ARRAY_SIZE(eq5p_eyeq5_pins) - EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
.regs = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},
},
};
static const struct eq5p_match_data eq5p_eyeq5_data = {
.npins = ARRAY_SIZE(eq5p_eyeq5_pins),
.nfunctions = ARRAY_SIZE(eq5p_eyeq5_functions),
.nbanks = ARRAY_SIZE(eq5p_eyeq5_banks),
.pins = eq5p_eyeq5_pins,
.functions = eq5p_eyeq5_functions,
.banks = eq5p_eyeq5_banks,
};
static const struct pinctrl_pin_desc eq5p_eyeq6lplus_pins[] = {
PINCTRL_PIN(0, "PA0"), /* GPIO_A0_TIMER0_CK0 */
PINCTRL_PIN(1, "PA1"), /* GPIO_A1_TIMER0_EOC */
PINCTRL_PIN(2, "PA2"), /* GPIO_A2_TIMER1_CK */
PINCTRL_PIN(3, "PA3"), /* GPIO_A3_TIMER1_EOC1 */
PINCTRL_PIN(4, "PA4"), /* GPIO_A4_SSI_UART_RX */
PINCTRL_PIN(5, "PA5"), /* GPIO_A5_SSI_UART_TX */
PINCTRL_PIN(6, "PA6"), /* GPIO_A6_SPI_0_CS */
PINCTRL_PIN(7, "PA7"), /* GPIO_A7_SPI_0_DI */
PINCTRL_PIN(8, "PA8"), /* GPIO_A8_SPI_0_CK */
PINCTRL_PIN(9, "PA9"), /* GPIO_A9_SPI_0_DO */
PINCTRL_PIN(10, "PA10"), /* GPIO_A10_SPI_0_CS1 */
PINCTRL_PIN(11, "PA11"), /* GPIO_A11_UART_0_RX */
PINCTRL_PIN(12, "PA12"), /* GPIO_A12_UART_0_TX */
PINCTRL_PIN(13, "PA13"), /* GPIO_A13_TIMER2_CK */
PINCTRL_PIN(14, "PA14"), /* GPIO_A14_TIMER2_EOC */
PINCTRL_PIN(15, "PA15"), /* GPIO_A15_TIMER3_CK */
PINCTRL_PIN(16, "PA16"), /* GPIO_A16_TIMER_EOC */
PINCTRL_PIN(17, "PA17"), /* GPIO_A17_TIMER_EXT0_INCA P1 */
PINCTRL_PIN(18, "PA18"), /* GPIO_A18_TIMER_EXT0_INCA P2 */
PINCTRL_PIN(19, "PA19"), /* GPIO_A19_TIMER_EXT0_OUT CMP1 */
PINCTRL_PIN(20, "PA20"), /* GPIO_A20_TIMER_EXT0_OUT CMP2 */
PINCTRL_PIN(21, "PA21"), /* GPIO_A21_SPI_1_CS0 */
PINCTRL_PIN(22, "PA22"), /* GPIO_A22_SPI_1_DI */
PINCTRL_PIN(23, "PA23"), /* GPIO_A23_SPI_1_CK */
PINCTRL_PIN(24, "PA24"), /* GPIO_A24_SPI_1_DO */
PINCTRL_PIN(25, "PA25"), /* GPIO_A25_SPI_1_CS1 */
PINCTRL_PIN(26, "PA26"), /* GPIO_A26_TIMER_EXT1_INCA P1 */
PINCTRL_PIN(27, "PA27"), /* GPIO_A27_TIMER_EXT1_INCA P2 */
PINCTRL_PIN(28, "PA28"), /* GPIO_A28_TIMER_EXT1_OUTC MP1 */
PINCTRL_PIN(29, "PA29"), /* GPIO_A29_TIMER_EXT1_OUTC MP2 */
PINCTRL_PIN(30, "PA30"), /* GPIO_A30_EXT_CLK */
PINCTRL_PIN(31, "PA31"), /* GPIO_A31_VDI_MCLK */
};
static const char * const eq5p_eyeq6lplus_gpio_groups[] = {
/* Bank A */
"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
"PA8", "PA9", "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",
"PA24", "PA25", "PA26", "PA27", "PA28", "PA29", "PA30", "PA31",
};
/* Groups of functions on bank A */
static const char * const eq5p_eyeq6lplus_timer0_groups[] = { "PA0", "PA1" };
static const char * const eq5p_eyeq6lplus_timer1_groups[] = { "PA2", "PA3" };
static const char * const eq5p_eyeq6lplus_uart_ssi_groups[] = { "PA4", "PA5" };
static const char * const eq5p_eyeq6lplus_spi0_groups[] = { "PA6", "PA7", "PA8", "PA9", "PA10" };
static const char * const eq5p_eyeq6lplus_uart0_groups[] = { "PA11", "PA12" };
static const char * const eq5p_eyeq6lplus_timer2_groups[] = { "PA13", "PA14" };
static const char * const eq5p_eyeq6lplus_timer3_groups[] = { "PA15", "PA16" };
static const char * const eq5p_eyeq6lplus_timer_ext0_groups[] = { "PA17", "PA18", "PA19", "PA20" };
static const char * const eq5p_eyeq6lplus_spi1_groups[] = {
"PA21", "PA22", "PA23", "PA24", "PA25"
};
static const char * const eq5p_eyeq6lplus_timer_ext1_groups[] = { "PA26", "PA27", "PA28", "PA29" };
static const char * const eq5p_eyeq6lplus_ext_ref_clk_groups[] = { "PA30" };
static const char * const eq5p_eyeq6lplus_mipi_ref_clk_groups[] = { "PA31" };
static const struct pinfunction eq5p_eyeq6lplus_functions[] = {
/* gpios function */
EQ5P_PINFUNCTION("gpio", eq5p_eyeq6lplus_gpio_groups),
/* Bank A alternate functions */
EQ5P_PINFUNCTION("timer0", eq5p_eyeq6lplus_timer0_groups),
EQ5P_PINFUNCTION("timer1", eq5p_eyeq6lplus_timer1_groups),
EQ5P_PINFUNCTION("uart_ssi", eq5p_eyeq6lplus_uart_ssi_groups),
EQ5P_PINFUNCTION("spi0", eq5p_eyeq6lplus_spi0_groups),
EQ5P_PINFUNCTION("uart0", eq5p_eyeq6lplus_uart0_groups),
EQ5P_PINFUNCTION("timer2", eq5p_eyeq6lplus_timer2_groups),
EQ5P_PINFUNCTION("timer3", eq5p_eyeq6lplus_timer3_groups),
EQ5P_PINFUNCTION("timer_ext0", eq5p_eyeq6lplus_timer_ext0_groups),
EQ5P_PINFUNCTION("spi1", eq5p_eyeq6lplus_spi1_groups),
EQ5P_PINFUNCTION("timer_ext1", eq5p_eyeq6lplus_timer_ext1_groups),
EQ5P_PINFUNCTION("ext_ref_clk", eq5p_eyeq6lplus_ext_ref_clk_groups),
EQ5P_PINFUNCTION("mipi_ref_clk", eq5p_eyeq6lplus_mipi_ref_clk_groups),
};
static const struct eq5p_bank eq5p_eyeq6lplus_banks[] = {
{
.npins = ARRAY_SIZE(eq5p_eyeq6lplus_pins),
.regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
},
};
static const struct eq5p_match_data eq5p_eyeq6lplus_data = {
.npins = ARRAY_SIZE(eq5p_eyeq6lplus_pins),
.nfunctions = ARRAY_SIZE(eq5p_eyeq6lplus_functions),
.nbanks = ARRAY_SIZE(eq5p_eyeq6lplus_banks),
.pins = eq5p_eyeq6lplus_pins,
.functions = eq5p_eyeq6lplus_functions,
.banks = eq5p_eyeq6lplus_banks,
};
static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl,
enum eq5p_bank bank, enum eq5p_regs reg,
u32 mask, u32 val)
const struct eq5p_bank *bank,
enum eq5p_regs reg, u32 mask, u32 val)
{
void __iomem *ptr = pctrl->base + eq5p_regs[bank][reg];
void __iomem *ptr = pctrl->base + bank->regs[reg];
writel((readl(ptr) & ~mask) | (val & mask), ptr);
}
static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,
enum eq5p_bank bank, enum eq5p_regs reg, int offset)
const struct eq5p_bank *bank,
enum eq5p_regs reg, int offset)
{
u32 val = readl(pctrl->base + eq5p_regs[bank][reg]);
u32 val = readl(pctrl->base + bank->regs[reg]);
if (WARN_ON(offset > 31))
return false;
@@ -218,25 +344,29 @@ static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,
return (val & BIT(offset)) != 0;
}
static enum eq5p_bank eq5p_pin_to_bank(unsigned int pin)
static int eq5p_pin_to_bank_offset(const struct eq5p_pinctrl *pctrl, unsigned int pin,
const struct eq5p_bank **bank, unsigned int *offset)
{
if (pin < EQ5P_PIN_OFFSET_BANK_B)
return EQ5P_BANK_A;
else
return EQ5P_BANK_B;
}
for (unsigned int i = 0; i < pctrl->data->nbanks; i++) {
const struct eq5p_bank *_bank = &pctrl->data->banks[i];
unsigned int npins = _bank->npins;
static unsigned int eq5p_pin_to_offset(unsigned int pin)
{
if (pin < EQ5P_PIN_OFFSET_BANK_B)
return pin;
else
return pin - EQ5P_PIN_OFFSET_BANK_B;
if (pin < npins) {
*bank = _bank;
*offset = pin;
return 0;
}
pin -= npins;
}
return -EINVAL;
}
static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(eq5p_pins);
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->data->npins;
}
static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
@@ -260,10 +390,15 @@ static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
{
enum pin_config_param param = pinconf_to_config_param(*config);
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned int offset = eq5p_pin_to_offset(pin);
enum eq5p_bank bank = eq5p_pin_to_bank(pin);
const struct eq5p_bank *bank;
unsigned int offset;
u32 val_ds, arg;
bool pd, pu;
int ret;
ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
if (ret)
return ret;
pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);
pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);
@@ -281,10 +416,10 @@ static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
case PIN_CONFIG_DRIVE_STRENGTH:
offset *= 2; /* two bits per pin */
if (offset >= 32) {
val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_HIGH]);
val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_HIGH]);
offset -= 32;
} else {
val_ds = readl(pctrl->base + eq5p_regs[bank][EQ5P_DS_LOW]);
val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_LOW]);
}
arg = (val_ds >> offset) & EQ5P_DS_MASK;
break;
@@ -302,30 +437,35 @@ static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const char *pin_name = pctrl->desc.pins[pin].name;
unsigned int offset = eq5p_pin_to_offset(pin);
enum eq5p_bank bank = eq5p_pin_to_bank(pin);
const struct eq5p_bank *bank;
const char *func_name, *bias;
unsigned long ds_config;
unsigned int offset;
u32 drive_strength;
bool pd, pu;
int i, j;
if (eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset)) {
seq_puts(s, "unknown pin");
return;
}
/*
* First, let's get the function name. All pins have only two functions:
* GPIO (IOCR == 0) and something else (IOCR == 1).
*/
if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) {
func_name = NULL;
for (i = 0; i < ARRAY_SIZE(eq5p_functions); i++) {
if (i == GPIO_FUNC_SELECTOR)
for (i = 0; i < pctrl->data->nfunctions; i++) {
if (i == EQ5P_GPIO_FUNC_SELECTOR)
continue;
for (j = 0; j < eq5p_functions[i].ngroups; j++) {
for (j = 0; j < pctrl->data->functions[i].ngroups; j++) {
/* Groups and pins are the same thing for us. */
const char *x = eq5p_functions[i].groups[j];
const char *x = pctrl->data->functions[i].groups[j];
if (strcmp(x, pin_name) == 0) {
func_name = eq5p_functions[i].name;
func_name = pctrl->data->functions[i].name;
break;
}
}
@@ -341,7 +481,7 @@ static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
if (!func_name)
func_name = "unknown";
} else {
func_name = eq5p_functions[GPIO_FUNC_SELECTOR].name;
func_name = pctrl->data->functions[EQ5P_GPIO_FUNC_SELECTOR].name;
}
/* Second, we retrieve the bias. */
@@ -376,13 +516,17 @@ static const struct pinctrl_ops eq5p_pinctrl_ops = {
static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(eq5p_functions);
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->data->nfunctions;
}
static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev,
unsigned int selector)
{
return eq5p_functions[selector].name;
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
return pctrl->data->functions[selector].name;
}
static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
@@ -390,8 +534,10 @@ static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
const char * const **groups,
unsigned int *num_groups)
{
*groups = eq5p_functions[selector].groups;
*num_groups = eq5p_functions[selector].ngroups;
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
*groups = pctrl->data->functions[selector].groups;
*num_groups = pctrl->data->functions[selector].ngroups;
return 0;
}
@@ -399,12 +545,17 @@ static int eq5p_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int func_selector, unsigned int pin)
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const char *func_name = eq5p_functions[func_selector].name;
const char *func_name = pctrl->data->functions[func_selector].name;
const char *group_name = pctldev->desc->pins[pin].name;
bool is_gpio = func_selector == GPIO_FUNC_SELECTOR;
unsigned int offset = eq5p_pin_to_offset(pin);
enum eq5p_bank bank = eq5p_pin_to_bank(pin);
bool is_gpio = func_selector == EQ5P_GPIO_FUNC_SELECTOR;
const struct eq5p_bank *bank;
unsigned int offset;
u32 mask, val;
int ret;
ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
if (ret)
return ret;
dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name);
@@ -419,7 +570,7 @@ static int eq5p_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
unsigned int pin)
{
/* Pin numbers and group selectors are the same thing in our case. */
return eq5p_pinmux_set_mux(pctldev, GPIO_FUNC_SELECTOR, pin);
return eq5p_pinmux_set_mux(pctldev, EQ5P_GPIO_FUNC_SELECTOR, pin);
}
static const struct pinmux_ops eq5p_pinmux_ops = {
@@ -435,10 +586,15 @@ static int eq5p_pinconf_set_drive_strength(struct pinctrl_dev *pctldev,
unsigned int pin, u32 arg)
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
unsigned int offset = eq5p_pin_to_offset(pin);
enum eq5p_bank bank = eq5p_pin_to_bank(pin);
const struct eq5p_bank *bank;
unsigned int offset;
unsigned int reg;
u32 mask, val;
int ret;
ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
if (ret)
return ret;
if (arg & ~EQ5P_DS_MASK) {
dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg);
@@ -465,12 +621,18 @@ static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
{
struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const char *pin_name = pctldev->desc->pins[pin].name;
unsigned int offset = eq5p_pin_to_offset(pin);
enum eq5p_bank bank = eq5p_pin_to_bank(pin);
struct device *dev = pctldev->dev;
u32 val = BIT(offset);
const struct eq5p_bank *bank;
unsigned int offset;
unsigned int i;
u32 val;
int ret;
ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
if (ret)
return ret;
val = BIT(offset);
for (i = 0; i < num_configs; i++) {
enum pin_config_param param = pinconf_to_config_param(configs[i]);
u32 arg = pinconf_to_config_argument(configs[i]);
@@ -533,19 +695,26 @@ static const struct pinconf_ops eq5p_pinconf_ops = {
static int eq5p_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
const struct of_device_id *match;
struct device *dev = &adev->dev;
struct pinctrl_dev *pctldev;
struct eq5p_pinctrl *pctrl;
int ret;
/* Get match data based on parent OF node set in clk-eyeq */
match = of_match_node(dev->driver->of_match_table, dev->of_node);
if (!match || !match->data)
return -ENODEV;
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
return -ENOMEM;
pctrl->base = (void __iomem *)dev_get_platdata(dev);
pctrl->data = match->data;
pctrl->desc.name = dev_name(dev);
pctrl->desc.pins = eq5p_pins;
pctrl->desc.npins = ARRAY_SIZE(eq5p_pins);
pctrl->desc.pins = pctrl->data->pins;
pctrl->desc.npins = pctrl->data->npins;
pctrl->desc.pctlops = &eq5p_pinctrl_ops;
pctrl->desc.pmxops = &eq5p_pinmux_ops;
pctrl->desc.confops = &eq5p_pinconf_ops;
@@ -562,6 +731,13 @@ static int eq5p_probe(struct auxiliary_device *adev,
return 0;
}
static const struct of_device_id eq5p_match_table[] = {
{ .compatible = "mobileye,eyeq5-olb", .data = &eq5p_eyeq5_data },
{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eq5p_eyeq6lplus_data },
{}
};
MODULE_DEVICE_TABLE(of, eq5p_match_table);
static const struct auxiliary_device_id eq5p_id_table[] = {
{ .name = "clk_eyeq.pinctrl" },
{}
@@ -571,5 +747,8 @@ MODULE_DEVICE_TABLE(auxiliary, eq5p_id_table);
static struct auxiliary_driver eq5p_driver = {
.probe = eq5p_probe,
.id_table = eq5p_id_table,
.driver = {
.of_match_table = eq5p_match_table,
}
};
module_auxiliary_driver(eq5p_driver);

View File

@@ -85,9 +85,9 @@ config RESET_EIC7700
config RESET_EYEQ
bool "Mobileye EyeQ reset controller"
depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST
depends on EYEQ || COMPILE_TEST
select AUXILIARY_BUS
default MACH_EYEQ5 || MACH_EYEQ6H
default EYEQ
help
This enables the Mobileye EyeQ reset controller, used in EyeQ5, EyeQ6L
and EyeQ6H SoCs.

View File

@@ -49,6 +49,18 @@
* 8. MPC0 9. MPC1 10. MPC2 11. MPC3
* 12. MPC4
*
* Known resets in EyeQ6Lplus domain 0 (type EQR_EYEQ5_PCIE):
* 0. SPI0 1. SPI1 2. UART0 3. I2C0
* 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2
* 8. TIMER3 9. WD0 10. WD1 11. EXT0
* 12. EXT1 13. GPIO
*
* Known resets in EyeQ6Lplus domain 1 (type EQR_EYEQ5_ACRP):
* 0. VMP0 1. VMP1 2. VMP2 3. VMP3
* 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
* 8. MPC0 9. MPC1 10. MPC2 11. MPC3
* 12. MPC4
*
* Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR):
* 0. CAN 1. SPI0 2. SPI1 3. UART0
* 4. UART1 5. I2C0 6. I2C1 7. -hole-
@@ -521,6 +533,24 @@ static const struct eqr_match_data eqr_eyeq6l_data = {
.domains = eqr_eyeq6l_domains,
};
static const struct eqr_domain_descriptor eqr_eyeq6lplus_domains[] = {
{
.type = EQR_EYEQ5_PCIE,
.valid_mask = 0x3FFF,
.offset = 0x004,
},
{
.type = EQR_EYEQ5_ACRP,
.valid_mask = 0x00FF,
.offset = 0x200,
},
};
static const struct eqr_match_data eqr_eyeq6lplus_data = {
.domain_count = ARRAY_SIZE(eqr_eyeq6lplus_domains),
.domains = eqr_eyeq6lplus_domains,
};
/* West and east OLBs each have an instance. */
static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] = {
{
@@ -555,6 +585,7 @@ static const struct eqr_match_data eqr_eyeq6h_acc_data = {
static const struct of_device_id eqr_match_table[] = {
{ .compatible = "mobileye,eyeq5-olb", .data = &eqr_eyeq5_data },
{ .compatible = "mobileye,eyeq6l-olb", .data = &eqr_eyeq6l_data },
{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eqr_eyeq6lplus_data },
{ .compatible = "mobileye,eyeq6h-west-olb", .data = &eqr_eyeq6h_we_data },
{ .compatible = "mobileye,eyeq6h-east-olb", .data = &eqr_eyeq6h_we_data },
{ .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqr_eyeq6h_acc_data },

View File

@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (C) 2025 Mobileye Vision Technologies Ltd.
*/
#ifndef _DT_BINDINGS_CLOCK_MOBILEYE_EYEQ6LPLUS_CLK_H
#define _DT_BINDINGS_CLOCK_MOBILEYE_EYEQ6LPLUS_CLK_H
#define EQ6LPC_PLL_CPU 0
#define EQ6LPC_PLL_DDR 1
#define EQ6LPC_PLL_PER 2
#define EQ6LPC_PLL_VDI 3
#define EQ6LPC_PLL_ACC 4
#define EQ6LPC_CPU_OCC 5
#define EQ6LPC_ACC_VDI 6
#define EQ6LPC_ACC_OCC 7
#define EQ6LPC_ACC_FCMU 8
#define EQ6LPC_DDR_OCC 9
#define EQ6LPC_PER_OCC 10
#define EQ6LPC_PER_I2C_SER 11
#define EQ6LPC_PER_PCLK 12
#define EQ6LPC_PER_TSU 13
#define EQ6LPC_PER_OSPI 14
#define EQ6LPC_PER_GPIO 15
#define EQ6LPC_PER_TIMER 16
#define EQ6LPC_PER_I2C 17
#define EQ6LPC_PER_UART 18
#define EQ6LPC_PER_SPI 19
#define EQ6LPC_PER_PERIPH 20
#define EQ6LPC_VDI_OCC 21
#endif