1
0
Fork 0

Merge tag 'qcom-drivers-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers

Qualcomm driver updates for v5.11

This adds support for the core power domains on MSM8916, MSM8939, SDM660
and SDX55. It adds SM8150 support to the last-level cache controller
driver and it makes it possible to build the Command DB and RPMh drivers
as modules.

It also contains a slew of smaller cleanups, style and bug fixes
throughout the various drivers.

* tag 'qcom-drivers-for-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (39 commits)
  soc: qcom: rpmhpd: Add SDX55 power domains
  dt-bindings: power: Add rpm power domain bindings for sdx55
  soc: qcom: rpmh: Use __fill_rpmh_msg API during rpmh_write()
  samples: qmi: Constify static qmi ops
  soc: qcom: pdr: Constify static qmi structs
  soc: qcom: initialize local variable
  soc: qcom: socinfo: add soc ids for msm8953 variants
  soc: qcom: geni: Remove "iova" check
  soc: qcom: llcc: Add configuration data for SM8150
  dt-bindings: msm: Add LLCC for SM8150
  soc: qcom: rpmh: Fix possible doc-rot in rpmh_write()'s header
  soc: qcom: kryo-l2-accessors: Fix misnaming of 'val'
  soc: qcom: rpmhpd: Provide some missing struct member descriptions
  soc: qcom: llcc-qcom: Fix expected kernel-doc formatting
  soc: qcom: smp2p: Remove unused struct attribute provide another
  soc: qcom: wcnss_ctrl: Demote non-conformant struct header and fix function headers
  soc: qcom: smsm: Fix some kernel-doc formatting and naming problems
  soc: qcom: smem: Fix formatting and missing documentation issues
  soc: qcom: qcom-geni-se: Fix misnamed function parameter 'rx_rfr'
  soc: qcom: qcom_aoss: Add missing description for 'cooling_devs'
  ...

Link: https://lore.kernel.org/r/20201130190142.345246-1-bjorn.andersson@linaro.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
zero-sugar-mainline-defconfig
Arnd Bergmann 2020-12-09 00:17:54 +01:00
commit a97d8ffac8
23 changed files with 345 additions and 99 deletions

View File

@ -23,6 +23,7 @@ properties:
enum:
- qcom,sc7180-llcc
- qcom,sdm845-llcc
- qcom,sm8150-llcc
reg:
items:

View File

@ -16,12 +16,16 @@ description:
properties:
compatible:
enum:
- qcom,msm8916-rpmpd
- qcom,msm8939-rpmpd
- qcom,msm8976-rpmpd
- qcom,msm8996-rpmpd
- qcom,msm8998-rpmpd
- qcom,qcs404-rpmpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sm8150-rpmhpd
- qcom,sm8250-rpmhpd

View File

@ -366,6 +366,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
geni_se_select_mode(se, GENI_SE_FIFO);
writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
geni_se_setup_m_cmd(se, I2C_READ, m_param);
if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) {
geni_se_select_mode(se, GENI_SE_FIFO);
@ -373,8 +374,6 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
dma_buf = NULL;
}
geni_se_setup_m_cmd(se, I2C_READ, m_param);
time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
if (!time_left)
geni_i2c_abort_xfer(gi2c);
@ -408,6 +407,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
geni_se_select_mode(se, GENI_SE_FIFO);
writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) {
geni_se_select_mode(se, GENI_SE_FIFO);
@ -415,8 +415,6 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
dma_buf = NULL;
}
geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
if (!dma_buf) /* Get FIFO IRQ */
writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG);

View File

@ -17,7 +17,7 @@ config QCOM_AOSS_QMP
Subsystem (AOSS) using Qualcomm Messaging Protocol (QMP).
config QCOM_COMMAND_DB
bool "Qualcomm Command DB"
tristate "Qualcomm Command DB"
depends on ARCH_QCOM || COMPILE_TEST
depends on OF_RESERVED_MEM
help
@ -108,8 +108,9 @@ config QCOM_RMTFS_MEM
Say y here if you intend to boot the modem remoteproc.
config QCOM_RPMH
bool "Qualcomm RPM-Hardened (RPMH) Communication"
tristate "Qualcomm RPM-Hardened (RPMH) Communication"
depends on ARCH_QCOM || COMPILE_TEST
depends on (QCOM_COMMAND_DB || !QCOM_COMMAND_DB)
help
Support for communication with the hardened-RPM blocks in
Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an

View File

@ -1,8 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
@ -340,12 +341,14 @@ static const struct of_device_id cmd_db_match_table[] = {
{ .compatible = "qcom,cmd-db" },
{ }
};
MODULE_DEVICE_TABLE(of, cmd_db_match_table);
static struct platform_driver cmd_db_dev_driver = {
.probe = cmd_db_dev_probe,
.driver = {
.name = "cmd-db",
.of_match_table = cmd_db_match_table,
.suppress_bind_attrs = true,
},
};
@ -354,3 +357,6 @@ static int __init cmd_db_device_init(void)
return platform_driver_register(&cmd_db_dev_driver);
}
arch_initcall(cmd_db_device_init);
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Command DB Driver");
MODULE_LICENSE("GPL v2");

View File

@ -16,7 +16,7 @@ static DEFINE_RAW_SPINLOCK(l2_access_lock);
/**
* kryo_l2_set_indirect_reg() - write value to an L2 register
* @reg: Address of L2 register.
* @value: Value to be written to register.
* @val: Value to be written to register.
*
* Use architecturally required barriers for ordering between system register
* accesses, and system registers with respect to device memory

View File

@ -45,10 +45,13 @@
#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
#define LLCC_TRP_PCB_ACT 0x21f04
#define BANK_OFFSET_STRIDE 0x80000
/**
* llcc_slice_config - Data associated with the llcc slice
* struct llcc_slice_config - Data associated with the llcc slice
* @usecase_id: Unique id for the client's use case
* @slice_id: llcc slice id for each client
* @max_cap: The maximum capacity of the cache slice provided in KB
@ -89,6 +92,7 @@ struct llcc_slice_config {
struct qcom_llcc_config {
const struct llcc_slice_config *sct_data;
int size;
bool need_llcc_cfg;
};
static const struct llcc_slice_config sc7180_data[] = {
@ -119,14 +123,45 @@ static const struct llcc_slice_config sdm845_data[] = {
{ LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 },
};
static const struct llcc_slice_config sm8150_data[] = {
{ LLCC_CPUSS, 1, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 1 },
{ LLCC_VIDSC0, 2, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_VIDSC1, 3, 512, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_AUDIO, 6, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMHPGRW, 7, 3072, 1, 0, 0xFF, 0xF00, 0, 0, 0, 1, 0 },
{ LLCC_MDM, 8, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MODHW, 9, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_CMPT, 10, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_GPUHTW , 11, 512, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_GPU, 12, 2560, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MMUHWT, 13, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 1 },
{ LLCC_CMPTDMA, 15, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_DISP, 16, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMHPFX, 20, 1024, 2, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMHPFX, 21, 1024, 0, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_AUDHW, 22, 1024, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_NPU, 23, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_WLHW, 24, 3072, 1, 1, 0xFFF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MODPE, 29, 256, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_APTCM, 30, 256, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 },
{ LLCC_WRCACHE, 31, 128, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0 },
};
static const struct qcom_llcc_config sc7180_cfg = {
.sct_data = sc7180_data,
.size = ARRAY_SIZE(sc7180_data),
.need_llcc_cfg = true,
};
static const struct qcom_llcc_config sdm845_cfg = {
.sct_data = sdm845_data,
.size = ARRAY_SIZE(sdm845_data),
.need_llcc_cfg = false,
};
static const struct qcom_llcc_config sm8150_cfg = {
.sct_data = sm8150_data,
.size = ARRAY_SIZE(sm8150_data),
};
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
@ -318,62 +353,91 @@ size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
}
EXPORT_SYMBOL_GPL(llcc_get_slice_size);
static int qcom_llcc_cfg_program(struct platform_device *pdev)
static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
const struct qcom_llcc_config *cfg)
{
int i;
int ret;
u32 attr1_cfg;
u32 attr0_cfg;
u32 attr1_val;
u32 attr0_val;
u32 max_cap_cacheline;
struct llcc_slice_desc desc;
attr1_val = config->cache_mode;
attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT;
attr1_val |= config->fixed_size << ATTR1_FIXED_SIZE_SHIFT;
attr1_val |= config->priority << ATTR1_PRIORITY_SHIFT;
max_cap_cacheline = MAX_CAP_TO_BYTES(config->max_cap);
/*
* LLCC instances can vary for each target.
* The SW writes to broadcast register which gets propagated
* to each llcc instance (llcc0,.. llccN).
* Since the size of the memory is divided equally amongst the
* llcc instances, we need to configure the max cap accordingly.
*/
max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
attr1_cfg = LLCC_TRP_ATTR1_CFGn(config->slice_id);
ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, attr1_val);
if (ret)
return ret;
attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;
attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id);
ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, attr0_val);
if (ret)
return ret;
if (cfg->need_llcc_cfg) {
u32 disable_cap_alloc, retain_pc;
disable_cap_alloc = config->dis_cap_alloc << config->slice_id;
ret = regmap_write(drv_data->bcast_regmap,
LLCC_TRP_SCID_DIS_CAP_ALLOC, disable_cap_alloc);
if (ret)
return ret;
retain_pc = config->retain_on_pc << config->slice_id;
ret = regmap_write(drv_data->bcast_regmap,
LLCC_TRP_PCB_ACT, retain_pc);
if (ret)
return ret;
}
if (config->activate_on_init) {
desc.slice_id = config->slice_id;
ret = llcc_slice_activate(&desc);
}
return ret;
}
static int qcom_llcc_cfg_program(struct platform_device *pdev,
const struct qcom_llcc_config *cfg)
{
int i;
u32 sz;
int ret = 0;
const struct llcc_slice_config *llcc_table;
struct llcc_slice_desc desc;
sz = drv_data->cfg_size;
llcc_table = drv_data->cfg;
for (i = 0; i < sz; i++) {
attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
attr1_val = llcc_table[i].cache_mode;
attr1_val |= llcc_table[i].probe_target_ways <<
ATTR1_PROBE_TARGET_WAYS_SHIFT;
attr1_val |= llcc_table[i].fixed_size <<
ATTR1_FIXED_SIZE_SHIFT;
attr1_val |= llcc_table[i].priority <<
ATTR1_PRIORITY_SHIFT;
max_cap_cacheline = MAX_CAP_TO_BYTES(llcc_table[i].max_cap);
/* LLCC instances can vary for each target.
* The SW writes to broadcast register which gets propagated
* to each llcc instace (llcc0,.. llccN).
* Since the size of the memory is divided equally amongst the
* llcc instances, we need to configure the max cap accordingly.
*/
max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
attr1_val);
ret = _qcom_llcc_cfg_program(&llcc_table[i], cfg);
if (ret)
return ret;
ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
attr0_val);
if (ret)
return ret;
if (llcc_table[i].activate_on_init) {
desc.slice_id = llcc_table[i].slice_id;
ret = llcc_slice_activate(&desc);
}
}
return ret;
}
@ -472,7 +536,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
mutex_init(&drv_data->lock);
platform_set_drvdata(pdev, drv_data);
ret = qcom_llcc_cfg_program(pdev);
ret = qcom_llcc_cfg_program(pdev, cfg);
if (ret)
goto err;
@ -494,6 +558,7 @@ err:
static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg },
{ .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
{ .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
{ }
};

View File

@ -110,7 +110,7 @@ static void pdr_locator_del_server(struct qmi_handle *qmi,
pdr->locator_addr.sq_port = 0;
}
static struct qmi_ops pdr_locator_ops = {
static const struct qmi_ops pdr_locator_ops = {
.new_server = pdr_locator_new_server,
.del_server = pdr_locator_del_server,
};
@ -238,7 +238,7 @@ static void pdr_notifier_del_server(struct qmi_handle *qmi,
mutex_unlock(&pdr->list_lock);
}
static struct qmi_ops pdr_notifier_ops = {
static const struct qmi_ops pdr_notifier_ops = {
.new_server = pdr_notifier_new_server,
.del_server = pdr_notifier_del_server,
};
@ -343,7 +343,7 @@ static void pdr_indication_cb(struct qmi_handle *qmi,
queue_work(pdr->indack_wq, &pdr->indack_work);
}
static struct qmi_msg_handler qmi_indication_handler[] = {
static const struct qmi_msg_handler qmi_indication_handler[] = {
{
.type = QMI_INDICATION,
.msg_id = SERVREG_STATE_UPDATED_IND_ID,
@ -569,7 +569,7 @@ EXPORT_SYMBOL(pdr_add_lookup);
int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
{
struct servreg_restart_pd_resp resp;
struct servreg_restart_pd_req req;
struct servreg_restart_pd_req req = { 0 };
struct sockaddr_qrtr addr;
struct pdr_service *tmp;
struct qmi_txn txn;

View File

@ -82,10 +82,11 @@
#define NUM_AHB_CLKS 2
/**
* @struct geni_wrapper - Data structure to represent the QUP Wrapper Core
* struct geni_wrapper - Data structure to represent the QUP Wrapper Core
* @dev: Device pointer of the QUP wrapper core
* @base: Base address of this instance of QUP wrapper core
* @ahb_clks: Handle to the primary & secondary AHB clocks
* @to_core: Core ICC path
*/
struct geni_wrapper {
struct device *dev;
@ -237,7 +238,7 @@ static void geni_se_irq_clear(struct geni_se *se)
* geni_se_init() - Initialize the GENI serial engine
* @se: Pointer to the concerned serial engine.
* @rx_wm: Receive watermark, in units of FIFO words.
* @rx_rfr_wm: Ready-for-receive watermark, in units of FIFO words.
* @rx_rfr: Ready-for-receive watermark, in units of FIFO words.
*
* This function is used to initialize the GENI serial engine, configure
* receive watermark and ready-for-receive watermarks.
@ -266,36 +267,63 @@ EXPORT_SYMBOL(geni_se_init);
static void geni_se_select_fifo_mode(struct geni_se *se)
{
u32 proto = geni_se_read_proto(se);
u32 val;
u32 val, val_old;
geni_se_irq_clear(se);
val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
/*
* The RX path for the UART is asynchronous and so needs more
* complex logic for enabling / disabling its interrupts.
*
* Specific notes:
* - The done and TX-related interrupts are managed manually.
* - We don't RX from the main sequencer (we use the secondary) so
* we don't need the RX-related interrupts enabled in the main
* sequencer for UART.
*/
if (proto != GENI_SE_UART) {
val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
}
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
if (proto != GENI_SE_UART)
val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
val |= S_CMD_DONE_EN;
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
}
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
val &= ~GENI_DMA_MODE_EN;
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
}
static void geni_se_select_dma_mode(struct geni_se *se)
{
u32 val;
u32 proto = geni_se_read_proto(se);
u32 val, val_old;
geni_se_irq_clear(se);
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
if (proto != GENI_SE_UART) {
val_old = val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN);
val_old = val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN);
val &= ~S_CMD_DONE_EN;
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN);
}
val_old = val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
val |= GENI_DMA_MODE_EN;
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
if (val != val_old)
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
}
/**
@ -651,7 +679,7 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
writel_relaxed(len, se->base + SE_DMA_TX_LEN);
writel(len, se->base + SE_DMA_TX_LEN);
return 0;
}
EXPORT_SYMBOL(geni_se_tx_dma_prep);
@ -688,7 +716,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
/* RX does not have EOT buffer type bit. So just reset RX_ATTR */
writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
writel_relaxed(len, se->base + SE_DMA_RX_LEN);
writel(len, se->base + SE_DMA_RX_LEN);
return 0;
}
EXPORT_SYMBOL(geni_se_rx_dma_prep);
@ -705,7 +733,7 @@ void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
{
struct geni_wrapper *wrapper = se->wrapper;
if (iova && !dma_mapping_error(wrapper->dev, iova))
if (!dma_mapping_error(wrapper->dev, iova))
dma_unmap_single(wrapper->dev, iova, len, DMA_TO_DEVICE);
}
EXPORT_SYMBOL(geni_se_tx_dma_unprep);
@ -722,7 +750,7 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
{
struct geni_wrapper *wrapper = se->wrapper;
if (iova && !dma_mapping_error(wrapper->dev, iova))
if (!dma_mapping_error(wrapper->dev, iova))
dma_unmap_single(wrapper->dev, iova, len, DMA_FROM_DEVICE);
}
EXPORT_SYMBOL(geni_se_rx_dma_unprep);

View File

@ -65,6 +65,7 @@ struct qmp_cooling_device {
* @tx_lock: provides synchronization between multiple callers of qmp_send()
* @qdss_clk: QDSS clock hw struct
* @pd_data: genpd data
* @cooling_devs: thermal cooling devices
*/
struct qmp {
void __iomem *msgram;
@ -225,7 +226,6 @@ static bool qmp_message_empty(struct qmp *qmp)
static int qmp_send(struct qmp *qmp, const void *data, size_t len)
{
long time_left;
size_t tlen;
int ret;
if (WARN_ON(len + sizeof(u32) > qmp->size))
@ -242,7 +242,7 @@ static int qmp_send(struct qmp *qmp, const void *data, size_t len)
writel(len, qmp->msgram + qmp->offset);
/* Read back len to confirm data written in message RAM */
tlen = readl(qmp->msgram + qmp->offset);
readl(qmp->msgram + qmp->offset);
qmp_kick(qmp);
time_left = wait_event_interruptible_timeout(qmp->event,

View File

@ -13,6 +13,7 @@
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
@ -497,7 +498,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
write_tcs_cmd(drv, RSC_DRV_CMD_MSGID, tcs_id, j, msgid);
write_tcs_cmd(drv, RSC_DRV_CMD_ADDR, tcs_id, j, cmd->addr);
write_tcs_cmd(drv, RSC_DRV_CMD_DATA, tcs_id, j, cmd->data);
trace_rpmh_send_msg_rcuidle(drv, tcs_id, j, msgid, cmd);
trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
}
write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete);
@ -1018,6 +1019,7 @@ static const struct of_device_id rpmh_drv_match[] = {
{ .compatible = "qcom,rpmh-rsc", },
{ }
};
MODULE_DEVICE_TABLE(of, rpmh_drv_match);
static struct platform_driver rpmh_driver = {
.probe = rpmh_rsc_probe,
@ -1033,3 +1035,6 @@ static int __init rpmh_driver_init(void)
return platform_driver_register(&rpmh_driver);
}
arch_initcall(rpmh_driver_init);
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver");
MODULE_LICENSE("GPL v2");

View File

@ -181,8 +181,6 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
struct cache_req *req;
int i;
rpm_msg->msg.state = state;
/* Cache the request in our store and link the payload */
for (i = 0; i < rpm_msg->msg.num_cmds; i++) {
req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]);
@ -190,8 +188,6 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
return PTR_ERR(req);
}
rpm_msg->msg.state = state;
if (state == RPMH_ACTIVE_ONLY_STATE) {
WARN_ON(irqs_disabled());
ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg);
@ -254,7 +250,7 @@ EXPORT_SYMBOL(rpmh_write_async);
/**
* rpmh_write: Write a set of RPMH commands and block until response
*
* @rc: The RPMH handle got from rpmh_get_client
* @dev: The device making the request
* @state: Active/sleep set
* @cmd: The payload data
* @n: The number of elements in @cmd
@ -268,11 +264,9 @@ int rpmh_write(const struct device *dev, enum rpmh_state state,
DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg);
int ret;
if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
return -EINVAL;
memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd));
rpm_msg.msg.num_cmds = n;
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
if (ret)
return ret;
ret = __rpmh_write(dev, state, &rpm_msg);
if (ret)

View File

@ -24,9 +24,12 @@
* struct rpmhpd - top level RPMh power domain resource data structure
* @dev: rpmh power domain controller device
* @pd: generic_pm_domain corrresponding to the power domain
* @parent: generic_pm_domain corrresponding to the parent's power domain
* @peer: A peer power domain in case Active only Voting is
* supported
* @active_only: True if it represents an Active only peer
* @corner: current corner
* @active_corner: current active corner
* @level: An array of level (vlvl) to corner (hlvl) mappings
* derived from cmd-db
* @level_count: Number of levels supported by the power domain. max
@ -132,6 +135,18 @@ static const struct rpmhpd_desc sdm845_desc = {
.num_pds = ARRAY_SIZE(sdm845_rpmhpds),
};
/* SDX55 RPMH powerdomains */
static struct rpmhpd *sdx55_rpmhpds[] = {
[SDX55_MSS] = &sdm845_mss,
[SDX55_MX] = &sdm845_mx,
[SDX55_CX] = &sdm845_cx,
};
static const struct rpmhpd_desc sdx55_desc = {
.rpmhpds = sdx55_rpmhpds,
.num_pds = ARRAY_SIZE(sdx55_rpmhpds),
};
/* SM8150 RPMH powerdomains */
static struct rpmhpd sm8150_mmcx_ao;
@ -205,6 +220,7 @@ static const struct rpmhpd_desc sc7180_desc = {
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
{ }

View File

@ -35,7 +35,7 @@
#define KEY_FLOOR_LEVEL 0x6c6676 /* vfl */
#define KEY_LEVEL 0x6c766c76 /* vlvl */
#define MAX_8996_RPMPD_STATE 6
#define MAX_CORNER_RPMPD_STATE 6
#define DEFINE_RPMPD_PAIR(_platform, _name, _active, r_type, r_key, \
r_id) \
@ -116,6 +116,52 @@ struct rpmpd_desc {
static DEFINE_MUTEX(rpmpd_lock);
/* msm8939 RPM Power Domains */
DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1);
DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1);
DEFINE_RPMPD_PAIR(msm8939, vddcx, vddcx_ao, SMPA, CORNER, 2);
DEFINE_RPMPD_VFC(msm8939, vddcx_vfc, SMPA, 2);
DEFINE_RPMPD_PAIR(msm8939, vddmx, vddmx_ao, LDOA, CORNER, 3);
static struct rpmpd *msm8939_rpmpds[] = {
[MSM8939_VDDMDCX] = &msm8939_vddmd,
[MSM8939_VDDMDCX_AO] = &msm8939_vddmd_ao,
[MSM8939_VDDMDCX_VFC] = &msm8939_vddmd_vfc,
[MSM8939_VDDCX] = &msm8939_vddcx,
[MSM8939_VDDCX_AO] = &msm8939_vddcx_ao,
[MSM8939_VDDCX_VFC] = &msm8939_vddcx_vfc,
[MSM8939_VDDMX] = &msm8939_vddmx,
[MSM8939_VDDMX_AO] = &msm8939_vddmx_ao,
};
static const struct rpmpd_desc msm8939_desc = {
.rpmpds = msm8939_rpmpds,
.num_pds = ARRAY_SIZE(msm8939_rpmpds),
.max_state = MAX_CORNER_RPMPD_STATE,
};
/* msm8916 RPM Power Domains */
DEFINE_RPMPD_PAIR(msm8916, vddcx, vddcx_ao, SMPA, CORNER, 1);
DEFINE_RPMPD_PAIR(msm8916, vddmx, vddmx_ao, LDOA, CORNER, 3);
DEFINE_RPMPD_VFC(msm8916, vddcx_vfc, SMPA, 1);
static struct rpmpd *msm8916_rpmpds[] = {
[MSM8916_VDDCX] = &msm8916_vddcx,
[MSM8916_VDDCX_AO] = &msm8916_vddcx_ao,
[MSM8916_VDDCX_VFC] = &msm8916_vddcx_vfc,
[MSM8916_VDDMX] = &msm8916_vddmx,
[MSM8916_VDDMX_AO] = &msm8916_vddmx_ao,
};
static const struct rpmpd_desc msm8916_desc = {
.rpmpds = msm8916_rpmpds,
.num_pds = ARRAY_SIZE(msm8916_rpmpds),
.max_state = MAX_CORNER_RPMPD_STATE,
};
/* msm8976 RPM Power Domains */
DEFINE_RPMPD_PAIR(msm8976, vddcx, vddcx_ao, SMPA, LEVEL, 2);
DEFINE_RPMPD_PAIR(msm8976, vddmx, vddmx_ao, SMPA, LEVEL, 6);
@ -159,7 +205,7 @@ static struct rpmpd *msm8996_rpmpds[] = {
static const struct rpmpd_desc msm8996_desc = {
.rpmpds = msm8996_rpmpds,
.num_pds = ARRAY_SIZE(msm8996_rpmpds),
.max_state = MAX_8996_RPMPD_STATE,
.max_state = MAX_CORNER_RPMPD_STATE,
};
/* msm8998 RPM Power domains */
@ -220,11 +266,46 @@ static const struct rpmpd_desc qcs404_desc = {
.max_state = RPM_SMD_LEVEL_BINNING,
};
/* sdm660 RPM Power domains */
DEFINE_RPMPD_PAIR(sdm660, vddcx, vddcx_ao, RWCX, LEVEL, 0);
DEFINE_RPMPD_VFL(sdm660, vddcx_vfl, RWCX, 0);
DEFINE_RPMPD_PAIR(sdm660, vddmx, vddmx_ao, RWMX, LEVEL, 0);
DEFINE_RPMPD_VFL(sdm660, vddmx_vfl, RWMX, 0);
DEFINE_RPMPD_LEVEL(sdm660, vdd_ssccx, RWLC, 0);
DEFINE_RPMPD_VFL(sdm660, vdd_ssccx_vfl, RWLC, 0);
DEFINE_RPMPD_LEVEL(sdm660, vdd_sscmx, RWLM, 0);
DEFINE_RPMPD_VFL(sdm660, vdd_sscmx_vfl, RWLM, 0);
static struct rpmpd *sdm660_rpmpds[] = {
[SDM660_VDDCX] = &sdm660_vddcx,
[SDM660_VDDCX_AO] = &sdm660_vddcx_ao,
[SDM660_VDDCX_VFL] = &sdm660_vddcx_vfl,
[SDM660_VDDMX] = &sdm660_vddmx,
[SDM660_VDDMX_AO] = &sdm660_vddmx_ao,
[SDM660_VDDMX_VFL] = &sdm660_vddmx_vfl,
[SDM660_SSCCX] = &sdm660_vdd_ssccx,
[SDM660_SSCCX_VFL] = &sdm660_vdd_ssccx_vfl,
[SDM660_SSCMX] = &sdm660_vdd_sscmx,
[SDM660_SSCMX_VFL] = &sdm660_vdd_sscmx_vfl,
};
static const struct rpmpd_desc sdm660_desc = {
.rpmpds = sdm660_rpmpds,
.num_pds = ARRAY_SIZE(sdm660_rpmpds),
.max_state = RPM_SMD_LEVEL_TURBO,
};
static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
{ .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },
{ .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc },
{ .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc },
{ .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc },
{ .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
{ }
};
MODULE_DEVICE_TABLE(of, rpmpd_match_table);

View File

@ -122,7 +122,7 @@ struct smem_global_entry {
* @free_offset: index of the first unallocated byte in smem
* @available: number of bytes available for allocation
* @reserved: reserved field, must be 0
* toc: array of references to items
* @toc: array of references to items
*/
struct smem_header {
struct smem_proc_comm proc_comm[4];
@ -255,6 +255,7 @@ struct smem_region {
* processor/host
* @cacheline: list of cacheline sizes for each host
* @item_count: max accepted item number
* @socinfo: platform device pointer
* @num_regions: number of @regions
* @regions: list of the memory regions defining the shared memory
*/

View File

@ -112,6 +112,7 @@ struct smp2p_entry {
* struct qcom_smp2p - device driver context
* @dev: device driver handle
* @in: pointer to the inbound smem item
* @out: pointer to the outbound smem item
* @smem_items: ids of the two smem items
* @valid_entries: already scanned inbound entries
* @local_pid: processor id of the inbound edge
@ -318,15 +319,16 @@ static int qcom_smp2p_inbound_entry(struct qcom_smp2p *smp2p,
static int smp2p_update_bits(void *data, u32 mask, u32 value)
{
struct smp2p_entry *entry = data;
unsigned long flags;
u32 orig;
u32 val;
spin_lock(&entry->lock);
spin_lock_irqsave(&entry->lock, flags);
val = orig = readl(entry->value);
val &= ~mask;
val |= value;
writel(val, entry->value);
spin_unlock(&entry->lock);
spin_unlock_irqrestore(&entry->lock, flags);
if (val != orig)
qcom_smp2p_kick(entry->smp2p);

View File

@ -130,7 +130,7 @@ struct smsm_host {
/**
* smsm_update_bits() - change bit in outgoing entry and inform subscribers
* @data: smsm context pointer
* @offset: bit in the entry
* @mask: value mask
* @value: new value
*
* Used to set and clear the bits in the outgoing/local entry and inform
@ -254,10 +254,8 @@ static void smsm_mask_irq(struct irq_data *irqd)
* smsm_unmask_irq() - subscribe to cascades of IRQs of a certain status bit
* @irqd: IRQ handle to be unmasked
*
* This subscribes the local CPU to interrupts upon changes to the defined
* status bit. The bit is also marked for cascading.
*/
static void smsm_unmask_irq(struct irq_data *irqd)
{

View File

@ -218,13 +218,19 @@ static const struct soc_id soc_id[] = {
{ 251, "MSM8992" },
{ 253, "APQ8094" },
{ 291, "APQ8096" },
{ 293, "MSM8953" },
{ 304, "APQ8053" },
{ 305, "MSM8996SG" },
{ 310, "MSM8996AU" },
{ 311, "APQ8096AU" },
{ 312, "APQ8096SG" },
{ 318, "SDM630" },
{ 321, "SDM845" },
{ 338, "SDM450" },
{ 341, "SDA845" },
{ 349, "SDM632" },
{ 350, "SDA632" },
{ 351, "SDA450" },
{ 356, "SM8250" },
{ 402, "IPQ6018" },
{ 425, "SC7180" },

View File

@ -68,9 +68,8 @@ struct wcnss_msg_hdr {
u32 len;
} __packed;
/**
/*
* struct wcnss_version_resp - version request response
* @hdr: common packet wcnss_msg_hdr header
*/
struct wcnss_version_resp {
struct wcnss_msg_hdr hdr;
@ -108,9 +107,11 @@ struct wcnss_download_nv_resp {
/**
* wcnss_ctrl_smd_callback() - handler from SMD responses
* @channel: smd channel handle
* @rpdev: remote processor message device pointer
* @data: pointer to the incoming data packet
* @count: size of the incoming data packet
* @priv: unused
* @addr: unused
*
* Handles any incoming packets from the remote WCNSS_CTRL service.
*/
@ -267,6 +268,7 @@ free_req:
* @wcnss: wcnss handle, retrieved from drvdata
* @name: SMD channel name
* @cb: callback to handle incoming data on the channel
* @priv: private data for use in the call-back
*/
struct rpmsg_endpoint *qcom_wcnss_open_channel(void *wcnss, const char *name, rpmsg_rx_cb_t cb, void *priv)
{

View File

@ -15,6 +15,11 @@
#define SDM845_GFX 7
#define SDM845_MSS 8
/* SDX55 Power Domain Indexes */
#define SDX55_MSS 0
#define SDX55_MX 1
#define SDX55_CX 2
/* SM8150 Power Domain Indexes */
#define SM8150_MSS 0
#define SM8150_EBI 1
@ -64,6 +69,23 @@
#define RPMH_REGULATOR_LEVEL_TURBO 384
#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
/* MSM8939 Power Domains */
#define MSM8939_VDDMDCX 0
#define MSM8939_VDDMDCX_AO 1
#define MSM8939_VDDMDCX_VFC 2
#define MSM8939_VDDCX 3
#define MSM8939_VDDCX_AO 4
#define MSM8939_VDDCX_VFC 5
#define MSM8939_VDDMX 6
#define MSM8939_VDDMX_AO 7
/* MSM8916 Power Domain Indexes */
#define MSM8916_VDDCX 0
#define MSM8916_VDDCX_AO 1
#define MSM8916_VDDCX_VFC 2
#define MSM8916_VDDMX 3
#define MSM8916_VDDMX_AO 4
/* MSM8976 Power Domain Indexes */
#define MSM8976_VDDCX 0
#define MSM8976_VDDCX_AO 1
@ -102,6 +124,18 @@
#define QCS404_LPIMX 5
#define QCS404_LPIMX_VFL 6
/* SDM660 Power Domains */
#define SDM660_VDDCX 0
#define SDM660_VDDCX_AO 1
#define SDM660_VDDCX_VFL 2
#define SDM660_VDDMX 3
#define SDM660_VDDMX_AO 4
#define SDM660_VDDMX_VFL 5
#define SDM660_SSCCX 6
#define SDM660_SSCCX_VFL 7
#define SDM660_SSCMX 8
#define SDM660_SSCMX_VFL 9
/* RPM SMD Power Domain performance levels */
#define RPM_SMD_LEVEL_RETENTION 16
#define RPM_SMD_LEVEL_RETENTION_PLUS 32

View File

@ -48,7 +48,6 @@ struct geni_icc_path {
* @clk_perf_tbl: Table of clock frequency input to serial engine clock
* @icc_paths: Array of ICC paths for SE
* @opp_table: Pointer to the OPP table
* @has_opp_table: Specifies if the SE has an OPP table
*/
struct geni_se {
void __iomem *base;
@ -59,7 +58,6 @@ struct geni_se {
unsigned long *clk_perf_tbl;
struct geni_icc_path icc_paths[3];
struct opp_table *opp_table;
bool has_opp_table;
};
/* Common SE registers */

View File

@ -16,6 +16,7 @@
#define LLCC_AUDIO 6
#define LLCC_MDMHPGRW 7
#define LLCC_MDM 8
#define LLCC_MODHW 9
#define LLCC_CMPT 10
#define LLCC_GPUHTW 11
#define LLCC_GPU 12
@ -26,6 +27,11 @@
#define LLCC_MDMHPFX 20
#define LLCC_MDMPNG 21
#define LLCC_AUDHW 22
#define LLCC_NPU 23
#define LLCC_WLHW 24
#define LLCC_MODPE 29
#define LLCC_APTCM 30
#define LLCC_WRCACHE 31
/**
* llcc_slice_desc - Cache slice descriptor

View File

@ -429,7 +429,7 @@ static const struct file_operations data_fops = {
.write = data_write,
};
static struct qmi_msg_handler qmi_sample_handlers[] = {
static const struct qmi_msg_handler qmi_sample_handlers[] = {
{
.type = QMI_RESPONSE,
.msg_id = TEST_PING_REQ_MSG_ID_V01,
@ -571,7 +571,7 @@ static void qmi_sample_del_server(struct qmi_handle *qmi,
static struct qmi_handle lookup_client;
static struct qmi_ops lookup_ops = {
static const struct qmi_ops lookup_ops = {
.new_server = qmi_sample_new_server,
.del_server = qmi_sample_del_server,
};