linux/drivers/reset/reset-eyeq.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Reset driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms.
 *
 * Controllers live in a shared register region called OLB. EyeQ5 and EyeQ6L
 * have a single OLB instance for a single reset controller. EyeQ6H has seven
 * OLB instances; three host reset controllers.
 *
 * Each reset controller has one or more domain. Domains are of a given type
 * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per
 * domain).
 *
 * Domain types define expected behavior: one-register-per-reset,
 * one-bit-per-reset, status detection method, busywait duration, etc.
 *
 * We use eqr_ as prefix, as-in "EyeQ Reset", but way shorter.
 *
 * Known resets in EyeQ5 domain 0 (type EQR_EYEQ5_SARCR):
 *  3. CAN0	 4. CAN1	 5. CAN2	 6. SPI0
 *  7. SPI1	 8. SPI2	 9. SPI3	10. UART0
 * 11. UART1	12. UART2	13. I2C0	14. I2C1
 * 15. I2C2	16. I2C3	17. I2C4	18. TIMER0
 * 19. TIMER1	20. TIMER2	21. TIMER3	22. TIMER4
 * 23. WD0	24. EXT0	25. EXT1	26. GPIO
 * 27. WD1
 *
 * Known resets in EyeQ5 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 EyeQ5 domain 2 (type EQR_EYEQ5_PCIE):
 *  0. PCIE0_CORE	 1. PCIE0_APB		 2. PCIE0_LINK_AXI	 3. PCIE0_LINK_MGMT
 *  4. PCIE0_LINK_HOT	 5. PCIE0_LINK_PIPE	 6. PCIE1_CORE		 7. PCIE1_APB
 *  8. PCIE1_LINK_AXI	 9. PCIE1_LINK_MGMT	10. PCIE1_LINK_HOT	11. PCIE1_LINK_PIPE
 * 12. MULTIPHY		13. MULTIPHY_APB	15. PCIE0_LINK_MGMT	16. PCIE1_LINK_MGMT
 * 17. PCIE0_LINK_PM	18. PCIE1_LINK_PM
 *
 * Known resets in EyeQ6L domain 0 (type EQR_EYEQ5_SARCR):
 *  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 EyeQ6L 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-
 *  8. TIMER0	 9. TIMER1	10. WD		11. EXT TIMER
 * 12. GPIO
 *
 * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP):
 *  1. XNN0	 2. XNN1	 3. XNN2	 4. XNN3
 *  5. VMP0	 6. VMP1	 7. VMP2	 8. VMP3
 *  9. PMA0	10. PMA1	11. MPC0	12. MPC1
 * 13. MPC2	14. MPC3	15. PERIPH
 *
 * Abbreviations:
 *  - PMA: Programmable Macro Array
 *  - MPC: Multi-threaded Processing Clusters
 *  - VMP: Vector Microcode Processors
 *
 * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
 */

#include <linux/array_size.h>
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/bug.h>
#include <linux/cleanup.h>
#include <linux/container_of.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/lockdep.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include <linux/types.h>

/*
 * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair.
 * Low byte is domain, rest is offset.
 */
#define ID_DOMAIN_MASK
#define ID_OFFSET_MASK

enum eqr_domain_type {};

/*
 * Domain type EQR_EYEQ5_SARCR register offsets.
 */
#define EQR_EYEQ5_SARCR_REQUEST
#define EQR_EYEQ5_SARCR_STATUS

/*
 * Domain type EQR_EYEQ5_ACRP register masks.
 * Registers are: base + 4 * offset.
 */
#define EQR_EYEQ5_ACRP_PD_REQ
#define EQR_EYEQ5_ACRP_ST_POWER_DOWN
#define EQR_EYEQ5_ACRP_ST_ACTIVE

/*
 * Domain type EQR_EYEQ6H_SARCR register offsets.
 */
#define EQR_EYEQ6H_SARCR_RST_REQUEST
#define EQR_EYEQ6H_SARCR_CLK_STATUS
#define EQR_EYEQ6H_SARCR_RST_STATUS
#define EQR_EYEQ6H_SARCR_CLK_REQUEST

struct eqr_busy_wait_timings {};

static const struct eqr_busy_wait_timings eqr_timings[] =;

#define EQR_MAX_DOMAIN_COUNT

struct eqr_domain_descriptor {};

struct eqr_match_data {};

struct eqr_private {};

static inline struct eqr_private *eqr_rcdev_to_priv(struct reset_controller_dev *x)
{}

static u32 eqr_double_readl(void __iomem *addr_a, void __iomem *addr_b,
			    u32 *dest_a, u32 *dest_b)
{}

static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev,
				u32 domain, u32 offset, bool assert)
{}

static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset)
{}

static int eqr_assert(struct reset_controller_dev *rcdev, unsigned long id)
{}

static void eqr_deassert_locked(struct eqr_private *priv, u32 domain,
				u32 offset)
{}

static int eqr_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{}

static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id)
{}

static const struct reset_control_ops eqr_ops =;

static int eqr_of_xlate_internal(struct reset_controller_dev *rcdev,
				 u32 domain, u32 offset)
{}

static int eqr_of_xlate_onecell(struct reset_controller_dev *rcdev,
				const struct of_phandle_args *reset_spec)
{}

static int eqr_of_xlate_twocells(struct reset_controller_dev *rcdev,
				 const struct of_phandle_args *reset_spec)
{}

static int eqr_probe(struct auxiliary_device *adev,
		     const struct auxiliary_device_id *id)
{}

static const struct eqr_domain_descriptor eqr_eyeq5_domains[] =;

static const struct eqr_match_data eqr_eyeq5_data =;

static const struct eqr_domain_descriptor eqr_eyeq6l_domains[] =;

static const struct eqr_match_data eqr_eyeq6l_data =;

/* West and east OLBs each have an instance. */
static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] =;

static const struct eqr_match_data eqr_eyeq6h_we_data =;

static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains[] =;

static const struct eqr_match_data eqr_eyeq6h_acc_data =;

/*
 * Table describes OLB system-controller compatibles.
 * It does not get used to match against devicetree node.
 */
static const struct of_device_id eqr_match_table[] =;
MODULE_DEVICE_TABLE(of, eqr_match_table);

static const struct auxiliary_device_id eqr_id_table[] =;
MODULE_DEVICE_TABLE(auxiliary, eqr_id_table);

static struct auxiliary_driver eqr_driver =;
module_auxiliary_driver();