Skip to content

Commit

Permalink
Merge tag 'qcom-drivers-for-4.19' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/agross/linux into regulator-4.19 for RPMH

Qualcomm ARM Based Driver Updates for v4.19

* Add Qualcomm LLCC driver
* Add Qualcomm RPMH controller
* Fix memleak in Qualcomm RMTFS
* Add dummy qcom_scm_assign_mem()
* Fix check for global partition in SMEM
  • Loading branch information
broonie committed Aug 10, 2018
2 parents 4f3fb28 + 78ee559 commit 2de4471
Show file tree
Hide file tree
Showing 17 changed files with 2,341 additions and 7 deletions.
26 changes: 26 additions & 0 deletions Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
== Introduction==

LLCC (Last Level Cache Controller) provides last level of cache memory in SOC,
that can be shared by multiple clients. Clients here are different cores in the
SOC, the idea is to minimize the local caches at the clients and migrate to
common pool of memory. Cache memory is divided into partitions called slices
which are assigned to clients. Clients can query the slice details, activate
and deactivate them.

Properties:
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,sdm845-llcc"

- reg:
Usage: required
Value Type: <prop-encoded-array>
Definition: Start address and the the size of the register region.

Example:

cache-controller@1100000 {
compatible = "qcom,sdm845-llcc";
reg = <0x1100000 0x250000>;
};
137 changes: 137 additions & 0 deletions Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
RPMH RSC:
------------

Resource Power Manager Hardened (RPMH) is the mechanism for communicating with
the hardened resource accelerators on Qualcomm SoCs. Requests to the resources
can be written to the Trigger Command Set (TCS) registers and using a (addr,
val) pair and triggered. Messages in the TCS are then sent in sequence over an
internal bus.

The hardware block (Direct Resource Voter or DRV) is a part of the h/w entity
(Resource State Coordinator a.k.a RSC) that can handle multiple sleep and
active/wake resource requests. Multiple such DRVs can exist in a SoC and can
be written to from Linux. The structure of each DRV follows the same template
with a few variations that are captured by the properties here.

A TCS may be triggered from Linux or triggered by the F/W after all the CPUs
have powered off to facilitate idle power saving. TCS could be classified as -

ACTIVE /* Triggered by Linux */
SLEEP /* Triggered by F/W */
WAKE /* Triggered by F/W */
CONTROL /* Triggered by F/W */

The order in which they are described in the DT, should match the hardware
configuration.

Requests can be made for the state of a resource, when the subsystem is active
or idle. When all subsystems like Modem, GPU, CPU are idle, the resource state
will be an aggregate of the sleep votes from each of those subsystems. Clients
may request a sleep value for their shared resources in addition to the active
mode requests.

Properties:

- compatible:
Usage: required
Value type: <string>
Definition: Should be "qcom,rpmh-rsc".

- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: The first register specifies the base address of the
DRV(s). The number of DRVs in the dependent on the RSC.
The tcs-offset specifies the start address of the
TCS in the DRVs.

- reg-names:
Usage: required
Value type: <string>
Definition: Maps the register specified in the reg property. Must be
"drv-0", "drv-1", "drv-2" etc and "tcs-offset". The

- interrupts:
Usage: required
Value type: <prop-encoded-interrupt>
Definition: The interrupt that trips when a message complete/response
is received for this DRV from the accelerators.

- qcom,drv-id:
Usage: required
Value type: <u32>
Definition: The id of the DRV in the RSC block that will be used by
this controller.

- qcom,tcs-config:
Usage: required
Value type: <prop-encoded-array>
Definition: The tuple defining the configuration of TCS.
Must have 2 cells which describe each TCS type.
<type number_of_tcs>.
The order of the TCS must match the hardware
configuration.
- Cell #1 (TCS Type): TCS types to be specified -
ACTIVE_TCS
SLEEP_TCS
WAKE_TCS
CONTROL_TCS
- Cell #2 (Number of TCS): <u32>

- label:
Usage: optional
Value type: <string>
Definition: Name for the RSC. The name would be used in trace logs.

Drivers that want to use the RSC to communicate with RPMH must specify their
bindings as child nodes of the RSC controllers they wish to communicate with.

Example 1:

For a TCS whose RSC base address is is 0x179C0000 and is at a DRV id of 2, the
register offsets for DRV2 start at 0D00, the register calculations are like
this -
DRV0: 0x179C0000
DRV2: 0x179C0000 + 0x10000 = 0x179D0000
DRV2: 0x179C0000 + 0x10000 * 2 = 0x179E0000
TCS-OFFSET: 0xD00

apps_rsc: rsc@179c0000 {
label = "apps_rsc";
compatible = "qcom,rpmh-rsc";
reg = <0x179c0000 0x10000>,
<0x179d0000 0x10000>,
<0x179e0000 0x10000>;
reg-names = "drv-0", "drv-1", "drv-2";
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>,
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 1>;
};

Example 2:

For a TCS whose RSC base address is 0xAF20000 and is at DRV id of 0, the
register offsets for DRV0 start at 01C00, the register calculations are like
this -
DRV0: 0xAF20000
TCS-OFFSET: 0x1C00

disp_rsc: rsc@af20000 {
label = "disp_rsc";
compatible = "qcom,rpmh-rsc";
reg = <0xaf20000 0x10000>;
reg-names = "drv-0";
interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
qcom,tcs-offset = <0x1c00>;
qcom,drv-id = <0>;
qcom,tcs-config = <ACTIVE_TCS 0>,
<SLEEP_TCS 1>,
<WAKE_TCS 1>,
<CONTROL_TCS 0>;
};
27 changes: 27 additions & 0 deletions drivers/soc/qcom/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ config QCOM_GSBI
functions for connecting the underlying serial UART, SPI, and I2C
devices to the output pins.

config QCOM_LLCC
tristate "Qualcomm Technologies, Inc. LLCC driver"
depends on ARCH_QCOM
help
Qualcomm Technologies, Inc. platform specific
Last Level Cache Controller(LLCC) driver. This provides interfaces
to clients that use the LLCC. Say yes here to enable LLCC slice
driver.

config QCOM_SDM845_LLCC
tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver"
depends on QCOM_LLCC
help
Say yes here to enable the LLCC driver for SDM845. This provides
data required to configure LLCC so that clients can start using the
LLCC slices.

config QCOM_MDT_LOADER
tristate
select QCOM_SCM
Expand Down Expand Up @@ -74,6 +91,16 @@ config QCOM_RMTFS_MEM

Say y here if you intend to boot the modem remoteproc.

config QCOM_RPMH
bool "Qualcomm RPM-Hardened (RPMH) Communication"
depends on ARCH_QCOM && ARM64 && OF || COMPILE_TEST
help
Support for communication with the hardened-RPM blocks in
Qualcomm Technologies Inc (QTI) SoCs. RPMH communication uses an
internal bus to transmit state requests for shared resources. A set
of hardware components aggregate requests for these resources and
help apply the aggregated state on the resource.

config QCOM_SMEM
tristate "Qualcomm Shared Memory Manager (SMEM)"
depends on ARCH_QCOM
Expand Down
6 changes: 6 additions & 0 deletions drivers/soc/qcom/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
CFLAGS_rpmh-rsc.o := -I$(src)
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o
Expand All @@ -8,10 +9,15 @@ obj-$(CONFIG_QCOM_PM) += spm.o
obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
qmi_helpers-y += qmi_encdec.o qmi_interface.o
obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o
obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o
qcom_rpmh-y += rpmh-rsc.o
qcom_rpmh-y += rpmh.o
obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) += smem.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
obj-$(CONFIG_QCOM_SMSM) += smsm.o
obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
obj-$(CONFIG_QCOM_APR) += apr.o
obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o
obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o
94 changes: 94 additions & 0 deletions drivers/soc/qcom/llcc-sdm845.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/soc/qcom/llcc-qcom.h>

/*
* SCT(System Cache Table) entry contains of the following members:
* 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
* priority: Priority of the client used to select victim line for replacement
* fixed_size: Boolean indicating if the slice has a fixed capacity
* bonus_ways: Bonus ways are additional ways to be used for any slice,
* if client ends up using more than reserved cache ways. Bonus
* ways are allocated only if they are not reserved for some
* other client.
* res_ways: Reserved ways for the cache slice, the reserved ways cannot
* be used by any other client than the one its assigned to.
* cache_mode: Each slice operates as a cache, this controls the mode of the
* slice: normal or TCM(Tightly Coupled Memory)
* probe_target_ways: Determines what ways to probe for access hit. When
* configured to 1 only bonus and reserved ways are probed.
* When configured to 0 all ways in llcc are probed.
* dis_cap_alloc: Disable capacity based allocation for a client
* retain_on_pc: If this bit is set and client has maintained active vote
* then the ways assigned to this client are not flushed on power
* collapse.
* activate_on_init: Activate the slice immediately after the SCT is programmed
*/
#define SCT_ENTRY(uid, sid, mc, p, fs, bway, rway, cmod, ptw, dca, rp, a) \
{ \
.usecase_id = uid, \
.slice_id = sid, \
.max_cap = mc, \
.priority = p, \
.fixed_size = fs, \
.bonus_ways = bway, \
.res_ways = rway, \
.cache_mode = cmod, \
.probe_target_ways = ptw, \
.dis_cap_alloc = dca, \
.retain_on_pc = rp, \
.activate_on_init = a, \
}

static struct llcc_slice_config sdm845_data[] = {
SCT_ENTRY(LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1),
SCT_ENTRY(LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0),
SCT_ENTRY(LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1),
SCT_ENTRY(LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0),
SCT_ENTRY(LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0),
};

static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
{
return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
}

static const struct of_device_id sdm845_qcom_llcc_of_match[] = {
{ .compatible = "qcom,sdm845-llcc", },
{ }
};

static struct platform_driver sdm845_qcom_llcc_driver = {
.driver = {
.name = "sdm845-llcc",
.of_match_table = sdm845_qcom_llcc_of_match,
},
.probe = sdm845_qcom_llcc_probe,
};
module_platform_driver(sdm845_qcom_llcc_driver);

MODULE_DESCRIPTION("QCOM sdm845 LLCC driver");
MODULE_LICENSE("GPL v2");
Loading

0 comments on commit 2de4471

Please sign in to comment.