Merge 84851d12f3 on remote branch
Change-Id: Ia6060b48ba72e1f2604cfca4a2d8ca1dead6e6d1
This commit is contained in:
@@ -3,5 +3,13 @@ CONFIG_TMPFS_POSIX_ACL=y
|
|||||||
CONFIG_USB_SERIAL=y
|
CONFIG_USB_SERIAL=y
|
||||||
CONFIG_USB_SERIAL_CH341=y
|
CONFIG_USB_SERIAL_CH341=y
|
||||||
CONFIG_USB_SERIAL_CP210X=y
|
CONFIG_USB_SERIAL_CP210X=y
|
||||||
|
CONFIG_I2C_MUX=y
|
||||||
|
CONFIG_PINCTRL_SX150X=y
|
||||||
CONFIG_GPIO_SYSFS=y
|
CONFIG_GPIO_SYSFS=y
|
||||||
CONFIG_PM_AUTOSLEEP=y
|
CONFIG_PM_AUTOSLEEP=y
|
||||||
|
CONFIG_CAN=y
|
||||||
|
CONFIG_USB_XHCI_PCI_RENESAS=y
|
||||||
|
CONFIG_HWMON=y
|
||||||
|
CONFIG_POWER_SUPPLY_HWMON=y
|
||||||
|
CONFIG_THERMAL_HWMON=y
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ CONFIG_QRTR_WAKEUP_MS=0
|
|||||||
CONFIG_QTI_CPUFREQ_CDEV=m
|
CONFIG_QTI_CPUFREQ_CDEV=m
|
||||||
CONFIG_QTI_CPU_HOTPLUG_COOLING_DEVICE=m
|
CONFIG_QTI_CPU_HOTPLUG_COOLING_DEVICE=m
|
||||||
# CONFIG_QTI_CPU_PAUSE_COOLING_DEVICE is not set
|
# CONFIG_QTI_CPU_PAUSE_COOLING_DEVICE is not set
|
||||||
|
CONFIG_QTI_CRYPTO_COMMON=m
|
||||||
|
CONFIG_QTI_CRYPTO_TZ=m
|
||||||
CONFIG_QTI_DEVFREQ_CDEV=m
|
CONFIG_QTI_DEVFREQ_CDEV=m
|
||||||
CONFIG_QTI_PMIC_PON_LOG=m
|
CONFIG_QTI_PMIC_PON_LOG=m
|
||||||
CONFIG_QTI_QMI_COOLING_DEVICE=m
|
CONFIG_QTI_QMI_COOLING_DEVICE=m
|
||||||
@@ -233,6 +235,7 @@ CONFIG_SA_DISPCC_LEMANS=m
|
|||||||
CONFIG_SA_GCC_LEMANS=m
|
CONFIG_SA_GCC_LEMANS=m
|
||||||
CONFIG_SA_GPUCC_LEMANS=m
|
CONFIG_SA_GPUCC_LEMANS=m
|
||||||
CONFIG_SA_VIDEOCC_LEMANS=m
|
CONFIG_SA_VIDEOCC_LEMANS=m
|
||||||
|
CONFIG_SCSI_UFS_CRYPTO_QTI=m
|
||||||
CONFIG_SCSI_UFS_QCOM=m
|
CONFIG_SCSI_UFS_QCOM=m
|
||||||
CONFIG_SERIAL_MSM_GENI=m
|
CONFIG_SERIAL_MSM_GENI=m
|
||||||
# CONFIG_SND_USB_AUDIO_QMI is not set
|
# CONFIG_SND_USB_AUDIO_QMI is not set
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
|
|||||||
CONFIG_EDAC_QCOM=m
|
CONFIG_EDAC_QCOM=m
|
||||||
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
||||||
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
||||||
|
CONFIG_EP_PCIE=m
|
||||||
# CONFIG_EXT4_KUNIT_TESTS is not set
|
# CONFIG_EXT4_KUNIT_TESTS is not set
|
||||||
# CONFIG_FAT_KUNIT_TEST is not set
|
# CONFIG_FAT_KUNIT_TEST is not set
|
||||||
CONFIG_GH_ARM64_DRV=m
|
CONFIG_GH_ARM64_DRV=m
|
||||||
@@ -114,6 +115,8 @@ CONFIG_MSM_CORE_HANG_DETECT=m
|
|||||||
CONFIG_MSM_GLOBAL_SYNX=m
|
CONFIG_MSM_GLOBAL_SYNX=m
|
||||||
CONFIG_MSM_GPI_DMA=m
|
CONFIG_MSM_GPI_DMA=m
|
||||||
# CONFIG_MSM_GPI_DMA_DEBUG is not set
|
# CONFIG_MSM_GPI_DMA_DEBUG is not set
|
||||||
|
CONFIG_MSM_MHI_DEV=m
|
||||||
|
CONFIG_MSM_MHI_NET_DEV=m
|
||||||
CONFIG_MSM_PERFORMANCE=m
|
CONFIG_MSM_PERFORMANCE=m
|
||||||
CONFIG_MSM_POWER_STATE=m
|
CONFIG_MSM_POWER_STATE=m
|
||||||
CONFIG_MSM_QBT_HANDLER=m
|
CONFIG_MSM_QBT_HANDLER=m
|
||||||
@@ -257,6 +260,7 @@ CONFIG_QCOM_WDT_CORE=m
|
|||||||
CONFIG_QRTR=m
|
CONFIG_QRTR=m
|
||||||
CONFIG_QRTR_GUNYAH=m
|
CONFIG_QRTR_GUNYAH=m
|
||||||
CONFIG_QRTR_MHI=m
|
CONFIG_QRTR_MHI=m
|
||||||
|
# CONFIG_QRTR_MHI_DEV is not set
|
||||||
CONFIG_QRTR_SMD=m
|
CONFIG_QRTR_SMD=m
|
||||||
# CONFIG_QRTR_TUN is not set
|
# CONFIG_QRTR_TUN is not set
|
||||||
CONFIG_QSEECOM_PROXY=m
|
CONFIG_QSEECOM_PROXY=m
|
||||||
@@ -368,6 +372,7 @@ CONFIG_USB_M31_MSM_EUSB2_PHY=m
|
|||||||
CONFIG_USB_MON=m
|
CONFIG_USB_MON=m
|
||||||
CONFIG_USB_MSM_EUSB2_PHY=m
|
CONFIG_USB_MSM_EUSB2_PHY=m
|
||||||
CONFIG_USB_MSM_SSPHY_QMP=m
|
CONFIG_USB_MSM_SSPHY_QMP=m
|
||||||
|
CONFIG_USB_NET_AX88179_178A=m
|
||||||
# CONFIG_USB_NET_RNDIS_WLAN is not set
|
# CONFIG_USB_NET_RNDIS_WLAN is not set
|
||||||
CONFIG_USB_QCOM_EMU_PHY=m
|
CONFIG_USB_QCOM_EMU_PHY=m
|
||||||
CONFIG_USB_REDRIVER=m
|
CONFIG_USB_REDRIVER=m
|
||||||
|
|||||||
11
arch/arm64/configs/vendor/kalama_lu_GKI.config
vendored
11
arch/arm64/configs/vendor/kalama_lu_GKI.config
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
CONFIG_ADS7052_TDK_THERMISTOR=m
|
||||||
CONFIG_ARCH_KAKA=y
|
CONFIG_ARCH_KAKA=y
|
||||||
CONFIG_ARCH_KALAMA=y
|
CONFIG_ARCH_KALAMA=y
|
||||||
CONFIG_ARCH_QCOM=y
|
CONFIG_ARCH_QCOM=y
|
||||||
@@ -7,6 +8,7 @@ CONFIG_ARM_SMMU=m
|
|||||||
CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
|
CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
|
||||||
# CONFIG_ARM_SMMU_SELFTEST is not set
|
# CONFIG_ARM_SMMU_SELFTEST is not set
|
||||||
CONFIG_BLK_DEV_NVME=m
|
CONFIG_BLK_DEV_NVME=m
|
||||||
|
CONFIG_CAN_MCP25XXFD=m
|
||||||
CONFIG_CFG80211=m
|
CONFIG_CFG80211=m
|
||||||
# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
|
# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
|
||||||
# CONFIG_CFG80211_CRDA_SUPPORT is not set
|
# CONFIG_CFG80211_CRDA_SUPPORT is not set
|
||||||
@@ -16,6 +18,8 @@ CONFIG_CFG80211=m
|
|||||||
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
|
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
|
||||||
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
|
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
|
||||||
# CONFIG_CFG80211_WEXT is not set
|
# CONFIG_CFG80211_WEXT is not set
|
||||||
|
CONFIG_CH101=m
|
||||||
|
CONFIG_CH101_I2C=m
|
||||||
# CONFIG_CHARGER_QCOM_SMBB is not set
|
# CONFIG_CHARGER_QCOM_SMBB is not set
|
||||||
CONFIG_CHR_DEV_SG=m
|
CONFIG_CHR_DEV_SG=m
|
||||||
CONFIG_COMMON_CLK_QCOM=m
|
CONFIG_COMMON_CLK_QCOM=m
|
||||||
@@ -31,10 +35,11 @@ CONFIG_CORESIGHT_TGU=m
|
|||||||
CONFIG_CORESIGHT_TPDA=m
|
CONFIG_CORESIGHT_TPDA=m
|
||||||
CONFIG_CORESIGHT_TPDM=m
|
CONFIG_CORESIGHT_TPDM=m
|
||||||
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
|
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
|
||||||
CONFIG_DRM_LT9611UXC=m
|
# CONFIG_DRM_LT9611UXC is not set
|
||||||
CONFIG_EDAC_QCOM=m
|
CONFIG_EDAC_QCOM=m
|
||||||
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
|
||||||
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
|
||||||
|
CONFIG_EP_PCIE=m
|
||||||
# CONFIG_EXT4_KUNIT_TESTS is not set
|
# CONFIG_EXT4_KUNIT_TESTS is not set
|
||||||
# CONFIG_FAT_KUNIT_TEST is not set
|
# CONFIG_FAT_KUNIT_TEST is not set
|
||||||
CONFIG_GH_ARM64_DRV=m
|
CONFIG_GH_ARM64_DRV=m
|
||||||
@@ -110,6 +115,8 @@ CONFIG_MSM_CORE_HANG_DETECT=m
|
|||||||
CONFIG_MSM_GLOBAL_SYNX=m
|
CONFIG_MSM_GLOBAL_SYNX=m
|
||||||
CONFIG_MSM_GPI_DMA=m
|
CONFIG_MSM_GPI_DMA=m
|
||||||
# CONFIG_MSM_GPI_DMA_DEBUG is not set
|
# CONFIG_MSM_GPI_DMA_DEBUG is not set
|
||||||
|
CONFIG_MSM_MHI_DEV=m
|
||||||
|
CONFIG_MSM_MHI_NET_DEV=m
|
||||||
CONFIG_MSM_PERFORMANCE=m
|
CONFIG_MSM_PERFORMANCE=m
|
||||||
CONFIG_MSM_POWER_STATE=m
|
CONFIG_MSM_POWER_STATE=m
|
||||||
CONFIG_MSM_QBT_HANDLER=m
|
CONFIG_MSM_QBT_HANDLER=m
|
||||||
@@ -253,6 +260,7 @@ CONFIG_QCOM_WDT_CORE=m
|
|||||||
CONFIG_QRTR=m
|
CONFIG_QRTR=m
|
||||||
CONFIG_QRTR_GUNYAH=m
|
CONFIG_QRTR_GUNYAH=m
|
||||||
CONFIG_QRTR_MHI=m
|
CONFIG_QRTR_MHI=m
|
||||||
|
# CONFIG_QRTR_MHI_DEV is not set
|
||||||
CONFIG_QRTR_SMD=m
|
CONFIG_QRTR_SMD=m
|
||||||
# CONFIG_QRTR_TUN is not set
|
# CONFIG_QRTR_TUN is not set
|
||||||
CONFIG_QSEECOM_PROXY=m
|
CONFIG_QSEECOM_PROXY=m
|
||||||
@@ -364,6 +372,7 @@ CONFIG_USB_M31_MSM_EUSB2_PHY=m
|
|||||||
CONFIG_USB_MON=m
|
CONFIG_USB_MON=m
|
||||||
CONFIG_USB_MSM_EUSB2_PHY=m
|
CONFIG_USB_MSM_EUSB2_PHY=m
|
||||||
CONFIG_USB_MSM_SSPHY_QMP=m
|
CONFIG_USB_MSM_SSPHY_QMP=m
|
||||||
|
CONFIG_USB_NET_AX88179_178A=m
|
||||||
# CONFIG_USB_NET_RNDIS_WLAN is not set
|
# CONFIG_USB_NET_RNDIS_WLAN is not set
|
||||||
CONFIG_USB_QCOM_EMU_PHY=m
|
CONFIG_USB_QCOM_EMU_PHY=m
|
||||||
CONFIG_USB_REDRIVER=m
|
CONFIG_USB_REDRIVER=m
|
||||||
|
|||||||
@@ -15,12 +15,15 @@ CONFIG_MSM_GPI_DMA_DEBUG=y
|
|||||||
# CONFIG_QCOM_DYN_MINIDUMP_STACK is not set
|
# CONFIG_QCOM_DYN_MINIDUMP_STACK is not set
|
||||||
CONFIG_QCOM_RTB=m
|
CONFIG_QCOM_RTB=m
|
||||||
CONFIG_QCOM_RTB_SEPARATE_CPUS=y
|
CONFIG_QCOM_RTB_SEPARATE_CPUS=y
|
||||||
|
CONFIG_QRC=m
|
||||||
|
CONFIG_QRC_DEBUG=m
|
||||||
CONFIG_QTI_PMIC_GLINK_CLIENT_DEBUG=y
|
CONFIG_QTI_PMIC_GLINK_CLIENT_DEBUG=y
|
||||||
CONFIG_RCU_TORTURE_TEST=m
|
CONFIG_RCU_TORTURE_TEST=m
|
||||||
CONFIG_REGMAP_QTI_DEBUGFS_ALLOW_WRITE=y
|
CONFIG_REGMAP_QTI_DEBUGFS_ALLOW_WRITE=y
|
||||||
CONFIG_RPMSG_QCOM_GLINK_DEBUG=y
|
CONFIG_RPMSG_QCOM_GLINK_DEBUG=y
|
||||||
CONFIG_RUNTIME_TESTING_MENU=y
|
CONFIG_RUNTIME_TESTING_MENU=y
|
||||||
CONFIG_SCHED_WALT_DEBUG=m
|
CONFIG_SCHED_WALT_DEBUG=m
|
||||||
|
CONFIG_SENSORS_PWM_FAN=m
|
||||||
CONFIG_SPI_SPIDEV=m
|
CONFIG_SPI_SPIDEV=m
|
||||||
CONFIG_TEST_USER_COPY=m
|
CONFIG_TEST_USER_COPY=m
|
||||||
CONFIG_UFS_DBG=y
|
CONFIG_UFS_DBG=y
|
||||||
|
|||||||
5
arch/arm64/configs/vendor/qcs605_GKI.config
vendored
5
arch/arm64/configs/vendor/qcs605_GKI.config
vendored
@@ -32,6 +32,9 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=m
|
|||||||
CONFIG_CPU_FREQ_GOV_USERSPACE=m
|
CONFIG_CPU_FREQ_GOV_USERSPACE=m
|
||||||
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
|
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
|
||||||
# CONFIG_DEBUG_PREEMPT is not set
|
# CONFIG_DEBUG_PREEMPT is not set
|
||||||
|
CONFIG_EDAC_KRYO_ARM64=m
|
||||||
|
# CONFIG_EDAC_KRYO_ARM64_PANIC_ON_CE is not set
|
||||||
|
CONFIG_EDAC_KRYO_ARM64_PANIC_ON_UE=y
|
||||||
CONFIG_EXTCON_USB_GPIO=m
|
CONFIG_EXTCON_USB_GPIO=m
|
||||||
CONFIG_HWSPINLOCK_QCOM=m
|
CONFIG_HWSPINLOCK_QCOM=m
|
||||||
CONFIG_HW_RANDOM_MSM_LEGACY=m
|
CONFIG_HW_RANDOM_MSM_LEGACY=m
|
||||||
@@ -111,7 +114,7 @@ CONFIG_QCOM_DMABUF_HEAPS_CMA=y
|
|||||||
CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL=y
|
CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL=y
|
||||||
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
|
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
|
||||||
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
|
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
|
||||||
# CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED is not set
|
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED=y
|
||||||
# CONFIG_QCOM_DYN_MINIDUMP_STACK is not set
|
# CONFIG_QCOM_DYN_MINIDUMP_STACK is not set
|
||||||
CONFIG_QCOM_EUD=m
|
CONFIG_QCOM_EUD=m
|
||||||
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
|
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
|
||||||
|
|||||||
@@ -103,9 +103,6 @@
|
|||||||
#define M_KERNEL_PERF_LIST (PERF_KEY_MAX)
|
#define M_KERNEL_PERF_LIST (PERF_KEY_MAX)
|
||||||
#define M_DSP_PERF_LIST (12)
|
#define M_DSP_PERF_LIST (12)
|
||||||
|
|
||||||
#define SESSION_ID_INDEX (30)
|
|
||||||
#define SESSION_ID_MASK (1 << SESSION_ID_INDEX)
|
|
||||||
#define PROCESS_ID_MASK ((2^SESSION_ID_INDEX) - 1)
|
|
||||||
#define FASTRPC_CTX_MAGIC (0xbeeddeed)
|
#define FASTRPC_CTX_MAGIC (0xbeeddeed)
|
||||||
|
|
||||||
/* Process status notifications from DSP will be sent with this unique context */
|
/* Process status notifications from DSP will be sent with this unique context */
|
||||||
@@ -198,6 +195,9 @@
|
|||||||
/* Max no. of persistent headers pre-allocated per process */
|
/* Max no. of persistent headers pre-allocated per process */
|
||||||
#define MAX_PERSISTENT_HEADERS (25)
|
#define MAX_PERSISTENT_HEADERS (25)
|
||||||
|
|
||||||
|
/* Max value of the unique fastrpc tgid */
|
||||||
|
#define MAX_FRPC_TGID 256
|
||||||
|
|
||||||
#define PERF_CAPABILITY_SUPPORT (1 << 1)
|
#define PERF_CAPABILITY_SUPPORT (1 << 1)
|
||||||
#define KERNEL_ERROR_CODE_V1_SUPPORT 1
|
#define KERNEL_ERROR_CODE_V1_SUPPORT 1
|
||||||
#define USERSPACE_ALLOCATION_SUPPORT 1
|
#define USERSPACE_ALLOCATION_SUPPORT 1
|
||||||
@@ -215,9 +215,18 @@
|
|||||||
|
|
||||||
#define FASTRPC_USER_PD_FORCE_KILL 2
|
#define FASTRPC_USER_PD_FORCE_KILL 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No of pages shared with DSP during process init with
|
||||||
|
* First page for init-mem and second page for proc-attrs
|
||||||
|
*/
|
||||||
|
#define PAGESLEN_WITH_SHAREDBUF 2
|
||||||
|
|
||||||
/* Unique index flag used for mini dump */
|
/* Unique index flag used for mini dump */
|
||||||
static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 };
|
static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/* Array to keep track unique tgid_frpc usage */
|
||||||
|
static bool frpc_tgid_usage_array[MAX_FRPC_TGID] = {0};
|
||||||
|
|
||||||
/* Fastrpc remote process attributes */
|
/* Fastrpc remote process attributes */
|
||||||
enum fastrpc_proc_attr {
|
enum fastrpc_proc_attr {
|
||||||
/* Macro for Debug attr */
|
/* Macro for Debug attr */
|
||||||
@@ -1102,8 +1111,8 @@ bail:
|
|||||||
kfree(map);
|
kfree(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
|
static int fastrpc_session_alloc_secure_memory(struct fastrpc_channel_ctx *chan, int secure,
|
||||||
int sharedcb, struct fastrpc_session_ctx **session);
|
int sharedcb, int pd_type, struct fastrpc_session_ctx **session);
|
||||||
|
|
||||||
static inline bool fastrpc_get_persistent_map(size_t len, struct fastrpc_mmap **pers_map)
|
static inline bool fastrpc_get_persistent_map(size_t len, struct fastrpc_mmap **pers_map)
|
||||||
{
|
{
|
||||||
@@ -1293,11 +1302,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf *
|
|||||||
map->secure = (mem_buf_dma_buf_exclusive_owner(map->buf)) ? 0 : 1;
|
map->secure = (mem_buf_dma_buf_exclusive_owner(map->buf)) ? 0 : 1;
|
||||||
if (map->secure) {
|
if (map->secure) {
|
||||||
if (!fl->secsctx)
|
if (!fl->secsctx)
|
||||||
err = fastrpc_session_alloc(chan, 1, 0,
|
err = fastrpc_session_alloc_secure_memory(chan, 1, 0,
|
||||||
&fl->secsctx);
|
fl->pd_type, &fl->secsctx);
|
||||||
if (err) {
|
if (err) {
|
||||||
ADSPRPC_ERR(
|
ADSPRPC_ERR(
|
||||||
"fastrpc_session_alloc failed for fd %d ret %d\n",
|
"fastrpc_session_alloc_secure_memory failed for fd %d ret %d\n",
|
||||||
fd, err);
|
fd, err);
|
||||||
err = -ENOSR;
|
err = -ENOSR;
|
||||||
goto bail;
|
goto bail;
|
||||||
@@ -1866,6 +1875,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
|
|||||||
}
|
}
|
||||||
ctx->retval = -1;
|
ctx->retval = -1;
|
||||||
ctx->pid = current->pid;
|
ctx->pid = current->pid;
|
||||||
|
/* Store HLOS PID in context, it is not being sent to DSP */
|
||||||
ctx->tgid = fl->tgid;
|
ctx->tgid = fl->tgid;
|
||||||
init_completion(&ctx->work);
|
init_completion(&ctx->work);
|
||||||
ctx->magic = FASTRPC_CTX_MAGIC;
|
ctx->magic = FASTRPC_CTX_MAGIC;
|
||||||
@@ -1883,6 +1893,10 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
memset(ctx->perf, 0, sizeof(*(ctx->perf)));
|
memset(ctx->perf, 0, sizeof(*(ctx->perf)));
|
||||||
|
/*
|
||||||
|
* Use HLOS PID, as perf tid is not being sent
|
||||||
|
* to DSP and is used to log in traces.
|
||||||
|
*/
|
||||||
ctx->perf->tid = fl->tgid;
|
ctx->perf->tid = fl->tgid;
|
||||||
}
|
}
|
||||||
if (invokefd->job) {
|
if (invokefd->job) {
|
||||||
@@ -2060,13 +2074,11 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif
|
|||||||
struct fastrpc_file *fl = NULL;
|
struct fastrpc_file *fl = NULL;
|
||||||
struct hlist_node *n;
|
struct hlist_node *n;
|
||||||
bool is_process_found = false;
|
bool is_process_found = false;
|
||||||
int sessionid = 0;
|
|
||||||
unsigned long irq_flags = 0;
|
unsigned long irq_flags = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&me->hlock, irq_flags);
|
spin_lock_irqsave(&me->hlock, irq_flags);
|
||||||
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
|
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
|
||||||
if (fl->tgid == notif->pid ||
|
if (fl->tgid_frpc == notif->pid) {
|
||||||
(fl->tgid == (notif->pid & PROCESS_ID_MASK))) {
|
|
||||||
is_process_found = true;
|
is_process_found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2075,9 +2087,7 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif
|
|||||||
|
|
||||||
if (!is_process_found)
|
if (!is_process_found)
|
||||||
return;
|
return;
|
||||||
if (notif->pid & SESSION_ID_MASK)
|
fastrpc_queue_pd_status(fl, domain, notif->status, fl->sessionid);
|
||||||
sessionid = 1;
|
|
||||||
fastrpc_queue_pd_status(fl, domain, notif->status, sessionid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void context_notify_user(struct smq_invoke_ctx *ctx,
|
static void context_notify_user(struct smq_invoke_ctx *ctx,
|
||||||
@@ -2909,10 +2919,9 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx,
|
|||||||
|
|
||||||
channel_ctx = &fl->apps->channel[cid];
|
channel_ctx = &fl->apps->channel[cid];
|
||||||
mutex_lock(&channel_ctx->smd_mutex);
|
mutex_lock(&channel_ctx->smd_mutex);
|
||||||
msg->pid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
msg->pid = fl->tgid_frpc;
|
||||||
msg->tid = current->pid;
|
msg->tid = current->pid;
|
||||||
if (fl->sessionid)
|
|
||||||
msg->tid |= SESSION_ID_MASK;
|
|
||||||
if (kernel == KERNEL_MSG_WITH_ZERO_PID)
|
if (kernel == KERNEL_MSG_WITH_ZERO_PID)
|
||||||
msg->pid = 0;
|
msg->pid = 0;
|
||||||
msg->invoke.header.ctx = ctx->ctxid | fl->pd;
|
msg->invoke.header.ctx = ctx->ctxid | fl->pd;
|
||||||
@@ -2996,6 +3005,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
|
|||||||
spin_lock_init(&me->hlock);
|
spin_lock_init(&me->hlock);
|
||||||
me->channel = &gcinfo[0];
|
me->channel = &gcinfo[0];
|
||||||
mutex_init(&me->mut_uid);
|
mutex_init(&me->mut_uid);
|
||||||
|
me->max_sess_per_proc = DEFAULT_MAX_SESS_PER_PROC;
|
||||||
for (i = 0; i < NUM_CHANNELS; i++) {
|
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||||
init_completion(&me->channel[i].work);
|
init_completion(&me->channel[i].work);
|
||||||
init_completion(&me->channel[i].workport);
|
init_completion(&me->channel[i].workport);
|
||||||
@@ -3555,6 +3565,70 @@ bail:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fastrpc_set_session_info(
|
||||||
|
struct fastrpc_proc_sess_info *sess_info,
|
||||||
|
void *param, struct fastrpc_file *fl)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
struct fastrpc_apps *me = &gfa;
|
||||||
|
|
||||||
|
if (fl->set_session_info) {
|
||||||
|
ADSPRPC_ERR("Set session info invoked multiple times\n");
|
||||||
|
err = -EBADR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Third-party apps don't have permission to open the fastrpc device, so
|
||||||
|
* it is opened on their behalf by DSP HAL. This is detected by
|
||||||
|
* comparing current PID with the one stored during device open.
|
||||||
|
*/
|
||||||
|
if (current->tgid != fl->tgid_open)
|
||||||
|
fl->untrusted_process = true;
|
||||||
|
VERIFY(err, sess_info->pd_type > DEFAULT_UNUSED &&
|
||||||
|
sess_info->pd_type < MAX_PD_TYPE);
|
||||||
|
if (err) {
|
||||||
|
ADSPRPC_ERR(
|
||||||
|
"Session PD type %u is invalid for the process\n",
|
||||||
|
sess_info->pd_type);
|
||||||
|
err = -EBADR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
if (fl->untrusted_process && sess_info->pd_type != USERPD) {
|
||||||
|
ADSPRPC_ERR(
|
||||||
|
"Session PD type %u not allowed for untrusted process\n",
|
||||||
|
sess_info->pd_type);
|
||||||
|
err = -EBADR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If PD type is not configured for context banks,
|
||||||
|
* ignore PD type passed by the user, leave pd_type set to DEFAULT_UNUSED(0)
|
||||||
|
*/
|
||||||
|
if (me->cb_pd_type)
|
||||||
|
fl->pd_type = sess_info->pd_type;
|
||||||
|
// Processes attaching to Sensor Static PD, share context bank.
|
||||||
|
if (sess_info->pd_type == SENSORS_STATICPD)
|
||||||
|
fl->sharedcb = 1;
|
||||||
|
if (sess_info->session_id >= me->max_sess_per_proc) {
|
||||||
|
ADSPRPC_ERR(
|
||||||
|
"Session ID %u cannot be beyond %u\n",
|
||||||
|
sess_info->session_id, me->max_sess_per_proc);
|
||||||
|
err = -EBADR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
fl->sessionid = sess_info->session_id;
|
||||||
|
// Set multi_session_support, to disable old way of setting session_id
|
||||||
|
fl->multi_session_support = true;
|
||||||
|
VERIFY(err, 0 == (err = fastrpc_get_info(fl, &(sess_info->domain_id))));
|
||||||
|
if (err)
|
||||||
|
goto bail;
|
||||||
|
K_COPY_TO_USER(err, 0, param, sess_info,
|
||||||
|
sizeof(struct fastrpc_proc_sess_info));
|
||||||
|
bail:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int fastrpc_create_persistent_headers(struct fastrpc_file *fl,
|
static int fastrpc_create_persistent_headers(struct fastrpc_file *fl,
|
||||||
uint32_t user_concurrency)
|
uint32_t user_concurrency)
|
||||||
{
|
{
|
||||||
@@ -3636,6 +3710,8 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl,
|
|||||||
struct fastrpc_ioctl_async_response async_res;
|
struct fastrpc_ioctl_async_response async_res;
|
||||||
uint32_t user_concurrency;
|
uint32_t user_concurrency;
|
||||||
struct fastrpc_ioctl_notif_rsp notif;
|
struct fastrpc_ioctl_notif_rsp notif;
|
||||||
|
struct fastrpc_proc_sharedbuf_info buff_info;
|
||||||
|
struct fastrpc_proc_sess_info sess_info;
|
||||||
} p;
|
} p;
|
||||||
struct fastrpc_dsp_capabilities *dsp_cap_ptr = NULL;
|
struct fastrpc_dsp_capabilities *dsp_cap_ptr = NULL;
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
@@ -3714,6 +3790,35 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl,
|
|||||||
err = fastrpc_get_notif_response(&p.notif,
|
err = fastrpc_get_notif_response(&p.notif,
|
||||||
(void *)inv2->invparam, fl);
|
(void *)inv2->invparam, fl);
|
||||||
break;
|
break;
|
||||||
|
case FASTRPC_INVOKE2_PROC_SHAREDBUF_INFO:
|
||||||
|
VERIFY(err,
|
||||||
|
sizeof(struct fastrpc_proc_sharedbuf_info) >= inv2->size);
|
||||||
|
if (err) {
|
||||||
|
err = -EBADE;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
K_COPY_FROM_USER(err, fl->is_compat, &p.buff_info,
|
||||||
|
(void *)inv2->invparam, inv2->size);
|
||||||
|
if (err)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
fl->sharedbuf_info.buf_fd = p.buff_info.buf_fd;
|
||||||
|
fl->sharedbuf_info.buf_size = p.buff_info.buf_size;
|
||||||
|
break;
|
||||||
|
case FASTRPC_INVOKE2_SESS_INFO:
|
||||||
|
VERIFY(err,
|
||||||
|
sizeof(struct fastrpc_proc_sess_info) >= inv2->size);
|
||||||
|
if (err) {
|
||||||
|
err = -EBADE;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
K_COPY_FROM_USER(err, fl->is_compat, &p.sess_info,
|
||||||
|
(void *)inv2->invparam, inv2->size);
|
||||||
|
if (err)
|
||||||
|
goto bail;
|
||||||
|
err = fastrpc_set_session_info(&p.sess_info,
|
||||||
|
(void *)inv2->invparam, fl);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
err = -ENOTTY;
|
err = -ENOTTY;
|
||||||
break;
|
break;
|
||||||
@@ -3764,7 +3869,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked);
|
|||||||
static int fastrpc_init_attach_process(struct fastrpc_file *fl,
|
static int fastrpc_init_attach_process(struct fastrpc_file *fl,
|
||||||
struct fastrpc_ioctl_init *init)
|
struct fastrpc_ioctl_init *init)
|
||||||
{
|
{
|
||||||
int err = 0, tgid = fl->tgid;
|
int err = 0, tgid = fl->tgid_frpc;
|
||||||
remote_arg_t ra[1];
|
remote_arg_t ra[1];
|
||||||
struct fastrpc_ioctl_invoke_async ioctl;
|
struct fastrpc_ioctl_invoke_async ioctl;
|
||||||
|
|
||||||
@@ -3777,6 +3882,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl,
|
|||||||
/*
|
/*
|
||||||
* Prepare remote arguments for creating thread group
|
* Prepare remote arguments for creating thread group
|
||||||
* in guestOS/staticPD on the remote subsystem.
|
* in guestOS/staticPD on the remote subsystem.
|
||||||
|
* Send unique fastrpc id to dsp
|
||||||
*/
|
*/
|
||||||
ra[0].buf.pv = (void *)&tgid;
|
ra[0].buf.pv = (void *)&tgid;
|
||||||
ra[0].buf.len = sizeof(tgid);
|
ra[0].buf.len = sizeof(tgid);
|
||||||
@@ -3814,7 +3920,8 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
|
|||||||
int err = 0, memlen = 0, mflags = 0, locked = 0;
|
int err = 0, memlen = 0, mflags = 0, locked = 0;
|
||||||
struct fastrpc_ioctl_invoke_async ioctl;
|
struct fastrpc_ioctl_invoke_async ioctl;
|
||||||
struct fastrpc_ioctl_init *init = &uproc->init;
|
struct fastrpc_ioctl_init *init = &uproc->init;
|
||||||
struct smq_phy_page pages[1];
|
/* First page for init-mem and second page for proc-attrs */
|
||||||
|
struct smq_phy_page pages[PAGESLEN_WITH_SHAREDBUF];
|
||||||
struct fastrpc_mmap *file = NULL;
|
struct fastrpc_mmap *file = NULL;
|
||||||
struct fastrpc_buf *imem = NULL;
|
struct fastrpc_buf *imem = NULL;
|
||||||
unsigned long imem_dma_attr = 0;
|
unsigned long imem_dma_attr = 0;
|
||||||
@@ -3823,6 +3930,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
|
|||||||
unsigned int gid = 0, one_mb = 1024*1024;
|
unsigned int gid = 0, one_mb = 1024*1024;
|
||||||
unsigned int dsp_userpd_memlen = 3 * one_mb;
|
unsigned int dsp_userpd_memlen = 3 * one_mb;
|
||||||
struct fastrpc_buf *init_mem;
|
struct fastrpc_buf *init_mem;
|
||||||
|
struct fastrpc_mmap *sharedbuf_map = NULL;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int pgid;
|
int pgid;
|
||||||
@@ -3843,7 +3951,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
|
|||||||
fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS;
|
fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS;
|
||||||
spin_unlock(&fl->hlock);
|
spin_unlock(&fl->hlock);
|
||||||
|
|
||||||
inbuf.pgid = fl->tgid;
|
inbuf.pgid = fl->tgid_frpc;
|
||||||
inbuf.namelen = strlen(current->comm) + 1;
|
inbuf.namelen = strlen(current->comm) + 1;
|
||||||
inbuf.filelen = init->filelen;
|
inbuf.filelen = init->filelen;
|
||||||
fl->pd = 1;
|
fl->pd = 1;
|
||||||
@@ -3934,11 +4042,23 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
|
|||||||
goto bail;
|
goto bail;
|
||||||
fl->init_mem = imem;
|
fl->init_mem = imem;
|
||||||
|
|
||||||
|
inbuf.pageslen = 1;
|
||||||
|
if ((fl->sharedbuf_info.buf_fd != -1) && fl->sharedbuf_info.buf_size) {
|
||||||
|
mutex_lock(&fl->map_mutex);
|
||||||
|
err = fastrpc_mmap_create(fl, fl->sharedbuf_info.buf_fd, NULL, 0,
|
||||||
|
0, fl->sharedbuf_info.buf_size, mflags, &sharedbuf_map);
|
||||||
|
mutex_unlock(&fl->map_mutex);
|
||||||
|
if (err)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
/* if shared buff is available send this as the second page and set pageslen as 2 */
|
||||||
|
inbuf.pageslen = PAGESLEN_WITH_SHAREDBUF;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare remote arguments for dynamic process create
|
* Prepare remote arguments for dynamic process create
|
||||||
* call to remote subsystem.
|
* call to remote subsystem.
|
||||||
*/
|
*/
|
||||||
inbuf.pageslen = 1;
|
|
||||||
ra[0].buf.pv = (void *)&inbuf;
|
ra[0].buf.pv = (void *)&inbuf;
|
||||||
ra[0].buf.len = sizeof(inbuf);
|
ra[0].buf.len = sizeof(inbuf);
|
||||||
fds[0] = -1;
|
fds[0] = -1;
|
||||||
@@ -3953,8 +4073,14 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
|
|||||||
|
|
||||||
pages[0].addr = imem->phys;
|
pages[0].addr = imem->phys;
|
||||||
pages[0].size = imem->size;
|
pages[0].size = imem->size;
|
||||||
|
|
||||||
|
/* Update IOVA of second page shared with DSP */
|
||||||
|
if (inbuf.pageslen > 1) {
|
||||||
|
pages[1].addr = sharedbuf_map->phys;
|
||||||
|
pages[1].size = sharedbuf_map->size;
|
||||||
|
}
|
||||||
ra[3].buf.pv = (void *)pages;
|
ra[3].buf.pv = (void *)pages;
|
||||||
ra[3].buf.len = 1 * sizeof(*pages);
|
ra[3].buf.len = (inbuf.pageslen) * sizeof(*pages);
|
||||||
fds[3] = -1;
|
fds[3] = -1;
|
||||||
|
|
||||||
inbuf.attrs = uproc->attrs;
|
inbuf.attrs = uproc->attrs;
|
||||||
@@ -4069,7 +4195,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fl->pd = 1;
|
fl->pd = 1;
|
||||||
inbuf.pgid = fl->tgid;
|
inbuf.pgid = fl->tgid_frpc;
|
||||||
inbuf.namelen = init->filelen;
|
inbuf.namelen = init->filelen;
|
||||||
inbuf.pageslen = 0;
|
inbuf.pageslen = 0;
|
||||||
|
|
||||||
@@ -4222,38 +4348,6 @@ bail:
|
|||||||
kfree(proc_name);
|
kfree(proc_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Function to restrict duplicate session creation with same tgid, cid.
|
|
||||||
* check introduced after extended session creation
|
|
||||||
* to avoid breaking in case of extended sessions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool fastrpc_session_exists(struct fastrpc_apps *me, uint32_t cid, int tgid)
|
|
||||||
{
|
|
||||||
struct fastrpc_file *fl;
|
|
||||||
struct hlist_node *n;
|
|
||||||
bool session_found = false;
|
|
||||||
unsigned long irq_flags = 0;
|
|
||||||
int total_session_count = 0;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&me->hlock, irq_flags);
|
|
||||||
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
|
|
||||||
if (fl->tgid == tgid && fl->cid == cid) {
|
|
||||||
++total_session_count;
|
|
||||||
if (total_session_count > 1) {
|
|
||||||
session_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&me->hlock, irq_flags);
|
|
||||||
if (session_found)
|
|
||||||
ADSPRPC_ERR(
|
|
||||||
"trying to open a session that already exists for tgid %d, channel ID %u\n",
|
|
||||||
tgid, cid);
|
|
||||||
|
|
||||||
return session_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fastrpc_init_process(struct fastrpc_file *fl,
|
int fastrpc_init_process(struct fastrpc_file *fl,
|
||||||
struct fastrpc_ioctl_init_attrs *uproc)
|
struct fastrpc_ioctl_init_attrs *uproc)
|
||||||
@@ -4279,11 +4373,6 @@ int fastrpc_init_process(struct fastrpc_file *fl,
|
|||||||
err = -ECHRNG;
|
err = -ECHRNG;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
VERIFY(err, !fastrpc_session_exists(me, fl->cid, fl->tgid));
|
|
||||||
if (err) {
|
|
||||||
err = -EEXIST;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
chan = &me->channel[cid];
|
chan = &me->channel[cid];
|
||||||
if (chan->unsigned_support && fl->dev_minor == MINOR_NUM_DEV) {
|
if (chan->unsigned_support && fl->dev_minor == MINOR_NUM_DEV) {
|
||||||
/* Make sure third party applications */
|
/* Make sure third party applications */
|
||||||
@@ -4523,7 +4612,8 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
|
|||||||
err = -ECONNRESET;
|
err = -ECONNRESET;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
tgid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
tgid = fl->tgid_frpc;
|
||||||
ra[0].buf.pv = (void *)&tgid;
|
ra[0].buf.pv = (void *)&tgid;
|
||||||
ra[0].buf.len = sizeof(tgid);
|
ra[0].buf.len = sizeof(tgid);
|
||||||
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
|
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
|
||||||
@@ -4582,7 +4672,8 @@ static int fastrpc_mem_map_to_dsp(struct fastrpc_file *fl, int fd, int offset,
|
|||||||
uint64_t vaddrout;
|
uint64_t vaddrout;
|
||||||
} routargs;
|
} routargs;
|
||||||
|
|
||||||
inargs.pid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
inargs.pid = fl->tgid_frpc;
|
||||||
inargs.fd = fd;
|
inargs.fd = fd;
|
||||||
inargs.offset = offset;
|
inargs.offset = offset;
|
||||||
inargs.vaddrin = (uintptr_t)va;
|
inargs.vaddrin = (uintptr_t)va;
|
||||||
@@ -4633,7 +4724,8 @@ static int fastrpc_mem_unmap_to_dsp(struct fastrpc_file *fl, int fd,
|
|||||||
uint64_t len;
|
uint64_t len;
|
||||||
} inargs;
|
} inargs;
|
||||||
|
|
||||||
inargs.pid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
inargs.pid = fl->tgid_frpc;
|
||||||
inargs.fd = fd;
|
inargs.fd = fd;
|
||||||
inargs.vaddrin = (uint64_t)va;
|
inargs.vaddrin = (uint64_t)va;
|
||||||
inargs.len = (uint64_t)size;
|
inargs.len = (uint64_t)size;
|
||||||
@@ -4669,7 +4761,8 @@ static int fastrpc_unmap_on_dsp(struct fastrpc_file *fl,
|
|||||||
size_t size;
|
size_t size;
|
||||||
} inargs;
|
} inargs;
|
||||||
|
|
||||||
inargs.pid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
inargs.pid = fl->tgid_frpc;
|
||||||
inargs.size = size;
|
inargs.size = size;
|
||||||
inargs.vaddrout = raddr;
|
inargs.vaddrout = raddr;
|
||||||
ra[0].buf.pv = (void *)&inargs;
|
ra[0].buf.pv = (void *)&inargs;
|
||||||
@@ -4721,7 +4814,8 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
cid = fl->cid;
|
cid = fl->cid;
|
||||||
inargs.pid = fl->tgid;
|
/* Send unique fastrpc process ID to dsp */
|
||||||
|
inargs.pid = fl->tgid_frpc;
|
||||||
inargs.vaddrin = (uintptr_t)va;
|
inargs.vaddrin = (uintptr_t)va;
|
||||||
inargs.flags = flags;
|
inargs.flags = flags;
|
||||||
inargs.num = fl->apps->compat ? num * sizeof(page) : num;
|
inargs.num = fl->apps->compat ? num * sizeof(page) : num;
|
||||||
@@ -5431,17 +5525,23 @@ int fastrpc_internal_mmap(struct fastrpc_file *fl,
|
|||||||
static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
|
static void fastrpc_context_list_dtor(struct fastrpc_file *fl);
|
||||||
|
|
||||||
static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
|
static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
|
||||||
int secure, int sharedcb, struct fastrpc_session_ctx **session)
|
int secure, int sharedcb, int pd_type, struct fastrpc_session_ctx **session)
|
||||||
{
|
{
|
||||||
struct fastrpc_apps *me = &gfa;
|
struct fastrpc_apps *me = &gfa;
|
||||||
uint64_t idx = 0;
|
uint64_t idx = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PD type can be either unused(DEFAULT_UNUSED) (or) if PD type
|
||||||
|
* is used, choose the context bank with matching PD type.
|
||||||
|
*/
|
||||||
if (chan->sesscount) {
|
if (chan->sesscount) {
|
||||||
for (idx = 0; idx < chan->sesscount; ++idx) {
|
for (idx = 0; idx < chan->sesscount; ++idx) {
|
||||||
if (!chan->session[idx].used &&
|
if (!chan->session[idx].used &&
|
||||||
chan->session[idx].smmu.secure == secure &&
|
chan->session[idx].smmu.secure == secure &&
|
||||||
chan->session[idx].smmu.sharedcb == sharedcb) {
|
chan->session[idx].smmu.sharedcb == sharedcb &&
|
||||||
|
(pd_type == DEFAULT_UNUSED ||
|
||||||
|
chan->session[idx].smmu.pd_type == pd_type)) {
|
||||||
chan->session[idx].used = 1;
|
chan->session[idx].used = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5493,7 +5593,11 @@ static void handle_remote_signal(uint64_t msg, int cid)
|
|||||||
|
|
||||||
spin_lock_irqsave(&me->hlock, irq_flags);
|
spin_lock_irqsave(&me->hlock, irq_flags);
|
||||||
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
|
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
|
||||||
if ((fl->tgid == pid) && (fl->cid == cid)) {
|
/*
|
||||||
|
* Response from DSP contains unique fastrpc process id,
|
||||||
|
* use unique fastrpc process ID to compare.
|
||||||
|
*/
|
||||||
|
if ((fl->tgid_frpc == pid) && (fl->cid == cid)) {
|
||||||
unsigned long fflags = 0;
|
unsigned long fflags = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&fl->dspsignals_lock, fflags);
|
spin_lock_irqsave(&fl->dspsignals_lock, fflags);
|
||||||
@@ -5632,14 +5736,22 @@ bail:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure,
|
static int fastrpc_session_alloc_secure_memory(struct fastrpc_channel_ctx *chan, int secure,
|
||||||
int sharedcb, struct fastrpc_session_ctx **session)
|
int sharedcb, int pd_type, struct fastrpc_session_ctx **session)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
struct fastrpc_apps *me = &gfa;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If PD type is configured for context banks,
|
||||||
|
* Use CPZ_USERPD, to allocate secure context bank type.
|
||||||
|
*/
|
||||||
|
if (pd_type != DEFAULT_UNUSED && me->cb_pd_type)
|
||||||
|
pd_type = CPZ_USERPD;
|
||||||
|
|
||||||
mutex_lock(&chan->smd_mutex);
|
mutex_lock(&chan->smd_mutex);
|
||||||
if (!*session)
|
if (!*session)
|
||||||
err = fastrpc_session_alloc_locked(chan, secure, sharedcb, session);
|
err = fastrpc_session_alloc_locked(chan, secure, sharedcb, pd_type, session);
|
||||||
mutex_unlock(&chan->smd_mutex);
|
mutex_unlock(&chan->smd_mutex);
|
||||||
if (err == -EUSERS) {
|
if (err == -EUSERS) {
|
||||||
ADSPRPC_WARN(
|
ADSPRPC_WARN(
|
||||||
@@ -5706,6 +5818,9 @@ skip_dump_wait:
|
|||||||
fl->is_ramdump_pend = false;
|
fl->is_ramdump_pend = false;
|
||||||
fl->is_dma_invoke_pend = false;
|
fl->is_dma_invoke_pend = false;
|
||||||
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
|
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
|
||||||
|
/* Reset the tgid usage to false */
|
||||||
|
if (fl->tgid_frpc != -1)
|
||||||
|
frpc_tgid_usage_array[fl->tgid_frpc] = false;
|
||||||
is_locked = false;
|
is_locked = false;
|
||||||
spin_unlock_irqrestore(&fl->apps->hlock, irq_flags);
|
spin_unlock_irqrestore(&fl->apps->hlock, irq_flags);
|
||||||
|
|
||||||
@@ -6150,9 +6265,12 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
|
|||||||
INIT_HLIST_NODE(&fl->hn);
|
INIT_HLIST_NODE(&fl->hn);
|
||||||
fl->sessionid = 0;
|
fl->sessionid = 0;
|
||||||
fl->tgid_open = current->tgid;
|
fl->tgid_open = current->tgid;
|
||||||
|
/* PD type is not known, when device is opened */
|
||||||
|
fl->pd_type = DEFAULT_UNUSED;
|
||||||
fl->apps = me;
|
fl->apps = me;
|
||||||
fl->mode = FASTRPC_MODE_SERIAL;
|
fl->mode = FASTRPC_MODE_SERIAL;
|
||||||
fl->cid = -1;
|
fl->cid = -1;
|
||||||
|
fl->tgid_frpc = -1;
|
||||||
fl->dev_minor = dev_minor;
|
fl->dev_minor = dev_minor;
|
||||||
fl->init_mem = NULL;
|
fl->init_mem = NULL;
|
||||||
fl->qos_request = 0;
|
fl->qos_request = 0;
|
||||||
@@ -6163,10 +6281,13 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
|
|||||||
fl->is_compat = false;
|
fl->is_compat = false;
|
||||||
fl->exit_notif = false;
|
fl->exit_notif = false;
|
||||||
fl->exit_async = false;
|
fl->exit_async = false;
|
||||||
|
fl->multi_session_support = false;
|
||||||
|
fl->set_session_info = false;
|
||||||
init_completion(&fl->work);
|
init_completion(&fl->work);
|
||||||
init_completion(&fl->dma_invoke);
|
init_completion(&fl->dma_invoke);
|
||||||
fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE;
|
fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE;
|
||||||
filp->private_data = fl;
|
filp->private_data = fl;
|
||||||
|
fl->sharedbuf_info.buf_fd = -1;
|
||||||
mutex_init(&fl->internal_map_mutex);
|
mutex_init(&fl->internal_map_mutex);
|
||||||
mutex_init(&fl->map_mutex);
|
mutex_init(&fl->map_mutex);
|
||||||
spin_lock_irqsave(&me->hlock, irq_flags);
|
spin_lock_irqsave(&me->hlock, irq_flags);
|
||||||
@@ -6210,6 +6331,25 @@ bail:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a unique process ID to DSP process
|
||||||
|
static int get_unique_hlos_process_id(void)
|
||||||
|
{
|
||||||
|
int tgid_frpc = -1, tgid_index = 1;
|
||||||
|
struct fastrpc_apps *me = &gfa;
|
||||||
|
|
||||||
|
spin_lock(&me->hlock);
|
||||||
|
for (tgid_index = 1; tgid_index < MAX_FRPC_TGID; tgid_index++) {
|
||||||
|
if (!frpc_tgid_usage_array[tgid_index]) {
|
||||||
|
tgid_frpc = tgid_index;
|
||||||
|
/* Set the tgid usage to false */
|
||||||
|
frpc_tgid_usage_array[tgid_index] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&me->hlock);
|
||||||
|
return tgid_frpc;
|
||||||
|
}
|
||||||
|
|
||||||
static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid)
|
static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid)
|
||||||
{
|
{
|
||||||
int err = 0, buf_size = 0;
|
int err = 0, buf_size = 0;
|
||||||
@@ -6219,6 +6359,13 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid)
|
|||||||
memcpy(cur_comm, current->comm, TASK_COMM_LEN);
|
memcpy(cur_comm, current->comm, TASK_COMM_LEN);
|
||||||
cur_comm[TASK_COMM_LEN-1] = '\0';
|
cur_comm[TASK_COMM_LEN-1] = '\0';
|
||||||
fl->tgid = current->tgid;
|
fl->tgid = current->tgid;
|
||||||
|
fl->tgid_frpc = get_unique_hlos_process_id();
|
||||||
|
VERIFY(err, fl->tgid_frpc != -1);
|
||||||
|
if (err) {
|
||||||
|
ADSPRPC_ERR("too many fastrpc clients, max %u allowed\n", MAX_FRPC_TGID);
|
||||||
|
err = -EUSERS;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Third-party apps don't have permission to open the fastrpc device, so
|
* Third-party apps don't have permission to open the fastrpc device, so
|
||||||
@@ -6251,8 +6398,12 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid)
|
|||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d",
|
/*
|
||||||
cur_comm, "_", current->pid, "_", cid);
|
* Use HLOS PID, unique fastrpc PID, CID in debugfs filename,
|
||||||
|
* for better ability to debug.
|
||||||
|
*/
|
||||||
|
snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d%s%d",
|
||||||
|
cur_comm, "_", current->pid, "_", fl->tgid_frpc, "_", cid);
|
||||||
fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
|
fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
|
||||||
debugfs_root, fl, &debugfs_fops);
|
debugfs_root, fl, &debugfs_fops);
|
||||||
if (IS_ERR_OR_NULL(fl->debugfs_file)) {
|
if (IS_ERR_OR_NULL(fl->debugfs_file)) {
|
||||||
@@ -6278,6 +6429,21 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
|
|||||||
err = -EBADF;
|
err = -EBADF;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
spin_lock(&fl->hlock);
|
||||||
|
if (fl->set_session_info) {
|
||||||
|
spin_unlock(&fl->hlock);
|
||||||
|
ADSPRPC_ERR("Set session info invoked multiple times\n");
|
||||||
|
err = -EBADR;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
// Set set_session_info to true
|
||||||
|
fl->set_session_info = true;
|
||||||
|
spin_unlock(&fl->hlock);
|
||||||
|
VERIFY(err, VALID_FASTRPC_CID(cid));
|
||||||
|
if (err) {
|
||||||
|
err = -ECHRNG;
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
fastrpc_get_process_gids(&fl->gidlist);
|
fastrpc_get_process_gids(&fl->gidlist);
|
||||||
err = fastrpc_set_process_info(fl, cid);
|
err = fastrpc_set_process_info(fl, cid);
|
||||||
@@ -6315,7 +6481,7 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
|
|||||||
fl->ssrcount = fl->apps->channel[cid].ssrcount;
|
fl->ssrcount = fl->apps->channel[cid].ssrcount;
|
||||||
mutex_lock(&fl->apps->channel[cid].smd_mutex);
|
mutex_lock(&fl->apps->channel[cid].smd_mutex);
|
||||||
err = fastrpc_session_alloc_locked(&fl->apps->channel[cid],
|
err = fastrpc_session_alloc_locked(&fl->apps->channel[cid],
|
||||||
0, fl->sharedcb, &fl->sctx);
|
0, fl->sharedcb, fl->pd_type, &fl->sctx);
|
||||||
mutex_unlock(&fl->apps->channel[cid].smd_mutex);
|
mutex_unlock(&fl->apps->channel[cid].smd_mutex);
|
||||||
if (err == -EUSERS) {
|
if (err == -EUSERS) {
|
||||||
ADSPRPC_WARN(
|
ADSPRPC_WARN(
|
||||||
@@ -6372,7 +6538,6 @@ int fastrpc_internal_control(struct fastrpc_file *fl,
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned int latency;
|
unsigned int latency;
|
||||||
struct fastrpc_apps *me = &gfa;
|
struct fastrpc_apps *me = &gfa;
|
||||||
int sessionid = 0;
|
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
|
||||||
@@ -6468,9 +6633,7 @@ int fastrpc_internal_control(struct fastrpc_file *fl,
|
|||||||
break;
|
break;
|
||||||
case FASTRPC_CONTROL_DSPPROCESS_CLEAN:
|
case FASTRPC_CONTROL_DSPPROCESS_CLEAN:
|
||||||
(void)fastrpc_release_current_dsp_process(fl);
|
(void)fastrpc_release_current_dsp_process(fl);
|
||||||
if (fl->tgid & SESSION_ID_MASK)
|
fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, fl->sessionid);
|
||||||
sessionid = 1;
|
|
||||||
fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, sessionid);
|
|
||||||
break;
|
break;
|
||||||
case FASTRPC_CONTROL_RPC_POLL:
|
case FASTRPC_CONTROL_RPC_POLL:
|
||||||
err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency);
|
err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency);
|
||||||
@@ -6547,8 +6710,8 @@ int fastrpc_setmode(unsigned long ioctl_param,
|
|||||||
"multiple sessions not allowed for untrusted apps\n");
|
"multiple sessions not allowed for untrusted apps\n");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
fl->sessionid = 1;
|
if (!fl->multi_session_support)
|
||||||
fl->tgid |= SESSION_ID_MASK;
|
fl->sessionid = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -ENOTTY;
|
err = -ENOTTY;
|
||||||
@@ -6619,8 +6782,9 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl,
|
|||||||
// track outgoing signals in the driver. The userspace library does a
|
// track outgoing signals in the driver. The userspace library does a
|
||||||
// basic sanity check and any security validation needs to be done by
|
// basic sanity check and any security validation needs to be done by
|
||||||
// the recipient.
|
// the recipient.
|
||||||
DSPSIGNAL_VERBOSE("Send signal PID %u, signal %u\n",
|
DSPSIGNAL_VERBOSE("Send signal PID %u, unique fastrpc pid %u signal %u\n",
|
||||||
(unsigned int)fl->tgid, (unsigned int)sig->signal_id);
|
(unsigned int)fl->tgid, (unsigned int)fl->tgid_frpc,
|
||||||
|
(unsigned int)sig->signal_id);
|
||||||
VERIFY(err, sig->signal_id < DSPSIGNAL_NUM_SIGNALS);
|
VERIFY(err, sig->signal_id < DSPSIGNAL_NUM_SIGNALS);
|
||||||
if (err) {
|
if (err) {
|
||||||
ADSPRPC_ERR("Sending bad signal %u for PID %u",
|
ADSPRPC_ERR("Sending bad signal %u for PID %u",
|
||||||
@@ -6644,7 +6808,8 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl,
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = (((uint64_t)fl->tgid) << 32) | ((uint64_t)sig->signal_id);
|
/* Use unique fastrpc pid, to signal DSP process */
|
||||||
|
msg = (((uint64_t)fl->tgid_frpc) << 32) | ((uint64_t)sig->signal_id);
|
||||||
err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->trusted_vm);
|
err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->trusted_vm);
|
||||||
mutex_unlock(&channel_ctx->smd_mutex);
|
mutex_unlock(&channel_ctx->smd_mutex);
|
||||||
|
|
||||||
@@ -7724,6 +7889,14 @@ static int fastrpc_cb_probe(struct device *dev)
|
|||||||
me->max_size_limit = (dma_addr_pool[1] == 0 ? 0x78000000 :
|
me->max_size_limit = (dma_addr_pool[1] == 0 ? 0x78000000 :
|
||||||
dma_addr_pool[1]);
|
dma_addr_pool[1]);
|
||||||
|
|
||||||
|
if (of_get_property(dev->of_node, "pd-type", NULL) != NULL) {
|
||||||
|
err = of_property_read_u32(dev->of_node, "pd-type",
|
||||||
|
&(sess->smmu.pd_type));
|
||||||
|
/* Set cb_pd_type, if the process type is set for context banks */
|
||||||
|
me->cb_pd_type = true;
|
||||||
|
if (err)
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
if (of_get_property(dev->of_node, "shared-cb", NULL) != NULL) {
|
if (of_get_property(dev->of_node, "shared-cb", NULL) != NULL) {
|
||||||
sess->smmu.sharedcb = 1;
|
sess->smmu.sharedcb = 1;
|
||||||
err = of_property_read_u32(dev->of_node, "shared-cb",
|
err = of_property_read_u32(dev->of_node, "shared-cb",
|
||||||
@@ -8056,6 +8229,8 @@ static int fastrpc_probe(struct platform_device *pdev)
|
|||||||
me->lowest_capacity_core_count = 1;
|
me->lowest_capacity_core_count = 1;
|
||||||
of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
|
of_property_read_u32(dev->of_node, "qcom,rpc-latency-us",
|
||||||
&me->latency);
|
&me->latency);
|
||||||
|
of_property_read_u32(dev->of_node, "qcom,max-sessions",
|
||||||
|
&me->max_sess_per_proc);
|
||||||
if (of_get_property(dev->of_node,
|
if (of_get_property(dev->of_node,
|
||||||
"qcom,secure-domains", NULL) != NULL) {
|
"qcom,secure-domains", NULL) != NULL) {
|
||||||
VERIFY(err, !of_property_read_u32(dev->of_node,
|
VERIFY(err, !of_property_read_u32(dev->of_node,
|
||||||
@@ -8472,17 +8647,24 @@ static int fastrpc_device_create(struct fastrpc_file *fl)
|
|||||||
frpc_dev->dev.parent = &fastrpc_bus;
|
frpc_dev->dev.parent = &fastrpc_bus;
|
||||||
frpc_dev->dev.bus = &fastrpc_bus_type;
|
frpc_dev->dev.bus = &fastrpc_bus_type;
|
||||||
|
|
||||||
dev_set_name(&frpc_dev->dev, "%s-%d-%d",
|
/*
|
||||||
dev_name(frpc_dev->dev.parent), fl->tgid, fl->cid);
|
* Use HLOS PID, unique fastrpc process ID and CID to create device file,
|
||||||
|
* Else names would conflict for multiple sessions
|
||||||
|
* And also for better ability to debug
|
||||||
|
*/
|
||||||
|
dev_set_name(&frpc_dev->dev, "%s-%d-%d-%d",
|
||||||
|
dev_name(frpc_dev->dev.parent), fl->tgid, fl->tgid_frpc, fl->cid);
|
||||||
frpc_dev->dev.release = fastrpc_dev_release;
|
frpc_dev->dev.release = fastrpc_dev_release;
|
||||||
frpc_dev->fl = fl;
|
frpc_dev->fl = fl;
|
||||||
frpc_dev->handle = fl->tgid;
|
/* Use unique fastrpc tgid as handle */
|
||||||
|
frpc_dev->handle = fl->tgid_frpc;
|
||||||
|
|
||||||
err = device_register(&frpc_dev->dev);
|
err = device_register(&frpc_dev->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
put_device(&frpc_dev->dev);
|
put_device(&frpc_dev->dev);
|
||||||
ADSPRPC_ERR("fastrpc device register failed for process %d with error %d\n",
|
ADSPRPC_ERR(
|
||||||
fl->tgid, err);
|
"fastrpc device register failed for process %d unique fastrpc tgid %d session %d with error %d\n",
|
||||||
|
fl->tgid, fl->tgid_frpc, fl->sessionid, err);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
fl->device = frpc_dev;
|
fl->device = frpc_dev;
|
||||||
|
|||||||
@@ -120,6 +120,9 @@
|
|||||||
#define NUM_CHANNELS (MAX_DOMAIN_ID + 1) /* adsp, mdsp, slpi, cdsp, cdsp1, gpdsp, gpdsp1*/
|
#define NUM_CHANNELS (MAX_DOMAIN_ID + 1) /* adsp, mdsp, slpi, cdsp, cdsp1, gpdsp, gpdsp1*/
|
||||||
#define NUM_SESSIONS 13 /* max 12 compute, 1 cpz */
|
#define NUM_SESSIONS 13 /* max 12 compute, 1 cpz */
|
||||||
|
|
||||||
|
/* Default maximum sessions allowed per process */
|
||||||
|
#define DEFAULT_MAX_SESS_PER_PROC 4
|
||||||
|
|
||||||
#define RH_CID ADSP_DOMAIN_ID
|
#define RH_CID ADSP_DOMAIN_ID
|
||||||
|
|
||||||
#define VALID_FASTRPC_CID(cid) \
|
#define VALID_FASTRPC_CID(cid) \
|
||||||
@@ -213,6 +216,15 @@ struct remote_buf {
|
|||||||
size_t len; /* length of buffer */
|
size_t len; /* length of buffer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* structure to hold fd and size of buffer shared with DSP,
|
||||||
|
* which contains initial debug parameters that needs to be passed
|
||||||
|
* during process initialization.
|
||||||
|
*/
|
||||||
|
struct fastrpc_proc_sharedbuf_info {
|
||||||
|
int buf_fd;
|
||||||
|
int buf_size;
|
||||||
|
};
|
||||||
|
|
||||||
struct remote_dma_handle {
|
struct remote_dma_handle {
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
@@ -296,6 +308,14 @@ struct fastrpc_ioctl_notif_rsp {
|
|||||||
uint32_t status; /* Status of the process */
|
uint32_t status; /* Status of the process */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* FastRPC ioctl structure to set session related info */
|
||||||
|
struct fastrpc_proc_sess_info {
|
||||||
|
uint32_t domain_id; /* Set the remote subsystem, Domain ID of the session */
|
||||||
|
uint32_t session_id; /* Unused, Set the Session ID on remote subsystem */
|
||||||
|
uint32_t pd_type; /* Set the process type on remote subsystem */
|
||||||
|
uint32_t sharedcb; /* Unused, Session can share context bank with other sessions */
|
||||||
|
};
|
||||||
|
|
||||||
/* INIT a new process or attach to guestos */
|
/* INIT a new process or attach to guestos */
|
||||||
enum fastrpc_init_flags {
|
enum fastrpc_init_flags {
|
||||||
FASTRPC_INIT_NO_CREATE = -1,
|
FASTRPC_INIT_NO_CREATE = -1,
|
||||||
@@ -310,6 +330,9 @@ enum fastrpc_invoke2_type {
|
|||||||
FASTRPC_INVOKE2_ASYNC_RESPONSE = 2,
|
FASTRPC_INVOKE2_ASYNC_RESPONSE = 2,
|
||||||
FASTRPC_INVOKE2_KERNEL_OPTIMIZATIONS,
|
FASTRPC_INVOKE2_KERNEL_OPTIMIZATIONS,
|
||||||
FASTRPC_INVOKE2_STATUS_NOTIF,
|
FASTRPC_INVOKE2_STATUS_NOTIF,
|
||||||
|
FASTRPC_INVOKE2_PROC_SHAREDBUF_INFO,
|
||||||
|
/* Set session info of remote sub system */
|
||||||
|
FASTRPC_INVOKE2_SESS_INFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fastrpc_ioctl_invoke2 {
|
struct fastrpc_ioctl_invoke2 {
|
||||||
@@ -710,6 +733,21 @@ struct gid_list {
|
|||||||
unsigned int gidcount;
|
unsigned int gidcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process types on remote subsystem
|
||||||
|
* Always add new PD types at the end, before MAX_PD_TYPE
|
||||||
|
*/
|
||||||
|
#define DEFAULT_UNUSED 0 /* pd type not configured for context banks */
|
||||||
|
#define ROOT_PD 1 /* Root PD */
|
||||||
|
#define AUDIO_STATICPD 2 /* ADSP Audio Static PD */
|
||||||
|
#define SENSORS_STATICPD 3 /* ADSP Sensors Static PD */
|
||||||
|
#define SECURE_STATICPD 4 /* CDSP Secure Static PD */
|
||||||
|
#define OIS_STATICPD 5 /* ADSP OIS Static PD */
|
||||||
|
#define CPZ_USERPD 6 /* CDSP CPZ USER PD */
|
||||||
|
#define USERPD 7 /* DSP User Dynamic PD */
|
||||||
|
#define GUEST_OS_SHARED 8 /* Legacy Guest OS Shared */
|
||||||
|
#define MAX_PD_TYPE 9 /* Max PD type */
|
||||||
|
|
||||||
struct fastrpc_file;
|
struct fastrpc_file;
|
||||||
|
|
||||||
struct fastrpc_buf {
|
struct fastrpc_buf {
|
||||||
@@ -850,6 +888,8 @@ struct fastrpc_smmu {
|
|||||||
int secure;
|
int secure;
|
||||||
int coherent;
|
int coherent;
|
||||||
int sharedcb;
|
int sharedcb;
|
||||||
|
/* Process type on remote sub system */
|
||||||
|
int pd_type;
|
||||||
/* gen pool for QRTR */
|
/* gen pool for QRTR */
|
||||||
struct gen_pool *frpc_genpool;
|
struct gen_pool *frpc_genpool;
|
||||||
/* fastrpc gen pool buffer */
|
/* fastrpc gen pool buffer */
|
||||||
@@ -956,6 +996,10 @@ struct fastrpc_apps {
|
|||||||
unsigned int lowest_capacity_core_count;
|
unsigned int lowest_capacity_core_count;
|
||||||
/* Flag to check if PM QoS vote needs to be done for only one core */
|
/* Flag to check if PM QoS vote needs to be done for only one core */
|
||||||
bool single_core_latency_vote;
|
bool single_core_latency_vote;
|
||||||
|
/* Indicates process type is configured for SMMU context bank */
|
||||||
|
bool cb_pd_type;
|
||||||
|
/* Maximum sessions allowed to be created per process */
|
||||||
|
uint32_t max_sess_per_proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fastrpc_mmap {
|
struct fastrpc_mmap {
|
||||||
@@ -1056,6 +1100,8 @@ struct fastrpc_file {
|
|||||||
int sessionid;
|
int sessionid;
|
||||||
int tgid_open; /* Process ID during device open */
|
int tgid_open; /* Process ID during device open */
|
||||||
int tgid; /* Process ID that uses device for RPC calls */
|
int tgid; /* Process ID that uses device for RPC calls */
|
||||||
|
/* Unique HLOS process ID created by fastrpc for each client */
|
||||||
|
int tgid_frpc;
|
||||||
int cid;
|
int cid;
|
||||||
bool trusted_vm;
|
bool trusted_vm;
|
||||||
uint64_t ssrcount;
|
uint64_t ssrcount;
|
||||||
@@ -1064,6 +1110,8 @@ struct fastrpc_file {
|
|||||||
int file_close;
|
int file_close;
|
||||||
int dsp_proc_init;
|
int dsp_proc_init;
|
||||||
int sharedcb;
|
int sharedcb;
|
||||||
|
/* Process type on remote sub system */
|
||||||
|
int pd_type;
|
||||||
struct fastrpc_apps *apps;
|
struct fastrpc_apps *apps;
|
||||||
struct dentry *debugfs_file;
|
struct dentry *debugfs_file;
|
||||||
struct dev_pm_qos_request *dev_pm_qos_req;
|
struct dev_pm_qos_request *dev_pm_qos_req;
|
||||||
@@ -1119,6 +1167,16 @@ struct fastrpc_file {
|
|||||||
bool exit_notif;
|
bool exit_notif;
|
||||||
/* Flag to indicate async thread exit requested*/
|
/* Flag to indicate async thread exit requested*/
|
||||||
bool exit_async;
|
bool exit_async;
|
||||||
|
/*
|
||||||
|
* structure to hold fd and size of buffer shared with DSP,
|
||||||
|
* which contains initial debug configurations and other initial
|
||||||
|
* config parameters.
|
||||||
|
*/
|
||||||
|
struct fastrpc_proc_sharedbuf_info sharedbuf_info;
|
||||||
|
/* Flag to indicate 4 session support available */
|
||||||
|
bool multi_session_support;
|
||||||
|
/* Flag to indicate session info is set */
|
||||||
|
bool set_session_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
union fastrpc_ioctl_param {
|
union fastrpc_ioctl_param {
|
||||||
|
|||||||
@@ -460,13 +460,6 @@ config SC_VIDEOCC_7280
|
|||||||
Say Y if you want to support video devices and functionality such as
|
Say Y if you want to support video devices and functionality such as
|
||||||
video encode and decode.
|
video encode and decode.
|
||||||
|
|
||||||
config SDM_CAMCC_845
|
|
||||||
tristate "SDM845 Camera Clock Controller"
|
|
||||||
select SDM_GCC_845
|
|
||||||
help
|
|
||||||
Support for the camera clock controller on SDM845 devices.
|
|
||||||
Say Y if you want to support camera devices and camera functionality.
|
|
||||||
|
|
||||||
config SDM_GCC_660
|
config SDM_GCC_660
|
||||||
tristate "SDM660 Global Clock Controller"
|
tristate "SDM660 Global Clock Controller"
|
||||||
select QCOM_GDSC
|
select QCOM_GDSC
|
||||||
@@ -507,9 +500,18 @@ config QCS_Q6SSTOP_404
|
|||||||
Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock
|
Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock
|
||||||
controller to reset the Q6SSTOP subsystem.
|
controller to reset the Q6SSTOP subsystem.
|
||||||
|
|
||||||
|
config SDM_CAMCC_845
|
||||||
|
tristate "SDM845 Camera Clock Controller"
|
||||||
|
select SDM_GCC_845
|
||||||
|
help
|
||||||
|
Support for the camera clock controller on Qualcomm Technologies, Inc
|
||||||
|
SDM845 devices.
|
||||||
|
Say Y if you want to support camera devices and functionality such as
|
||||||
|
capturing pictures.
|
||||||
|
|
||||||
config SDM_GCC_845
|
config SDM_GCC_845
|
||||||
tristate "SDM845 Global Clock Controller"
|
tristate "SDM845 Global Clock Controller"
|
||||||
select QCOM_GDSC
|
depends on COMMON_CLK_QCOM
|
||||||
help
|
help
|
||||||
Support for the global clock controller on SDM845 devices.
|
Support for the global clock controller on SDM845 devices.
|
||||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,42 @@ static struct measure_clk_data debug_mux_priv = {
|
|||||||
.xo_div4_cbcr = 0x28008,
|
.xo_div4_cbcr = 0x28008,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *const cpu_cc_debug_mux_parent_names[] = {
|
||||||
|
"pwrcl_clk",
|
||||||
|
"perfcl_clk",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int apss_cc_debug_mux_pre_divs[] = {
|
||||||
|
0x8, /* pwrcl_clk */
|
||||||
|
0x8, /* perfcl_clk */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cpu_cc_debug_mux_sels[] = {
|
||||||
|
0x0, /* pwrcl_clk */
|
||||||
|
0x1, /* perfcl_clk */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_debug_mux cpu_cc_debug_mux = {
|
||||||
|
.priv = &debug_mux_priv,
|
||||||
|
.debug_offset = 0x0,
|
||||||
|
.post_div_offset = 0x0,
|
||||||
|
.cbcr_offset = U32_MAX,
|
||||||
|
.src_sel_mask = 0x3FF,
|
||||||
|
.src_sel_shift = 8,
|
||||||
|
.post_div_mask = 0xF,
|
||||||
|
.post_div_shift = 28,
|
||||||
|
.post_div_val = 1,
|
||||||
|
.pre_div_vals = apss_cc_debug_mux_pre_divs,
|
||||||
|
.mux_sels = cpu_cc_debug_mux_sels,
|
||||||
|
.num_mux_sels = ARRAY_SIZE(cpu_cc_debug_mux_sels),
|
||||||
|
.hw.init = &(const struct clk_init_data){
|
||||||
|
.name = "cpu_cc_debug_mux",
|
||||||
|
.ops = &clk_debug_mux_ops,
|
||||||
|
.parent_names = cpu_cc_debug_mux_parent_names,
|
||||||
|
.num_parents = ARRAY_SIZE(cpu_cc_debug_mux_parent_names),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static const char *const disp_cc_debug_mux_parent_names[] = {
|
static const char *const disp_cc_debug_mux_parent_names[] = {
|
||||||
"disp_cc_mdss_ahb_clk",
|
"disp_cc_mdss_ahb_clk",
|
||||||
"disp_cc_mdss_byte0_clk",
|
"disp_cc_mdss_byte0_clk",
|
||||||
@@ -235,6 +271,7 @@ static const char *const gcc_debug_mux_parent_names[] = {
|
|||||||
"measure_only_ipa_2x_clk",
|
"measure_only_ipa_2x_clk",
|
||||||
"measure_only_snoc_clk",
|
"measure_only_snoc_clk",
|
||||||
"video_cc_debug_mux",
|
"video_cc_debug_mux",
|
||||||
|
"cpu_cc_debug_mux",
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gcc_debug_mux_sels[] = {
|
static int gcc_debug_mux_sels[] = {
|
||||||
@@ -389,6 +426,7 @@ static int gcc_debug_mux_sels[] = {
|
|||||||
0xC2, /* measure_only_ipa_2x_clk */
|
0xC2, /* measure_only_ipa_2x_clk */
|
||||||
0x7, /* measure_only_snoc_clk */
|
0x7, /* measure_only_snoc_clk */
|
||||||
0x42, /* video_cc_debug_mux */
|
0x42, /* video_cc_debug_mux */
|
||||||
|
0xAB, /* cpu_cc_debug_mux */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_debug_mux gcc_debug_mux = {
|
static struct clk_debug_mux gcc_debug_mux = {
|
||||||
@@ -520,11 +558,28 @@ static struct clk_debug_mux mc_cc_debug_mux = {
|
|||||||
static struct mux_regmap_names mux_list[] = {
|
static struct mux_regmap_names mux_list[] = {
|
||||||
{ .mux = &mc_cc_debug_mux, .regmap_name = "qcom,mccc" },
|
{ .mux = &mc_cc_debug_mux, .regmap_name = "qcom,mccc" },
|
||||||
{ .mux = &video_cc_debug_mux, .regmap_name = "qcom,videocc" },
|
{ .mux = &video_cc_debug_mux, .regmap_name = "qcom,videocc" },
|
||||||
|
{ .mux = &cpu_cc_debug_mux, .regmap_name = "qcom,cpucc" },
|
||||||
{ .mux = &gpu_cc_debug_mux, .regmap_name = "qcom,gpucc" },
|
{ .mux = &gpu_cc_debug_mux, .regmap_name = "qcom,gpucc" },
|
||||||
{ .mux = &disp_cc_debug_mux, .regmap_name = "qcom,dispcc" },
|
{ .mux = &disp_cc_debug_mux, .regmap_name = "qcom,dispcc" },
|
||||||
{ .mux = &gcc_debug_mux, .regmap_name = "qcom,gcc" },
|
{ .mux = &gcc_debug_mux, .regmap_name = "qcom,gcc" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct clk_dummy perfcl_clk = {
|
||||||
|
.rrate = 1000,
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "perfcl_clk",
|
||||||
|
.ops = &clk_dummy_ops,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_dummy pwrcl_clk = {
|
||||||
|
.rrate = 1000,
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "pwrcl_clk",
|
||||||
|
.ops = &clk_dummy_ops,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct clk_dummy measure_only_mccc_clk = {
|
static struct clk_dummy measure_only_mccc_clk = {
|
||||||
.rrate = 1000,
|
.rrate = 1000,
|
||||||
.hw.init = &(struct clk_init_data){
|
.hw.init = &(struct clk_init_data){
|
||||||
@@ -562,6 +617,8 @@ static struct clk_hw *debugcc_trinket_hws[] = {
|
|||||||
&measure_only_ipa_2x_clk.hw,
|
&measure_only_ipa_2x_clk.hw,
|
||||||
&measure_only_mccc_clk.hw,
|
&measure_only_mccc_clk.hw,
|
||||||
&measure_only_snoc_clk.hw,
|
&measure_only_snoc_clk.hw,
|
||||||
|
&perfcl_clk.hw,
|
||||||
|
&pwrcl_clk.hw,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id clk_debug_match_table[] = {
|
static const struct of_device_id clk_debug_match_table[] = {
|
||||||
@@ -581,6 +638,8 @@ static int clk_debug_trinket_probe(struct platform_device *pdev)
|
|||||||
ARRAY_SIZE(gpu_cc_debug_mux_sels));
|
ARRAY_SIZE(gpu_cc_debug_mux_sels));
|
||||||
BUILD_BUG_ON(ARRAY_SIZE(video_cc_debug_mux_parent_names) !=
|
BUILD_BUG_ON(ARRAY_SIZE(video_cc_debug_mux_parent_names) !=
|
||||||
ARRAY_SIZE(video_cc_debug_mux_sels));
|
ARRAY_SIZE(video_cc_debug_mux_sels));
|
||||||
|
BUILD_BUG_ON(ARRAY_SIZE(cpu_cc_debug_mux_parent_names) !=
|
||||||
|
ARRAY_SIZE(cpu_cc_debug_mux_sels));
|
||||||
|
|
||||||
clk = devm_clk_get(&pdev->dev, "xo_clk_src");
|
clk = devm_clk_get(&pdev->dev, "xo_clk_src");
|
||||||
if (IS_ERR(clk)) {
|
if (IS_ERR(clk)) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
@@ -19,6 +20,13 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "gdsc.h"
|
#include "gdsc.h"
|
||||||
#include "reset.h"
|
#include "reset.h"
|
||||||
|
#include "vdd-level-sdm845.h"
|
||||||
|
|
||||||
|
static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner);
|
||||||
|
|
||||||
|
static struct clk_vdd_class *disp_cc_sdm845_regulators[] = {
|
||||||
|
&vdd_cx,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
P_BI_TCXO,
|
P_BI_TCXO,
|
||||||
@@ -33,18 +41,34 @@ enum {
|
|||||||
P_DP_PHY_PLL_VCO_DIV_CLK,
|
P_DP_PHY_PLL_VCO_DIV_CLK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct pll_vco fabia_vco[] = {
|
||||||
|
{ 249600000, 2000000000, 0 },
|
||||||
|
{ 125000000, 1000000000, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
static struct clk_alpha_pll disp_cc_pll0 = {
|
static struct clk_alpha_pll disp_cc_pll0 = {
|
||||||
.offset = 0x0,
|
.offset = 0x0,
|
||||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||||
|
.vco_table = fabia_vco,
|
||||||
|
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||||
.clkr = {
|
.clkr = {
|
||||||
.hw.init = &(struct clk_init_data){
|
.hw.init = &(struct clk_init_data){
|
||||||
.name = "disp_cc_pll0",
|
.name = "disp_cc_pll0",
|
||||||
.parent_data = &(const struct clk_parent_data){
|
.parent_data = &(const struct clk_parent_data){
|
||||||
.fw_name = "bi_tcxo", .name = "bi_tcxo",
|
.fw_name = "bi_tcxo",
|
||||||
},
|
},
|
||||||
.num_parents = 1,
|
.num_parents = 1,
|
||||||
.ops = &clk_alpha_pll_fabia_ops,
|
.ops = &clk_alpha_pll_fabia_ops,
|
||||||
},
|
},
|
||||||
|
.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 615000000,
|
||||||
|
[VDD_LOW] = 1066000000,
|
||||||
|
[VDD_LOW_L1] = 1600000000,
|
||||||
|
[VDD_NOMINAL] = 2000000000 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,7 +79,7 @@ static const struct parent_map disp_cc_parent_map_0[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data disp_cc_parent_data_0[] = {
|
static const struct clk_parent_data disp_cc_parent_data_0[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
{ .fw_name = "dsi0_phy_pll_out_byteclk", .name = "dsi0_phy_pll_out_byteclk" },
|
{ .fw_name = "dsi0_phy_pll_out_byteclk", .name = "dsi0_phy_pll_out_byteclk" },
|
||||||
{ .fw_name = "dsi1_phy_pll_out_byteclk", .name = "dsi1_phy_pll_out_byteclk" },
|
{ .fw_name = "dsi1_phy_pll_out_byteclk", .name = "dsi1_phy_pll_out_byteclk" },
|
||||||
};
|
};
|
||||||
@@ -67,7 +91,7 @@ static const struct parent_map disp_cc_parent_map_1[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data disp_cc_parent_data_1[] = {
|
static const struct clk_parent_data disp_cc_parent_data_1[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
{ .fw_name = "dp_link_clk_divsel_ten", .name = "dp_link_clk_divsel_ten" },
|
{ .fw_name = "dp_link_clk_divsel_ten", .name = "dp_link_clk_divsel_ten" },
|
||||||
{ .fw_name = "dp_vco_divided_clk_src_mux", .name = "dp_vco_divided_clk_src_mux" },
|
{ .fw_name = "dp_vco_divided_clk_src_mux", .name = "dp_vco_divided_clk_src_mux" },
|
||||||
};
|
};
|
||||||
@@ -77,7 +101,7 @@ static const struct parent_map disp_cc_parent_map_2[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data disp_cc_parent_data_2[] = {
|
static const struct clk_parent_data disp_cc_parent_data_2[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct parent_map disp_cc_parent_map_3[] = {
|
static const struct parent_map disp_cc_parent_map_3[] = {
|
||||||
@@ -88,7 +112,7 @@ static const struct parent_map disp_cc_parent_map_3[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data disp_cc_parent_data_3[] = {
|
static const struct clk_parent_data disp_cc_parent_data_3[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
{ .hw = &disp_cc_pll0.clkr.hw },
|
{ .hw = &disp_cc_pll0.clkr.hw },
|
||||||
{ .fw_name = "gcc_disp_gpll0_clk_src", .name = "gcc_disp_gpll0_clk_src" },
|
{ .fw_name = "gcc_disp_gpll0_clk_src", .name = "gcc_disp_gpll0_clk_src" },
|
||||||
{ .fw_name = "gcc_disp_gpll0_div_clk_src", .name = "gcc_disp_gpll0_div_clk_src" },
|
{ .fw_name = "gcc_disp_gpll0_div_clk_src", .name = "gcc_disp_gpll0_div_clk_src" },
|
||||||
@@ -101,7 +125,7 @@ static const struct parent_map disp_cc_parent_map_4[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data disp_cc_parent_data_4[] = {
|
static const struct clk_parent_data disp_cc_parent_data_4[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
{ .fw_name = "dsi0_phy_pll_out_dsiclk", .name = "dsi0_phy_pll_out_dsiclk" },
|
{ .fw_name = "dsi0_phy_pll_out_dsiclk", .name = "dsi0_phy_pll_out_dsiclk" },
|
||||||
{ .fw_name = "dsi1_phy_pll_out_dsiclk", .name = "dsi1_phy_pll_out_dsiclk" },
|
{ .fw_name = "dsi1_phy_pll_out_dsiclk", .name = "dsi1_phy_pll_out_dsiclk" },
|
||||||
};
|
};
|
||||||
@@ -119,6 +143,16 @@ static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_byte2_ops,
|
.ops = &clk_byte2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 150000000,
|
||||||
|
[VDD_LOW] = 240000000,
|
||||||
|
[VDD_LOW_L1] = 262500000,
|
||||||
|
[VDD_NOMINAL] = 358000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the HW recalc rate for idle use case */
|
/* Return the HW recalc rate for idle use case */
|
||||||
@@ -134,6 +168,16 @@ static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_byte2_ops,
|
.ops = &clk_byte2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 150000000,
|
||||||
|
[VDD_LOW] = 240000000,
|
||||||
|
[VDD_LOW_L1] = 262500000,
|
||||||
|
[VDD_NOMINAL] = 358000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
|
static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
|
||||||
@@ -154,6 +198,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
||||||
@@ -165,8 +215,19 @@ static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
|||||||
.name = "disp_cc_mdss_dp_crypto_clk_src",
|
.name = "disp_cc_mdss_dp_crypto_clk_src",
|
||||||
.parent_data = disp_cc_parent_data_1,
|
.parent_data = disp_cc_parent_data_1,
|
||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_byte2_ops,
|
.ops = &clk_byte2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 12800000,
|
||||||
|
[VDD_LOWER] = 108000000,
|
||||||
|
[VDD_LOW] = 180000000,
|
||||||
|
[VDD_LOW_L1] = 360000000,
|
||||||
|
[VDD_NOMINAL] = 540000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
||||||
@@ -181,6 +242,16 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_byte2_ops,
|
.ops = &clk_byte2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 162000000,
|
||||||
|
[VDD_LOW] = 270000000,
|
||||||
|
[VDD_LOW_L1] = 540000000,
|
||||||
|
[VDD_NOMINAL] = 810000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
|
||||||
@@ -195,6 +266,15 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_dp_ops,
|
.ops = &clk_dp_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 202500000,
|
||||||
|
[VDD_LOW] = 296735000,
|
||||||
|
[VDD_LOW_L1] = 675000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
||||||
@@ -209,6 +289,15 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_dp_ops,
|
.ops = &clk_dp_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 202500000,
|
||||||
|
[VDD_LOW] = 296735000,
|
||||||
|
[VDD_LOW_L1] = 675000000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
|
static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
|
||||||
@@ -226,8 +315,15 @@ static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
|
|||||||
.name = "disp_cc_mdss_esc0_clk_src",
|
.name = "disp_cc_mdss_esc0_clk_src",
|
||||||
.parent_data = disp_cc_parent_data_0,
|
.parent_data = disp_cc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
|
||||||
@@ -242,15 +338,35 @@ static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
|
|||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
|
||||||
.ops = &clk_rcg2_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
|
static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
|
||||||
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
|
F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
|
||||||
|
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||||
|
F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
|
||||||
|
F(165000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
|
||||||
|
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||||
|
F(275000000, P_DISP_CC_PLL0_OUT_MAIN, 1.5, 0, 0),
|
||||||
|
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||||
|
F(412500000, P_DISP_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src_sdm670[] = {
|
||||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
|
F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0),
|
||||||
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||||
F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
|
F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
|
||||||
F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
|
F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
|
||||||
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||||
|
F(286666667, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
|
||||||
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||||
F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
|
F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
|
||||||
F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
|
F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
|
||||||
@@ -267,8 +383,18 @@ static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
|
|||||||
.name = "disp_cc_mdss_mdp_clk_src",
|
.name = "disp_cc_mdss_mdp_clk_src",
|
||||||
.parent_data = disp_cc_parent_data_3,
|
.parent_data = disp_cc_parent_data_3,
|
||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_shared_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 165000000,
|
||||||
|
[VDD_LOW] = 300000000,
|
||||||
|
[VDD_NOMINAL] = 412500000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the HW recalc rate for idle use case */
|
/* Return the HW recalc rate for idle use case */
|
||||||
@@ -284,6 +410,16 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_pixel_ops,
|
.ops = &clk_pixel_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 184000000,
|
||||||
|
[VDD_LOW] = 295000000,
|
||||||
|
[VDD_LOW_L1] = 350000000,
|
||||||
|
[VDD_NOMINAL] = 571428571 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the HW recalc rate for idle use case */
|
/* Return the HW recalc rate for idle use case */
|
||||||
@@ -299,9 +435,27 @@ static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
|
|||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_pixel_ops,
|
.ops = &clk_pixel_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 184000000,
|
||||||
|
[VDD_LOW] = 295000000,
|
||||||
|
[VDD_LOW_L1] = 350000000,
|
||||||
|
[VDD_NOMINAL] = 571428571 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
|
static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {
|
||||||
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
|
F(165000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
|
||||||
|
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||||
|
F(412500000, P_DISP_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src_sdm670[] = {
|
||||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
|
F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0),
|
||||||
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||||
@@ -320,8 +474,18 @@ static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
|
|||||||
.name = "disp_cc_mdss_rot_clk_src",
|
.name = "disp_cc_mdss_rot_clk_src",
|
||||||
.parent_data = disp_cc_parent_data_3,
|
.parent_data = disp_cc_parent_data_3,
|
||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_shared_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000,
|
||||||
|
[VDD_LOWER] = 165000000,
|
||||||
|
[VDD_LOW] = 300000000,
|
||||||
|
[VDD_NOMINAL] = 412500000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
|
static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
|
||||||
@@ -334,8 +498,15 @@ static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
|
|||||||
.name = "disp_cc_mdss_vsync_clk_src",
|
.name = "disp_cc_mdss_vsync_clk_src",
|
||||||
.parent_data = disp_cc_parent_data_2,
|
.parent_data = disp_cc_parent_data_2,
|
||||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
|
.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_ops,
|
.ops = &clk_rcg2_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 19200000 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_branch disp_cc_mdss_ahb_clk = {
|
static struct clk_branch disp_cc_mdss_ahb_clk = {
|
||||||
@@ -829,7 +1000,7 @@ static const struct regmap_config disp_cc_sdm845_regmap_config = {
|
|||||||
.fast_io = true,
|
.fast_io = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct qcom_cc_desc disp_cc_sdm845_desc = {
|
static struct qcom_cc_desc disp_cc_sdm845_desc = {
|
||||||
.config = &disp_cc_sdm845_regmap_config,
|
.config = &disp_cc_sdm845_regmap_config,
|
||||||
.clks = disp_cc_sdm845_clocks,
|
.clks = disp_cc_sdm845_clocks,
|
||||||
.num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks),
|
.num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks),
|
||||||
@@ -837,23 +1008,86 @@ static const struct qcom_cc_desc disp_cc_sdm845_desc = {
|
|||||||
.num_resets = ARRAY_SIZE(disp_cc_sdm845_resets),
|
.num_resets = ARRAY_SIZE(disp_cc_sdm845_resets),
|
||||||
.gdscs = disp_cc_sdm845_gdscs,
|
.gdscs = disp_cc_sdm845_gdscs,
|
||||||
.num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs),
|
.num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs),
|
||||||
|
.clk_regulators = disp_cc_sdm845_regulators,
|
||||||
|
.num_clk_regulators = ARRAY_SIZE(disp_cc_sdm845_regulators),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id disp_cc_sdm845_match_table[] = {
|
static const struct of_device_id disp_cc_sdm845_match_table[] = {
|
||||||
{ .compatible = "qcom,sdm845-dispcc" },
|
{ .compatible = "qcom,sdm845-dispcc" },
|
||||||
|
{ .compatible = "qcom,sdm670-dispcc" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table);
|
MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table);
|
||||||
|
|
||||||
|
static void disp_cc_sdm845_fixup_sdm670(void)
|
||||||
|
{
|
||||||
|
disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
180000000;
|
||||||
|
disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
275000000;
|
||||||
|
disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
358000000;
|
||||||
|
disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
180000000;
|
||||||
|
disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
275000000;
|
||||||
|
disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
358000000;
|
||||||
|
disp_cc_mdss_dp_pixel1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
337500000;
|
||||||
|
disp_cc_mdss_dp_pixel_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
337500000;
|
||||||
|
disp_cc_mdss_mdp_clk_src.freq_tbl =
|
||||||
|
ftbl_disp_cc_mdss_mdp_clk_src_sdm670;
|
||||||
|
disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
171428571;
|
||||||
|
disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
344000000;
|
||||||
|
disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] =
|
||||||
|
430000000;
|
||||||
|
disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
280000000;
|
||||||
|
disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
430000000;
|
||||||
|
disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
430000000;
|
||||||
|
disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
280000000;
|
||||||
|
disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] =
|
||||||
|
430000000;
|
||||||
|
disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
430000000;
|
||||||
|
disp_cc_mdss_rot_clk_src.freq_tbl =
|
||||||
|
ftbl_disp_cc_mdss_rot_clk_src_sdm670;
|
||||||
|
disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] =
|
||||||
|
171428571;
|
||||||
|
disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
344000000;
|
||||||
|
disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] =
|
||||||
|
430000000;
|
||||||
|
}
|
||||||
|
|
||||||
static int disp_cc_sdm845_probe(struct platform_device *pdev)
|
static int disp_cc_sdm845_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct alpha_pll_config disp_cc_pll0_config = {};
|
struct alpha_pll_config disp_cc_pll0_config = {};
|
||||||
|
int ret;
|
||||||
|
bool sdm670;
|
||||||
|
|
||||||
|
sdm670 = of_device_is_compatible(pdev->dev.of_node,
|
||||||
|
"qcom,sdm670-dispcc");
|
||||||
|
|
||||||
regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc);
|
regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc);
|
||||||
if (IS_ERR(regmap))
|
if (IS_ERR(regmap))
|
||||||
return PTR_ERR(regmap);
|
return PTR_ERR(regmap);
|
||||||
|
|
||||||
|
if (sdm670)
|
||||||
|
disp_cc_sdm845_fixup_sdm670();
|
||||||
|
|
||||||
|
disp_cc_sdm845_desc.gdscs = NULL;
|
||||||
|
disp_cc_sdm845_desc.num_gdscs = 0;
|
||||||
|
|
||||||
|
/* 960 MHz Configuration*/
|
||||||
disp_cc_pll0_config.l = 0x2c;
|
disp_cc_pll0_config.l = 0x2c;
|
||||||
disp_cc_pll0_config.alpha = 0xcaaa;
|
disp_cc_pll0_config.alpha = 0xcaaa;
|
||||||
|
|
||||||
@@ -862,7 +1096,19 @@ static int disp_cc_sdm845_probe(struct platform_device *pdev)
|
|||||||
/* Enable hardware clock gating for DSI and MDP clocks */
|
/* Enable hardware clock gating for DSI and MDP clocks */
|
||||||
regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
|
regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
|
||||||
|
|
||||||
return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap);
|
ret = qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Failed to register Display CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Registered Display CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disp_cc_sdm845_sync_state(struct device *dev)
|
||||||
|
{
|
||||||
|
qcom_cc_sync_state(dev, &disp_cc_sdm845_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver disp_cc_sdm845_driver = {
|
static struct platform_driver disp_cc_sdm845_driver = {
|
||||||
@@ -870,7 +1116,7 @@ static struct platform_driver disp_cc_sdm845_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "disp_cc-sdm845",
|
.name = "disp_cc-sdm845",
|
||||||
.of_match_table = disp_cc_sdm845_match_table,
|
.of_match_table = disp_cc_sdm845_match_table,
|
||||||
.sync_state = clk_sync_state,
|
.sync_state = disp_cc_sdm845_sync_state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -567,6 +567,7 @@ static const struct qcom_reset_map gpu_cc_crow_resets[] = {
|
|||||||
[GPUCC_GPU_CC_GX_BCR] = { 0x9058 },
|
[GPUCC_GPU_CC_GX_BCR] = { 0x9058 },
|
||||||
[GPUCC_GPU_CC_RBCPR_BCR] = { 0x91e0 },
|
[GPUCC_GPU_CC_RBCPR_BCR] = { 0x91e0 },
|
||||||
[GPUCC_GPU_CC_XO_BCR] = { 0x9000 },
|
[GPUCC_GPU_CC_XO_BCR] = { 0x9000 },
|
||||||
|
[GPUCC_GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR] = { 0x9538 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regmap_config gpu_cc_crow_regmap_config = {
|
static const struct regmap_config gpu_cc_crow_regmap_config = {
|
||||||
@@ -605,6 +606,9 @@ static int gpu_cc_crow_probe(struct platform_device *pdev)
|
|||||||
clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
|
clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
|
||||||
clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
|
clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
|
||||||
|
|
||||||
|
/* Enable frequency limiter irq */
|
||||||
|
regmap_write(regmap, 0x9534, 0x0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep clocks always enabled:
|
* Keep clocks always enabled:
|
||||||
* gpu_cc_cxo_aon_clk
|
* gpu_cc_cxo_aon_clk
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
@@ -17,6 +18,8 @@
|
|||||||
#include "clk-rcg.h"
|
#include "clk-rcg.h"
|
||||||
#include "clk-regmap.h"
|
#include "clk-regmap.h"
|
||||||
#include "gdsc.h"
|
#include "gdsc.h"
|
||||||
|
#include "reset.h"
|
||||||
|
#include "vdd-level-sdm845.h"
|
||||||
|
|
||||||
#define CX_GMU_CBCR_SLEEP_MASK 0xf
|
#define CX_GMU_CBCR_SLEEP_MASK 0xf
|
||||||
#define CX_GMU_CBCR_SLEEP_SHIFT 4
|
#define CX_GMU_CBCR_SLEEP_SHIFT 4
|
||||||
@@ -25,51 +28,188 @@
|
|||||||
#define CLK_DIS_WAIT_SHIFT 12
|
#define CLK_DIS_WAIT_SHIFT 12
|
||||||
#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
|
#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
|
||||||
|
|
||||||
|
static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner);
|
||||||
|
static DEFINE_VDD_REGULATORS(vdd_mx, VDD_NUM, 1, vdd_corner);
|
||||||
|
static DEFINE_VDD_REGULATORS(vdd_gfx, VDD_GX_NUM, 1, vdd_gx_corner);
|
||||||
|
|
||||||
|
static struct clk_vdd_class *gpu_cc_sdm845_regulators[] = {
|
||||||
|
&vdd_cx,
|
||||||
|
&vdd_mx,
|
||||||
|
&vdd_gfx,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
P_BI_TCXO,
|
P_BI_TCXO,
|
||||||
P_GPLL0_OUT_MAIN,
|
P_GPLL0_OUT_MAIN,
|
||||||
P_GPLL0_OUT_MAIN_DIV,
|
P_GPLL0_OUT_MAIN_DIV,
|
||||||
|
P_GPU_CC_PLL0_OUT_EVEN,
|
||||||
|
P_GPU_CC_PLL0_OUT_MAIN,
|
||||||
|
P_GPU_CC_PLL0_OUT_ODD,
|
||||||
|
P_GPU_CC_PLL1_OUT_EVEN,
|
||||||
P_GPU_CC_PLL1_OUT_MAIN,
|
P_GPU_CC_PLL1_OUT_MAIN,
|
||||||
|
P_GPU_CC_PLL1_OUT_ODD,
|
||||||
|
P_CRC_DIV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct alpha_pll_config gpu_cc_pll1_config = {
|
static struct pll_vco fabia_vco[] = {
|
||||||
.l = 0x1a,
|
{ 249600000, 2000000000, 0 },
|
||||||
.alpha = 0xaab,
|
{ 125000000, 1000000000, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_alpha_pll gpu_cc_pll0 = {
|
||||||
|
.offset = 0x0,
|
||||||
|
.vco_table = fabia_vco,
|
||||||
|
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||||
|
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||||
|
.clkr = {
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_pll0",
|
||||||
|
.parent_data = &(const struct clk_parent_data){
|
||||||
|
.fw_name = "bi_tcxo",
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.ops = &clk_alpha_pll_fabia_ops,
|
||||||
|
},
|
||||||
|
.vdd_data = {
|
||||||
|
.vdd_class = &vdd_mx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 615000000,
|
||||||
|
[VDD_LOW] = 1066000000,
|
||||||
|
[VDD_LOW_L1] = 1600000000,
|
||||||
|
[VDD_NOMINAL] = 2000000000 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct clk_div_table post_div_table_fabia_even[] = {
|
||||||
|
{ 0x0, 1 },
|
||||||
|
{ 0x1, 2 },
|
||||||
|
{ 0x3, 4 },
|
||||||
|
{ 0x7, 8 },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
|
||||||
|
.offset = 0x0,
|
||||||
|
.post_div_shift = 8,
|
||||||
|
.post_div_table = post_div_table_fabia_even,
|
||||||
|
.num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
|
||||||
|
.width = 4,
|
||||||
|
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||||
|
.clkr.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_pll0_out_even",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_pll0.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_alpha_pll gpu_cc_pll1 = {
|
static struct clk_alpha_pll gpu_cc_pll1 = {
|
||||||
.offset = 0x100,
|
.offset = 0x100,
|
||||||
|
.vco_table = fabia_vco,
|
||||||
|
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||||
.clkr = {
|
.clkr = {
|
||||||
.hw.init = &(struct clk_init_data){
|
.hw.init = &(struct clk_init_data){
|
||||||
.name = "gpu_cc_pll1",
|
.name = "gpu_cc_pll1",
|
||||||
.parent_data = &(const struct clk_parent_data){
|
.parent_data = &(const struct clk_parent_data){
|
||||||
.fw_name = "bi_tcxo", .name = "bi_tcxo",
|
.fw_name = "bi_tcxo",
|
||||||
},
|
},
|
||||||
.num_parents = 1,
|
.num_parents = 1,
|
||||||
.ops = &clk_alpha_pll_fabia_ops,
|
.ops = &clk_alpha_pll_fabia_ops,
|
||||||
},
|
},
|
||||||
|
.vdd_data = {
|
||||||
|
.vdd_class = &vdd_mx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 615000000,
|
||||||
|
[VDD_LOW] = 1066000000,
|
||||||
|
[VDD_LOW_L1] = 1600000000,
|
||||||
|
[VDD_NOMINAL] = 2000000000 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_fixed_factor crc_div = {
|
||||||
|
.mult = 1,
|
||||||
|
.div = 1,
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "crc_div",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_pll0_out_even.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_fixed_factor_ops,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct parent_map gpu_cc_parent_map_0[] = {
|
static const struct parent_map gpu_cc_parent_map_0[] = {
|
||||||
{ P_BI_TCXO, 0 },
|
{ P_BI_TCXO, 0 },
|
||||||
|
{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
|
||||||
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
|
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
|
||||||
{ P_GPLL0_OUT_MAIN, 5 },
|
{ P_GPLL0_OUT_MAIN, 5 },
|
||||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data gpu_cc_parent_data_0[] = {
|
static const struct clk_parent_data gpu_cc_parent_data_0[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
|
{ .hw = &gpu_cc_pll0.clkr.hw },
|
||||||
{ .hw = &gpu_cc_pll1.clkr.hw },
|
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||||
{ .fw_name = "gcc_gpu_gpll0_clk_src", .name = "gcc_gpu_gpll0_clk_src" },
|
{ .fw_name = "gcc_gpu_gpll0_clk_src" },
|
||||||
{ .fw_name = "gcc_gpu_gpll0_div_clk_src", .name = "gcc_gpu_gpll0_div_clk_src" },
|
{ .fw_name = "gcc_gpu_gpll0_div_clk_src" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct parent_map gpu_cc_parent_map_1[] = {
|
||||||
|
{ P_BI_TCXO, 0 },
|
||||||
|
{ P_GPU_CC_PLL0_OUT_EVEN, 1 },
|
||||||
|
{ P_GPU_CC_PLL0_OUT_ODD, 2 },
|
||||||
|
{ P_GPU_CC_PLL1_OUT_EVEN, 3 },
|
||||||
|
{ P_GPU_CC_PLL1_OUT_ODD, 4 },
|
||||||
|
{ P_GPLL0_OUT_MAIN, 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct clk_parent_data gpu_cc_parent_data_1[] = {
|
||||||
|
{ .fw_name = "bi_tcxo" },
|
||||||
|
{ .hw = &gpu_cc_pll0_out_even.clkr.hw },
|
||||||
|
{ .hw = &gpu_cc_pll0.clkr.hw },
|
||||||
|
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||||
|
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||||
|
{ .fw_name = "gcc_gpu_gpll0_clk_src" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct parent_map gpu_cc_parent_map_2[] = {
|
||||||
|
{ P_BI_TCXO, 0 },
|
||||||
|
{ P_CRC_DIV, 1 },
|
||||||
|
{ P_GPU_CC_PLL0_OUT_ODD, 2 },
|
||||||
|
{ P_GPU_CC_PLL1_OUT_EVEN, 3 },
|
||||||
|
{ P_GPU_CC_PLL1_OUT_ODD, 4 },
|
||||||
|
{ P_GPLL0_OUT_MAIN, 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct clk_parent_data gpu_cc_parent_data_2[] = {
|
||||||
|
{ .fw_name = "bi_tcxo" },
|
||||||
|
{ .hw = &crc_div.hw },
|
||||||
|
{ .hw = &gpu_cc_pll0.clkr.hw },
|
||||||
|
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||||
|
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||||
|
{ .fw_name = "gcc_gpu_gpll0_clk_src" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
|
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
|
||||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
|
F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
|
||||||
F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
|
F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sdm670[] = {
|
||||||
|
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||||
|
F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,8 +223,160 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = {
|
|||||||
.name = "gpu_cc_gmu_clk_src",
|
.name = "gpu_cc_gmu_clk_src",
|
||||||
.parent_data = gpu_cc_parent_data_0,
|
.parent_data = gpu_cc_parent_data_0,
|
||||||
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
|
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_shared_ops,
|
||||||
},
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 200000000,
|
||||||
|
[VDD_LOW] = 400000000 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
|
||||||
|
F(147000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(210000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(280000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(338000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(425000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(487000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(548000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(600000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670[] = {
|
||||||
|
F(180000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(267000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(355000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(430000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(504000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(565000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(610000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(650000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(700000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(750000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
F(780000000, P_CRC_DIV, 1, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
|
||||||
|
.cmd_rcgr = 0x101c,
|
||||||
|
.mnd_width = 0,
|
||||||
|
.hid_width = 5,
|
||||||
|
.parent_map = gpu_cc_parent_map_2,
|
||||||
|
.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
|
||||||
|
.flags = FORCE_ENABLE_RCG,
|
||||||
|
.clkr.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_gx_gfx3d_clk_src",
|
||||||
|
.parent_data = gpu_cc_parent_data_2,
|
||||||
|
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_rcg2_ops,
|
||||||
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_gfx,
|
||||||
|
.num_rate_max = VDD_GX_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_GX_NUM]) {
|
||||||
|
[VDD_GX_MIN] = 147000000,
|
||||||
|
[VDD_GX_LOWER] = 210000000,
|
||||||
|
[VDD_GX_LOW] = 280000000,
|
||||||
|
[VDD_GX_LOW_L1] = 338000000,
|
||||||
|
[VDD_GX_NOMINAL] = 425000000,
|
||||||
|
[VDD_GX_NOMINAL_L1] = 487000000,
|
||||||
|
[VDD_GX_HIGH] = 548000000,
|
||||||
|
[VDD_GX_HIGH_L1] = 600000000 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_acd_ahb_clk = {
|
||||||
|
.halt_reg = 0x1168,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1168,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_acd_ahb_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_acd_cxo_clk = {
|
||||||
|
.halt_reg = 0x1164,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1164,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_acd_cxo_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_crc_ahb_clk = {
|
||||||
|
.halt_reg = 0x107c,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x107c,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_crc_ahb_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_cx_apb_clk = {
|
||||||
|
.halt_reg = 0x1088,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1088,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_cx_apb_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_cx_gfx3d_clk = {
|
||||||
|
.halt_reg = 0x10a4,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x10a4,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_cx_gfx3d_clk",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
|
||||||
|
.halt_reg = 0x10a8,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x10a8,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_cx_gfx3d_slv_clk",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_branch gpu_cc_cx_gmu_clk = {
|
static struct clk_branch gpu_cc_cx_gmu_clk = {
|
||||||
@@ -105,6 +397,32 @@ static struct clk_branch gpu_cc_cx_gmu_clk = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
|
||||||
|
.halt_reg = 0x108c,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x108c,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_cx_snoc_dvm_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_cxo_aon_clk = {
|
||||||
|
.halt_reg = 0x1004,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1004,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_cxo_aon_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct clk_branch gpu_cc_cxo_clk = {
|
static struct clk_branch gpu_cc_cxo_clk = {
|
||||||
.halt_reg = 0x109c,
|
.halt_reg = 0x109c,
|
||||||
.halt_check = BRANCH_HALT,
|
.halt_check = BRANCH_HALT,
|
||||||
@@ -118,6 +436,55 @@ static struct clk_branch gpu_cc_cxo_clk = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_gx_gfx3d_clk = {
|
||||||
|
.halt_reg = 0x1054,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1054,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_gx_gfx3d_clk",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_gx_gmu_clk = {
|
||||||
|
.halt_reg = 0x1064,
|
||||||
|
.halt_check = BRANCH_HALT,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1064,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_gx_gmu_clk",
|
||||||
|
.parent_hws = (const struct clk_hw*[]){
|
||||||
|
&gpu_cc_gmu_clk_src.clkr.hw,
|
||||||
|
},
|
||||||
|
.num_parents = 1,
|
||||||
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_branch gpu_cc_gx_vsense_clk = {
|
||||||
|
.halt_reg = 0x1058,
|
||||||
|
.halt_check = BRANCH_HALT_VOTED,
|
||||||
|
.clkr = {
|
||||||
|
.enable_reg = 0x1058,
|
||||||
|
.enable_mask = BIT(0),
|
||||||
|
.hw.init = &(struct clk_init_data){
|
||||||
|
.name = "gpu_cc_gx_vsense_clk",
|
||||||
|
.ops = &clk_branch2_ops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct gdsc gpu_cx_gdsc = {
|
static struct gdsc gpu_cx_gdsc = {
|
||||||
.gdscr = 0x106c,
|
.gdscr = 0x106c,
|
||||||
.gds_hw_ctrl = 0x1540,
|
.gds_hw_ctrl = 0x1540,
|
||||||
@@ -140,15 +507,34 @@ static struct gdsc gpu_gx_gdsc = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
|
static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
|
||||||
[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
|
[GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr,
|
||||||
|
[GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr,
|
||||||
|
[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
|
||||||
|
[GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
|
||||||
|
[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
|
||||||
|
[GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
|
||||||
[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
|
[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
|
||||||
|
[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
|
||||||
|
[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
|
||||||
|
[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
|
||||||
[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
|
[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
|
||||||
|
[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
|
||||||
|
[GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
|
||||||
|
[GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
|
||||||
|
[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
|
||||||
|
[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
|
||||||
|
[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
|
||||||
[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
|
[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gdsc *gpu_cc_sdm845_gdscs[] = {
|
static const struct qcom_reset_map gpu_cc_sdm845_resets[] = {
|
||||||
[GPU_CX_GDSC] = &gpu_cx_gdsc,
|
[GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
|
||||||
[GPU_GX_GDSC] = &gpu_gx_gdsc,
|
[GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
|
||||||
|
[GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
|
||||||
|
[GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
|
||||||
|
[GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
|
||||||
|
[GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
|
||||||
|
[GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regmap_config gpu_cc_sdm845_regmap_config = {
|
static const struct regmap_config gpu_cc_sdm845_regmap_config = {
|
||||||
@@ -159,30 +545,90 @@ static const struct regmap_config gpu_cc_sdm845_regmap_config = {
|
|||||||
.fast_io = true,
|
.fast_io = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
|
static struct gdsc *gpu_cc_sdm845_gdscs[] = {
|
||||||
|
[GPU_CX_GDSC] = &gpu_cx_gdsc,
|
||||||
|
[GPU_GX_GDSC] = &gpu_gx_gdsc,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct qcom_cc_desc gpu_cc_sdm845_desc = {
|
||||||
.config = &gpu_cc_sdm845_regmap_config,
|
.config = &gpu_cc_sdm845_regmap_config,
|
||||||
.clks = gpu_cc_sdm845_clocks,
|
.clks = gpu_cc_sdm845_clocks,
|
||||||
.num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
|
.num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
|
||||||
|
.resets = gpu_cc_sdm845_resets,
|
||||||
|
.num_resets = ARRAY_SIZE(gpu_cc_sdm845_resets),
|
||||||
.gdscs = gpu_cc_sdm845_gdscs,
|
.gdscs = gpu_cc_sdm845_gdscs,
|
||||||
.num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs),
|
.num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs),
|
||||||
|
.clk_regulators = gpu_cc_sdm845_regulators,
|
||||||
|
.num_clk_regulators = ARRAY_SIZE(gpu_cc_sdm845_regulators),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id gpu_cc_sdm845_match_table[] = {
|
static const struct of_device_id gpu_cc_sdm845_match_table[] = {
|
||||||
{ .compatible = "qcom,sdm845-gpucc" },
|
{ .compatible = "qcom,sdm845-gpucc" },
|
||||||
|
{ .compatible = "qcom,sdm670-gpucc" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
|
MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
|
||||||
|
|
||||||
|
static void gpu_cc_sdm845_fixup_sdm670(void)
|
||||||
|
{
|
||||||
|
gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sdm670;
|
||||||
|
gpu_cc_gmu_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 200000000;
|
||||||
|
|
||||||
|
/* GFX clocks */
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.freq_tbl =
|
||||||
|
ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_MIN] = 180000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOWER] =
|
||||||
|
267000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOW] = 355000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOW_L1] =
|
||||||
|
430000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_NOMINAL] =
|
||||||
|
565000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_NOMINAL_L1] =
|
||||||
|
650000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_HIGH] = 750000000;
|
||||||
|
gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_HIGH_L1] =
|
||||||
|
780000000;
|
||||||
|
}
|
||||||
|
|
||||||
static int gpu_cc_sdm845_probe(struct platform_device *pdev)
|
static int gpu_cc_sdm845_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
unsigned int value, mask;
|
unsigned int value, mask;
|
||||||
|
struct alpha_pll_config gpu_cc_pll0_config = {};
|
||||||
|
int ret;
|
||||||
|
bool sdm670;
|
||||||
|
|
||||||
|
sdm670 = of_device_is_compatible(pdev->dev.of_node,
|
||||||
|
"qcom,sdm670-gpucc");
|
||||||
|
|
||||||
regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
|
regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
|
||||||
if (IS_ERR(regmap))
|
if (IS_ERR(regmap))
|
||||||
return PTR_ERR(regmap);
|
return PTR_ERR(regmap);
|
||||||
|
|
||||||
clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
|
/* Register clock fixed factor for CRC divide. */
|
||||||
|
ret = devm_clk_hw_register(&pdev->dev, &crc_div.hw);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Failed to register hardware clock\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdm670)
|
||||||
|
gpu_cc_sdm845_fixup_sdm670();
|
||||||
|
|
||||||
|
gpu_cc_sdm845_desc.gdscs = NULL;
|
||||||
|
gpu_cc_sdm845_desc.num_gdscs = 0;
|
||||||
|
|
||||||
|
/* 560 MHz configuration */
|
||||||
|
gpu_cc_pll0_config.l = 0x1d,
|
||||||
|
gpu_cc_pll0_config.alpha = 0x2aaa,
|
||||||
|
clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
|
||||||
|
|
||||||
|
/* 512 Mhz configuration */
|
||||||
|
gpu_cc_pll0_config.l = 0x1a,
|
||||||
|
gpu_cc_pll0_config.alpha = 0xaaaa,
|
||||||
|
clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll0_config);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure gpu_cc_cx_gmu_clk with recommended
|
* Configure gpu_cc_cx_gmu_clk with recommended
|
||||||
@@ -197,7 +643,19 @@ static int gpu_cc_sdm845_probe(struct platform_device *pdev)
|
|||||||
regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
|
regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
|
||||||
8 << CLK_DIS_WAIT_SHIFT);
|
8 << CLK_DIS_WAIT_SHIFT);
|
||||||
|
|
||||||
return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
|
ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Failed to register GPU CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Registered GPU CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gpu_cc_sdm845_sync_state(struct device *dev)
|
||||||
|
{
|
||||||
|
qcom_cc_sync_state(dev, &gpu_cc_sdm845_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver gpu_cc_sdm845_driver = {
|
static struct platform_driver gpu_cc_sdm845_driver = {
|
||||||
@@ -205,7 +663,7 @@ static struct platform_driver gpu_cc_sdm845_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "sdm845-gpucc",
|
.name = "sdm845-gpucc",
|
||||||
.of_match_table = gpu_cc_sdm845_match_table,
|
.of_match_table = gpu_cc_sdm845_match_table,
|
||||||
.sync_state = clk_sync_state,
|
.sync_state = gpu_cc_sdm845_sync_state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
58
drivers/clk/qcom/vdd-level-sdm845.h
Normal file
58
drivers/clk/qcom/vdd-level-sdm845.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM845_H
|
||||||
|
#define __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM845_H
|
||||||
|
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
|
#include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h>
|
||||||
|
|
||||||
|
enum vdd_levels {
|
||||||
|
VDD_NONE,
|
||||||
|
VDD_MIN, /* MIN SVS */
|
||||||
|
VDD_LOWER, /* SVS2 */
|
||||||
|
VDD_LOW, /* SVS */
|
||||||
|
VDD_LOW_L1, /* SVSL1 */
|
||||||
|
VDD_NOMINAL, /* NOM */
|
||||||
|
VDD_HIGH, /* TURBO */
|
||||||
|
VDD_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int vdd_corner[] = {
|
||||||
|
[VDD_NONE] = 0,
|
||||||
|
[VDD_MIN] = RPMH_REGULATOR_LEVEL_MIN_SVS,
|
||||||
|
[VDD_LOWER] = RPMH_REGULATOR_LEVEL_LOW_SVS,
|
||||||
|
[VDD_LOW] = RPMH_REGULATOR_LEVEL_SVS,
|
||||||
|
[VDD_LOW_L1] = RPMH_REGULATOR_LEVEL_SVS_L1,
|
||||||
|
[VDD_NOMINAL] = RPMH_REGULATOR_LEVEL_NOM,
|
||||||
|
[VDD_HIGH] = RPMH_REGULATOR_LEVEL_TURBO,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vdd_gx_levels {
|
||||||
|
VDD_GX_NONE,
|
||||||
|
VDD_GX_MIN, /* MIN SVS */
|
||||||
|
VDD_GX_LOWER, /* SVS2 */
|
||||||
|
VDD_GX_LOW, /* SVS */
|
||||||
|
VDD_GX_LOW_L1, /* SVSL1 */
|
||||||
|
VDD_GX_NOMINAL, /* NOM */
|
||||||
|
VDD_GX_NOMINAL_L1, /* NOM1 */
|
||||||
|
VDD_GX_HIGH, /* TURBO */
|
||||||
|
VDD_GX_HIGH_L1, /* TURBO1 */
|
||||||
|
VDD_GX_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int vdd_gx_corner[] = {
|
||||||
|
[VDD_GX_NONE] = 0, /* VDD_GX_NONE */
|
||||||
|
[VDD_GX_MIN] = RPMH_REGULATOR_LEVEL_MIN_SVS, /* VDD_GX_MIN */
|
||||||
|
[VDD_GX_LOWER] = RPMH_REGULATOR_LEVEL_LOW_SVS, /* VDD_GX_LOWER */
|
||||||
|
[VDD_GX_LOW] = RPMH_REGULATOR_LEVEL_SVS, /* VDD_GX_LOW */
|
||||||
|
[VDD_GX_LOW_L1] = RPMH_REGULATOR_LEVEL_SVS_L1, /* VDD_GX_LOW_L1 */
|
||||||
|
[VDD_GX_NOMINAL] = RPMH_REGULATOR_LEVEL_NOM, /* VDD_GX_NOMINAL */
|
||||||
|
[VDD_GX_NOMINAL_L1] = RPMH_REGULATOR_LEVEL_NOM_L1, /* VDD_GX_NOMINAL_L1 */
|
||||||
|
[VDD_GX_HIGH] = RPMH_REGULATOR_LEVEL_TURBO, /* VDD_GX_HIGH */
|
||||||
|
[VDD_GX_HIGH_L1] = RPMH_REGULATOR_LEVEL_TURBO_L1, /* VDD_GX_HIGH_L1 */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -493,32 +493,16 @@ static struct clk_branch video_cc_mvs1c_clk = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_branch video_cc_sleep_clk = {
|
|
||||||
.halt_reg = 0x8140,
|
|
||||||
.halt_check = BRANCH_HALT,
|
|
||||||
.clkr = {
|
|
||||||
.enable_reg = 0x8140,
|
|
||||||
.enable_mask = BIT(0),
|
|
||||||
.hw.init = &(struct clk_init_data){
|
|
||||||
.name = "video_cc_sleep_clk",
|
|
||||||
.parent_hws = (const struct clk_hw*[]){
|
|
||||||
&video_cc_sleep_clk_src.clkr.hw,
|
|
||||||
},
|
|
||||||
.num_parents = 1,
|
|
||||||
.flags = CLK_SET_RATE_PARENT,
|
|
||||||
.ops = &clk_branch2_ops,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* video_cc_ahb_clk
|
* video_cc_ahb_clk
|
||||||
* video_cc_xo_clk
|
* video_cc_xo_clk
|
||||||
|
* video_cc_sleep_clk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct critical_clk_offset critical_clk_list[] = {
|
static struct critical_clk_offset critical_clk_list[] = {
|
||||||
{ .offset = 0x80f4, .mask = BIT(0) },
|
{ .offset = 0x80f4, .mask = BIT(0) },
|
||||||
{ .offset = 0x8124, .mask = BIT(0) },
|
{ .offset = 0x8124, .mask = BIT(0) },
|
||||||
|
{ .offset = 0x8140, .mask = BIT(0) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_regmap *video_cc_kalama_clocks[] = {
|
static struct clk_regmap *video_cc_kalama_clocks[] = {
|
||||||
@@ -535,7 +519,6 @@ static struct clk_regmap *video_cc_kalama_clocks[] = {
|
|||||||
[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
|
[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
|
||||||
[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
|
[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
|
||||||
[VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
|
[VIDEO_CC_PLL1] = &video_cc_pll1.clkr,
|
||||||
[VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr,
|
|
||||||
[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
|
[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
|
||||||
[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
|
[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
@@ -17,58 +18,102 @@
|
|||||||
#include "clk-regmap.h"
|
#include "clk-regmap.h"
|
||||||
#include "clk-pll.h"
|
#include "clk-pll.h"
|
||||||
#include "gdsc.h"
|
#include "gdsc.h"
|
||||||
|
#include "reset.h"
|
||||||
|
#include "vdd-level-sdm845.h"
|
||||||
|
|
||||||
|
static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner);
|
||||||
|
|
||||||
|
static struct clk_vdd_class *video_cc_sdm845_regulators[] = {
|
||||||
|
&vdd_cx,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
P_BI_TCXO,
|
P_BI_TCXO,
|
||||||
|
P_VIDEO_PLL0_OUT_EVEN,
|
||||||
P_VIDEO_PLL0_OUT_MAIN,
|
P_VIDEO_PLL0_OUT_MAIN,
|
||||||
/* P_VIDEO_PLL0_OUT_EVEN, */
|
P_VIDEO_PLL0_OUT_ODD,
|
||||||
/* P_VIDEO_PLL0_OUT_ODD, */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct alpha_pll_config video_pll0_config = {
|
static struct pll_vco fabia_vco[] = {
|
||||||
|
{ 249600000, 2000000000, 0 },
|
||||||
|
{ 125000000, 1000000000, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*320 MHz configuration */
|
||||||
|
static struct alpha_pll_config video_pll0_config = {
|
||||||
.l = 0x10,
|
.l = 0x10,
|
||||||
.alpha = 0xaaab,
|
.cal_l = 0x32,
|
||||||
|
.alpha = 0xaaaa,
|
||||||
|
.config_ctl_val = 0x20485699,
|
||||||
|
.config_ctl_hi_val = 0x00002067,
|
||||||
|
.test_ctl_val = 0x40000000,
|
||||||
|
.test_ctl_hi_val = 0x00000002,
|
||||||
|
.user_ctl_val = 0x00000000,
|
||||||
|
.user_ctl_hi_val = 0x00004805,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_alpha_pll video_pll0 = {
|
static struct clk_alpha_pll video_pll0 = {
|
||||||
.offset = 0x42c,
|
.offset = 0x42c,
|
||||||
|
.vco_table = fabia_vco,
|
||||||
|
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||||
.clkr = {
|
.clkr = {
|
||||||
.hw.init = &(struct clk_init_data){
|
.hw.init = &(struct clk_init_data){
|
||||||
.name = "video_pll0",
|
.name = "video_pll0",
|
||||||
.parent_data = &(const struct clk_parent_data){
|
.parent_data = &(const struct clk_parent_data){
|
||||||
.fw_name = "bi_tcxo", .name = "bi_tcxo",
|
.fw_name = "bi_tcxo",
|
||||||
},
|
},
|
||||||
.num_parents = 1,
|
.num_parents = 1,
|
||||||
.ops = &clk_alpha_pll_fabia_ops,
|
.ops = &clk_alpha_pll_fabia_ops,
|
||||||
},
|
},
|
||||||
|
.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 615000000,
|
||||||
|
[VDD_LOW] = 1066000000,
|
||||||
|
[VDD_LOW_L1] = 1600000000,
|
||||||
|
[VDD_NOMINAL] = 2000000000 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct parent_map video_cc_parent_map_0[] = {
|
static const struct parent_map video_cc_parent_map_0[] = {
|
||||||
{ P_BI_TCXO, 0 },
|
{ P_BI_TCXO, 0 },
|
||||||
{ P_VIDEO_PLL0_OUT_MAIN, 1 },
|
{ P_VIDEO_PLL0_OUT_MAIN, 1 },
|
||||||
/* { P_VIDEO_PLL0_OUT_EVEN, 2 }, */
|
{ P_VIDEO_PLL0_OUT_EVEN, 2 },
|
||||||
/* { P_VIDEO_PLL0_OUT_ODD, 3 }, */
|
{ P_VIDEO_PLL0_OUT_ODD, 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct clk_parent_data video_cc_parent_data_0[] = {
|
static const struct clk_parent_data video_cc_parent_data_0[] = {
|
||||||
{ .fw_name = "bi_tcxo", .name = "bi_tcxo" },
|
{ .fw_name = "bi_tcxo" },
|
||||||
|
{ .hw = &video_pll0.clkr.hw },
|
||||||
|
{ .hw = &video_pll0.clkr.hw },
|
||||||
{ .hw = &video_pll0.clkr.hw },
|
{ .hw = &video_pll0.clkr.hw },
|
||||||
/* { .name = "video_pll0_out_even" }, */
|
|
||||||
/* { .name = "video_pll0_out_odd" }, */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
|
static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
|
||||||
F(100000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
|
F(100000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
|
||||||
F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||||
F(330000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
F(320000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
F(380000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
F(444000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
F(533000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct freq_tbl ftbl_video_cc_venus_clk_src_sdm670[] = {
|
||||||
|
F(100000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
|
||||||
|
F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||||
|
F(330000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||||
|
F(364700000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||||
F(404000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
F(404000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
F(444000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
F(444000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
F(533000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
F(533000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct clk_rcg2 video_cc_venus_clk_src = {
|
static struct clk_rcg2 video_cc_venus_clk_src = {
|
||||||
.cmd_rcgr = 0x7f0,
|
.cmd_rcgr = 0x7f0,
|
||||||
.mnd_width = 0,
|
.mnd_width = 0,
|
||||||
@@ -81,6 +126,17 @@ static struct clk_rcg2 video_cc_venus_clk_src = {
|
|||||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
|
.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
|
||||||
.flags = CLK_SET_RATE_PARENT,
|
.flags = CLK_SET_RATE_PARENT,
|
||||||
.ops = &clk_rcg2_shared_ops,
|
.ops = &clk_rcg2_shared_ops,
|
||||||
|
},
|
||||||
|
.clkr.vdd_data = {
|
||||||
|
.vdd_class = &vdd_cx,
|
||||||
|
.num_rate_max = VDD_NUM,
|
||||||
|
.rate_max = (unsigned long[VDD_NUM]) {
|
||||||
|
[VDD_MIN] = 100000000,
|
||||||
|
[VDD_LOWER] = 200000000,
|
||||||
|
[VDD_LOW] = 320000000,
|
||||||
|
[VDD_LOW_L1] = 380000000,
|
||||||
|
[VDD_NOMINAL] = 444000000,
|
||||||
|
[VDD_HIGH] = 533000000 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,31 +361,65 @@ static const struct regmap_config video_cc_sdm845_regmap_config = {
|
|||||||
.fast_io = true,
|
.fast_io = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct qcom_cc_desc video_cc_sdm845_desc = {
|
static struct qcom_cc_desc video_cc_sdm845_desc = {
|
||||||
.config = &video_cc_sdm845_regmap_config,
|
.config = &video_cc_sdm845_regmap_config,
|
||||||
.clks = video_cc_sdm845_clocks,
|
.clks = video_cc_sdm845_clocks,
|
||||||
.num_clks = ARRAY_SIZE(video_cc_sdm845_clocks),
|
.num_clks = ARRAY_SIZE(video_cc_sdm845_clocks),
|
||||||
.gdscs = video_cc_sdm845_gdscs,
|
.gdscs = video_cc_sdm845_gdscs,
|
||||||
.num_gdscs = ARRAY_SIZE(video_cc_sdm845_gdscs),
|
.num_gdscs = ARRAY_SIZE(video_cc_sdm845_gdscs),
|
||||||
|
.clk_regulators = video_cc_sdm845_regulators,
|
||||||
|
.num_clk_regulators = ARRAY_SIZE(video_cc_sdm845_regulators),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id video_cc_sdm845_match_table[] = {
|
static const struct of_device_id video_cc_sdm845_match_table[] = {
|
||||||
{ .compatible = "qcom,sdm845-videocc" },
|
{ .compatible = "qcom,sdm845-videocc" },
|
||||||
|
{ .compatible = "qcom,sdm670-videocc" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, video_cc_sdm845_match_table);
|
MODULE_DEVICE_TABLE(of, video_cc_sdm845_match_table);
|
||||||
|
|
||||||
|
static void video_cc_sdm845_fixup_sdm670(void)
|
||||||
|
{
|
||||||
|
video_cc_venus_clk_src.freq_tbl = ftbl_video_cc_venus_clk_src_sdm670;
|
||||||
|
video_cc_venus_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 330000000;
|
||||||
|
video_cc_venus_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] =
|
||||||
|
404000000;
|
||||||
|
}
|
||||||
|
|
||||||
static int video_cc_sdm845_probe(struct platform_device *pdev)
|
static int video_cc_sdm845_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
int ret;
|
||||||
|
bool sdm670;
|
||||||
|
|
||||||
|
sdm670 = of_device_is_compatible(pdev->dev.of_node,
|
||||||
|
"qcom,sdm670-videocc");
|
||||||
|
|
||||||
regmap = qcom_cc_map(pdev, &video_cc_sdm845_desc);
|
regmap = qcom_cc_map(pdev, &video_cc_sdm845_desc);
|
||||||
if (IS_ERR(regmap))
|
if (IS_ERR(regmap))
|
||||||
return PTR_ERR(regmap);
|
return PTR_ERR(regmap);
|
||||||
|
|
||||||
|
if (sdm670)
|
||||||
|
video_cc_sdm845_fixup_sdm670();
|
||||||
|
|
||||||
|
video_cc_sdm845_desc.gdscs = NULL;
|
||||||
|
video_cc_sdm845_desc.num_gdscs = 0;
|
||||||
|
|
||||||
clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
||||||
|
|
||||||
return qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap);
|
ret = qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Failed to register Video CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Registered Video CC clocks\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void video_cc_sdm845_sync_state(struct device *dev)
|
||||||
|
{
|
||||||
|
qcom_cc_sync_state(dev, &video_cc_sdm845_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver video_cc_sdm845_driver = {
|
static struct platform_driver video_cc_sdm845_driver = {
|
||||||
@@ -337,7 +427,7 @@ static struct platform_driver video_cc_sdm845_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "sdm845-videocc",
|
.name = "sdm845-videocc",
|
||||||
.of_match_table = video_cc_sdm845_match_table,
|
.of_match_table = video_cc_sdm845_match_table,
|
||||||
.sync_state = clk_sync_state,
|
.sync_state = video_cc_sdm845_sync_state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -775,10 +775,12 @@ int tmc_etr_usb_init(struct amba_device *adev,
|
|||||||
mapping_config = qcom_iommu_get_mappings_configuration(domain);
|
mapping_config = qcom_iommu_get_mappings_configuration(domain);
|
||||||
if (mapping_config < 0)
|
if (mapping_config < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (!(mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS))
|
if (!(mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS)) {
|
||||||
pr_debug("%s: setting SPS_BAM_SMMU_EN flag with (%s)\n",
|
pr_debug("%s: setting SPS_BAM_SMMU_EN flag with (%s)\n",
|
||||||
__func__, dev_name(dev));
|
__func__, dev_name(dev));
|
||||||
bamdata->props.options |= SPS_BAM_SMMU_EN;
|
|
||||||
|
bamdata->props.options |= SPS_BAM_SMMU_EN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sps_register_bam_device(&bamdata->props, &bamdata->handle);
|
return sps_register_bam_device(&bamdata->props, &bamdata->handle);
|
||||||
|
|||||||
@@ -679,6 +679,12 @@ static void geni_i2c_irq_handle_watermark(struct geni_i2c_dev *gi2c, u32 m_stat)
|
|||||||
int i, j;
|
int i, j;
|
||||||
u32 rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
|
u32 rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
|
||||||
|
|
||||||
|
if (!cur) {
|
||||||
|
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s: Spurious irq\n", __func__);
|
||||||
|
geni_i2c_err(gi2c, GENI_SPURIOUS_IRQ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (((m_stat & M_RX_FIFO_WATERMARK_EN) ||
|
if (((m_stat & M_RX_FIFO_WATERMARK_EN) ||
|
||||||
(m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) {
|
(m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) {
|
||||||
u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
|
u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
|
||||||
@@ -737,7 +743,7 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
|
|||||||
"%s: m_irq_status:0x%x\n", __func__, m_stat);
|
"%s: m_irq_status:0x%x\n", __func__, m_stat);
|
||||||
|
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
I2C_LOG_ERR(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n");
|
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n");
|
||||||
geni_i2c_err(gi2c, GENI_SPURIOUS_IRQ);
|
geni_i2c_err(gi2c, GENI_SPURIOUS_IRQ);
|
||||||
gi2c->cmd_done = true;
|
gi2c->cmd_done = true;
|
||||||
is_clear_watermark = true;
|
is_clear_watermark = true;
|
||||||
@@ -2420,7 +2426,7 @@ static int geni_i2c_suspend_late(struct device *device)
|
|||||||
pm_runtime_enable(device);
|
pm_runtime_enable(device);
|
||||||
}
|
}
|
||||||
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
|
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
|
||||||
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__);
|
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -453,11 +453,14 @@ static int __arm_smmu_alloc_cb(unsigned long *map, int start, int end,
|
|||||||
{
|
{
|
||||||
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
|
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
|
||||||
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
|
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
|
||||||
struct arm_smmu_device *smmu = cfg->smmu;
|
struct arm_smmu_device *smmu;
|
||||||
int idx;
|
int idx;
|
||||||
int i;
|
int i;
|
||||||
int cb = -EINVAL;
|
int cb = -EINVAL;
|
||||||
|
|
||||||
|
if (!fwspec || !cfg)
|
||||||
|
return cb;
|
||||||
|
smmu = cfg->smmu;
|
||||||
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
||||||
if (smmu->s2crs[idx].pinned)
|
if (smmu->s2crs[idx].pinned)
|
||||||
cb = smmu->s2crs[idx].cbndx;
|
cb = smmu->s2crs[idx].cbndx;
|
||||||
@@ -1113,7 +1116,7 @@ static bool arm_smmu_master_attached(struct arm_smmu_device *smmu,
|
|||||||
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
|
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
|
||||||
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
|
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
|
||||||
|
|
||||||
if (!cfg || !fwspec)
|
if (!fwspec || !cfg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
||||||
@@ -1959,6 +1962,9 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
|
|||||||
bool config_smrs = !dev_defer_smr_configuration(dev);
|
bool config_smrs = !dev_defer_smr_configuration(dev);
|
||||||
int i, idx, ret;
|
int i, idx, ret;
|
||||||
|
|
||||||
|
if (!fwspec || !cfg)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&smmu->stream_map_mutex);
|
mutex_lock(&smmu->stream_map_mutex);
|
||||||
/* Figure out a viable stream map entry allocation */
|
/* Figure out a viable stream map entry allocation */
|
||||||
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
for_each_cfg_sme(cfg, fwspec, i, idx) {
|
||||||
@@ -2771,6 +2777,9 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
|
|||||||
struct iommu_group *group = NULL;
|
struct iommu_group *group = NULL;
|
||||||
int i, idx;
|
int i, idx;
|
||||||
|
|
||||||
|
if (!cfg || !fwspec)
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
mutex_lock(&smmu->stream_map_mutex);
|
mutex_lock(&smmu->stream_map_mutex);
|
||||||
group = of_get_device_group(dev);
|
group = of_get_device_group(dev);
|
||||||
if (group)
|
if (group)
|
||||||
|
|||||||
@@ -3031,6 +3031,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* Read en_wol from device tree */
|
/* Read en_wol from device tree */
|
||||||
priv->en_wol = of_property_read_bool(np, "enable-wol");
|
priv->en_wol = of_property_read_bool(np, "enable-wol");
|
||||||
|
if (of_property_read_bool(np, "disable-frame-preem"))
|
||||||
|
priv->dma_cap.fpesel = 0;
|
||||||
|
|
||||||
/* enable safety feature from device tree */
|
/* enable safety feature from device tree */
|
||||||
if (of_property_read_bool(np, "safety-feat") && priv->dma_cap.asp)
|
if (of_property_read_bool(np, "safety-feat") && priv->dma_cap.asp)
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ struct stmmac_priv {
|
|||||||
|
|
||||||
int tx_coalesce;
|
int tx_coalesce;
|
||||||
int hwts_tx_en;
|
int hwts_tx_en;
|
||||||
|
int irq_number;
|
||||||
bool tx_path_in_lpi_mode;
|
bool tx_path_in_lpi_mode;
|
||||||
bool tso;
|
bool tso;
|
||||||
int sph;
|
int sph;
|
||||||
|
|||||||
@@ -3956,6 +3956,8 @@ static int stmmac_open(struct net_device *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto irq_error;
|
goto irq_error;
|
||||||
|
|
||||||
|
priv->irq_number = dev->irq;
|
||||||
|
|
||||||
stmmac_enable_all_queues(priv);
|
stmmac_enable_all_queues(priv);
|
||||||
netif_tx_start_all_queues(priv->dev);
|
netif_tx_start_all_queues(priv->dev);
|
||||||
stmmac_enable_all_dma_irq(priv);
|
stmmac_enable_all_dma_irq(priv);
|
||||||
@@ -7659,6 +7661,12 @@ int stmmac_suspend(struct device *dev)
|
|||||||
hrtimer_cancel(&priv->tx_queue[chan].txtimer);
|
hrtimer_cancel(&priv->tx_queue[chan].txtimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free the IRQ lines */
|
||||||
|
if (priv->irq_number != 0) {
|
||||||
|
free_irq(ndev->irq, ndev);
|
||||||
|
priv->irq_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->eee_enabled) {
|
if (priv->eee_enabled) {
|
||||||
priv->tx_path_in_lpi_mode = false;
|
priv->tx_path_in_lpi_mode = false;
|
||||||
del_timer_sync(&priv->eee_ctrl_timer);
|
del_timer_sync(&priv->eee_ctrl_timer);
|
||||||
@@ -7813,6 +7821,16 @@ int stmmac_resume(struct device *dev)
|
|||||||
|
|
||||||
stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
|
stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
|
||||||
|
|
||||||
|
if (priv->irq_number == 0) {
|
||||||
|
ret = request_irq(ndev->irq, stmmac_interrupt,
|
||||||
|
IRQF_SHARED, ndev->name, ndev);
|
||||||
|
if (unlikely(ret < 0))
|
||||||
|
netdev_err(priv->dev,
|
||||||
|
"%s: ERROR: allocating the IRQ %d (error: %d)\n",
|
||||||
|
__func__, ndev->irq, ret);
|
||||||
|
priv->irq_number = ndev->irq;
|
||||||
|
}
|
||||||
|
|
||||||
stmmac_enable_all_queues(priv);
|
stmmac_enable_all_queues(priv);
|
||||||
stmmac_enable_all_dma_irq(priv);
|
stmmac_enable_all_dma_irq(priv);
|
||||||
|
|
||||||
|
|||||||
@@ -8005,11 +8005,15 @@ static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev,
|
|||||||
LINK_WIDTH_MASK << LINK_WIDTH_SHIFT,
|
LINK_WIDTH_MASK << LINK_WIDTH_SHIFT,
|
||||||
link_width);
|
link_width);
|
||||||
|
|
||||||
/* Set NUM_OF_LANES in GEN2_CTRL_OFF */
|
/*
|
||||||
|
* It's advisable to set NUM_OF_LANES[8:0] field to 0x1. It allows
|
||||||
|
* establishing connection on one line even if there is a termination
|
||||||
|
* on the second line. Otherwise the link will go to compliance.
|
||||||
|
*/
|
||||||
msm_pcie_write_reg_field(pcie_dev->dm_core,
|
msm_pcie_write_reg_field(pcie_dev->dm_core,
|
||||||
PCIE_GEN3_GEN2_CTRL,
|
PCIE_GEN3_GEN2_CTRL,
|
||||||
NUM_OF_LANES_MASK << NUM_OF_LANES_SHIFT,
|
NUM_OF_LANES_MASK << NUM_OF_LANES_SHIFT,
|
||||||
link_width);
|
LINK_WIDTH_X1);
|
||||||
|
|
||||||
/* enable write access to RO register */
|
/* enable write access to RO register */
|
||||||
msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, 0,
|
msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, 0,
|
||||||
@@ -8017,7 +8021,8 @@ static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev,
|
|||||||
|
|
||||||
/* Set Maximum link width as current width */
|
/* Set Maximum link width as current width */
|
||||||
msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE20_CAP + PCI_EXP_LNKCAP,
|
msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE20_CAP + PCI_EXP_LNKCAP,
|
||||||
PCI_EXP_LNKCAP_MLW, link_width);
|
PCI_EXP_LNKCAP_MLW,
|
||||||
|
target_link_width >> PCI_EXP_LNKSTA_NLW_SHIFT);
|
||||||
|
|
||||||
/* disable write access to RO register */
|
/* disable write access to RO register */
|
||||||
msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, BIT(0),
|
msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, BIT(0),
|
||||||
|
|||||||
@@ -478,7 +478,6 @@ struct ep_pcie_dev_t {
|
|||||||
bool enumerated;
|
bool enumerated;
|
||||||
enum ep_pcie_link_status link_status;
|
enum ep_pcie_link_status link_status;
|
||||||
bool power_on;
|
bool power_on;
|
||||||
bool suspending;
|
|
||||||
bool l23_ready;
|
bool l23_ready;
|
||||||
bool l1ss_enabled;
|
bool l1ss_enabled;
|
||||||
bool no_notify;
|
bool no_notify;
|
||||||
|
|||||||
@@ -2434,7 +2434,6 @@ checkbme:
|
|||||||
dev->link_status = EP_PCIE_LINK_UP;
|
dev->link_status = EP_PCIE_LINK_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->suspending = false;
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
link_fail_pipe_clk_deinit:
|
link_fail_pipe_clk_deinit:
|
||||||
@@ -2631,13 +2630,13 @@ static irqreturn_t ep_pcie_handle_linkdown_irq(int irq, void *data)
|
|||||||
EP_PCIE_DBG(dev,
|
EP_PCIE_DBG(dev,
|
||||||
"PCIe V%d:Linkdown IRQ happened when the link is disabled\n",
|
"PCIe V%d:Linkdown IRQ happened when the link is disabled\n",
|
||||||
dev->rev);
|
dev->rev);
|
||||||
} else if (dev->suspending) {
|
} else if (!atomic_read(&dev->perst_deast)) {
|
||||||
EP_PCIE_DBG(dev,
|
EP_PCIE_DBG(dev,
|
||||||
"PCIe V%d:Linkdown IRQ happened when the link is suspending\n",
|
"PCIe V%d:Linkdown IRQ happened when PERST asserted\n",
|
||||||
dev->rev);
|
dev->rev);
|
||||||
} else {
|
} else {
|
||||||
dev->link_status = EP_PCIE_LINK_DISABLED;
|
dev->link_status = EP_PCIE_LINK_DISABLED;
|
||||||
EP_PCIE_ERR(dev, "PCIe V%d:PCIe link is down for %ld times\n",
|
EP_PCIE_DBG(dev, "PCIe V%d:PCIe link is down for %ld times\n",
|
||||||
dev->rev, dev->linkdown_counter);
|
dev->rev, dev->linkdown_counter);
|
||||||
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_PHY) |
|
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_PHY) |
|
||||||
BIT(EP_PCIE_RES_PARF), true);
|
BIT(EP_PCIE_RES_PARF), true);
|
||||||
|
|||||||
@@ -309,8 +309,6 @@ static void ep_pcie_show_status(struct ep_pcie_dev_t *dev)
|
|||||||
EP_PCIE_DBG_FS("PCIe: link is %s\n",
|
EP_PCIE_DBG_FS("PCIe: link is %s\n",
|
||||||
(dev->link_status == EP_PCIE_LINK_ENABLED)
|
(dev->link_status == EP_PCIE_LINK_ENABLED)
|
||||||
? "enabled" : "disabled");
|
? "enabled" : "disabled");
|
||||||
EP_PCIE_DBG_FS("the link is %s suspending\n",
|
|
||||||
dev->suspending ? "" : "not");
|
|
||||||
EP_PCIE_DBG_FS("the power is %s on\n",
|
EP_PCIE_DBG_FS("the power is %s on\n",
|
||||||
dev->power_on ? "" : "not");
|
dev->power_on ? "" : "not");
|
||||||
EP_PCIE_DBG_FS("linkdown_counter: %lu\n",
|
EP_PCIE_DBG_FS("linkdown_counter: %lu\n",
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
|
|||||||
bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon);
|
bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon);
|
||||||
uint32_t qcom_sysmon_get_txn_id(struct qcom_sysmon *sysmon);
|
uint32_t qcom_sysmon_get_txn_id(struct qcom_sysmon *sysmon);
|
||||||
int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon, char *buf, size_t len);
|
int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon, char *buf, size_t len);
|
||||||
|
void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend);
|
||||||
#else
|
#else
|
||||||
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
|
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
|
||||||
const char *name,
|
const char *name,
|
||||||
@@ -120,6 +121,9 @@ static inline int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon,
|
|||||||
{
|
{
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon,
|
||||||
|
bool suspend) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <soc/qcom/secure_buffer.h>
|
#include <soc/qcom/secure_buffer.h>
|
||||||
#include <trace/events/rproc_qcom.h>
|
#include <trace/events/rproc_qcom.h>
|
||||||
#include <soc/qcom/qcom_ramdump.h>
|
#include <soc/qcom/qcom_ramdump.h>
|
||||||
|
#include <linux/remoteproc/qcom_rproc.h>
|
||||||
|
|
||||||
#include "qcom_common.h"
|
#include "qcom_common.h"
|
||||||
#include "qcom_pil_info.h"
|
#include "qcom_pil_info.h"
|
||||||
@@ -635,6 +636,52 @@ static int adsp_stop(struct rproc *rproc)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int adsp_shutdown(struct rproc *rproc)
|
||||||
|
{
|
||||||
|
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
||||||
|
int handover;
|
||||||
|
|
||||||
|
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "enter");
|
||||||
|
|
||||||
|
scm_pas_enable_bw();
|
||||||
|
/*
|
||||||
|
* ADSP teardown is not possible in LPM. Ignore the SCM call return
|
||||||
|
* status for the teardown sequence.
|
||||||
|
*/
|
||||||
|
if (adsp->retry_shutdown)
|
||||||
|
qcom_scm_pas_shutdown_retry(adsp->pas_id);
|
||||||
|
else
|
||||||
|
qcom_scm_pas_shutdown(adsp->pas_id);
|
||||||
|
|
||||||
|
if (adsp->dtb_pas_id)
|
||||||
|
qcom_scm_pas_shutdown(adsp->dtb_pas_id);
|
||||||
|
|
||||||
|
scm_pas_disable_bw();
|
||||||
|
adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
|
||||||
|
if (adsp->qmp)
|
||||||
|
qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false);
|
||||||
|
handover = qcom_q6v5_unprepare(&adsp->q6v5);
|
||||||
|
if (handover)
|
||||||
|
qcom_pas_handover(&adsp->q6v5);
|
||||||
|
|
||||||
|
trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "exit");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void adsp_set_ops_stop(struct rproc *rproc, bool suspend)
|
||||||
|
{
|
||||||
|
struct qcom_adsp *adsp;
|
||||||
|
|
||||||
|
adsp = (struct qcom_adsp *)rproc->priv;
|
||||||
|
qcom_sysmon_set_ops_stop(adsp->sysmon, suspend);
|
||||||
|
if (suspend)
|
||||||
|
rproc->ops->stop = adsp_shutdown;
|
||||||
|
else
|
||||||
|
rproc->ops->stop = adsp_stop;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(adsp_set_ops_stop);
|
||||||
|
|
||||||
static int adsp_attach(struct rproc *rproc)
|
static int adsp_attach(struct rproc *rproc)
|
||||||
{
|
{
|
||||||
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ static void slate_coredump(struct rproc *rproc)
|
|||||||
slate_tz_req.address_fw = start_addr;
|
slate_tz_req.address_fw = start_addr;
|
||||||
slate_tz_req.size_fw = size;
|
slate_tz_req.size_fw = size;
|
||||||
ret = slate_tzapp_comm(slate_data, &slate_tz_req);
|
ret = slate_tzapp_comm(slate_data, &slate_tz_req);
|
||||||
if (ret != 0) {
|
if (ret != 0 || slate_data->cmd_status) {
|
||||||
dev_dbg(slate_data->dev,
|
dev_dbg(slate_data->dev,
|
||||||
"%s: SLATE RPROC ramdmp collection failed\n",
|
"%s: SLATE RPROC ramdmp collection failed\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
|||||||
@@ -40,10 +40,6 @@
|
|||||||
#define SP_SCSR_MB1_SP2CL_GP0_ADDR 0x1888020
|
#define SP_SCSR_MB1_SP2CL_GP0_ADDR 0x1888020
|
||||||
#define SP_SCSR_MB3_SP2CL_GP0_ADDR 0x188C020
|
#define SP_SCSR_MB3_SP2CL_GP0_ADDR 0x188C020
|
||||||
|
|
||||||
#define MAX_ROT_DATA_SIZE_IN_BYTES 4096
|
|
||||||
|
|
||||||
static bool ssr_already_occurred_since_boot;
|
|
||||||
|
|
||||||
#define NUM_OF_DEBUG_REGISTERS_READ 0x3
|
#define NUM_OF_DEBUG_REGISTERS_READ 0x3
|
||||||
struct spss_data {
|
struct spss_data {
|
||||||
const char *firmware_name;
|
const char *firmware_name;
|
||||||
@@ -302,74 +298,13 @@ static bool check_status(struct qcom_spss *spss, int *ret_error)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manage_unused_pil_region_memory(struct qcom_spss *spss)
|
|
||||||
{
|
|
||||||
unsigned int src_vmid_list;
|
|
||||||
struct qcom_scm_vmperm newvm[2];
|
|
||||||
u8 *spss_rot_data;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
spss_rot_data = kcalloc(MAX_ROT_DATA_SIZE_IN_BYTES, sizeof(*spss_rot_data), GFP_KERNEL);
|
|
||||||
if (!spss_rot_data)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When assigning memory to different ownership, previous data is erased,
|
|
||||||
* ROT data needs to remain in SPSS region as written by SPSS before.
|
|
||||||
*/
|
|
||||||
memcpy(spss_rot_data,
|
|
||||||
(uint8_t *)(uintptr_t)(spss->mem_region+spss->mem_size-MAX_ROT_DATA_SIZE_IN_BYTES),
|
|
||||||
MAX_ROT_DATA_SIZE_IN_BYTES);
|
|
||||||
|
|
||||||
src_vmid_list = BIT(QCOM_SCM_VMID_HLOS);
|
|
||||||
|
|
||||||
newvm[0].vmid = QCOM_SCM_VMID_HLOS;
|
|
||||||
newvm[0].perm = QCOM_SCM_PERM_RW;
|
|
||||||
newvm[1].vmid = QCOM_SCM_VMID_CP_SPSS_SP;
|
|
||||||
newvm[1].perm = QCOM_SCM_PERM_RW;
|
|
||||||
|
|
||||||
res = qcom_scm_assign_mem(spss->mem_phys + spss->mem_size - MAX_ROT_DATA_SIZE_IN_BYTES,
|
|
||||||
MAX_ROT_DATA_SIZE_IN_BYTES, &src_vmid_list, newvm, 2);
|
|
||||||
if (res) {
|
|
||||||
dev_err(spss->dev, "qcom_scm_assign_mem failed %d\n", res);
|
|
||||||
kfree(spss_rot_data);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy((uint8_t *)(uintptr_t)(spss->mem_region+spss->mem_size-MAX_ROT_DATA_SIZE_IN_BYTES),
|
|
||||||
spss_rot_data, MAX_ROT_DATA_SIZE_IN_BYTES);
|
|
||||||
|
|
||||||
kfree(spss_rot_data);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spss_load(struct rproc *rproc, const struct firmware *fw)
|
static int spss_load(struct rproc *rproc, const struct firmware *fw)
|
||||||
{
|
{
|
||||||
struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
|
struct qcom_spss *spss = (struct qcom_spss *)rproc->priv;
|
||||||
int res;
|
|
||||||
|
|
||||||
res = qcom_mdt_load(spss->dev, fw, rproc->firmware, spss->pas_id,
|
return qcom_mdt_load(spss->dev, fw, rproc->firmware, spss->pas_id,
|
||||||
spss->mem_region, spss->mem_phys, spss->mem_size,
|
spss->mem_region, spss->mem_phys, spss->mem_size,
|
||||||
&spss->mem_reloc);
|
&spss->mem_reloc);
|
||||||
|
|
||||||
if (res) {
|
|
||||||
dev_err(spss->dev, "qcom_mdt_load of SPSS image failed, error value %d\n", res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* During SSR only PIL memory is released.
|
|
||||||
* If an SSR already occurred, the memory beyond image_size
|
|
||||||
* remains assigned since PIL didn't own it.
|
|
||||||
*/
|
|
||||||
if (!ssr_already_occurred_since_boot) {
|
|
||||||
res = manage_unused_pil_region_memory(spss);
|
|
||||||
/* Set to true only if memory was successfully assigned*/
|
|
||||||
if (!res)
|
|
||||||
ssr_already_occurred_since_boot = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spss_stop(struct rproc *rproc)
|
static int spss_stop(struct rproc *rproc)
|
||||||
|
|||||||
@@ -775,6 +775,51 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
|
|||||||
del_timer_sync(&sysmon->timeout_data.timer);
|
del_timer_sync(&sysmon->timeout_data.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sysmon_shutdown(struct rproc_subdev *subdev, bool crashed)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, subdev);
|
||||||
|
|
||||||
|
trace_rproc_qcom_event(dev_name(sysmon->rproc->dev.parent), SYSMON_SUBDEV_NAME,
|
||||||
|
crashed ? "crash stop" : "stop");
|
||||||
|
|
||||||
|
sysmon->shutdown_acked = false;
|
||||||
|
|
||||||
|
mutex_lock(&sysmon->state_lock);
|
||||||
|
sysmon->state = QCOM_SSR_BEFORE_SHUTDOWN;
|
||||||
|
|
||||||
|
sysmon->transaction_id++;
|
||||||
|
dev_info(sysmon->dev, "Incrementing tid for %s to %d\n", sysmon->name,
|
||||||
|
sysmon->transaction_id);
|
||||||
|
|
||||||
|
blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)sysmon);
|
||||||
|
mutex_unlock(&sysmon->state_lock);
|
||||||
|
|
||||||
|
/* Don't request graceful shutdown if we've crashed */
|
||||||
|
if (crashed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sysmon->timeout_data.timer.function = sysmon_shutdown_notif_timeout_handler;
|
||||||
|
timeout = jiffies + msecs_to_jiffies(SYSMON_NOTIF_TIMEOUT);
|
||||||
|
mod_timer(&sysmon->timeout_data.timer, timeout);
|
||||||
|
|
||||||
|
if (sysmon->ssctl_instance) {
|
||||||
|
if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2))
|
||||||
|
dev_err(sysmon->dev, "timeout waiting for ssctl service\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
del_timer_sync(&sysmon->timeout_data.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend)
|
||||||
|
{
|
||||||
|
if (suspend)
|
||||||
|
sysmon->subdev.stop = sysmon_shutdown;
|
||||||
|
else
|
||||||
|
sysmon->subdev.stop = sysmon_stop;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(qcom_sysmon_set_ops_stop);
|
||||||
|
|
||||||
static void sysmon_unprepare(struct rproc_subdev *subdev)
|
static void sysmon_unprepare(struct rproc_subdev *subdev)
|
||||||
{
|
{
|
||||||
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
|
struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon,
|
||||||
|
|||||||
@@ -5402,14 +5402,20 @@ static void ufs_qcom_hook_prepare_command(void *param, struct ufs_hba *hba,
|
|||||||
#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
|
#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
|
||||||
struct ice_data_setting setting;
|
struct ice_data_setting setting;
|
||||||
|
|
||||||
if (!crypto_qti_ice_config_start(rq, &setting)) {
|
if (!rq->crypt_keyslot) {
|
||||||
if ((rq_data_dir(rq) == WRITE) ? setting.encr_bypass : setting.decr_bypass) {
|
if (!crypto_qti_ice_config_start(rq, &setting)) {
|
||||||
lrbp->crypto_key_slot = -1;
|
if ((rq_data_dir(rq) == WRITE) ? setting.encr_bypass :
|
||||||
} else {
|
setting.decr_bypass) {
|
||||||
lrbp->crypto_key_slot = setting.crypto_data.key_index;
|
lrbp->crypto_key_slot = -1;
|
||||||
lrbp->data_unit_num = rq->bio->bi_iter.bi_sector >>
|
} else {
|
||||||
ICE_CRYPTO_DATA_UNIT_4_KB;
|
lrbp->crypto_key_slot = setting.crypto_data.key_index;
|
||||||
|
lrbp->data_unit_num = rq->bio->bi_iter.bi_sector >>
|
||||||
|
ICE_CRYPTO_DATA_UNIT_4_KB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
lrbp->crypto_key_slot = blk_ksm_get_slot_idx(rq->crypt_keyslot);
|
||||||
|
lrbp->data_unit_num = rq->crypt_ctx->bc_dun[0];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ int ufshcd_qti_hba_init_crypto_capabilities(struct ufs_hba *hba)
|
|||||||
{
|
{
|
||||||
int cap_idx;
|
int cap_idx;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
unsigned int max_slots = 0;
|
||||||
enum blk_crypto_mode_num blk_mode_num;
|
enum blk_crypto_mode_num blk_mode_num;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -212,9 +213,27 @@ int ufshcd_qti_hba_init_crypto_capabilities(struct ufs_hba *hba)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
max_slots = hba->crypto_capabilities.config_count + 1;
|
||||||
|
#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
|
||||||
|
if (max_slots > crypto_qti_ice_get_num_fde_slots()) {
|
||||||
|
/*
|
||||||
|
* Reduce the total number of slots available to FBE
|
||||||
|
* (by the number reserved for the FDE)
|
||||||
|
* Check at least one slot for backward compatibility,
|
||||||
|
* otherwise return failure
|
||||||
|
*/
|
||||||
|
if (max_slots - crypto_qti_ice_get_num_fde_slots() < 1) {
|
||||||
|
pr_err("%s: Too much slots allocated to fde\n", __func__);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
max_slots = max_slots - crypto_qti_ice_get_num_fde_slots();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The actual number of configurations supported is (CFGC+1) */
|
/* The actual number of configurations supported is (CFGC+1) */
|
||||||
err = devm_blk_ksm_init(hba->dev, &hba->ksm,
|
err = devm_blk_ksm_init(hba->dev, &hba->ksm, max_slots);
|
||||||
hba->crypto_capabilities.config_count + 1);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|||||||
@@ -614,7 +614,8 @@ static void hab_recv_unimport_msg(struct physical_channel *pchan, int vchan_exis
|
|||||||
|
|
||||||
static int hab_try_get_vchan(struct physical_channel *pchan,
|
static int hab_try_get_vchan(struct physical_channel *pchan,
|
||||||
struct hab_header *header,
|
struct hab_header *header,
|
||||||
struct virtual_channel **vchan_out)
|
struct virtual_channel **vchan_out,
|
||||||
|
int *need_ret)
|
||||||
{
|
{
|
||||||
struct virtual_channel *vchan = NULL;
|
struct virtual_channel *vchan = NULL;
|
||||||
size_t sizebytes = HAB_HEADER_GET_SIZE(*header);
|
size_t sizebytes = HAB_HEADER_GET_SIZE(*header);
|
||||||
@@ -644,6 +645,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan,
|
|||||||
*/
|
*/
|
||||||
vchan = hab_vchan_get(pchan, header);
|
vchan = hab_vchan_get(pchan, header);
|
||||||
if (!vchan) {
|
if (!vchan) {
|
||||||
|
*need_ret = 1;
|
||||||
pr_debug("vchan not found type %d vcid %x sz %zx sesn %d\n",
|
pr_debug("vchan not found type %d vcid %x sz %zx sesn %d\n",
|
||||||
payload_type, vchan_id, sizebytes, session_id);
|
payload_type, vchan_id, sizebytes, session_id);
|
||||||
|
|
||||||
@@ -661,6 +663,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan,
|
|||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else if (vchan->otherend_closed) {
|
} else if (vchan->otherend_closed) {
|
||||||
|
*need_ret = 1;
|
||||||
hab_vchan_put(vchan);
|
hab_vchan_put(vchan);
|
||||||
pr_info("vchan remote closed type %d, vchan id %x, sizebytes %zx, session %d\n",
|
pr_info("vchan remote closed type %d, vchan id %x, sizebytes %zx, session %d\n",
|
||||||
payload_type, vchan_id,
|
payload_type, vchan_id,
|
||||||
@@ -675,6 +678,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sizebytes != sizeof(struct hab_open_send_data)) {
|
if (sizebytes != sizeof(struct hab_open_send_data)) {
|
||||||
|
*need_ret = 1;
|
||||||
pr_err("%s Invalid open req type %d vcid %x bytes %zx session %d\n",
|
pr_err("%s Invalid open req type %d vcid %x bytes %zx session %d\n",
|
||||||
pchan->name, payload_type, vchan_id,
|
pchan->name, payload_type, vchan_id,
|
||||||
sizebytes, session_id);
|
sizebytes, session_id);
|
||||||
@@ -712,9 +716,10 @@ int hab_msg_recv(struct physical_channel *pchan,
|
|||||||
int found = 0;
|
int found = 0;
|
||||||
struct hab_import_data imp_data = {0};
|
struct hab_import_data imp_data = {0};
|
||||||
int irqs_disabled = irqs_disabled();
|
int irqs_disabled = irqs_disabled();
|
||||||
|
int need_ret = 0;
|
||||||
|
|
||||||
ret = hab_try_get_vchan(pchan, header, &vchan);
|
ret = hab_try_get_vchan(pchan, header, &vchan, &need_ret);
|
||||||
if (ret != 0 || ((vchan == NULL) && (payload_type == HAB_PAYLOAD_TYPE_UNIMPORT)))
|
if (need_ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (payload_type) {
|
switch (payload_type) {
|
||||||
|
|||||||
@@ -511,10 +511,9 @@ static int hgsl_alloc_pages(struct device *dev, uint32_t requested_pcount,
|
|||||||
for (i = 0; i < pcount; i++)
|
for (i = 0; i < pcount; i++)
|
||||||
pages[i] = nth_page(page, i);
|
pages[i] = nth_page(page, i);
|
||||||
_dma_cache_op(dev, page, pcount, GSL_CACHEFLAGS_FLUSH);
|
_dma_cache_op(dev, page, pcount, GSL_CACHEFLAGS_FLUSH);
|
||||||
}
|
mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
|
||||||
|
|
||||||
mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
|
|
||||||
(1 << order));
|
(1 << order));
|
||||||
|
}
|
||||||
|
|
||||||
return pcount;
|
return pcount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -968,7 +968,6 @@ static void md_dump_data(unsigned long addr, int nbytes, const char *name)
|
|||||||
|
|
||||||
static void md_reg_context_data(struct pt_regs *regs)
|
static void md_reg_context_data(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
int nbytes = 128;
|
int nbytes = 128;
|
||||||
|
|
||||||
if (user_mode(regs) || !regs->pc)
|
if (user_mode(regs) || !regs->pc)
|
||||||
@@ -977,12 +976,6 @@ static void md_reg_context_data(struct pt_regs *regs)
|
|||||||
md_dump_data(regs->pc - nbytes, nbytes * 2, "PC");
|
md_dump_data(regs->pc - nbytes, nbytes * 2, "PC");
|
||||||
md_dump_data(regs->regs[30] - nbytes, nbytes * 2, "LR");
|
md_dump_data(regs->regs[30] - nbytes, nbytes * 2, "LR");
|
||||||
md_dump_data(regs->sp - nbytes, nbytes * 2, "SP");
|
md_dump_data(regs->sp - nbytes, nbytes * 2, "SP");
|
||||||
for (i = 0; i < 30; i++) {
|
|
||||||
char name[4];
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "X%u", i);
|
|
||||||
md_dump_data(regs->regs[i] - nbytes, nbytes * 2, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void md_dump_panic_regs(void)
|
static inline void md_dump_panic_regs(void)
|
||||||
|
|||||||
@@ -1318,7 +1318,7 @@ static int init_lplh_notif(const char *buf)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
cp = buf;
|
cp = buf;
|
||||||
if (sscanf(cp, INIT ":%hu", &nClusters)) {
|
if (sscanf(cp, INIT ":%hu", &nClusters)) {
|
||||||
if (!nClusters)
|
if (!nClusters || nClusters > LPLH_CLUSTER_MAX_CNT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*ptmp++ = nClusters;
|
*ptmp++ = nClusters;
|
||||||
@@ -1358,7 +1358,7 @@ static int init_lplh_notif(const char *buf)
|
|||||||
while ((cp1 = strpbrk(cp1 + 1, ",")))
|
while ((cp1 = strpbrk(cp1 + 1, ",")))
|
||||||
nValues++;
|
nValues++;
|
||||||
|
|
||||||
if (nValues % 2 != 0)
|
if (nValues % 2 != 0 || LPLH_IPC_FREQ_VTBL_MAX_CNT < nValues/2)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*ptmp++ = nValues/2;
|
*ptmp++ = nValues/2;
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ static int subsys_suspend(struct subsystem_data *ss_data, struct rproc *rproc, u
|
|||||||
case SUBSYS_DEEPSLEEP:
|
case SUBSYS_DEEPSLEEP:
|
||||||
case SUBSYS_HIBERNATE:
|
case SUBSYS_HIBERNATE:
|
||||||
ss_data->ignore_ssr = true;
|
ss_data->ignore_ssr = true;
|
||||||
|
adsp_set_ops_stop(rproc, true);
|
||||||
rproc_shutdown(rproc);
|
rproc_shutdown(rproc);
|
||||||
ss_data->ignore_ssr = false;
|
ss_data->ignore_ssr = false;
|
||||||
break;
|
break;
|
||||||
@@ -144,6 +145,7 @@ static int subsys_resume(struct subsystem_data *ss_data, struct rproc *rproc, u3
|
|||||||
case SUBSYS_DEEPSLEEP:
|
case SUBSYS_DEEPSLEEP:
|
||||||
case SUBSYS_HIBERNATE:
|
case SUBSYS_HIBERNATE:
|
||||||
ss_data->ignore_ssr = true;
|
ss_data->ignore_ssr = true;
|
||||||
|
adsp_set_ops_stop(rproc, false);
|
||||||
ret = rproc_boot(rproc);
|
ret = rproc_boot(rproc);
|
||||||
ss_data->ignore_ssr = false;
|
ss_data->ignore_ssr = false;
|
||||||
break;
|
break;
|
||||||
@@ -571,6 +573,12 @@ static int power_state_probe(struct platform_device *pdev)
|
|||||||
if (!drv)
|
if (!drv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_NOTIFY_AOP)) {
|
||||||
|
drv->qmp = qmp_get(&pdev->dev);
|
||||||
|
if (IS_ERR(drv->qmp))
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
drv->ps_pm_nb.notifier_call = ps_pm_cb;
|
drv->ps_pm_nb.notifier_call = ps_pm_cb;
|
||||||
drv->ps_pm_nb.priority = PS_PM_NOTIFIER_PRIORITY;
|
drv->ps_pm_nb.priority = PS_PM_NOTIFIER_PRIORITY;
|
||||||
ret = register_pm_notifier(&drv->ps_pm_nb);
|
ret = register_pm_notifier(&drv->ps_pm_nb);
|
||||||
@@ -599,7 +607,7 @@ static int power_state_probe(struct platform_device *pdev)
|
|||||||
goto remove_ss;
|
goto remove_ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss_data->name = name;
|
ss_data->name = kstrdup_const(name, GFP_KERNEL);
|
||||||
ss_data->rproc_handle = rproc_handle;
|
ss_data->rproc_handle = rproc_handle;
|
||||||
|
|
||||||
ss_data->ps_ssr_nb.notifier_call = ps_ssr_cb;
|
ss_data->ps_ssr_nb.notifier_call = ps_ssr_cb;
|
||||||
@@ -625,14 +633,6 @@ static int power_state_probe(struct platform_device *pdev)
|
|||||||
list_add_tail(&ss_data->list, &drv->sub_sys_list);
|
list_add_tail(&ss_data->list, &drv->sub_sys_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_NOTIFY_AOP)) {
|
|
||||||
drv->qmp = qmp_get(&pdev->dev);
|
|
||||||
if (IS_ERR(drv->qmp)) {
|
|
||||||
ret = PTR_ERR(drv->qmp);
|
|
||||||
goto remove_ss;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = power_state_dev_init(drv);
|
ret = power_state_dev_init(drv);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto remove_ss;
|
goto remove_ss;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -28,8 +28,25 @@
|
|||||||
#define SOLVER_PRESENT 1
|
#define SOLVER_PRESENT 1
|
||||||
#define HW_CHANNEL_PRESENT 2
|
#define HW_CHANNEL_PRESENT 2
|
||||||
|
|
||||||
|
#define CMD_DB_MAX_RESOURCES 250
|
||||||
|
|
||||||
struct rsc_drv;
|
struct rsc_drv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cache_req: the request object for caching
|
||||||
|
*
|
||||||
|
* @addr: the address of the resource
|
||||||
|
* @sleep_val: the sleep vote
|
||||||
|
* @wake_val: the wake vote
|
||||||
|
* @list: linked list obj
|
||||||
|
*/
|
||||||
|
struct cache_req {
|
||||||
|
u32 addr;
|
||||||
|
u32 sleep_val;
|
||||||
|
u32 wake_val;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
|
* struct tcs_group: group of Trigger Command Sets (TCS) to send state requests
|
||||||
* to the controller
|
* to the controller
|
||||||
@@ -70,20 +87,17 @@ struct tcs_group {
|
|||||||
* @cmd: the payload that will be part of the @msg
|
* @cmd: the payload that will be part of the @msg
|
||||||
* @completion: triggered when request is done
|
* @completion: triggered when request is done
|
||||||
* @dev: the device making the request
|
* @dev: the device making the request
|
||||||
* @needs_free: check to free dynamically allocated request object
|
|
||||||
*/
|
*/
|
||||||
struct rpmh_request {
|
struct rpmh_request {
|
||||||
struct tcs_request msg;
|
struct tcs_request msg;
|
||||||
struct tcs_cmd cmd[MAX_RPMH_PAYLOAD];
|
struct tcs_cmd cmd[MAX_RPMH_PAYLOAD];
|
||||||
struct completion *completion;
|
struct completion *completion;
|
||||||
const struct device *dev;
|
const struct device *dev;
|
||||||
bool needs_free;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct rpmh_ctrlr: our representation of the controller
|
* struct rpmh_ctrlr: our representation of the controller
|
||||||
*
|
*
|
||||||
* @cache: the list of cached requests
|
|
||||||
* @cache_lock: synchronize access to the cache data
|
* @cache_lock: synchronize access to the cache data
|
||||||
* @dirty: was the cache updated since flush
|
* @dirty: was the cache updated since flush
|
||||||
* @in_solver_mode: Controller is busy in solver mode
|
* @in_solver_mode: Controller is busy in solver mode
|
||||||
@@ -91,12 +105,13 @@ struct rpmh_request {
|
|||||||
* @batch_cache: Cache sleep and wake requests sent as batch
|
* @batch_cache: Cache sleep and wake requests sent as batch
|
||||||
*/
|
*/
|
||||||
struct rpmh_ctrlr {
|
struct rpmh_ctrlr {
|
||||||
struct list_head cache;
|
|
||||||
spinlock_t cache_lock;
|
spinlock_t cache_lock;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
bool in_solver_mode;
|
bool in_solver_mode;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct list_head batch_cache;
|
struct rpmh_request batch_cache[RPMH_ACTIVE_ONLY_STATE];
|
||||||
|
u32 non_batch_cache_idx;
|
||||||
|
struct cache_req *non_batch_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -704,11 +704,22 @@ static int find_free_tcs(struct tcs_group *tcs)
|
|||||||
const struct rsc_drv *drv = tcs->drv;
|
const struct rsc_drv *drv = tcs->drv;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned long max = tcs->offset + tcs->num_tcs;
|
unsigned long max = tcs->offset + tcs->num_tcs;
|
||||||
|
int timeout = 100;
|
||||||
|
|
||||||
i = find_next_zero_bit(drv->tcs_in_use, max, tcs->offset);
|
i = find_next_zero_bit(drv->tcs_in_use, max, tcs->offset);
|
||||||
if (i >= max)
|
if (i >= max)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
while (timeout) {
|
||||||
|
if (read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], i))
|
||||||
|
break;
|
||||||
|
timeout--;
|
||||||
|
udelay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!timeout)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,17 +802,20 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int c
|
|||||||
|
|
||||||
tcs->req[tcs_id - tcs->offset] = msg;
|
tcs->req[tcs_id - tcs->offset] = msg;
|
||||||
set_bit(tcs_id, drv->tcs_in_use);
|
set_bit(tcs_id, drv->tcs_in_use);
|
||||||
if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
|
|
||||||
/*
|
/*
|
||||||
* Clear previously programmed WAKE commands in selected
|
* Clear previously programmed ACTIVE/WAKE commands in selected
|
||||||
* repurposed TCS to avoid triggering them. tcs->slots will be
|
* repurposed TCS to avoid triggering them. tcs->slots will be
|
||||||
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
|
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
|
||||||
*/
|
*/
|
||||||
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
|
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
|
||||||
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0);
|
write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0);
|
||||||
|
|
||||||
|
if (msg->wait_for_compl || (msg->state == RPMH_ACTIVE_ONLY_STATE &&
|
||||||
|
tcs->type != ACTIVE_TCS))
|
||||||
enable_tcs_irq(drv, tcs_id, true);
|
enable_tcs_irq(drv, tcs_id, true);
|
||||||
}
|
else
|
||||||
spin_unlock_irqrestore(&drv->lock, flags);
|
enable_tcs_irq(drv, tcs_id, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These two can be done after the lock is released because:
|
* These two can be done after the lock is released because:
|
||||||
@@ -813,7 +827,16 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int c
|
|||||||
*/
|
*/
|
||||||
__tcs_buffer_write(drv, tcs_id, 0, msg);
|
__tcs_buffer_write(drv, tcs_id, 0, msg);
|
||||||
__tcs_set_trigger(drv, tcs_id, true);
|
__tcs_set_trigger(drv, tcs_id, true);
|
||||||
ipc_log_string(drv->ipc_log_ctx, "TCS trigger: m=%d", tcs_id);
|
ipc_log_string(drv->ipc_log_ctx, "TCS trigger: m=%d wait_for_compl=%u",
|
||||||
|
tcs_id, msg->wait_for_compl);
|
||||||
|
|
||||||
|
if (!msg->wait_for_compl)
|
||||||
|
clear_bit(tcs_id, drv->tcs_in_use);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&drv->lock, flags);
|
||||||
|
|
||||||
|
if (!msg->wait_for_compl)
|
||||||
|
wake_up(&drv->tcs_wait);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1195,6 +1218,13 @@ int rpmh_rsc_is_tcs_completed(struct rsc_drv *drv, int ch)
|
|||||||
sts &= CH1_WAKE_TCS_STATUS;
|
sts &= CH1_WAKE_TCS_STATUS;
|
||||||
|
|
||||||
retry--;
|
retry--;
|
||||||
|
/*
|
||||||
|
* Wait till all the WAKE votes of the new channel are
|
||||||
|
* applied during channel switch.
|
||||||
|
* Maximum delay of 100 usec.
|
||||||
|
*/
|
||||||
|
if (!sts)
|
||||||
|
udelay(10);
|
||||||
} while (!sts && retry);
|
} while (!sts && retry);
|
||||||
|
|
||||||
if (!retry) {
|
if (!retry) {
|
||||||
@@ -1586,7 +1616,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
|||||||
struct rsc_drv_top *rsc_top;
|
struct rsc_drv_top *rsc_top;
|
||||||
int ret, irq;
|
int ret, irq;
|
||||||
u32 rsc_id, major_ver, minor_ver, solver_config;
|
u32 rsc_id, major_ver, minor_ver, solver_config;
|
||||||
int i, drv_count;
|
int i, j, drv_count;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1717,6 +1747,13 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
|||||||
spin_lock_init(&drv[i].lock);
|
spin_lock_init(&drv[i].lock);
|
||||||
init_waitqueue_head(&drv[i].tcs_wait);
|
init_waitqueue_head(&drv[i].tcs_wait);
|
||||||
bitmap_zero(drv[i].tcs_in_use, MAX_TCS_NR);
|
bitmap_zero(drv[i].tcs_in_use, MAX_TCS_NR);
|
||||||
|
drv[i].client.non_batch_cache = devm_kcalloc(&pdev->dev, CMD_DB_MAX_RESOURCES,
|
||||||
|
sizeof(struct cache_req), GFP_KERNEL);
|
||||||
|
if (!drv[i].client.non_batch_cache)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (j = 0; j < CMD_DB_MAX_RESOURCES; j++)
|
||||||
|
INIT_LIST_HEAD(&drv[i].client.non_batch_cache[j].list);
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, drv[i].id);
|
irq = platform_get_irq(pdev, drv[i].id);
|
||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
@@ -1731,8 +1768,6 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
spin_lock_init(&drv[i].client.cache_lock);
|
spin_lock_init(&drv[i].client.cache_lock);
|
||||||
INIT_LIST_HEAD(&drv[i].client.cache);
|
|
||||||
INIT_LIST_HEAD(&drv[i].client.batch_cache);
|
|
||||||
|
|
||||||
drv[i].ipc_log_ctx = ipc_log_context_create(
|
drv[i].ipc_log_ctx = ipc_log_context_create(
|
||||||
RSC_DRV_IPC_LOG_SIZE,
|
RSC_DRV_IPC_LOG_SIZE,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
@@ -36,40 +36,10 @@
|
|||||||
.cmd = { { 0 } }, \
|
.cmd = { { 0 } }, \
|
||||||
.completion = q, \
|
.completion = q, \
|
||||||
.dev = device, \
|
.dev = device, \
|
||||||
.needs_free = false, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
|
#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
|
||||||
|
|
||||||
/**
|
|
||||||
* struct cache_req: the request object for caching
|
|
||||||
*
|
|
||||||
* @addr: the address of the resource
|
|
||||||
* @sleep_val: the sleep vote
|
|
||||||
* @wake_val: the wake vote
|
|
||||||
* @list: linked list obj
|
|
||||||
*/
|
|
||||||
struct cache_req {
|
|
||||||
u32 addr;
|
|
||||||
u32 sleep_val;
|
|
||||||
u32 wake_val;
|
|
||||||
struct list_head list;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct batch_cache_req - An entry in our batch catch
|
|
||||||
*
|
|
||||||
* @list: linked list obj
|
|
||||||
* @count: number of messages
|
|
||||||
* @rpm_msgs: the messages
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct batch_cache_req {
|
|
||||||
struct list_head list;
|
|
||||||
int count;
|
|
||||||
struct rpmh_request *rpm_msgs;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev)
|
static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct rsc_drv *drv = dev_get_drvdata(dev->parent);
|
struct rsc_drv *drv = dev_get_drvdata(dev->parent);
|
||||||
@@ -108,30 +78,32 @@ void rpmh_tx_done(const struct tcs_request *msg)
|
|||||||
struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
|
struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request,
|
||||||
msg);
|
msg);
|
||||||
struct completion *compl = rpm_msg->completion;
|
struct completion *compl = rpm_msg->completion;
|
||||||
bool free = rpm_msg->needs_free;
|
|
||||||
|
|
||||||
if (!compl)
|
if (!compl)
|
||||||
goto exit;
|
return;
|
||||||
|
|
||||||
/* Signal the blocking thread we are done */
|
/* Signal the blocking thread we are done */
|
||||||
complete(compl);
|
complete(compl);
|
||||||
|
|
||||||
exit:
|
|
||||||
if (free)
|
|
||||||
kfree(rpm_msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr)
|
static struct cache_req *get_non_batch_cache_req(struct rpmh_ctrlr *ctrlr, u32 addr)
|
||||||
{
|
{
|
||||||
struct cache_req *p, *req = NULL;
|
struct cache_req *req = ctrlr->non_batch_cache;
|
||||||
|
int i;
|
||||||
|
|
||||||
list_for_each_entry(p, &ctrlr->cache, list) {
|
if (ctrlr->non_batch_cache_idx >= CMD_DB_MAX_RESOURCES)
|
||||||
if (p->addr == addr) {
|
return NULL;
|
||||||
req = p;
|
|
||||||
break;
|
for (i = 0; i < ctrlr->non_batch_cache_idx; i++) {
|
||||||
}
|
req = &ctrlr->non_batch_cache[i];
|
||||||
|
if (req->addr == addr)
|
||||||
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req = &ctrlr->non_batch_cache[ctrlr->non_batch_cache_idx];
|
||||||
|
req->sleep_val = req->wake_val = UINT_MAX;
|
||||||
|
ctrlr->non_batch_cache_idx++;
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,21 +116,14 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
|
|||||||
u32 old_sleep_val, old_wake_val;
|
u32 old_sleep_val, old_wake_val;
|
||||||
|
|
||||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||||
req = __find_req(ctrlr, cmd->addr);
|
|
||||||
if (req)
|
|
||||||
goto existing;
|
|
||||||
|
|
||||||
req = kzalloc(sizeof(*req), GFP_ATOMIC);
|
req = get_non_batch_cache_req(ctrlr, cmd->addr);
|
||||||
if (!req) {
|
if (!req) {
|
||||||
req = ERR_PTR(-ENOMEM);
|
req = ERR_PTR(-ENOMEM);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->addr = cmd->addr;
|
req->addr = cmd->addr;
|
||||||
req->sleep_val = req->wake_val = UINT_MAX;
|
|
||||||
list_add_tail(&req->list, &ctrlr->cache);
|
|
||||||
|
|
||||||
existing:
|
|
||||||
old_sleep_val = req->sleep_val;
|
old_sleep_val = req->sleep_val;
|
||||||
old_wake_val = req->wake_val;
|
old_wake_val = req->wake_val;
|
||||||
|
|
||||||
@@ -255,29 +220,23 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
|
|||||||
int rpmh_write_async(const struct device *dev, enum rpmh_state state,
|
int rpmh_write_async(const struct device *dev, enum rpmh_state state,
|
||||||
const struct tcs_cmd *cmd, u32 n)
|
const struct tcs_cmd *cmd, u32 n)
|
||||||
{
|
{
|
||||||
|
DEFINE_RPMH_MSG_ONSTACK(dev, state, NULL, rpm_msg);
|
||||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||||
struct rpmh_request *rpm_msg;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (rpmh_standalone)
|
if (rpmh_standalone)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
rpm_msg.msg.wait_for_compl = false;
|
||||||
ret = check_ctrlr_state(ctrlr, state);
|
ret = check_ctrlr_state(ctrlr, state);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC);
|
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n);
|
||||||
if (!rpm_msg)
|
if (ret)
|
||||||
return -ENOMEM;
|
|
||||||
rpm_msg->needs_free = true;
|
|
||||||
|
|
||||||
ret = __fill_rpmh_msg(rpm_msg, state, cmd, n);
|
|
||||||
if (ret) {
|
|
||||||
kfree(rpm_msg);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
return __rpmh_write(dev, state, rpm_msg);
|
return __rpmh_write(dev, state, &rpm_msg);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rpmh_write_async);
|
EXPORT_SYMBOL(rpmh_write_async);
|
||||||
|
|
||||||
@@ -324,35 +283,18 @@ int rpmh_write(const struct device *dev, enum rpmh_state state,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rpmh_write);
|
EXPORT_SYMBOL(rpmh_write);
|
||||||
|
|
||||||
static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
|
||||||
list_add_tail(&req->list, &ctrlr->batch_cache);
|
|
||||||
ctrlr->dirty = true;
|
|
||||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch)
|
static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch)
|
||||||
{
|
{
|
||||||
struct batch_cache_req *req;
|
int ret;
|
||||||
const struct rpmh_request *rpm_msg;
|
|
||||||
int ret = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Send Sleep/Wake requests to the controller, expect no response */
|
/* Send Sleep/Wake requests to the controller, expect no response IRQ */
|
||||||
list_for_each_entry(req, &ctrlr->batch_cache, list) {
|
ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr),
|
||||||
for (i = 0; i < req->count; i++) {
|
&ctrlr->batch_cache[RPMH_SLEEP_STATE].msg, ch);
|
||||||
rpm_msg = req->rpm_msgs + i;
|
if (ret)
|
||||||
ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr),
|
return ret;
|
||||||
&rpm_msg->msg, ch);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr),
|
||||||
|
&ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE].msg, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -375,14 +317,10 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch)
|
|||||||
int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
||||||
const struct tcs_cmd *cmd, u32 *n)
|
const struct tcs_cmd *cmd, u32 *n)
|
||||||
{
|
{
|
||||||
struct batch_cache_req *req;
|
DECLARE_COMPLETION_ONSTACK(compl);
|
||||||
struct rpmh_request *rpm_msgs;
|
DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg);
|
||||||
struct completion *compls;
|
|
||||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||||
unsigned long time_left;
|
int ret, ch;
|
||||||
int count = 0;
|
|
||||||
int ret, i, ch;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
if (rpmh_standalone)
|
if (rpmh_standalone)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -391,73 +329,46 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!cmd || !n)
|
if (state == RPMH_ACTIVE_ONLY_STATE) {
|
||||||
return -EINVAL;
|
ret = __fill_rpmh_msg(&rpm_msg, state, cmd, *n);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
memset(&ctrlr->batch_cache[state], 0, sizeof(struct rpmh_request));
|
||||||
|
ret = __fill_rpmh_msg(&ctrlr->batch_cache[state], state, cmd, *n);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
while (n[count] > 0)
|
spin_lock(&ctrlr->cache_lock);
|
||||||
count++;
|
ctrlr->dirty = true;
|
||||||
if (!count)
|
spin_unlock(&ctrlr->cache_lock);
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ptr = kzalloc(sizeof(*req) +
|
|
||||||
count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)),
|
|
||||||
GFP_ATOMIC);
|
|
||||||
if (!ptr)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
req = ptr;
|
|
||||||
rpm_msgs = ptr + sizeof(*req);
|
|
||||||
compls = ptr + sizeof(*req) + count * sizeof(*rpm_msgs);
|
|
||||||
|
|
||||||
req->count = count;
|
|
||||||
req->rpm_msgs = rpm_msgs;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
__fill_rpmh_msg(rpm_msgs + i, state, cmd, n[i]);
|
|
||||||
cmd += n[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state != RPMH_ACTIVE_ONLY_STATE) {
|
|
||||||
cache_batch(ctrlr, req);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr));
|
ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr));
|
||||||
if (ch < 0) {
|
if (ch < 0)
|
||||||
kfree(ptr);
|
|
||||||
return ch;
|
return ch;
|
||||||
|
|
||||||
|
ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Error(%d) sending RPMH message addr=%#x\n",
|
||||||
|
ret, rpm_msg.msg.cmds[0].addr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
ret = wait_for_completion_timeout(&compl, RPMH_TIMEOUT_MS);
|
||||||
struct completion *compl = &compls[i];
|
if (!ret) {
|
||||||
|
/*
|
||||||
init_completion(compl);
|
* Better hope they never finish because they'll signal
|
||||||
rpm_msgs[i].completion = compl;
|
* the completion that we're going to free once
|
||||||
ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg, ch);
|
* we've returned from this function.
|
||||||
if (ret) {
|
*/
|
||||||
pr_err("Error(%d) sending RPMH message addr=%#x\n",
|
rpmh_rsc_debug(ctrlr_to_drv(ctrlr), &compl);
|
||||||
ret, rpm_msgs[i].msg.cmds[0].addr);
|
BUG_ON(1);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_left = RPMH_TIMEOUT_MS;
|
return 0;
|
||||||
while (i--) {
|
|
||||||
time_left = wait_for_completion_timeout(&compls[i], time_left);
|
|
||||||
if (!time_left) {
|
|
||||||
/*
|
|
||||||
* Better hope they never finish because they'll signal
|
|
||||||
* the completion that we're going to free once
|
|
||||||
* we've returned from this function.
|
|
||||||
*/
|
|
||||||
rpmh_rsc_debug(ctrlr_to_drv(ctrlr), &compls[i]);
|
|
||||||
BUG_ON(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(ptr);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rpmh_write_batch);
|
EXPORT_SYMBOL(rpmh_write_batch);
|
||||||
|
|
||||||
@@ -485,7 +396,7 @@ static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state,
|
|||||||
int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
||||||
{
|
{
|
||||||
struct cache_req *p;
|
struct cache_req *p;
|
||||||
int ret = 0;
|
int ret = 0, i;
|
||||||
|
|
||||||
if (!ctrlr->dirty) {
|
if (!ctrlr->dirty) {
|
||||||
pr_debug("Skipping flush, TCS has latest data.\n");
|
pr_debug("Skipping flush, TCS has latest data.\n");
|
||||||
@@ -500,7 +411,8 @@ int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
list_for_each_entry(p, &ctrlr->cache, list) {
|
for (i = 0; i < ctrlr->non_batch_cache_idx; i++) {
|
||||||
|
p = &ctrlr->non_batch_cache[i];
|
||||||
if (!is_req_valid(p)) {
|
if (!is_req_valid(p)) {
|
||||||
pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x\n",
|
pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x\n",
|
||||||
__func__, p->addr, p->sleep_val, p->wake_val);
|
__func__, p->addr, p->sleep_val, p->wake_val);
|
||||||
@@ -533,6 +445,7 @@ int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
|||||||
*/
|
*/
|
||||||
int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (rpmh_standalone)
|
if (rpmh_standalone)
|
||||||
@@ -552,14 +465,9 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch)
|
|||||||
if (!(ctrlr->flags & SOLVER_PRESENT))
|
if (!(ctrlr->flags & SOLVER_PRESENT))
|
||||||
lockdep_assert_irqs_disabled();
|
lockdep_assert_irqs_disabled();
|
||||||
|
|
||||||
/*
|
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||||
* If the lock is busy it means another transaction is on going,
|
|
||||||
* in such case it's better to abort than spin.
|
|
||||||
*/
|
|
||||||
if (!spin_trylock(&ctrlr->cache_lock))
|
|
||||||
return -EBUSY;
|
|
||||||
ret = _rpmh_flush(ctrlr, ch);
|
ret = _rpmh_flush(ctrlr, ch);
|
||||||
spin_unlock(&ctrlr->cache_lock);
|
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -628,19 +536,14 @@ EXPORT_SYMBOL(rpmh_write_sleep_and_wake_no_child);
|
|||||||
void rpmh_invalidate(const struct device *dev)
|
void rpmh_invalidate(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||||
struct batch_cache_req *req, *tmp;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (rpmh_standalone)
|
if (rpmh_standalone)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||||
list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) {
|
memset(&ctrlr->batch_cache[RPMH_SLEEP_STATE], 0, sizeof(struct rpmh_request));
|
||||||
list_del(&req->list);
|
memset(&ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE], 0, sizeof(struct rpmh_request));
|
||||||
kfree(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ctrlr->batch_cache);
|
|
||||||
ctrlr->dirty = true;
|
ctrlr->dirty = true;
|
||||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1051,10 +1051,15 @@ static ssize_t slatecom_char_write(struct file *f, const char __user *buf,
|
|||||||
unsigned char qcli_cmnd;
|
unsigned char qcli_cmnd;
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct slatedaemon_priv *dev = container_of(slatecom_intf_drv,
|
struct slatedaemon_priv *dev = NULL;
|
||||||
|
|
||||||
|
if (!slatecom_intf_drv) {
|
||||||
|
pr_err("Invalid use-case, slatecom driver is not ready\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
dev = container_of(slatecom_intf_drv,
|
||||||
struct slatedaemon_priv,
|
struct slatedaemon_priv,
|
||||||
lhndl);
|
lhndl);
|
||||||
|
|
||||||
if (copy_from_user(&qcli_cmnd, buf, sizeof(unsigned char)))
|
if (copy_from_user(&qcli_cmnd, buf, sizeof(unsigned char)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ static int slatecom_transfer(void *handle, uint8_t *tx_buf,
|
|||||||
struct spi_transfer *tx_xfer;
|
struct spi_transfer *tx_xfer;
|
||||||
struct slate_spi_priv *slate_spi;
|
struct slate_spi_priv *slate_spi;
|
||||||
struct slate_context *cntx;
|
struct slate_context *cntx;
|
||||||
struct spi_device *spi;
|
struct spi_device *spi = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!handle || !tx_buf)
|
if (!handle || !tx_buf)
|
||||||
@@ -428,8 +428,11 @@ void send_event(enum slatecom_event_type event,
|
|||||||
|
|
||||||
void slatecom_slatedown_handler(void)
|
void slatecom_slatedown_handler(void)
|
||||||
{
|
{
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
|
if (!is_slatecom_ready())
|
||||||
|
return;
|
||||||
|
spi = get_spi_device();
|
||||||
g_slav_status_reg = 0;
|
g_slav_status_reg = 0;
|
||||||
atomic_set(&ok_to_sleep, 0);
|
atomic_set(&ok_to_sleep, 0);
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
@@ -863,7 +866,7 @@ int slatecom_ahb_read(void *handle, uint32_t ahb_start_addr,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint8_t cmnd = 0;
|
uint8_t cmnd = 0;
|
||||||
uint32_t ahb_addr = 0;
|
uint32_t ahb_addr = 0;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!handle || !read_buf || num_words == 0
|
if (!handle || !read_buf || num_words == 0
|
||||||
|| num_words > SLATE_SPI_MAX_WORDS) {
|
|| num_words > SLATE_SPI_MAX_WORDS) {
|
||||||
@@ -877,7 +880,7 @@ int slatecom_ahb_read(void *handle, uint32_t ahb_start_addr,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -928,7 +931,7 @@ int slatecom_ahb_write_bytes(void *handle, uint32_t ahb_start_addr,
|
|||||||
uint8_t cmnd = 0;
|
uint8_t cmnd = 0;
|
||||||
uint32_t ahb_addr = 0;
|
uint32_t ahb_addr = 0;
|
||||||
uint32_t curr_num_bytes;
|
uint32_t curr_num_bytes;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!handle || !write_buf || num_bytes == 0
|
if (!handle || !write_buf || num_bytes == 0
|
||||||
|| num_bytes > (SLATE_SPI_MAX_WORDS * sizeof(int))) {
|
|| num_bytes > (SLATE_SPI_MAX_WORDS * sizeof(int))) {
|
||||||
@@ -943,7 +946,7 @@ int slatecom_ahb_write_bytes(void *handle, uint32_t ahb_start_addr,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -998,7 +1001,7 @@ int slatecom_ahb_write(void *handle, uint32_t ahb_start_addr,
|
|||||||
uint32_t ahb_addr = 0;
|
uint32_t ahb_addr = 0;
|
||||||
uint32_t curr_num_words;
|
uint32_t curr_num_words;
|
||||||
uint32_t curr_num_bytes;
|
uint32_t curr_num_bytes;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!handle || !write_buf || num_words == 0
|
if (!handle || !write_buf || num_words == 0
|
||||||
|| num_words > SLATE_SPI_MAX_WORDS) {
|
|| num_words > SLATE_SPI_MAX_WORDS) {
|
||||||
@@ -1013,7 +1016,7 @@ int slatecom_ahb_write(void *handle, uint32_t ahb_start_addr,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -1062,13 +1065,11 @@ int slatecom_fifo_write(void *handle, uint32_t num_words,
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint8_t cmnd = 0;
|
uint8_t cmnd = 0;
|
||||||
struct spi_device *spi;
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!is_slatecom_ready())
|
if (!is_slatecom_ready())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
spi = get_spi_device();
|
|
||||||
|
|
||||||
if (!handle || !write_buf || num_words == 0
|
if (!handle || !write_buf || num_words == 0
|
||||||
|| num_words > SLATE_SPI_MAX_WORDS) {
|
|| num_words > SLATE_SPI_MAX_WORDS) {
|
||||||
SLATECOM_ERR("Invalid param\n");
|
SLATECOM_ERR("Invalid param\n");
|
||||||
@@ -1079,7 +1080,7 @@ int slatecom_fifo_write(void *handle, uint32_t num_words,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -1116,7 +1117,7 @@ int slatecom_fifo_read(void *handle, uint32_t num_words,
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t cmnd = 0;
|
uint8_t cmnd = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!handle || !read_buf || num_words == 0
|
if (!handle || !read_buf || num_words == 0
|
||||||
|| num_words > SLATE_SPI_MAX_WORDS) {
|
|| num_words > SLATE_SPI_MAX_WORDS) {
|
||||||
@@ -1131,7 +1132,7 @@ int slatecom_fifo_read(void *handle, uint32_t num_words,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -1216,8 +1217,9 @@ int slatecom_reg_write(void *handle, uint8_t reg_start_addr,
|
|||||||
uint8_t num_regs, void *write_buf)
|
uint8_t num_regs, void *write_buf)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
@@ -1294,7 +1296,7 @@ int slatecom_reg_read(void *handle, uint8_t reg_start_addr,
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint8_t cmnd = 0;
|
uint8_t cmnd = 0;
|
||||||
struct spi_device *spi = get_spi_device();
|
struct spi_device *spi = NULL;
|
||||||
|
|
||||||
if (!handle || !read_buf || num_regs == 0
|
if (!handle || !read_buf || num_regs == 0
|
||||||
|| num_regs > SLATE_SPI_MAX_REGS) {
|
|| num_regs > SLATE_SPI_MAX_REGS) {
|
||||||
@@ -1309,7 +1311,7 @@ int slatecom_reg_read(void *handle, uint8_t reg_start_addr,
|
|||||||
SLATECOM_ERR("Device busy\n");
|
SLATECOM_ERR("Device busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
spi = get_spi_device();
|
||||||
pm_runtime_get_sync(&spi->dev);
|
pm_runtime_get_sync(&spi->dev);
|
||||||
mutex_lock(&slate_task_mutex);
|
mutex_lock(&slate_task_mutex);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2017, 2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2009-2017, 2021 The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2017-2019, Linaro Ltd.
|
* Copyright (c) 2017-2019, Linaro Ltd.
|
||||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
@@ -371,10 +371,14 @@ struct smem_image_version {
|
|||||||
int num_parts = 0; \
|
int num_parts = 0; \
|
||||||
int str_pos = 0, i = 0, ret = 0; \
|
int str_pos = 0, i = 0, ret = 0; \
|
||||||
num_parts = socinfo_get_part_count(part_enum); \
|
num_parts = socinfo_get_part_count(part_enum); \
|
||||||
|
if (num_parts <= 0) \
|
||||||
|
return -EINVAL; \
|
||||||
part_info = kmalloc_array(num_parts, sizeof(*part_info), GFP_KERNEL); \
|
part_info = kmalloc_array(num_parts, sizeof(*part_info), GFP_KERNEL); \
|
||||||
ret = socinfo_get_subpart_info(part_enum, part_info, num_parts); \
|
ret = socinfo_get_subpart_info(part_enum, part_info, num_parts); \
|
||||||
if (ret < 0) \
|
if (ret < 0) { \
|
||||||
|
kfree(part_info); \
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
|
} \
|
||||||
for (i = 0; i < num_parts; i++) { \
|
for (i = 0; i < num_parts; i++) { \
|
||||||
str_pos += scnprintf(buf+str_pos, PAGE_SIZE-str_pos, "0x%x", \
|
str_pos += scnprintf(buf+str_pos, PAGE_SIZE-str_pos, "0x%x", \
|
||||||
part_info[i]); \
|
part_info[i]); \
|
||||||
@@ -886,8 +890,9 @@ bool
|
|||||||
socinfo_get_part_info(enum subset_part_type part)
|
socinfo_get_part_info(enum subset_part_type part)
|
||||||
{
|
{
|
||||||
uint32_t partinfo;
|
uint32_t partinfo;
|
||||||
|
uint32_t num_parts = socinfo_get_num_subset_parts();
|
||||||
|
|
||||||
if (part >= NUM_PARTS_MAX) {
|
if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX) || (part >= num_parts)) {
|
||||||
pr_err("Bad part number\n");
|
pr_err("Bad part number\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -925,10 +930,11 @@ int
|
|||||||
socinfo_get_part_count(enum subset_part_type part)
|
socinfo_get_part_count(enum subset_part_type part)
|
||||||
{
|
{
|
||||||
int part_count = 1;
|
int part_count = 1;
|
||||||
|
uint32_t num_parts = socinfo_get_num_subset_parts();
|
||||||
|
|
||||||
/* TODO: part_count to be read from SMEM after firmware adds support */
|
/* TODO: part_count to be read from SMEM after firmware adds support */
|
||||||
|
|
||||||
if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX)) {
|
if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX) || (part >= num_parts)) {
|
||||||
pr_err("Bad part number\n");
|
pr_err("Bad part number\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1249,6 +1255,7 @@ static const struct soc_id soc_id[] = {
|
|||||||
{ 606, "MONACOAU_IVI"},
|
{ 606, "MONACOAU_IVI"},
|
||||||
{ 607, "MONACOAU_SRV1L"},
|
{ 607, "MONACOAU_SRV1L"},
|
||||||
{ 608, "CROW" },
|
{ 608, "CROW" },
|
||||||
|
{ 644, "CROW_LTE" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct qcom_socinfo *qsocinfo;
|
static struct qcom_socinfo *qsocinfo;
|
||||||
|
|||||||
@@ -3876,13 +3876,65 @@ disable_sleep_clk:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dwc3_msm_suspend_phy(struct dwc3_msm *mdwc)
|
||||||
|
{
|
||||||
|
bool can_suspend_ssphy, no_active_ss;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synopsys Superspeed PHY does not support ss_phy_irq, so to detect
|
||||||
|
* any wakeup events in host mode PHY cannot be suspended.
|
||||||
|
* This Superspeed PHY can be suspended only in the following cases:
|
||||||
|
* 1. The core is not in host mode
|
||||||
|
* 2. A Highspeed device is connected but not a Superspeed device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
no_active_ss = (!mdwc->in_host_mode) || (mdwc->in_host_mode &&
|
||||||
|
((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) &&
|
||||||
|
!dwc3_msm_is_superspeed(mdwc)));
|
||||||
|
can_suspend_ssphy = dwc3_msm_get_max_speed(mdwc) >= USB_SPEED_SUPER &&
|
||||||
|
(!(mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) || no_active_ss);
|
||||||
|
|
||||||
|
/* Suspend SS PHY */
|
||||||
|
if (can_suspend_ssphy) {
|
||||||
|
if (mdwc->in_host_mode) {
|
||||||
|
u32 reg = dwc3_msm_read_reg(mdwc->base,
|
||||||
|
DWC3_GUSB3PIPECTL(0));
|
||||||
|
|
||||||
|
reg |= DWC3_GUSB3PIPECTL_DISRXDETU3;
|
||||||
|
dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0),
|
||||||
|
reg);
|
||||||
|
}
|
||||||
|
/* indicate phy about SS mode */
|
||||||
|
if (dwc3_msm_is_superspeed(mdwc))
|
||||||
|
mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
|
||||||
|
usb_phy_set_suspend(mdwc->ss_phy, 1);
|
||||||
|
mdwc->lpm_flags |= MDWC3_SS_PHY_SUSPEND;
|
||||||
|
} else if (mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) {
|
||||||
|
mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When operating in HS host mode, check if pwr event IRQ is
|
||||||
|
* required for wakeup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mdwc->in_host_mode && (mdwc->use_pwr_event_for_wakeup
|
||||||
|
& PWR_EVENT_HS_WAKEUP))
|
||||||
|
mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP;
|
||||||
|
|
||||||
|
if (mdwc->lpm_flags & MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP) {
|
||||||
|
dwc3_msm_set_pwr_events(mdwc, true);
|
||||||
|
enable_irq(mdwc->wakeup_irq[PWR_EVNT_IRQ].irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse)
|
static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct dwc3 *dwc = NULL;
|
struct dwc3 *dwc = NULL;
|
||||||
struct dwc3_event_buffer *evt;
|
struct dwc3_event_buffer *evt;
|
||||||
struct usb_irq *uirq;
|
struct usb_irq *uirq;
|
||||||
bool can_suspend_ssphy, no_active_ss;
|
|
||||||
|
|
||||||
if (mdwc->dwc3)
|
if (mdwc->dwc3)
|
||||||
dwc = platform_get_drvdata(mdwc->dwc3);
|
dwc = platform_get_drvdata(mdwc->dwc3);
|
||||||
@@ -3959,49 +4011,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse)
|
|||||||
/* Suspend HS PHY */
|
/* Suspend HS PHY */
|
||||||
usb_phy_set_suspend(mdwc->hs_phy, 1);
|
usb_phy_set_suspend(mdwc->hs_phy, 1);
|
||||||
|
|
||||||
/*
|
dwc3_msm_suspend_phy(mdwc);
|
||||||
* Synopsys Superspeed PHY does not support ss_phy_irq, so to detect
|
|
||||||
* any wakeup events in host mode PHY cannot be suspended.
|
|
||||||
* This Superspeed PHY can be suspended only in the following cases:
|
|
||||||
* 1. The core is not in host mode
|
|
||||||
* 2. A Highspeed device is connected but not a Superspeed device
|
|
||||||
*/
|
|
||||||
no_active_ss = (!mdwc->in_host_mode) || (mdwc->in_host_mode &&
|
|
||||||
((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) &&
|
|
||||||
!dwc3_msm_is_superspeed(mdwc)));
|
|
||||||
can_suspend_ssphy = dwc3_msm_get_max_speed(mdwc) >= USB_SPEED_SUPER &&
|
|
||||||
(!(mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) || no_active_ss);
|
|
||||||
/* Suspend SS PHY */
|
|
||||||
if (can_suspend_ssphy) {
|
|
||||||
if (mdwc->in_host_mode) {
|
|
||||||
u32 reg = dwc3_msm_read_reg(mdwc->base,
|
|
||||||
DWC3_GUSB3PIPECTL(0));
|
|
||||||
|
|
||||||
reg |= DWC3_GUSB3PIPECTL_DISRXDETU3;
|
|
||||||
dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0),
|
|
||||||
reg);
|
|
||||||
}
|
|
||||||
/* indicate phy about SS mode */
|
|
||||||
if (dwc3_msm_is_superspeed(mdwc))
|
|
||||||
mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
|
|
||||||
usb_phy_set_suspend(mdwc->ss_phy, 1);
|
|
||||||
mdwc->lpm_flags |= MDWC3_SS_PHY_SUSPEND;
|
|
||||||
} else if (mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) {
|
|
||||||
mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When operating in HS host mode, check if pwr event IRQ is
|
|
||||||
* required for wakeup.
|
|
||||||
*/
|
|
||||||
if (mdwc->in_host_mode && (mdwc->use_pwr_event_for_wakeup
|
|
||||||
& PWR_EVENT_HS_WAKEUP))
|
|
||||||
mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP;
|
|
||||||
|
|
||||||
if (mdwc->lpm_flags & MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP) {
|
|
||||||
dwc3_msm_set_pwr_events(mdwc, true);
|
|
||||||
enable_irq(mdwc->wakeup_irq[PWR_EVNT_IRQ].irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure above writes are completed before turning off clocks */
|
/* make sure above writes are completed before turning off clocks */
|
||||||
wmb();
|
wmb();
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ extern enum qcom_scm_custom_reset_type qcom_scm_custom_reset_type;
|
|||||||
#define QCOM_SCM_VMID_MSS_MSA 0xF
|
#define QCOM_SCM_VMID_MSS_MSA 0xF
|
||||||
#define QCOM_SCM_VMID_WLAN 0x18
|
#define QCOM_SCM_VMID_WLAN 0x18
|
||||||
#define QCOM_SCM_VMID_WLAN_CE 0x19
|
#define QCOM_SCM_VMID_WLAN_CE 0x19
|
||||||
#define QCOM_SCM_VMID_CP_SPSS_SP 0x1A
|
|
||||||
#define QCOM_SCM_PERM_READ 0x4
|
#define QCOM_SCM_PERM_READ 0x4
|
||||||
#define QCOM_SCM_PERM_WRITE 0x2
|
#define QCOM_SCM_PERM_WRITE 0x2
|
||||||
#define QCOM_SCM_PERM_EXEC 0x1
|
#define QCOM_SCM_PERM_EXEC 0x1
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ static inline int qcom_rproc_set_dtb_firmware(struct rproc *rproc, const char *d
|
|||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_QCOM_Q6V5_PAS)
|
||||||
|
void adsp_set_ops_stop(struct rproc *rproc, bool suspend);
|
||||||
|
#else
|
||||||
|
static inline void adsp_set_ops_stop(struct rproc *rproc, bool suspend) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2585,6 +2586,8 @@ enum ipa_ep_desc_type_enum_v01 {
|
|||||||
DATA_EP_DESC_TYPE_TETH_RMNET_PROD_V01 = 0x09,
|
DATA_EP_DESC_TYPE_TETH_RMNET_PROD_V01 = 0x09,
|
||||||
DATA_EP_DESC_TYPE_EMB_FLOW_CTL_CONS_V01 = 0x0A,
|
DATA_EP_DESC_TYPE_EMB_FLOW_CTL_CONS_V01 = 0x0A,
|
||||||
DATA_EP_DESC_TYPE_EMB_FLOW_CTL_PROD_V01 = 0x0B,
|
DATA_EP_DESC_TYPE_EMB_FLOW_CTL_PROD_V01 = 0x0B,
|
||||||
|
DATA_EP_DESC_TYPE_TETH_LL_CONS_V01 = 0x0C,
|
||||||
|
DATA_EP_DESC_TYPE_TETH_LL_PROD_V01 = 0x0D,
|
||||||
IPA_EP_DESC_TYPE_ENUM_MAX_VAL_V01 = IPA_INT_MAX,
|
IPA_EP_DESC_TYPE_ENUM_MAX_VAL_V01 = IPA_INT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
qcom_wdt_core.ko
|
qcom_wdt_core.ko
|
||||||
qcom_cpu_vendor_hooks.ko
|
qcom_cpu_vendor_hooks.ko
|
||||||
clk-rpmh.ko
|
|
||||||
gcc-sdm845.ko
|
|
||||||
icc-rpmh.ko
|
|
||||||
qcom_ipcc.ko
|
qcom_ipcc.ko
|
||||||
qcom_ipc_logging.ko
|
qcom_ipc_logging.ko
|
||||||
qcom-pdc.ko
|
qcom-pdc.ko
|
||||||
rpmh-regulator.ko
|
rpmh-regulator.ko
|
||||||
bwmon.ko
|
bwmon.ko
|
||||||
|
qcom_rpmh.ko
|
||||||
qcom-cpufreq-hw.ko
|
qcom-cpufreq-hw.ko
|
||||||
sched-walt.ko
|
sched-walt.ko
|
||||||
clk-dummy.ko
|
clk-rpmh.ko
|
||||||
clk-qcom.ko
|
clk-qcom.ko
|
||||||
|
clk-dummy.ko
|
||||||
|
gdsc-regulator.ko
|
||||||
|
gcc-sdm845.ko
|
||||||
|
dispcc-sdm845.ko
|
||||||
cmd-db.ko
|
cmd-db.ko
|
||||||
cqhci.ko
|
cqhci.ko
|
||||||
crypto-qti-common.ko
|
crypto-qti-common.ko
|
||||||
@@ -19,7 +21,6 @@ crypto-qti-hwkm.ko
|
|||||||
dcc_v2.ko
|
dcc_v2.ko
|
||||||
dcvs_fp.ko
|
dcvs_fp.ko
|
||||||
debug-regulator.ko
|
debug-regulator.ko
|
||||||
gdsc-regulator.ko
|
|
||||||
smp2p.ko
|
smp2p.ko
|
||||||
rproc_qcom_common.ko
|
rproc_qcom_common.ko
|
||||||
qcom_pil_info.ko
|
qcom_pil_info.ko
|
||||||
@@ -31,6 +32,9 @@ qcom_smd.ko
|
|||||||
mdt_loader.ko
|
mdt_loader.ko
|
||||||
hwkm.ko
|
hwkm.ko
|
||||||
icc-bcm-voter.ko
|
icc-bcm-voter.ko
|
||||||
|
icc-rpmh.ko
|
||||||
|
qnoc-qos.ko
|
||||||
|
qnoc-sdm670.ko
|
||||||
icc-debug.ko
|
icc-debug.ko
|
||||||
iommu-logger.ko
|
iommu-logger.ko
|
||||||
llcc-qcom.ko
|
llcc-qcom.ko
|
||||||
@@ -54,9 +58,7 @@ qcom_llcc_pmu.ko
|
|||||||
qcom-pmu-lib.ko
|
qcom-pmu-lib.ko
|
||||||
qcom-spmi-pmic.ko
|
qcom-spmi-pmic.ko
|
||||||
spmi-pmic-arb.ko
|
spmi-pmic-arb.ko
|
||||||
qcom_rpmh.ko
|
|
||||||
qcom-scm.ko
|
qcom-scm.ko
|
||||||
qnoc-qos.ko
|
|
||||||
qrtr.ko
|
qrtr.ko
|
||||||
qti-regmap-debugfs.ko
|
qti-regmap-debugfs.ko
|
||||||
regmap-spmi.ko
|
regmap-spmi.ko
|
||||||
|
|||||||
Reference in New Issue
Block a user