162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __SOC_TEGRA_BPMP_H 762306a36Sopenharmony_ci#define __SOC_TEGRA_BPMP_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/iosys-map.h> 1062306a36Sopenharmony_ci#include <linux/mailbox_client.h> 1162306a36Sopenharmony_ci#include <linux/pm_domain.h> 1262306a36Sopenharmony_ci#include <linux/reset-controller.h> 1362306a36Sopenharmony_ci#include <linux/semaphore.h> 1462306a36Sopenharmony_ci#include <linux/types.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <soc/tegra/bpmp-abi.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct tegra_bpmp_clk; 1962306a36Sopenharmony_cistruct tegra_bpmp_ops; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistruct tegra_bpmp_soc { 2262306a36Sopenharmony_ci struct { 2362306a36Sopenharmony_ci struct { 2462306a36Sopenharmony_ci unsigned int offset; 2562306a36Sopenharmony_ci unsigned int count; 2662306a36Sopenharmony_ci unsigned int timeout; 2762306a36Sopenharmony_ci } cpu_tx, thread, cpu_rx; 2862306a36Sopenharmony_ci } channels; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci const struct tegra_bpmp_ops *ops; 3162306a36Sopenharmony_ci unsigned int num_resets; 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistruct tegra_bpmp_mb_data { 3562306a36Sopenharmony_ci u32 code; 3662306a36Sopenharmony_ci u32 flags; 3762306a36Sopenharmony_ci u8 data[MSG_DATA_MIN_SZ]; 3862306a36Sopenharmony_ci} __packed; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define tegra_bpmp_mb_read(dst, mb, size) \ 4162306a36Sopenharmony_ci iosys_map_memcpy_from(dst, mb, offsetof(struct tegra_bpmp_mb_data, data), size) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define tegra_bpmp_mb_write(mb, src, size) \ 4462306a36Sopenharmony_ci iosys_map_memcpy_to(mb, offsetof(struct tegra_bpmp_mb_data, data), src, size) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define tegra_bpmp_mb_read_field(mb, field) \ 4762306a36Sopenharmony_ci iosys_map_rd_field(mb, 0, struct tegra_bpmp_mb_data, field) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define tegra_bpmp_mb_write_field(mb, field, value) \ 5062306a36Sopenharmony_ci iosys_map_wr_field(mb, 0, struct tegra_bpmp_mb_data, field, value) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistruct tegra_bpmp_channel { 5362306a36Sopenharmony_ci struct tegra_bpmp *bpmp; 5462306a36Sopenharmony_ci struct iosys_map ib; 5562306a36Sopenharmony_ci struct iosys_map ob; 5662306a36Sopenharmony_ci struct completion completion; 5762306a36Sopenharmony_ci struct tegra_ivc *ivc; 5862306a36Sopenharmony_ci unsigned int index; 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_citypedef void (*tegra_bpmp_mrq_handler_t)(unsigned int mrq, 6262306a36Sopenharmony_ci struct tegra_bpmp_channel *channel, 6362306a36Sopenharmony_ci void *data); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistruct tegra_bpmp_mrq { 6662306a36Sopenharmony_ci struct list_head list; 6762306a36Sopenharmony_ci unsigned int mrq; 6862306a36Sopenharmony_ci tegra_bpmp_mrq_handler_t handler; 6962306a36Sopenharmony_ci void *data; 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct tegra_bpmp { 7362306a36Sopenharmony_ci const struct tegra_bpmp_soc *soc; 7462306a36Sopenharmony_ci struct device *dev; 7562306a36Sopenharmony_ci void *priv; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci struct { 7862306a36Sopenharmony_ci struct mbox_client client; 7962306a36Sopenharmony_ci struct mbox_chan *channel; 8062306a36Sopenharmony_ci } mbox; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci spinlock_t atomic_tx_lock; 8362306a36Sopenharmony_ci struct tegra_bpmp_channel *tx_channel, *rx_channel, *threaded_channels; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci struct { 8662306a36Sopenharmony_ci unsigned long *allocated; 8762306a36Sopenharmony_ci unsigned long *busy; 8862306a36Sopenharmony_ci unsigned int count; 8962306a36Sopenharmony_ci struct semaphore lock; 9062306a36Sopenharmony_ci } threaded; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci struct list_head mrqs; 9362306a36Sopenharmony_ci spinlock_t lock; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci struct tegra_bpmp_clk **clocks; 9662306a36Sopenharmony_ci unsigned int num_clocks; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci struct reset_controller_dev rstc; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci struct genpd_onecell_data genpd; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 10362306a36Sopenharmony_ci struct dentry *debugfs_mirror; 10462306a36Sopenharmony_ci#endif 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci bool suspended; 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define TEGRA_BPMP_MESSAGE_RESET BIT(0) 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistruct tegra_bpmp_message { 11262306a36Sopenharmony_ci unsigned int mrq; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci struct { 11562306a36Sopenharmony_ci const void *data; 11662306a36Sopenharmony_ci size_t size; 11762306a36Sopenharmony_ci } tx; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci struct { 12062306a36Sopenharmony_ci void *data; 12162306a36Sopenharmony_ci size_t size; 12262306a36Sopenharmony_ci int ret; 12362306a36Sopenharmony_ci } rx; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci unsigned long flags; 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_TEGRA_BPMP) 12962306a36Sopenharmony_cistruct tegra_bpmp *tegra_bpmp_get(struct device *dev); 13062306a36Sopenharmony_civoid tegra_bpmp_put(struct tegra_bpmp *bpmp); 13162306a36Sopenharmony_ciint tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, 13262306a36Sopenharmony_ci struct tegra_bpmp_message *msg); 13362306a36Sopenharmony_ciint tegra_bpmp_transfer(struct tegra_bpmp *bpmp, 13462306a36Sopenharmony_ci struct tegra_bpmp_message *msg); 13562306a36Sopenharmony_civoid tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, int code, 13662306a36Sopenharmony_ci const void *data, size_t size); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ciint tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, 13962306a36Sopenharmony_ci tegra_bpmp_mrq_handler_t handler, void *data); 14062306a36Sopenharmony_civoid tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, 14162306a36Sopenharmony_ci void *data); 14262306a36Sopenharmony_cibool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq); 14362306a36Sopenharmony_ci#else 14462306a36Sopenharmony_cistatic inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci return ERR_PTR(-ENOTSUPP); 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_cistatic inline void tegra_bpmp_put(struct tegra_bpmp *bpmp) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_cistatic inline int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, 15262306a36Sopenharmony_ci struct tegra_bpmp_message *msg) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci return -ENOTSUPP; 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_cistatic inline int tegra_bpmp_transfer(struct tegra_bpmp *bpmp, 15762306a36Sopenharmony_ci struct tegra_bpmp_message *msg) 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci return -ENOTSUPP; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_cistatic inline void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, 16262306a36Sopenharmony_ci int code, const void *data, 16362306a36Sopenharmony_ci size_t size) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic inline int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, 16862306a36Sopenharmony_ci unsigned int mrq, 16962306a36Sopenharmony_ci tegra_bpmp_mrq_handler_t handler, 17062306a36Sopenharmony_ci void *data) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci return -ENOTSUPP; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_cistatic inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, 17562306a36Sopenharmony_ci unsigned int mrq, void *data) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic inline bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, 18062306a36Sopenharmony_ci unsigned int mrq) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci return false; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci#endif 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_civoid tegra_bpmp_handle_rx(struct tegra_bpmp *bpmp); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP) 18962306a36Sopenharmony_ciint tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp); 19062306a36Sopenharmony_ci#else 19162306a36Sopenharmony_cistatic inline int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci return 0; 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci#endif 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_RESET_TEGRA_BPMP) 19862306a36Sopenharmony_ciint tegra_bpmp_init_resets(struct tegra_bpmp *bpmp); 19962306a36Sopenharmony_ci#else 20062306a36Sopenharmony_cistatic inline int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci#endif 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SOC_TEGRA_POWERGATE_BPMP) 20762306a36Sopenharmony_ciint tegra_bpmp_init_powergates(struct tegra_bpmp *bpmp); 20862306a36Sopenharmony_ci#else 20962306a36Sopenharmony_cistatic inline int tegra_bpmp_init_powergates(struct tegra_bpmp *bpmp) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci return 0; 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci#endif 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DEBUG_FS) 21662306a36Sopenharmony_ciint tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp); 21762306a36Sopenharmony_ci#else 21862306a36Sopenharmony_cistatic inline int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci return 0; 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci#endif 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci#endif /* __SOC_TEGRA_BPMP_H */ 226