Add samsung specific changes

This commit is contained in:
2025-08-11 14:29:00 +02:00
parent c66122e619
commit 4d134a1294
2688 changed files with 1127995 additions and 11475 deletions

View File

@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_ADC_TM_H_CLIENTS__
#define __QCOM_ADC_TM_H_CLIENTS__
#include <linux/err.h>
#include <linux/types.h>
struct adc_tm_chip;
struct adc5_chip;
/**
* enum adc_tm_state - This lets the client know whether the threshold
* that was crossed was high/low.
* %ADC_TM_HIGH_STATE: Client is notified of crossing the requested high
* voltage threshold.
* %ADC_TM_COOL_STATE: Client is notified of crossing the requested cool
* temperature threshold.
* %ADC_TM_LOW_STATE: Client is notified of crossing the requested low
* voltage threshold.
* %ADC_TM_WARM_STATE: Client is notified of crossing the requested high
* temperature threshold.
*/
enum adc_tm_state {
ADC_TM_HIGH_STATE = 0,
ADC_TM_COOL_STATE = ADC_TM_HIGH_STATE,
ADC_TM_LOW_STATE,
ADC_TM_WARM_STATE = ADC_TM_LOW_STATE,
ADC_TM_STATE_NUM,
};
/**
* enum adc_tm_state_request - Request to enable/disable the corresponding
* high/low voltage/temperature thresholds.
* %ADC_TM_HIGH_THR_ENABLE: Enable high voltage threshold.
* %ADC_TM_COOL_THR_ENABLE = Enables cool temperature threshold.
* %ADC_TM_LOW_THR_ENABLE: Enable low voltage/temperature threshold.
* %ADC_TM_WARM_THR_ENABLE = Enables warm temperature threshold.
* %ADC_TM_HIGH_LOW_THR_ENABLE: Enable high and low voltage/temperature
* threshold.
* %ADC_TM_HIGH_THR_DISABLE: Disable high voltage/temperature threshold.
* %ADC_TM_COOL_THR_ENABLE = Disables cool temperature threshold.
* %ADC_TM_LOW_THR_DISABLE: Disable low voltage/temperature threshold.
* %ADC_TM_WARM_THR_ENABLE = Disables warm temperature threshold.
* %ADC_TM_HIGH_THR_DISABLE: Disable high and low voltage/temperature
* threshold.
*/
enum adc_tm_state_request {
ADC_TM_HIGH_THR_ENABLE = 0,
ADC_TM_COOL_THR_ENABLE = ADC_TM_HIGH_THR_ENABLE,
ADC_TM_LOW_THR_ENABLE,
ADC_TM_WARM_THR_ENABLE = ADC_TM_LOW_THR_ENABLE,
ADC_TM_HIGH_LOW_THR_ENABLE,
ADC_TM_HIGH_THR_DISABLE,
ADC_TM_COOL_THR_DISABLE = ADC_TM_HIGH_THR_DISABLE,
ADC_TM_LOW_THR_DISABLE,
ADC_TM_WARM_THR_DISABLE = ADC_TM_LOW_THR_DISABLE,
ADC_TM_HIGH_LOW_THR_DISABLE,
ADC_TM_THR_NUM,
};
struct adc_tm_param {
unsigned long id;
int low_thr;
int high_thr;
uint32_t channel;
enum adc_tm_state_request state_request;
void *btm_ctx;
void (*threshold_notification)(enum adc_tm_state state,
void *ctx);
};
struct device;
/* Public API */
#if IS_ENABLED(CONFIG_QCOM_SPMI_ADC5_GEN3)
struct adc5_chip *get_adc_tm_gen3(struct device *dev, const char *name);
int32_t adc_tm_channel_measure_gen3(struct adc5_chip *chip,
struct adc_tm_param *param);
int32_t adc_tm_disable_chan_meas_gen3(struct adc5_chip *chip,
struct adc_tm_param *param);
#else
static inline struct adc5_chip *get_adc_tm_gen3(
struct device *dev, const char *name)
{ return ERR_PTR(-ENXIO); }
static inline int32_t adc_tm_channel_measure_gen3(
struct adc5_chip *chip,
struct adc_tm_param *param)
{ return -ENXIO; }
static inline int32_t adc_tm_disable_chan_meas_gen3(
struct adc5_chip *chip,
struct adc_tm_param *param)
{ return -ENXIO; }
#endif
#endif /* __QCOM_ADC_TM_H_CLIENTS__ */

View File

@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 Google, Inc
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __ADRENO_SMMU_PRIV_H
#define __ADRENO_SMMU_PRIV_H
#include <linux/io-pgtable.h>
#include <linux/qcom-io-pgtable.h>
/**
* struct adreno_smmu_fault_info - container for key fault information
@@ -49,6 +51,7 @@ struct adreno_smmu_fault_info {
* before set_ttbr0_cfg(). If stalling on fault is enabled,
* the GPU driver must call resume_translation()
* @resume_translation: Resume translation after a fault
* @pgtbl_info: io-pagetables info for the GPUs context-bank
*
*
* The GPU driver (drm/msm) and adreno-smmu work together for controlling
@@ -61,12 +64,13 @@ struct adreno_smmu_fault_info {
* it's domain.
*/
struct adreno_smmu_priv {
const void *cookie;
const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg *cfg);
void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
void (*set_stall)(const void *cookie, bool enabled);
void (*resume_translation)(const void *cookie, bool terminate);
const void *cookie;
const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg *cfg);
void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
void (*set_stall)(const void *cookie, bool enabled);
void (*resume_translation)(const void *cookie, bool terminate);
struct qcom_io_pgtable_info pgtbl_info;
};
#endif /* __ADRENO_SMMU_PRIV_H */

View File

@@ -0,0 +1,300 @@
/*
* Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ADSP_FT_COMMON_H__
#define __ADSP_FT_COMMON_H__
#ifdef SS_SLPI_PROJECT// hal build
#ifndef IS_ENABLED
#define IS_ENABLED(x) 0
#endif
#else// kernel build
#include <linux/kernel.h>
#endif
#define PID 20000
#define NETLINK_ADSP_FAC 23
#define MAX_REG_NUM 128
/* max size of each sensor's msg_buf */
#define MSG_TYPE_SIZE_ZERO 0
#define MSG_ACCEL_MAX 128
#define MSG_GYRO_MAX 20
#define MSG_MAG_MAX 16
#define MSG_LIGHT_MAX 16
#define MSG_PROX_MAX 16
#define MSG_GYRO_TEMP_MAX 3
#define MSG_PRESSURE_TEMP_MAX 3
#define MSG_PRESSURE_MAX 128
#define MSG_FLIP_COVER_DETECTOR_MAX 3
#define MSG_BACKTAP_MAX 1
#define MSG_VOPTIC_MAX 2
#define MSG_REG_SNS_MAX 24 /* 8 * 3 */
#if IS_ENABLED(CONFIG_SUPPORT_AK09973) || defined(CONFIG_SUPPORT_AK09973)
#define MSG_DIGITAL_HALL_MAX 15
#define MSG_DIGITAL_HALL_ANGLE_MAX 58
#elif IS_ENABLED(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL) || defined(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL)
#define MSG_REF_ANGLE_MAX 9
#endif
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_DDI_COPR_FOR_LIGHT_SENSOR) || defined(CONFIG_SUPPORT_DUAL_DDI_COPR_FOR_LIGHT_SENSOR)
#define MSG_DDI_MAX 12
#endif
#if IS_ENABLED(CONFIG_SUPPORT_FLICKER) || defined(CONFIG_SUPPORT_FLICKER)
#define MSG_FLICKER_MAX 12
#endif
#define MSG_COMMON_INFO_MAX BD_SENSOR_MAX
#define ACCEL_FACTORY_CAL_PATH "/efs/FactoryApp/accel_factory_cal"
#define SUB_ACCEL_FACTORY_CAL_PATH "/efs/FactoryApp/sub_accel_factory_cal"
#define SUB2_ACCEL_FACTORY_CAL_PATH "/efs/FactoryApp/sub2_accel_factory_cal"
#define ACCEL_HIGHG_FACTORY_CAL_PATH "/efs/FactoryApp/accel_highg_factory_cal"
#define SW_OFFSET_FILE_PATH "/efs/FactoryApp/baro_sw_offset"
#if IS_ENABLED(CONFIG_SUPPORT_AK09973) || defined(CONFIG_SUPPORT_AK09973)
#define AUTO_CAL_DATA_NUM 19
#define AUTO_CAL_FILE_BUF_LEN 140
#define DIGITAL_HALL_AUTO_CAL_X_PATH "/efs/FactoryApp/digital_hall_auto_cal_x"
#define DIGITAL_HALL_AUTO_CAL_Y_PATH "/efs/FactoryApp/digital_hall_auto_cal_y"
#define DIGITAL_HALL_AUTO_CAL_Z_PATH "/efs/FactoryApp/digital_hall_auto_cal_z"
#define ENABLE_LF_STREAM 0
#endif
#define DEVICE_MODE_HALL_OPEN 0
#define DEVICE_MODE_HALL_CLOSE 1
#define SNS_SLEEP_DURATION_10S (10)
#define SNS_ISLAND_EXIT_MAX_CNT (50)
enum {
MSG_ACCEL,
MSG_GYRO,
MSG_MAG,
MSG_PRESSURE,
MSG_LIGHT,
MSG_PROX, //5
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_OPTIC) || defined(CONFIG_SUPPORT_DUAL_OPTIC)
MSG_LIGHT_SUB,
MSG_PROX_SUB,
#endif
#if IS_ENABLED(CONFIG_FLICKER_FACTORY) || defined(CONFIG_FLICKER_FACTORY)
MSG_FLICKER,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_6AXIS) || defined(CONFIG_SUPPORT_DUAL_6AXIS)
MSG_ACCEL_SUB,
MSG_GYRO_SUB,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_TRIPLE_6AXIS) || defined(CONFIG_SUPPORT_TRIPLE_6AXIS)
MSG_ACCEL_SUB2,
MSG_GYRO_SUB2,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_ACCEL_HIGHG) || defined(CONFIG_SUPPORT_ACCEL_HIGHG)
MSG_ACCEL_HIGHG,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_MAG) || defined(CONFIG_SUPPORT_DUAL_MAG)
MSG_MAG_SUB,
#endif
PHYSICAL_SENSOR_SYSFS,//MSG_TYPE_SIZE_ZERO
MSG_GYRO_TEMP,
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_6AXIS) || defined(CONFIG_SUPPORT_DUAL_6AXIS)
MSG_GYRO_SUB_TEMP,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_TRIPLE_6AXIS) || defined(CONFIG_SUPPORT_TRIPLE_6AXIS)
MSG_GYRO_SUB2_TEMP,
#endif
MSG_PRESSURE_TEMP,
MSG_MAG_CAL,//MSG_TYPE_SIZE_ZERO
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_MAG) || defined(CONFIG_SUPPORT_DUAL_MAG)
MSG_MAG_CAL_SUB,
#endif
#if IS_ENABLED(CONFIG_FLIP_COVER_DETECTOR_FACTORY) || defined(CONFIG_FLIP_COVER_DETECTOR_FACTORY)
MSG_FLIP_COVER_DETECTOR,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_VIRTUAL_OPTIC) || defined(CONFIG_SUPPORT_VIRTUAL_OPTIC)
MSG_VIR_OPTIC,
#endif
MSG_REG_SNS,//MSG_REG_SNS_MAX
#if IS_ENABLED(CONFIG_SUPPORT_AK09973) || defined(CONFIG_SUPPORT_AK09973)
MSG_DIGITAL_HALL,
MSG_DIGITAL_HALL_ANGLE,
#if ENABLE_LF_STREAM
MSG_LF_STREAM,
#endif
#elif IS_ENABLED(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL) || defined(CONFIG_SUPPORT_REF_ANGLE_WITHOUT_DIGITAL_HALL)
MSG_REF_ANGLE,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_DDI_COPR_FOR_LIGHT_SENSOR) || defined(CONFIG_SUPPORT_DUAL_DDI_COPR_FOR_LIGHT_SENSOR)
MSG_DDI,
#endif
#if IS_ENABLED(CONFIG_SUPPORT_LIGHT_MAIN2_SENSOR) || defined(CONFIG_SUPPORT_LIGHT_MAIN2_SENSOR)
MSG_LIGHT_MAIN2,
#endif
#if IS_ENABLED(CONFIG_BACKTAP_FACTORY) || defined(CONFIG_BACKTAP_FACTORY)
MSG_BACKTAP,
#endif
MSG_FACTORY_INIT_CMD,//MSG_TYPE_SIZE_ZERO
MSG_SSC_CORE,//MSG_TYPE_SIZE_ZERO
MSG_SENSOR_MAX
};
/* Netlink ENUMS Message Protocols */
enum {
MSG_TYPE_GET_RAW_DATA,
MSG_TYPE_ST_SHOW_DATA,
MSG_TYPE_SET_ACCEL_LPF,
MSG_TYPE_SET_ACCEL_MOTOR,
MSG_TYPE_GET_THRESHOLD,
MSG_TYPE_SET_THRESHOLD,
MSG_TYPE_SET_TEMPORARY_MSG,
MSG_TYPE_GET_REGISTER,
MSG_TYPE_SET_REGISTER,
MSG_TYPE_GET_DUMP_REGISTER,
MSG_TYPE_GET_CAL_DATA, /*10*/
MSG_TYPE_SET_CAL_DATA,
MSG_TYPE_GET_DHR_INFO,
MSG_TYPE_FACTORY_ENABLE,
MSG_TYPE_FACTORY_DISABLE,
MSG_TYPE_OPTION_DEFINE,
MSG_TYPE_DUMPSTATE,
MSG_TYPE_MAX
};
/* Sensor types defined by android */
/* (Keep in sync with hardware/sensors-base.h and Sensor.java.) */
#define SENSOR_HANDLE_ACCELEROMETER (1)
#define SENSOR_HANDLE_GEOMAGNETIC_FIELD (2)
#define SENSOR_HANDLE_GYROSCOPE (4)
#define SENSOR_HANDLE_LIGHT (5)
#define SENSOR_HANDLE_PRESSURE (6)
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_6AXIS)
#define SENSOR_HANDLE_ACCELEROMETER_SUB (65687)
#endif
#define SENSOR_HANDLE_ALL (0)
#define SENSOR_NAME_MAX 40
#if IS_ENABLED(CONFIG_SUPPORT_DUAL_OPTIC) || defined(CONFIG_SUPPORT_DUAL_OPTIC)
enum {
FSTATE_INACTIVE,
FSTATE_ACTIVE,
FSTATE_FAC_INACTIVE,
FSTATE_FAC_ACTIVE,
FSTATE_FAC_INACTIVE_2
};
#define LIGHT_DUAL_CHECK_MODE 13
enum {
VOPTIC_OP_CMD_FAC_FLIP,
VOPTIC_OP_CMD_SSC_FLIP,
VOPTIC_OP_CMD_SSC_FLIP_UPDATE,
VOPTIC_OP_CMD_MAX
};
#endif
enum {
COMMON_DATA_SET_ABS_OFF, // 0x00 00 47 C1
COMMON_DATA_SET_ABS_ON, // 0x01 00 47 C1
#if IS_ENABLED(CONFIG_SUPPORT_VFOLD_FLEX) || defined(CONFIG_SUPPORT_VFOLD_FLEX)
COMMON_DATA_SET_MAIN_ON, // 0x02 00 47 C1
COMMON_DATA_SET_SUB_ON, // 0x03 00 47 C1
#endif
COMMON_DATA_SET_LCD_INTENT_ON = 0xf1, // 0xf1 00 47 C1
COMMON_DATA_SET_LCD_INTENT_OFF, // 0xf2 00 47 C1
};
// for ssc_core sensor type
enum {
OPTION_TYPE_SSC_CHARGING_STATE, // for pocket mode
OPTION_TYPE_SSC_ABS_LCD_TYPE, // for pocket mode
OPTION_TYPE_SSC_LCD_TYPE, // for pocket mode + auto roation
OPTION_TYPE_SSC_LCD_INTENT_TYPE, // for auto rotation
OPTION_TYPE_SSC_DUMP_TYPE, // for pocket mode
OPTION_TYPE_SSC_AOD_RECT, // for AOD
OPTION_TYPE_SSC_AOD_LIGHT_CIRCLE, // for AOD
OPTION_TYPE_SSC_LIGHT_SEAMLESS, // for light seamless
OPTION_TYPE_SSC_AUTO_ROTATION_MODE, // for auto rotation
OPTION_TYPE_SSC_SBM_INIT, // for sar backoff motion
OPTION_TYPE_SSC_WAKEUP_REASON, // for commoninfo
OPTION_TYPE_SSC_RECOVERY, // for commoninfo
OPTION_TYPE_SSC_POCKET_INJECT, // for pocket mode
OPTION_TYPE_SSC_SSR_DUMP, // for commoninfo
OPTION_TYPE_SSC_DEVICE_MODE, // for device mode
OPTION_TYPE_SSC_MAX
};
enum {
BD_SMD, //0
BD_TILT,
BD_PICKUP,
BD_SBM,
BD_WAKEUP_MOTION,
BD_PROXIMITY,
BD_CALL_GESTURE,
BD_POCKET_MODE,
BD_LED_COVER,
BD_FLIP_COVER,
BD_DROP_CLASSIFIER, // 10
BD_POCKET_PS_MODE,
BD_STEP_CNT_ALERT,
BD_FOLDING_STATE_LPM,
BD_HINGE_ANGLE,
BD_LID_ANGLE_FUSION,
BD_ANGLE_SENSOR_STATUS,
BD_SCONTEXT_START_IDX,
BD_SEM_MOVEMENT = BD_SCONTEXT_START_IDX, //17
BD_SEM_AUTO_ROTATION,
BD_SEM_WIRELESS_CHARGING_DET,
BD_SEM_PUT_DOWN_MOTION, //20
BD_SEM_SLOCATION,
BD_SEM_AMD,
BD_SEM_AOD,
BD_SEM_FLAT_MOTION,
BD_SEM_SNS_STATUS_CHECK,
BD_SEM_DEVICE_POSITION,
BD_SEM_LOC_CHANGE_TRIGGER,
BD_SEM_FREE_FALL_DET,
BD_SEM_START_ACTIVITIES,
BD_SEM_PEDOMETER = BD_SEM_START_ACTIVITIES,
BD_SEM_STEP_LEVEL_MONITOR, //30
BD_SEM_AT_NORMAL,
BD_SEM_AT_INT,
BD_SEM_AT_BATCH,
BD_SEM_AT_EXT_INT,
BD_SEM_ACTIVITY_CAL, // Activity vehicle
BD_SENSOR_MAX
};
enum {
DEVICE_MODE_FLIP_OPEN = 1, //Folding
DEVICE_MODE_RESERVED_FOR_OEM_1 = 62,
DEVICE_MODE_MAX= 63,
};
enum {
SNS_RECOVERY_SSR = 0,
SNS_RECOVERY_SSR_DUMP_ON,
SNS_RECOVERY_SSR_DUMP_OFF,
SNS_RECOVERY_SSR_DUMP_START,
SNS_RECOVERY_SSR_DUMP_COMPLETE,
SNS_RECOVERY_SSR_RECOVERY_MSG_MAX
};
enum {
SNS_TRIGGER_SKIP = 0,
SNS_TRIGGER_PANIC,
SNS_TRIGGER_SSR,
SNS_TRIGGER_SSR_DUMP,
SNS_TRIGGER_MAX
};
#endif

View File

@@ -0,0 +1,18 @@
/* Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SLPI_LOADER_H_
#define _SLPI_LOADER_H_
#ifdef CONFIG_DSP_SLEEP_RECOVERY
int slpi_ssr(void);
#endif
#endif

View File

@@ -0,0 +1,6 @@
#ifndef SSC_SSR_REASON_H
#define SSC_SSR_REASON_H
void ssr_reason_call_back(char reason[], int len);
bool ssc_get_fssr_ignore(void);
#endif /* SSP_MOTOR_H */

View File

@@ -0,0 +1,50 @@
/*
* sb_def.h
* Samsung Mobile Battery DEF Header
*
* Copyright (C) 2012 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SB_DEF_H
#define __SB_DEF_H __FILE__
enum sb_dev_type {
SB_DEV_UNKNOWN = 0,
SB_DEV_BATTERY,
SB_DEV_DIRECT_CHARGER,
SB_DEV_DUAL_BATTERY,
SB_DEV_CHARGER,
SB_DEV_FUEL_GAUGE,
SB_DEV_WIRELESS_CHARGER,
SB_DEV_LIMITTER,
SB_DEV_DIVIDER,
SB_DEV_MODULE,
SB_DEV_MAX,
};
typedef unsigned long long sb_data;
#define cast_to_sb_data(data) ((sb_data)(data))
#define cast_to_sb_pdata(data) ((sb_data *)(data))
#define cast_sb_data(type, data) ((type)(data))
#define cast_sb_data_ptr(type, data) ((type *)(data))
#define cast_sb_pdata(type, pdata) ((type)(*pdata))
#define cast_sb_pdata_ptr(type, pdata) ((type *)(*pdata))
#endif /* __SB_DEF_H */

View File

@@ -0,0 +1,79 @@
/*
* sb_notify.h
* Samsung Mobile Battery Notify Header
*
* Copyright (C) 2012 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SB_NOTIFY_H
#define __SB_NOTIFY_H __FILE__
#include <linux/notifier.h>
#include <linux/battery/sb_def.h>
enum sbn_type {
SB_NOTIFY_UNKNOWN = 0,
SB_NOTIFY_DEV_PROBE,
SB_NOTIFY_DEV_SHUTDOWN,
SB_NOTIFY_DEV_LIST,
SB_NOTIFY_EVENT_MISC,
SB_NOTIFY_EVENT_SIOP,
SB_NOTIFY_EVENT_SLATE_MODE,
SB_NOTIFY_MAX,
};
enum{
OCP_WARN_ON,
OCP_WARN_OFF
};
struct sbn_dev_list {
const char **list;
unsigned int count;
};
struct sbn_bit_event {
unsigned int value;
unsigned int mask;
};
#define SB_NOTIFY_DISABLE (-3661)
#if IS_ENABLED(CONFIG_SB_NOTIFY)
int sb_notify_call(enum sbn_type ntype, sb_data *ndata);
int sb_notify_register(struct notifier_block *nb,
notifier_fn_t notifier, const char *name, enum sb_dev_type type);
int sb_notify_unregister(struct notifier_block *nb);
#else
static inline int sb_notify_call(enum sbn_type ntype, sb_data *ndata)
{ return SB_NOTIFY_DISABLE; }
static inline int sb_notify_register(struct notifier_block *nb,
notifier_fn_t notifier, const char *name, enum sb_dev_type type)
{ return SB_NOTIFY_DISABLE; }
static inline int sb_notify_unregister(struct notifier_block *nb)
{ return SB_NOTIFY_DISABLE; }
#endif
extern int register_ocp_warn_notifier(struct notifier_block *nb);
extern int unregister_ocp_warn_notifier(struct notifier_block *nb);
extern int ocp_warn_notifier_call_chain(unsigned long val);
#endif /* __SB_NOTIFY_H */

View File

@@ -0,0 +1,81 @@
/*
* sb_pqueue.h
* Samsung Mobile Priority Queue Header
*
* Copyright (C) 2021 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SB_PQUEUE_H
#define __SB_PQUEUE_H __FILE__
#include <linux/err.h>
#include <linux/battery/sb_def.h>
#define PQF_REMOVE 0x1
#define PQF_PRIORITY 0x2
struct sb_pqueue;
/* priority condition : data1 > data2 = true, data1 < data2 = false */
typedef bool (*cmp_func)(sb_data *data1, sb_data *data2);
#define SB_PQUEUE_DISABLE (-3660)
#if IS_ENABLED(CONFIG_SB_PQUEUE)
struct sb_pqueue *sb_pq_create(unsigned int flag, unsigned int size, cmp_func cmp);
void sb_pq_destroy(struct sb_pqueue *pq);
sb_data *sb_pq_pop(struct sb_pqueue *pq);
int sb_pq_push(struct sb_pqueue *pq, unsigned int idx, sb_data *data);
int sb_pq_get_en(struct sb_pqueue *pq, unsigned int idx);
int sb_pq_set_pri(struct sb_pqueue *pq, unsigned int idx, int pri);
int sb_pq_get_pri(struct sb_pqueue *pq, unsigned int idx);
int sb_pq_set_data(struct sb_pqueue *pq, unsigned int idx, sb_data *data);
sb_data *sb_pq_get_data(struct sb_pqueue *pq, unsigned int idx);
sb_data *sb_pq_top(struct sb_pqueue *pq);
int sb_pq_remove(struct sb_pqueue *pq, unsigned int idx);
#else
static inline struct sb_pqueue *sb_pq_create(unsigned int flag, unsigned int size, cmp_func cmp)
{ return ERR_PTR(SB_PQUEUE_DISABLE); }
static inline void sb_pq_destroy(struct sb_pqueue *pq) {}
static inline sb_data *sb_pq_pop(struct sb_pqueue *pq)
{ return ERR_PTR(SB_PQUEUE_DISABLE); }
static inline int sb_pq_push(struct sb_pqueue *pq, unsigned int idx, sb_data *data)
{ return SB_PQUEUE_DISABLE; }
static inline int sb_pq_get_en(struct sb_pqueue *pq, unsigned int idx)
{ return SB_PQUEUE_DISABLE; }
static inline int sb_pq_set_pri(struct sb_pqueue *pq, unsigned int idx, int pri)
{ return SB_PQUEUE_DISABLE; }
static inline int sb_pq_get_pri(struct sb_pqueue *pq, unsigned int idx)
{ return SB_PQUEUE_DISABLE; }
static inline int sb_pq_set_data(struct sb_pqueue *pq, unsigned int idx, sb_data *data)
{ return SB_PQUEUE_DISABLE; }
static inline sb_data *sb_pq_get_data(struct sb_pqueue *pq, unsigned int idx)
{ return ERR_PTR(SB_PQUEUE_DISABLE); }
static inline sb_data *sb_pq_top(struct sb_pqueue *pq)
{ return ERR_PTR(SB_PQUEUE_DISABLE); }
static inline int sb_pq_remove(struct sb_pqueue *pq, unsigned int idx)
{ return SB_PQUEUE_DISABLE; }
#endif
#endif /* __SB_PQUEUE_H */

View File

@@ -0,0 +1,43 @@
/*
* sb_sysfs.h
* Samsung Mobile SysFS Header
*
* Copyright (C) 2021 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SB_SYSFS_H
#define __SB_SYSFS_H __FILE__
#include <linux/err.h>
#include <linux/device.h>
#define SB_SYSFS_DISABLE (-3662)
#if IS_ENABLED(CONFIG_SB_SYSFS)
int sb_sysfs_add_attrs(const char *name, void *pdata, struct device_attribute *attr, unsigned long size);
int sb_sysfs_remove_attrs(const char *name);
void *sb_sysfs_get_pdata(const char *name);
int sb_sysfs_create_attrs(struct device *dev);
#else
static inline int sb_sysfs_add_attrs(const char *name, void *pdata, struct device_attribute *attr, unsigned long size)
{ return SB_SYSFS_DISABLE; }
static inline int sb_sysfs_remove_attrs(const char *name)
{ return SB_SYSFS_DISABLE; }
static inline void *sb_sysfs_get_pdata(const char *name)
{ return ERR_PTR(SB_SYSFS_DISABLE); }
static inline int sb_sysfs_create_attrs(struct device *dev)
{ return SB_SYSFS_DISABLE; }
#endif
#endif /* __SB_SYSFS_H */

View File

@@ -0,0 +1,101 @@
/*
* sb_vote.h
* Samsung Mobile Battery Vote Header
*
* Copyright (C) 2021 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SB_VOTE_H
#define __SB_VOTE_H __FILE__
#include <linux/err.h>
#include <linux/battery/sb_def.h>
enum {
SB_VOTE_MIN,
SB_VOTE_MAX,
SB_VOTE_EN,
SB_VOTE_DATA,
};
enum {
VOTE_PRI_0 = 0,
VOTE_PRI_1,
VOTE_PRI_2,
VOTE_PRI_3,
VOTE_PRI_4,
VOTE_PRI_5,
VOTE_PRI_6,
VOTE_PRI_7,
VOTE_PRI_8,
VOTE_PRI_9,
VOTE_PRI_10,
};
#define VOTE_PRI_MIN VOTE_PRI_0
#define VOTE_PRI_MAX VOTE_PRI_10
struct sb_vote;
typedef int (*cb_vote)(void *pdata, sb_data vdata);
typedef bool (*cmp_vote)(sb_data *vdata1, sb_data *vdata2);
struct sb_vote_cfg {
const char *name;
int type;
const char **voter_list;
int voter_num;
cb_vote cb;
cmp_vote cmp;
};
#define SB_VOTE_DISABLE (-3663)
#define SB_VOTE_DISABLE_STR "voteoff"
#if IS_ENABLED(CONFIG_SB_VOTE)
struct sb_vote *sb_vote_create(const struct sb_vote_cfg *vote_cfg, void *pdata, sb_data init_data);
void sb_vote_destroy(struct sb_vote *vote);
struct sb_vote *sb_vote_find(const char *name);
int sb_vote_get(struct sb_vote *vote, int event, sb_data *data);
int sb_vote_get_result(struct sb_vote *vote, sb_data *data);
int _sb_vote_set(struct sb_vote *vote, int event, bool en, sb_data data, const char *fname, int line);
int sb_vote_set_pri(struct sb_vote *vote, int event, int pri);
int sb_vote_refresh(struct sb_vote *vote);
#else
static inline struct sb_vote *sb_vote_create(const struct sb_vote_cfg *vote_cfg, void *pdata, sb_data init_data)
{ return ERR_PTR(SB_VOTE_DISABLE); }
static inline void sb_vote_destroy(struct sb_vote *vote) {}
static inline struct sb_vote *sb_vote_find(const char *name)
{ return ERR_PTR(SB_VOTE_DISABLE); }
static inline int sb_vote_get(struct sb_vote *vote, int event, sb_data *data)
{ return SB_VOTE_DISABLE; }
static inline int sb_vote_get_result(struct sb_vote *vote, sb_data *data)
{ return SB_VOTE_DISABLE; }
static inline int _sb_vote_set(struct sb_vote *vote, int event, bool en, sb_data data, const char *fname, int linee)
{ return SB_VOTE_DISABLE; }
static inline int sb_vote_set_pri(struct sb_vote *vote, int event, int pri)
{ return SB_VOTE_DISABLE; }
static inline int sb_vote_refresh(struct sb_vote *vote)
{ return SB_VOTE_DISABLE; }
#endif
#define sb_vote_set(vote, event, en, value) _sb_vote_set(vote, event, en, value, __func__, __LINE__)
#endif /* __SB_VOTE_H */

View File

@@ -0,0 +1,55 @@
/*
* include/linux/battery/sb_wireless.h
*
* header file supporting samsung battery wireless information
*
* Copyright (C) 2023 Samsung Electronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __SB_WIRELESS_H__
#define __SB_WIRELESS_H__
enum wpc_op_mode {
WPC_OP_MODE_NONE = 0, /* AC MISSING */
WPC_OP_MODE_BPP,
WPC_OP_MODE_PPDE,
WPC_OP_MODE_EPP,
WPC_OP_MODE_MPP,
WPC_OP_MODE_MAX
};
enum wpc_auth_mode {
WPC_AUTH_MODE_NONE = 0,
WPC_AUTH_MODE_BPP,
WPC_AUTH_MODE_PPDE,
WPC_AUTH_MODE_EPP,
WPC_AUTH_MODE_MPP,
WPC_AUTH_MODE_MAX
};
struct sb_wireless_op {
int (*get_op_mode)(void *pdata);
int (*get_qi_ver)(void *pdata);
int (*get_auth_mode)(void *pdata);
};
const char *sb_wrl_op_mode_str(int op_mode);
int sb_wireless_set_op(void *pdata, const struct sb_wireless_op *op);
#endif /* __SB_WIRELESS_H__ */

View File

@@ -0,0 +1,443 @@
/*
* sec_battery_common.h
* Samsung Mobile Charging Common Header
*
* Copyright (C) 2020 Samsung Electronics, Inc.
*
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __SEC_BATTERY_COMMON_H
#define __SEC_BATTERY_COMMON_H __FILE__
#include <linux/version.h>
#include <linux/power_supply.h>
#include <dt-bindings/battery/sec-battery.h>
enum power_supply_ext_property {
POWER_SUPPLY_EXT_PROP_MIN = 1000,
POWER_SUPPLY_EXT_PROP_CHECK_SUB_CHG_I2C = POWER_SUPPLY_EXT_PROP_MIN,
POWER_SUPPLY_EXT_PROP_MULTI_CHARGER_MODE,
POWER_SUPPLY_EXT_PROP_WIRELESS_OP_FREQ,
POWER_SUPPLY_EXT_PROP_WIRELESS_OP_FREQ_STRENGTH,
POWER_SUPPLY_EXT_PROP_WIRELESS_TRX_CMD,
POWER_SUPPLY_EXT_PROP_WIRELESS_TRX_VAL,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_ID,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_ID_CNT,
POWER_SUPPLY_EXT_PROP_WIRELESS_ERR,
POWER_SUPPLY_EXT_PROP_WIRELESS_SWITCH,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_ENABLE,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_VOUT,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_IOUT,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_UNO_VIN,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_UNO_IIN,
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_CONNECTED,
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_POWER,
POWER_SUPPLY_EXT_PROP_WIRELESS_WR_CONNECTED,
POWER_SUPPLY_EXT_PROP_WIRELESS_MAX_VOUT,
POWER_SUPPLY_EXT_PROP_WIRELESS_AUTH_ADT_STATUS,
POWER_SUPPLY_EXT_PROP_WIRELESS_AUTH_ADT_DATA,
POWER_SUPPLY_EXT_PROP_WIRELESS_AUTH_ADT_SIZE,
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_TYPE,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_ERR,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_RETRY_CASE,
POWER_SUPPLY_EXT_PROP_WIRELESS_MIN_DUTY,
POWER_SUPPLY_EXT_PROP_WIRELESS_SEND_FSK,
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_VOUT,
POWER_SUPPLY_EXT_PROP_WIRELESS_INITIAL_WC_CHECK,
POWER_SUPPLY_EXT_PROP_WIRELESS_PARAM_INFO,
POWER_SUPPLY_EXT_PROP_WIRELESS_CHECK_FW_VER,
POWER_SUPPLY_EXT_PROP_WIRELESS_SGF,
POWER_SUPPLY_EXT_PROP_WIRELESS_MST_PWR_EN,
POWER_SUPPLY_EXT_PROP_WIRELESS_JIG_PAD,
POWER_SUPPLY_EXT_PROP_WIRELESS_OP_MODE,
POWER_SUPPLY_EXT_PROP_WIRELESS_WC_STATUS,
POWER_SUPPLY_EXT_PROP_AICL_CURRENT,
POWER_SUPPLY_EXT_PROP_CHIP_ID,
POWER_SUPPLY_EXT_PROP_ERROR_CAUSE,
POWER_SUPPLY_EXT_PROP_FGSRC_SWITCHING,
POWER_SUPPLY_EXT_PROP_USB_CONFIGURE,
POWER_SUPPLY_EXT_PROP_WDT_STATUS,
POWER_SUPPLY_EXT_PROP_WATER_DETECT,
POWER_SUPPLY_EXT_PROP_SURGE,
POWER_SUPPLY_EXT_PROP_HV_DISABLE,
POWER_SUPPLY_EXT_PROP_FUELGAUGE_RESET,
POWER_SUPPLY_EXT_PROP_FACTORY_VOLTAGE_REGULATION,
POWER_SUPPLY_EXT_PROP_FUELGAUGE_FACTORY,
POWER_SUPPLY_EXT_PROP_DISABLE_FACTORY_MODE,
POWER_SUPPLY_EXT_PROP_OVERHEAT_NOTIFY,
POWER_SUPPLY_EXT_PROP_CHARGE_POWER,
POWER_SUPPLY_EXT_PROP_MEASURE_SYS,
POWER_SUPPLY_EXT_PROP_MEASURE_INPUT,
POWER_SUPPLY_EXT_PROP_WC_CONTROL,
POWER_SUPPLY_EXT_PROP_WC_EPT_UNKNOWN,
POWER_SUPPLY_EXT_PROP_CHGINSEL,
POWER_SUPPLY_EXT_PROP_JIG_GPIO,
POWER_SUPPLY_EXT_PROP_MONITOR_WORK,
POWER_SUPPLY_EXT_PROP_SHIPMODE_TEST,
POWER_SUPPLY_EXT_PROP_AUTO_SHIPMODE_CONTROL,
POWER_SUPPLY_EXT_PROP_WIRELESS_TIMER_ON,
POWER_SUPPLY_EXT_PROP_CALL_EVENT,
POWER_SUPPLY_EXT_PROP_GEAR_PHM_EVENT,
POWER_SUPPLY_EXT_PROP_RX_PHM,
#if IS_ENABLED(CONFIG_DUAL_BATTERY)
POWER_SUPPLY_EXT_PROP_CHGIN_OK,
POWER_SUPPLY_EXT_PROP_SUPLLEMENT_MODE,
POWER_SUPPLY_EXT_PROP_RECHG_ON,
POWER_SUPPLY_EXT_PROP_EOC_ON,
POWER_SUPPLY_EXT_PROP_DISCHG_MODE,
POWER_SUPPLY_EXT_PROP_CHG_MODE,
POWER_SUPPLY_EXT_PROP_CHG_VOLTAGE,
POWER_SUPPLY_EXT_PROP_FASTCHG_LIMIT_CURRENT,
POWER_SUPPLY_EXT_PROP_TRICKLECHG_LIMIT_CURRENT,
POWER_SUPPLY_EXT_PROP_DISCHG_LIMIT_CURRENT,
POWER_SUPPLY_EXT_PROP_RECHG_VOLTAGE,
POWER_SUPPLY_EXT_PROP_EOC_VOLTAGE,
POWER_SUPPLY_EXT_PROP_EOC_CURRENT,
POWER_SUPPLY_EXT_PROP_POWERMETER_ENABLE,
POWER_SUPPLY_EXT_PROP_POWER_MODE2,
POWER_SUPPLY_EXT_PROP_DUAL_BAT_DET,
POWER_SUPPLY_EXT_PROP_FULL_CONDITION,
POWER_SUPPLY_EXT_PROP_LIMITER_SHIPMODE,
#ifdef CONFIG_IFPMIC_LIMITER
POWER_SUPPLY_EXT_PROP_TRACE_VTRACK,
#endif
#endif
POWER_SUPPLY_EXT_PROP_REPSOC,
POWER_SUPPLY_EXT_PROP_REPCAP,
POWER_SUPPLY_EXT_PROP_FULLCAPREP,
POWER_SUPPLY_EXT_PROP_FULLCAPNOM,
POWER_SUPPLY_EXT_PROP_DESIGNCAP,
POWER_SUPPLY_EXT_PROP_CYCLES,
POWER_SUPPLY_EXT_PROP_VFREMCAP,
POWER_SUPPLY_EXT_PROP_VFSOC,
#if IS_ENABLED(CONFIG_DUAL_FUELGAUGE)
POWER_SUPPLY_EXT_PROP_523K_JIG,
POWER_SUPPLY_EXT_PROP_FG_SOC,
POWER_SUPPLY_EXT_PROP_RAWSOC,
POWER_SUPPLY_EXT_PROP_MAIN_ENERGY_FULL,
POWER_SUPPLY_EXT_PROP_SUB_ENERGY_FULL,
POWER_SUPPLY_EXT_PROP_CAPACITY_DUAL,
POWER_SUPPLY_EXT_PROP_VEMPTY_DUAL,
POWER_SUPPLY_EXT_PROP_SUB_BAT_TEMP,
POWER_SUPPLY_EXT_PROP_SUB_VOLTAGE_NOW_TEST,
#elif IS_ENABLED(CONFIG_DUAL_SBP)
POWER_SUPPLY_EXT_PROP_FG_SOC,
POWER_SUPPLY_EXT_PROP_DUAL_SBP_CURRENT_NOW,
POWER_SUPPLY_EXT_PROP_DUAL_SBP_CURRENT_AVG,
POWER_SUPPLY_EXT_PROP_DUAL_SBP_VOLTAGE_NOW,
#endif
POWER_SUPPLY_EXT_PROP_VOLTAGE_NOW_TEST,
POWER_SUPPLY_EXT_PROP_CURRENT_EVENT,
POWER_SUPPLY_EXT_PROP_CURRENT_EVENT_CLEAR,
POWER_SUPPLY_EXT_PROP_PAD_VOLT_CTRL,
POWER_SUPPLY_EXT_PROP_WIRELESS_VOUT,
POWER_SUPPLY_EXT_PROP_WIRELESS_TX_AVG_CURR,
POWER_SUPPLY_EXT_PROP_WIRELESS_1ST_DONE,
POWER_SUPPLY_EXT_PROP_WIRELESS_2ND_DONE,
POWER_SUPPLY_EXT_PROP_CURRENT_MEASURE,
POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_MODE,
POWER_SUPPLY_EXT_PROP_CHARGING_ENABLED_DC,
POWER_SUPPLY_EXT_PROP_DIRECT_DONE,
POWER_SUPPLY_EXT_PROP_DIRECT_FIXED_PDO,
POWER_SUPPLY_EXT_PROP_DIRECT_WDT_CONTROL,
POWER_SUPPLY_EXT_PROP_DIRECT_CONSTANT_CHARGE_VOLTAGE,
POWER_SUPPLY_EXT_PROP_DIRECT_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_EXT_PROP_DIRECT_CURRENT_MAX,
POWER_SUPPLY_EXT_PROP_DIRECT_ADC_CTRL,
POWER_SUPPLY_EXT_PROP_DIRECT_HAS_APDO,
POWER_SUPPLY_EXT_PROP_DIRECT_TA_ALERT,
POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_CHG_STATUS,
POWER_SUPPLY_EXT_PROP_CHANGE_CHARGING_SOURCE,
POWER_SUPPLY_EXT_PROP_REFRESH_CHARGING_SOURCE,
POWER_SUPPLY_EXT_PROP_DIRECT_CLEAR_ERR,
POWER_SUPPLY_EXT_PROP_DIRECT_SEND_UVDM,
POWER_SUPPLY_EXT_PROP_UPDATE_BATTERY_DATA,
POWER_SUPPLY_EXT_PROP_SRCCAP,
POWER_SUPPLY_EXT_PROP_HV_PDO,
POWER_SUPPLY_EXT_PROP_CHARGE_BOOST,
POWER_SUPPLY_EXT_PROP_CHARGING_ENABLED,
POWER_SUPPLY_EXT_PROP_INPUT_VOLTAGE_REGULATION,
POWER_SUPPLY_EXT_PROP_POWER_DESIGN,
POWER_SUPPLY_EXT_PROP_FILTER_CFG,
POWER_SUPPLY_EXT_PROP_CHARGE_OTG_CONTROL,
POWER_SUPPLY_EXT_PROP_CHARGE_OTG_ICL_CONTROL,
POWER_SUPPLY_EXT_PROP_CHARGE_POWERED_OTG_CONTROL,
POWER_SUPPLY_EXT_PROP_CHARGE_UNO_CONTROL,
POWER_SUPPLY_EXT_PROP_CHARGE_COUNTER_SHADOW,
POWER_SUPPLY_EXT_PROP_WPC_EN,
POWER_SUPPLY_EXT_PROP_WPC_EN_MST,
POWER_SUPPLY_EXT_PROP_MST_MODE,
POWER_SUPPLY_EXT_PROP_MST_DELAY,
POWER_SUPPLY_EXT_PROP_WPC_FREQ_STRENGTH,
POWER_SUPPLY_EXT_PROP_HEALTH,
POWER_SUPPLY_EXT_PROP_SLEEP_MODE,
POWER_SUPPLY_EXT_PROP_MFC_FW_UPDATE,
POWER_SUPPLY_EXT_PROP_THERMAL_ZONE,
POWER_SUPPLY_EXT_PROP_TEMP_CHECK_TYPE,
POWER_SUPPLY_EXT_PROP_DC_INITIALIZE,
POWER_SUPPLY_EXT_PROP_BATTERY_ID,
#if IS_ENABLED(CONFIG_DUAL_BATTERY)
POWER_SUPPLY_EXT_PROP_DIRECT_VBAT_CHECK,
POWER_SUPPLY_EXT_PROP_VOLTAGE_PACK_MAIN,
POWER_SUPPLY_EXT_PROP_VOLTAGE_PACK_SUB,
#endif
POWER_SUPPLY_EXT_PROP_WIRELESS_RX_CONTROL,
POWER_SUPPLY_EXT_PROP_INPUT_CURRENT_LIMIT_WRL,
POWER_SUPPLY_EXT_PROP_CONSTANT_CHARGE_CURRENT_WRL,
POWER_SUPPLY_EXT_PROP_SUB_TEMP,
POWER_SUPPLY_EXT_PROP_MIX_LIMIT,
POWER_SUPPLY_EXT_PROP_ENABLE_HW_FACTORY_MODE,
POWER_SUPPLY_EXT_PROP_FACTORY_MODE,
POWER_SUPPLY_EXT_PROP_CHECK_INIT,
POWER_SUPPLY_EXT_PROP_IB_MODE,
POWER_SUPPLY_EXT_PROP_OB_MODE_CABLE_REMOVED,
POWER_SUPPLY_EXT_PROP_BATT_F_MODE,
POWER_SUPPLY_EXT_PROP_FACTORY_MODE_RELIEVE,
POWER_SUPPLY_EXT_PROP_FACTORY_MODE_BYPASS,
POWER_SUPPLY_EXT_PROP_LCD_FLICKER,
POWER_SUPPLY_EXT_PROP_PASS_THROUGH_MODE,
POWER_SUPPLY_EXT_PROP_PASS_THROUGH_MODE_TA_VOL,
POWER_SUPPLY_EXT_PROP_D2D_REVERSE_VOLTAGE,
POWER_SUPPLY_EXT_PROP_FUELGAUGE_LOG,
POWER_SUPPLY_EXT_PROP_CHARGER_IC_NAME,
POWER_SUPPLY_EXT_PROP_D2D_REVERSE_OCP,
POWER_SUPPLY_EXT_PROP_BATT_DUMP,
POWER_SUPPLY_EXT_PROP_FLASH_STATE,
POWER_SUPPLY_EXT_PROP_PMIC_BAT_VOLTAGE,
POWER_SUPPLY_EXT_PROP_USB_BOOTCOMPLETE,
#if IS_ENABLED(CONFIG_MTK_CHARGER)
POWER_SUPPLY_EXT_PROP_BATT_VSYS,
POWER_SUPPLY_EXT_PROP_RP_LEVEL,
POWER_SUPPLY_EXT_PROP_BUCK_STATE,
POWER_SUPPLY_EXT_PROP_AFC_INIT,
POWER_SUPPLY_EXT_PROP_MTK_FG_INIT,
#endif
POWER_SUPPLY_EXT_PROP_D2D_REVERSE_VBUS,
POWER_SUPPLY_EXT_PROP_ADC_MODE,
POWER_SUPPLY_EXT_PROP_DC_OP_MODE,
POWER_SUPPLY_EXT_PROP_LRP_CHG_SRC,
POWER_SUPPLY_EXT_PROP_MISC_EVENT,
POWER_SUPPLY_EXT_PROP_MISC_EVENT_CLEAR,
POWER_SUPPLY_EXT_PROP_MST_EN,
#if defined(CONFIG_SEC_FACTORY)
POWER_SUPPLY_EXT_PROP_AFC_TEST_FG_MODE,
POWER_SUPPLY_EXT_PROP_NOZX_CTRL,
#endif
POWER_SUPPLY_EXT_PROP_SPSN_TEST,
POWER_SUPPLY_EXT_PROP_ABNORMAL_SRCCAP,
POWER_SUPPLY_EXT_PROP_CHARGE_FULL_REPCAP,
POWER_SUPPLY_EXT_PROP_STATUS_FULL_REPCAP,
POWER_SUPPLY_EXT_PROP_DC_VIN_OVERCURRENT,
POWER_SUPPLY_EXT_PROP_DC_REVERSE_MODE,
POWER_SUPPLY_EXT_PROP_OTG_VBUS_CTRL,
POWER_SUPPLY_EXT_PROP_TX_PWR_BUDG,
POWER_SUPPLY_EXT_PROP_HARDRESET_OCCUR,
POWER_SUPPLY_EXT_PROP_FPDO_DC_THERMAL_CHECK,
POWER_SUPPLY_EXT_PROP_CHARGER_MODE_DIRECT,
POWER_SUPPLY_EXT_PROP_DCHG_READ_BATP_BATN,
POWER_SUPPLY_EXT_PROP_ABNORMAL_TA,
POWER_SUPPLY_EXT_PROP_WIRELESS_PING_DUTY,
POWER_SUPPLY_EXT_PROP_WARM_FOD,
POWER_SUPPLY_EXT_PROP_MPP_COVER,
POWER_SUPPLY_EXT_PROP_MPP_CLOAK,
POWER_SUPPLY_EXT_PROP_MPP_ICL_CTRL,
POWER_SUPPLY_EXT_PROP_MPP_INC_INT_CTRL,
POWER_SUPPLY_EXT_PROP_MPP_VALUE,
POWER_SUPPLY_EXT_PROP_DC_RCP,
#if IS_ENABLED(CONFIG_SBP_FG)
POWER_SUPPLY_EXT_PROP_FAKE_SOC,
#endif
POWER_SUPPLY_EXT_PROP_ARI_CNT,
POWER_SUPPLY_EXT_PROP_SYS_TRACK_DIS,
POWER_SUPPLY_EXT_PROP_DIRECT_INPUT_CURRENT_MAX,
POWER_SUPPLY_EXT_PROP_LIMITER_CHG_ENABLE,
POWER_SUPPLY_EXT_PROP_WDT_KICK,
POWER_SUPPLY_EXT_PROP_I2C_RECOVERY_STATUS,
POWER_SUPPLY_EXT_PROP_REMAINING_CAPACITY,
POWER_SUPPLY_EXT_PROP_WDT_KICK_TEST,
POWER_SUPPLY_EXT_PROP_WC_SELECT_PPS,
POWER_SUPPLY_EXT_PROP_WC_DC,
POWER_SUPPLY_EXT_PROP_FG_PROBE_STATUS,
POWER_SUPPLY_EXT_PROP_PRSWAP,
POWER_SUPPLY_EXT_PROP_DC_ERR_TEST,
POWER_SUPPLY_EXT_PROP_CHECK_VALID_DC_IC,
POWER_SUPPLY_EXT_PROP_WIRELESS_MPP_PWR,
POWER_SUPPLY_EXT_PROP_DC_ERROR_CAUSE,
POWER_SUPPLY_EXT_PROP_DC_IBUSUCP,
POWER_SUPPLY_EXT_PROP_DC_TA_MAX_OP,
#ifdef CONFIG_BATTERY_HOTSWAP
POWER_SUPPLY_EXT_PROP_BATTERY_HOT_SWAP_STATUS,
POWER_SUPPLY_EXT_PROP_CHECK_EOC,
POWER_SUPPLY_EXT_PROP_CLEAR_FULL_STATUS,
POWER_SUPPLY_EXT_PROP_MAIN_LIMITER_CHG_VOLTAGE,
POWER_SUPPLY_EXT_PROP_SUB_LIMITER_CHG_VOLTAGE,
#endif
POWER_SUPPLY_EXT_PROP_OCPWARN,
POWER_SUPPLY_EXT_PROP_MPLA_THR_RECOV,
POWER_SUPPLY_EXT_PROP_FORCE_SWC,
POWER_SUPPLY_EXT_PROP_MAX,
};
enum {
POWER_SUPPLY_DC_REVERSE_STOP, /* stop reverse mode */
POWER_SUPPLY_DC_REVERSE_BYP, /* 1:1 reverse bypass mode */
POWER_SUPPLY_DC_REVERSE_1TO2, /* 1:2 reverse switching mode */
POWER_SUPPLY_DC_REVERSE_1TO3, /* 1:3 reverse switching mode */
};
enum {
TURN_OTG_OFF,
TURN_OTG_ON,
TURN_RB_OFF, /* REVERSE BYPASS for Earphone*/
TURN_RB_ON,
TURN_OTG_OFF_RB_ON,
};
enum sec_battery_usb_conf {
USB_CURRENT_NONE = 0,
USB_CURRENT_SUSPENDED = 1,
USB_CURRENT_CLEAR = 2,
USB_CURRENT_UNCONFIGURED = 100,
USB_CURRENT_HIGH_SPEED = 475,
USB_CURRENT_SUPER_SPEED = 850,
};
enum sec_battery_wpc_en_ctrl {
WPC_EN_SYSFS = 0x1,
WPC_EN_CCIC = 0x2,
WPC_EN_CHARGING = 0x4,
WPC_EN_TX = 0x8,
WPC_EN_MST = 0x10,
WPC_EN_FW = 0x20,
WPC_EN_SLATE = 0x40,
};
static inline struct power_supply *get_power_supply_by_name(char *name)
{
if (!name)
return (struct power_supply *)NULL;
else
return power_supply_get_by_name(name);
}
#define psy_do_property(name, function, property, value) \
({ \
struct power_supply *psy; \
int ret = 0; \
psy = get_power_supply_by_name((name)); \
if (!psy) { \
pr_err("%s: Fail to "#function" psy (%s)\n", \
__func__, (name)); \
value.intval = 0; \
ret = -ENOENT; \
} else { \
if (psy->desc->function##_property != NULL) { \
ret = psy->desc->function##_property(psy, \
(enum power_supply_property) (property), &(value)); \
if (ret < 0) { \
pr_err("%s: Fail to %s "#function" "#property" (%d)\n", \
__func__, name, ret); \
value.intval = 0; \
} \
} else { \
ret = -ENOSYS; \
} \
power_supply_put(psy); \
} \
ret; \
})
#if defined(CONFIG_OF)
#define sb_of_parse_u32(np, pdata, value, deft) \
({ \
int ret = 0; \
ret = of_property_read_u32(np, #value, (unsigned int *)&pdata->value); \
if (!ret) \
pr_info("%s: %s - write "#value" to %d\n", __func__, np->name, pdata->value); \
else \
pdata->value = deft; \
ret;\
})
#define sb_of_parse_str(np, pdata, value) \
({ \
int ret = 0; \
ret = of_property_read_string(np, #value, (const char **)&pdata->value); \
if (!ret) \
pr_info("%s: %s - write "#value" to %s\n", __func__, np->name, pdata->value); \
ret;\
})
#define sb_of_parse_bool(np, pdata, value) \
({ \
pdata->value = of_property_read_bool(np, #value); \
pr_info("%s: %s - write "#value" to %d\n", __func__, np->name, pdata->value); \
})
#define sb_of_parse_str_dt(np, dt_name, pdata, path) \
({ \
int ret = 0; \
ret = of_property_read_string(np, dt_name, (const char **)&pdata->path); \
if (!ret) \
pr_info("%s: %s - write "dt_name" to %s\n", __func__, np->name, pdata->path); \
ret;\
})
#define sb_of_parse_u32_dt(np, dt_name, pdata, path, deft) \
({ \
int ret = 0; \
ret = of_property_read_u32(np, dt_name, (unsigned int *)&pdata->path); \
if (ret) \
pdata->path = deft; \
pr_info("%s: %s - write "dt_name" to %d\n", __func__, np->name, pdata->path); \
ret;\
})
#define sb_of_parse_bool_dt(np, dt_name, pdata, path) \
({ \
pdata->path = of_property_read_bool(np, dt_name); \
pr_info("%s: %s - write "dt_name" to %d\n", __func__, np->name, pdata->path); \
})
#endif
#if (KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE)
#define sb_of_gpio_named_count(np, dt_name) \
({ \
int ret = 0; \
ret = of_count_phandle_with_args(np, dt_name, "#gpio-cells"); \
ret;\
})
#define sb_of_get_named_gpio_flags(np, dt_name) \
({ \
int ret = 0; \
ret = of_get_named_gpio(np, dt_name, 0); \
ret;\
})
#else
#define sb_of_gpio_named_count(np, dt_name) \
({ \
int ret = 0; \
ret = of_gpio_named_count(np, dt_name); \
ret;\
})
#define sb_of_get_named_gpio_flags(np, dt_name) \
({ \
int ret = 0; \
enum of_gpio_flags irq_gpio_flags; \
ret = of_get_named_gpio_flags(np, dt_name, 0, &irq_gpio_flags); \
ret;\
})
#endif
#endif /* __SEC_BATTERY_COMMON_H */

View File

@@ -0,0 +1,156 @@
/*
* include/linux/battery/sec_pd.h
*
* header file supporting samsung pd information
*
* Copyright (C) 2020 Samsung Electronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __SEC_PD_H__
#define __SEC_PD_H__
#define MAX_PDO_NUM 8
#define AVAILABLE_VOLTAGE 9000
#define DEFAULT_VOLTAGE 5000
#define UNIT_FOR_VOLTAGE 50
#define UNIT_FOR_CURRENT 10
#define UNIT_FOR_APDO_VOLTAGE 100
#define UNIT_FOR_APDO_CURRENT 50
/* d2d 15w authentication information */
#define AUTH_VENDOR_ID 0x04e8
#define AUTH_PRODUCT_ID 0x6860
typedef enum {
PDIC_NOTIFY_EVENT_DETACH = 0,
PDIC_NOTIFY_EVENT_PDIC_ATTACH,
PDIC_NOTIFY_EVENT_PD_SINK,
PDIC_NOTIFY_EVENT_PD_SOURCE,
PDIC_NOTIFY_EVENT_PD_SINK_CAP,
PDIC_NOTIFY_EVENT_PD_PRSWAP_SNKTOSRC,
PDIC_NOTIFY_EVENT_PD_PRSWAP_SRCTOSNK,
} pdic_notifier_event_t;
typedef enum
{
RP_CURRENT_LEVEL_NONE = 0,
RP_CURRENT_LEVEL_DEFAULT,
RP_CURRENT_LEVEL2,
RP_CURRENT_LEVEL3,
RP_CURRENT_ABNORMAL,
} RP_CURRENT_LEVEL;
typedef enum
{
FPDO_TYPE = 0,
APDO_TYPE,
VPDO_TYPE,
} PDO_TYPE_T;
typedef enum {
AUTH_NONE = 0,
AUTH_LOW_PWR,
AUTH_HIGH_PWR,
} AUTH_TYPE_T;
typedef struct _power_list {
int accept;
int max_voltage;
int min_voltage;
int max_current;
int pdo_type;
int apdo;
int comm_capable;
int suspend;
} POWER_LIST;
typedef struct sec_pd_sink_status
{
POWER_LIST power_list[MAX_PDO_NUM+1];
int has_apdo; // pd source has apdo or not
int has_vpdo;
int available_pdo_num; // the number of available PDO
int selected_pdo_num; // selected number of PDO to change
int current_pdo_num; // current number of PDO
unsigned short vid;
unsigned short pid;
unsigned int xid;
int pps_voltage;
int pps_current;
unsigned int rp_currentlvl; // rp current level by ccic
void (*fp_sec_pd_select_pdo)(int num);
int (*fp_sec_pd_select_pps)(int num, int ppsVol, int ppsCur);
void (*fp_sec_pd_vpdo_auth)(int auth, int d2d_type);
void (*fp_sec_pd_ext_cb)(unsigned short v_id, unsigned short p_id);
void (*fp_sec_pd_manual_ccopen_req)(int is_on);
void (*fp_sec_pd_manual_jig_ctrl)(bool mode);
void (*fp_sec_pd_detach_with_cc)(int state);
void (*fp_sec_pd_change_src)(int max_cur);
} SEC_PD_SINK_STATUS;
struct pdic_notifier_struct {
pdic_notifier_event_t event;
SEC_PD_SINK_STATUS sink_status;
void *pusbpd;
};
#if IS_ENABLED(CONFIG_SEC_PD)
const char* sec_pd_pdo_type_str(int pdo_type);
int sec_pd_select_pdo(int num);
int sec_pd_select_pps(int num, int ppsVol, int ppsCur);
int sec_pd_vpdo_auth(int auth, int d2d_type);
int sec_pd_get_current_pdo(unsigned int *pdo);
int sec_pd_get_selected_pdo(unsigned int *pdo);
int sec_pd_is_apdo(unsigned int pdo);
int sec_pd_get_apdo_prog_volt(unsigned int pdo_type, unsigned int max_volt);
int sec_pd_get_max_power(unsigned int pdo_type, unsigned int min_volt, unsigned int max_volt, unsigned int max_curr);
int sec_pd_get_pdo_power(unsigned int *pdo, unsigned int *min_volt, unsigned int *max_volt, unsigned int *curr);
int sec_pd_get_apdo_max_power(unsigned int *pdo_pos, unsigned int *taMaxVol, unsigned int *taMaxCur, unsigned int *taMaxPwr);
void sec_pd_init_data(SEC_PD_SINK_STATUS* psink_status);
int sec_pd_register_chg_info_cb(void *cb);
int sec_pd_get_chg_info(void);
void sec_pd_get_vid_pid(unsigned short *vid, unsigned short *pid, unsigned int *xid);
void sec_pd_get_vid(unsigned short *vid);
void sec_pd_manual_ccopen_req(int is_on);
void sec_pd_manual_jig_ctrl(bool mode);
int sec_pd_detach_with_cc(int state);
int sec_pd_change_src(int max_cur);
#else
static inline char* sec_pd_pdo_type_str(int pdo_type) { return "\0"; }
static inline int sec_pd_select_pdo(int num) { return -ENODEV; }
static inline int sec_pd_select_pps(int num, int ppsVol, int ppsCur) { return -ENODEV; }
static inline int sec_pd_vpdo_auth(int auth, int d2d_type) { return -ENODEV; }
static inline int sec_pd_get_current_pdo(unsigned int *pdo) { return -ENODEV; }
static inline int sec_pd_get_selected_pdo(unsigned int *pdo) { return -ENODEV; }
static inline int sec_pd_is_apdo(unsigned int pdo) { return -ENODEV; }
static inline int sec_pd_get_apdo_prog_volt(unsigned int pdo_type, unsigned int max_volt) { return -ENODEV; }
static inline int sec_pd_get_max_power(unsigned int pdo_type, unsigned int min_volt, unsigned int max_volt, unsigned int max_curr) { return -ENODEV; }
static inline int sec_pd_get_pdo_power(unsigned int *pdo, unsigned int *min_volt, unsigned int *max_volt, unsigned int *curr) { return -ENODEV; }
static inline int sec_pd_get_apdo_max_power(unsigned int *pdo_pos, unsigned int *taMaxVol, unsigned int *taMaxCur, unsigned int *taMaxPwr) { return -ENODEV; }
static inline void sec_pd_init_data(SEC_PD_SINK_STATUS* psink_status) { }
static inline int sec_pd_register_chg_info_cb(void *cb) { return 0; }
static inline void sec_pd_get_vid_pid(unsigned short *vid, unsigned short *pid, unsigned int *xid) { }
static inline void sec_pd_get_vid(unsigned short *vid) { }
static inline void sec_pd_manual_ccopen_req(int is_on) { }
static inline void sec_pd_manual_jig_ctrl(bool mode) { }
static inline int sec_pd_detach_with_cc(int state) { return 0; }
static inline int sec_pd_change_src(int max_cur) { return 0; }
#endif
#endif /* __SEC_PD_H__ */

36
include/linux/clk/qcom.h Normal file
View File

@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved
*/
#ifndef __LINUX_CLK_QCOM_H_
#define __LINUX_CLK_QCOM_H_
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <soc/qcom/crm.h>
enum branch_mem_flags {
CLKFLAG_RETAIN_PERIPH,
CLKFLAG_NORETAIN_PERIPH,
CLKFLAG_RETAIN_MEM,
CLKFLAG_NORETAIN_MEM,
CLKFLAG_PERIPH_OFF_SET,
CLKFLAG_PERIPH_OFF_CLEAR,
};
int qcom_clk_get_voltage(struct clk *clk, unsigned long rate);
int qcom_clk_set_flags(struct clk *clk, unsigned long flags);
void qcom_clk_dump(struct clk *clk, struct regulator *regulator,
bool calltrace);
void qcom_gdsc_pd_dump(struct device *dev);
void qcom_clk_bulk_dump(int num_clks, struct clk_bulk_data *clks,
struct regulator *regulator, bool calltrace);
int qcom_clk_crm_set_rate(struct clk *clk,
enum crm_drv_type client_type, u32 client_idx,
u32 pwr_st, unsigned long rate);
int qcom_clk_crmb_set_rate(struct clk *clk,
enum crm_drv_type client_type, u32 client_idx,
u32 nd_idx, u32 pwr_st, u32 ab_rate, u32 ib_rate);
#endif /* __LINUX_CLK_QCOM_H_ */

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_CORESIGHT_H
@@ -166,6 +167,7 @@ struct coresight_desc {
/**
* struct coresight_connection - representation of a single connection
* @source_name: source component's name.
* @src_port: a connection's output port number.
* @dest_port: destination's input port number @src_port is connected to.
* @dest_fwnode: destination component's fwnode handle.
@@ -194,6 +196,7 @@ struct coresight_desc {
* +-----------------------------+
*/
struct coresight_connection {
const char *source_name;
int src_port;
int dest_port;
struct fwnode_handle *dest_fwnode;

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/types.h>
#ifndef _CPU_PHYS_LOG_MAP_H
#define _CPU_PHYS_LOG_MAP_H
#if IS_ENABLED(CONFIG_QCOM_CPU_PHYS_LOG_MAP)
int cpu_logical_to_phys(int cpu);
#else
static inline int cpu_logical_to_phys(int cpu)
{
return cpu;
}
#endif
#endif /* _CPU_PHYS_LOG_MAP_H */

View File

@@ -0,0 +1,40 @@
/*
* drivers/cpufreq/cpufreq_limit.c
*
* Remade according to cpufreq change
* (refer to commit df0eea4488081e0698b0b58ccd1e8c8823e22841
* 18c49926c4bf4915e5194d1de3299c0537229f9f)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_CPUFREQ_LIMIT_H__
#define __LINUX_CPUFREQ_LIMIT_H__
#define MAX_BUF_SIZE 1024
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/* adaptive boost from walt */
extern int cpufreq_walt_set_adaptive_freq(unsigned int cpu,
unsigned int adaptive_level_1,
unsigned int adaptive_low_freq,
unsigned int adaptive_high_freq);
extern int cpufreq_walt_get_adaptive_freq(unsigned int cpu,
unsigned int *adaptive_level_1,
unsigned int *adaptive_low_freq,
unsigned int *adaptive_high_freq);
extern int cpufreq_walt_reset_adaptive_freq(unsigned int cpu);
enum {
CFLM_USERSPACE = 0, /* user(/sys/power/cpufreq*limit) */
CFLM_TOUCH = 1, /* touch */
CFLM_FINGER = 2, /* fingerprint */
CFLM_ARGOS = 3, /* argos */
CFLM_MAX_ITEM
};
#endif /* __LINUX_CPUFREQ_LIMIT_H__ */

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2017 Samsung Electronics.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __DEV_RIL_BRIDGE_H__
#define __DEV_RIL_BRIDGE_H__
#define IPC_SYSTEM_CP_CHANNEL_INFO 0x01
#define IPC_SYSTEM_CHARGING_DOCK_INFO 0x02
#define IPC_SYSTEM_CP_ADAPTIVE_MIPI_INFO 0x05
struct __packed sipc_fmt_hdr {
u16 len;
u8 msg_seq;
u8 ack_seq;
u8 main_cmd;
u8 sub_cmd;
u8 cmd_type;
};
struct dev_ril_bridge_msg {
unsigned int dev_id;
unsigned int data_len;
void *data;
};
#if IS_ENABLED(CONFIG_DEV_RIL_BRIDGE)
extern int register_dev_ril_bridge_event_notifier(struct notifier_block *nb);
extern int unregister_dev_ril_bridge_event_notifier(struct notifier_block *nb);
extern int dev_ril_bridge_send_msg(int id, int size, void *buf);
#else
static inline int register_dev_ril_bridge_event_notifier(
struct notifier_block *nb) {return 0;}
static inline int unregister_dev_ril_bridge_event_notifier(
struct notifier_block *nb) {return 0;}
static inline int dev_ril_bridge_send_msg(int id, int size, void *buf) {return 0;}
#endif
#endif/*__DEV_RIL_BRIDGE_H__*/

View File

@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_DMA_MAPPING_FAST_H
#define __LINUX_DMA_MAPPING_FAST_H
#include <linux/iommu.h>
#include <linux/io-pgtable-fast.h>
#include <linux/rbtree.h>
#include <linux/mutex.h>
struct dma_iommu_mapping;
struct io_pgtable_ops;
struct iova_domain;
struct dma_fast_smmu_mapping {
struct device *dev;
struct iommu_domain *domain;
struct iova_domain *iovad;
dma_addr_t base;
size_t size;
size_t num_4k_pages;
unsigned int bitmap_size;
/* bitmap has 1s marked only valid mappings */
unsigned long *bitmap;
/* clean_bitmap has 1s marked for both valid and stale tlb mappings */
unsigned long *clean_bitmap;
unsigned long next_start;
bool have_stale_tlbs;
dma_addr_t pgtbl_dma_handle;
struct io_pgtable_ops *pgtbl_ops;
spinlock_t lock;
struct notifier_block notifier;
struct rb_node node;
struct mutex msi_cookie_init_lock;
};
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
int fast_smmu_init_mapping(struct device *dev, struct iommu_domain *domain,
struct io_pgtable_ops *pgtable_ops);
void fast_smmu_put_dma_cookie(struct iommu_domain *domain);
void fast_smmu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size);
int __init dma_mapping_fast_init(void);
#else
static inline int fast_smmu_init_mapping(struct device *dev,
struct iommu_domain *domain,
struct io_pgtable_ops *pgtable_ops)
{
return -ENODEV;
}
static inline void fast_smmu_put_dma_cookie(struct iommu_domain *domain) {}
static inline void fast_smmu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size) {}
static inline int __init dma_mapping_fast_init(void)
{
return 0;
}
#endif
#endif /* __LINUX_DMA_MAPPING_FAST_H */

View File

@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014, 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __ESOC_CLIENT_H_
#define __ESOC_CLIENT_H_
#include <linux/device.h>
#include <linux/esoc_ctrl.h>
#include <linux/notifier.h>
/* Flag values used with the power_on and power_off hooks */
#define ESOC_HOOK_MDM_CRASH 0x0001 /* In crash handling path */
#define ESOC_HOOK_MDM_DOWN 0x0002 /* MDM about to go down */
struct esoc_client_hook {
char *name;
void *priv;
enum esoc_client_hook_prio prio;
int (*esoc_link_power_on)(void *priv, unsigned int flags);
void (*esoc_link_power_off)(void *priv, unsigned int flags);
u64 (*esoc_link_get_id)(void *priv);
void (*esoc_link_mdm_crash)(void *priv);
};
/*
* struct esoc_desc: Describes an external soc
* @name: external soc name
* @priv: private data for external soc
*/
struct esoc_desc {
const char *name;
const char *link;
const char *link_info;
void *priv;
};
#if IS_ENABLED(CONFIG_QCOM_ESOC_CLIENT)
/* Can return probe deferral */
struct esoc_desc *devm_register_esoc_client(struct device *dev,
const char *name);
void devm_unregister_esoc_client(struct device *dev,
struct esoc_desc *esoc_desc);
int esoc_register_client_notifier(struct notifier_block *nb);
int esoc_register_client_hook(struct esoc_desc *desc,
struct esoc_client_hook *client_hook);
int esoc_unregister_client_hook(struct esoc_desc *desc,
struct esoc_client_hook *client_hook);
#else
struct esoc_desc *devm_register_esoc_client(struct device *dev,
const char *name)
{
return NULL;
}
void devm_unregister_esoc_client(struct device *dev,
struct esoc_desc *esoc_desc)
{
}
int esoc_register_client_notifier(struct notifier_block *nb)
{
return -EPERM;
}
int esoc_register_client_hook(struct esoc_desc *desc,
struct esoc_client_hook *client_hook)
{
return -EPERM;
}
int esoc_unregister_client_hook(struct esoc_desc *desc,
struct esoc_client_hook *client_hook)
{
return -EPERM;
}
#endif
#endif

View File

@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
*
* header file supporting usb notify layer
* external notify call chain information
*
* Copyright (C) 2016-2023 Samsung Electronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* usb notify layer v4.0 */
#ifndef __EXTERNAL_NOTIFY_H__
#define __EXTERNAL_NOTIFY_H__
#include <linux/notifier.h>
/* external notifier call chain command */
enum external_notify_cmd {
EXTERNAL_NOTIFY_3S_NODEVICE = 1,
EXTERNAL_NOTIFY_DEVICE_CONNECT,
EXTERNAL_NOTIFY_HOSTBLOCK_PRE,
EXTERNAL_NOTIFY_HOSTBLOCK_POST,
EXTERNAL_NOTIFY_MDMBLOCK_PRE,
EXTERNAL_NOTIFY_MDMBLOCK_POST,
EXTERNAL_NOTIFY_POWERROLE,
EXTERNAL_NOTIFY_DEVICEADD,
EXTERNAL_NOTIFY_HOSTBLOCK_EARLY,
EXTERNAL_NOTIFY_VBUS_RESET,
EXTERNAL_NOTIFY_POSSIBLE_USB,
};
/* external notifier call sequence,
* largest priority number device will be called first.
*/
enum external_notify_device {
EXTERNAL_NOTIFY_DEV_MUIC,
EXTERNAL_NOTIFY_DEV_CHARGER,
EXTERNAL_NOTIFY_DEV_PDIC,
EXTERNAL_NOTIFY_DEV_MANAGER,
};
enum external_notify_condev {
EXTERNAL_NOTIFY_NONE = 0,
EXTERNAL_NOTIFY_GPAD,
EXTERNAL_NOTIFY_LANHUB,
};
#ifdef CONFIG_USB_EXTERNAL_NOTIFY
extern int send_external_notify(unsigned long cmd, int data);
extern int usb_external_notify_register(struct notifier_block *nb,
notifier_fn_t notifier, int listener);
extern int usb_external_notify_unregister(struct notifier_block *nb);
extern void external_notifier_init(void);
#else
static inline int send_external_notify(unsigned long cmd,
int data) {return 0; }
static inline int usb_external_notify_register(struct notifier_block *nb,
notifier_fn_t notifier, int listener) {return 0; }
static inline int usb_external_notify_unregister(struct notifier_block *nb)
{return 0; }
static inline void external_notifier_init(void) {}
#endif
#endif /* __EXTERNAL_NOTIFY_H__ */

View File

@@ -0,0 +1,419 @@
/* SPDX-License-Identifier: GPL-2.0
*
* cl_dsp.h -- DSP control for non-ALSA Cirrus Logic devices
*
* Copyright 2021 Cirrus Logic, Inc.
*
* Author: Fred Treven <fred.treven@cirrus.com>
*/
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/regmap.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
#ifndef __CL_DSP_H__
#define __CL_DSP_H__
#define CL_DSP_BYTES_PER_WORD 4
#define CL_DSP_BITS_PER_BYTE 8
#define CL_DSP_BYTE_MASK GENMASK(7, 0)
#define CL_DSP_NIBBLE_MASK GENMASK(15, 0)
#define CL_DSP_FW_FILE_HEADER_SIZE 40
#define CL_DSP_COEFF_FILE_HEADER_SIZE 16
#define CL_DSP_MAGIC_ID_SIZE 4
#define CL_DSP_WMFW_MAGIC_ID "WMFW"
#define CL_DSP_WMDR_MAGIC_ID "WMDR"
#define CL_DSP_DBLK_HEADER_SIZE 8
#define CL_DSP_COEFF_DBLK_HEADER_SIZE 20
#define CL_DSP_ALIGN 0x00000003
#define CL_DSP_TARGET_CORE_ADSP1 0x01
#define CL_DSP_TARGET_CORE_ADSP2 0x02
#define CL_DSP_TARGET_CORE_HALO 0x04
#define CL_DSP_TARGET_CORE_WARP2 0x12
#define CL_DSP_TARGET_CORE_MCU 0x45
#define CL_DSP_MIN_FORMAT_VERSION 0x03
#define CL_DSP_API_REVISION 0x0300
#define CL_DSP_ALGO_NAME_LEN_SIZE 1
#define CL_DSP_ALGO_DESC_LEN_SIZE 2
#define CL_DSP_ALGO_ID_SIZE 4
#define CL_DSP_COEFF_COUNT_SIZE 4
#define CL_DSP_COEFF_OFFSET_SIZE 2
#define CL_DSP_COEFF_TYPE_SIZE 2
#define CL_DSP_COEFF_NAME_LEN_SIZE 1
#define CL_DSP_COEFF_FULLNAME_LEN_SIZE 1
#define CL_DSP_COEFF_DESC_LEN_SIZE 2
#define CL_DSP_COEFF_LEN_SIZE 4
#define CL_DSP_COEFF_FLAGS_SIZE 4
#define CL_DSP_COEFF_FLAGS_SHIFT 16
#define CL_DSP_COEFF_NAME_LEN_MAX 32
#define CL_DSP_COEFF_MIN_FORMAT_VERSION 0x01
#define CL_DSP_COEFF_API_REV_HALO 0x030000
#define CL_DSP_COEFF_API_REV_ADSP2 0x000500
#define CL_DSP_ALGO_LIST_TERM 0xBEDEAD
#define CL_DSP_REV_OFFSET_SHIFT 8
#define CL_DSP_REV_MAJOR_MASK GENMASK(23, 16)
#define CL_DSP_REV_MAJOR_SHIFT 16
#define CL_DSP_REV_MINOR_MASK GENMASK(15, 8)
#define CL_DSP_REV_MINOR_SHIFT 8
#define CL_DSP_REV_PATCH_MASK GENMASK(7, 0)
#define CL_DSP_NUM_ALGOS_MAX 32
#ifndef CONFIG_CS40L26_SAMSUNG_USE_MAX_DATA_TX_SIZE
#define CL_DSP_MAX_WLEN 32
#else
#define CL_DSP_MAX_WLEN 4096
#endif
#define CL_DSP_XM_UNPACKED_TYPE 0x0005
#define CL_DSP_YM_UNPACKED_TYPE 0x0006
#define CL_DSP_PM_PACKED_TYPE 0x0010
#define CL_DSP_XM_PACKED_TYPE 0x0011
#define CL_DSP_YM_PACKED_TYPE 0x0012
#define CL_DSP_ALGO_INFO_TYPE 0x00F2
#define CL_DSP_WMFW_INFO_TYPE 0x00FF
#define CL_DSP_MEM_REG_TYPE_MASK GENMASK(27, 20)
#define CL_DSP_MEM_REG_TYPE_SHIFT 20
#define CL_DSP_PM_NUM_BYTES 5
#define CL_DSP_PACKED_NUM_BYTES 3
#define CL_DSP_UNPACKED_NUM_BYTES 4
#define CL_DSP_WMDR_DBLK_OFFSET_SIZE 2
#define CL_DSP_WMDR_DBLK_TYPE_SIZE 2
#define CL_DSP_WMDR_ALGO_ID_SIZE 4
#define CL_DSP_WMDR_ALGO_REV_SIZE 4
#define CL_DSP_WMDR_SAMPLE_RATE_SIZE 4
#define CL_DSP_WMDR_DBLK_LEN_SIZE 4
#define CL_DSP_WMDR_NAME_LEN 32
#define CL_DSP_WMDR_DATE_LEN 16
#define CL_DSP_WMDR_HEADER_LEN_SIZE 4
#define CL_DSP_WMDR_DATE_PREFIX "Date: "
#define CL_DSP_WMDR_DATE_PREFIX_LEN 6
#define CL_DSP_WMDR_FILE_NAME_MISSING "N/A"
#define CL_DSP_WMDR_FILE_DATE_MISSING "N/A"
#define CL_DSP_WMDR_NAME_TYPE 0xFE00
#define CL_DSP_WMDR_INFO_TYPE 0xFF00
/* HALO core */
#define CL_DSP_HALO_XMEM_PACKED_BASE 0x02000000
#define CL_DSP_HALO_XROM_PACKED_BASE 0x02006000
#define CL_DSP_HALO_XMEM_UNPACKED32_BASE 0x02400000
#define CL_DSP_HALO_XMEM_UNPACKED24_BASE 0x02800000
#define CL_DSP_HALO_XROM_UNPACKED24_BASE 0x02808000
#define CL_DSP_HALO_YMEM_PACKED_BASE 0x02C00000
#define CL_DSP_HALO_YMEM_UNPACKED32_BASE 0x03000000
#define CL_DSP_HALO_YMEM_UNPACKED24_BASE 0x03400000
#define CL_DSP_HALO_PMEM_BASE 0x03800000
#define CL_DSP_HALO_PROM_BASE 0x03C60000
#define CL_DSP_HALO_XM_FW_ID_REG 0x0280000C
#define CL_DSP_HALO_NUM_ALGOS_REG 0x02800024
#define CL_DSP_HALO_ALGO_REV_OFFSET 4
#define CL_DSP_HALO_ALGO_XM_BASE_OFFSET 8
#define CL_DSP_HALO_ALGO_XM_SIZE_OFFSET 12
#define CL_DSP_HALO_ALGO_YM_BASE_OFFSET 16
#define CL_DSP_HALO_ALGO_YM_SIZE_OFFSET 20
#define CL_DSP_ALGO_ENTRY_SIZE 24
#define CL_DSP_HALO_FLAG_READ BIT(0)
#define CL_DSP_HALO_FLAG_WRITE BIT(1)
#define CL_DSP_HALO_FLAG_VOLATILE BIT(2)
/* open wavetable */
#define CL_DSP_OWT_HEADER_MAX_LEN 254
#define CL_DSP_OWT_HEADER_ENTRY_SIZE 12
/* Waveform metadata */
#define CL_DSP_SVC_ID 1
#define CL_DSP_SVC_LEN 1
#define CL_DSP_MD_SIZE_MAX_BYTES 28
#define CL_DSP_MD_PRESENT BIT(10)
#define CL_DSP_MD_TERMINATOR 0xFFFFFF
#define CL_DSP_MD_TYPE_MASK GENMASK(23, 16)
#define CL_DSP_MD_LENGTH_MASK GENMASK(15, 8)
/* macros */
#define CL_DSP_WORD_ALIGN(n) (CL_DSP_BYTES_PER_WORD +\
(((n) / CL_DSP_BYTES_PER_WORD) *\
CL_DSP_BYTES_PER_WORD))
#define CL_DSP_GET_MAJOR(n) (((n) & CL_DSP_REV_MAJOR_MASK) >>\
CL_DSP_REV_MAJOR_SHIFT)
#define CL_DSP_GET_MINOR(n) (((n) & CL_DSP_REV_MINOR_MASK) >>\
CL_DSP_REV_MINOR_SHIFT)
#define CL_DSP_GET_PATCH(n) ((n) & CL_DSP_REV_PATCH_MASK)
#define CL_DSP_MEM_REGION_PREFIX(n) (((n) & CL_DSP_MEM_REG_TYPE_MASK) >>\
CL_DSP_MEM_REG_TYPE_SHIFT)
enum cl_dsp_wt_type {
WT_TYPE_V4_PCM = 0,
WT_TYPE_V4_PWLE = 1,
WT_TYPE_V4_PCM_F0_REDC = 2,
WT_TYPE_V4_PCM_F0_REDC_VAR = 3,
WT_TYPE_V4_COMPOSITE = 4,
WT_TYPE_V5_PCM_PCM_F0_REDC_Q = 5,
WT_TYPE_V5_PWLE_LONG = 6,
WT_TYPE_V5_PWLE_LINEAR = 7,
WT_TYPE_V6_PCM_F0_REDC = 8,
WT_TYPE_V6_PCM_F0_REDC_VAR = 9,
WT_TYPE_V6_COMPOSITE = 10,
WT_TYPE_V6_PCM_F0_REDC_Q = 11,
WT_TYPE_V6_PWLE = 12,
WT_TYPE_TERMINATOR = 0xFF,
};
union cl_dsp_wmdr_header {
struct {
char magic[CL_DSP_BYTES_PER_WORD];
u32 header_len;
u32 fw_revision : 24;
u8 file_format_version;
u32 api_revision : 24;
u8 target_core;
} __attribute__((__packed__));
u8 data[CL_DSP_COEFF_FILE_HEADER_SIZE];
};
union cl_dsp_wmfw_header {
struct {
char magic[CL_DSP_BYTES_PER_WORD];
u32 header_len;
u16 api_revision;
u8 target_core;
u8 file_format_version;
u32 xm_size;
u32 ym_size;
u32 pm_size;
u32 zm_size;
u32 timestamp[2];
u32 checksum;
} __attribute__((__packed__));
u8 data[CL_DSP_FW_FILE_HEADER_SIZE];
};
union cl_dsp_data_block_header {
struct {
u32 start_offset : 24;
u8 block_type;
u32 data_len;
} __attribute__((__packed__));
u8 data[CL_DSP_DBLK_HEADER_SIZE];
};
union cl_dsp_coeff_data_block_header {
struct {
u16 start_offset;
u16 block_type;
u32 algo_id;
u32 algo_rev;
u32 sample_rate;
u32 data_len;
} __attribute__((__packed__));
u8 data[CL_DSP_COEFF_DBLK_HEADER_SIZE];
};
struct cl_dsp_data_block {
union cl_dsp_data_block_header header;
u8 *payload;
};
struct cl_dsp_coeff_data_block {
union cl_dsp_coeff_data_block_header header;
u8 *payload;
};
struct cl_dsp_coeff_desc {
u32 parent_id;
char *parent_name;
u16 block_offset;
u16 block_type;
unsigned char name[CL_DSP_COEFF_NAME_LEN_MAX];
unsigned int reg;
unsigned int flags;
unsigned int length;
struct list_head list;
};
struct cl_dsp_memchunk {
u8 *data;
u8 *max;
int bytes;
u32 cache;
int cachebits;
};
struct cl_dsp_owt_header {
enum cl_dsp_wt_type type;
u16 flags;
u32 offset;
u32 size;
void *data;
u32 braking_time;
};
struct cl_dsp_owt_desc {
struct cl_dsp_owt_header waves[CL_DSP_OWT_HEADER_MAX_LEN];
int nwaves;
int bytes;
u8 *raw_data;
};
struct cl_dsp_wt_desc {
unsigned int id;
char wt_name_xm[CL_DSP_WMDR_NAME_LEN];
char wt_name_ym[CL_DSP_WMDR_NAME_LEN];
unsigned int wt_limit_xm;
unsigned int wt_limit_ym;
char wt_file[CL_DSP_WMDR_NAME_LEN];
char wt_date[CL_DSP_WMDR_DATE_LEN];
struct cl_dsp_owt_desc owt;
bool is_xm;
};
struct cl_dsp_algo_info {
unsigned int id;
unsigned int rev;
unsigned int xm_base;
unsigned int xm_size;
unsigned int ym_base;
unsigned int ym_size;
};
struct cl_dsp {
struct device *dev;
struct regmap *regmap;
struct list_head coeff_desc_head;
unsigned int num_algos;
struct cl_dsp_algo_info algo_info[CL_DSP_NUM_ALGOS_MAX + 1];
const struct cl_dsp_fw_desc *fw_desc;
const struct cl_dsp_mem_reg_desc *mem_reg_desc;
const struct cl_dsp_algo_params *algo_params;
struct cl_dsp_wt_desc *wt_desc;
};
#ifdef CONFIG_DEBUG_FS
/* Debug Logger */
struct cl_dsp_host_buffer {
__be32 buf1_base;
__be32 buf1_size;
__be32 buf2_base;
__be32 buf1_buf2_size;
__be32 buf3_base;
__be32 buf_total_size;
__be32 high_water_mark;
__be32 irq_count;
__be32 irq_ack;
__be32 next_write_index;
__be32 next_read_index;
__be32 error;
__be32 oldest_block_index;
__be32 requested_rewind;
__be32 reserved_space;
__be32 min_free;
__be32 blocks_written[2];
__be32 words_written[2];
} __packed;
struct cl_dsp_logger {
u32 *buf_data;
u32 buf_data_size;
u32 algo_id;
u32 host_buf_ptr;
u32 host_buf_base;
int host_buf_size_words;
u32 high_watermark;
};
struct cl_dsp_debugfs {
struct cl_dsp *core;
struct dentry *debugfs_root;
struct dentry *debugfs_node;
struct mutex lock;
struct cl_dsp_logger dl;
};
#define CL_DSP_DEBUGFS_NUM_CONTROLS 3
#define CL_DSP_DEBUGFS_RW_FILE_MODE 0600
#define CL_DSP_DEBUGFS_RO_FILE_MODE 0400
#define CL_DSP_DEBUGFS_WO_FILE_MOADE 0200
#define CL_DSP_DEBUGFS_TRACE_LOG_STRING_SIZE 3
#define CL_DSP_DEBUGFS_TRACE_LOG_DISABLE 0
#define CL_DSP_DEBUGFS_TRACE_LOG_ENABLE 1
#define CL_DSP_HOST_BUFFER_DATA_MASK 0x00FFFFFFu
#define CL_DSP_HOST_BUFFER_ERROR_OVERFLOW BIT(0)
#define CL_DSP_HOST_BUFFER_READ_INDEX_RESET 0x00FFFFFF
#define CL_DSP_HOST_BUFFER_IRQ_MASK BIT(0)
#define CL_DSP_HOST_BUFFER_DATA_SLOT_SIZE 10
#define HOST_BUFFER_FIELD(field) (offsetof(struct cl_dsp_host_buffer, field) / sizeof(__be32))
int cl_dsp_logger_update(struct cl_dsp_debugfs *db);
struct cl_dsp_debugfs *cl_dsp_debugfs_create(struct cl_dsp *dsp,
struct dentry *parent_node, u32 event_log_algo_id);
void cl_dsp_debugfs_destroy(struct cl_dsp_debugfs *db);
#endif /* CONFIG_DEBUG_FS */
/* Exported Functions */
struct cl_dsp *cl_dsp_create(struct device *dev, struct regmap *regmap);
int cl_dsp_destroy(struct cl_dsp *dsp);
int cl_dsp_wavetable_create(struct cl_dsp *dsp, unsigned int id,
const char *wt_name_xm, const char *wt_name_ym,
const char *wt_file);
int cl_dsp_firmware_parse(struct cl_dsp *dsp, const struct firmware *fw,
bool write_fw);
int cl_dsp_coeff_file_parse(struct cl_dsp *dsp, const struct firmware *fw);
int cl_dsp_get_reg(struct cl_dsp *dsp, const char *coeff_name,
const unsigned int block_type, const unsigned int algo_id,
unsigned int *reg);
int cl_dsp_get_flags(struct cl_dsp *dsp, const char *coeff_name,
const unsigned int block_type, const unsigned int algo_id,
unsigned int *flags);
int cl_dsp_get_length(struct cl_dsp *dsp, const char *coeff_name,
const unsigned int block_type, const unsigned int algo_id,
size_t *length);
bool cl_dsp_algo_is_present(struct cl_dsp *dsp, const unsigned int algo_id);
struct cl_dsp_memchunk cl_dsp_memchunk_create(void *data, int size);
int cl_dsp_memchunk_write(struct cl_dsp_memchunk *ch, int nbits, u32 val);
inline bool cl_dsp_memchunk_end(struct cl_dsp_memchunk *ch);
int cl_dsp_memchunk_read(struct cl_dsp *dsp, struct cl_dsp_memchunk *ch,
int nbits, void *val);
int cl_dsp_memchunk_flush(struct cl_dsp_memchunk *ch);
int cl_dsp_raw_write(struct cl_dsp *dsp, unsigned int reg,
const void *val, size_t val_len, size_t limit);
int cl_dsp_fw_id_get(struct cl_dsp *dsp, unsigned int *id);
int cl_dsp_fw_rev_get(struct cl_dsp *dsp, unsigned int *rev);
#endif /* __CL_DSP_H */

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (C) 2015 Linaro Ltd.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_SCM_H
#define __QCOM_SCM_H
@@ -15,6 +16,19 @@
#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0
#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1
#define QCOM_SCM_HDCP_MAX_REQ_CNT 5
#define QCOM_SCM_CAMERA_MAX_QOS_CNT 20
struct qcom_scm_camera_qos {
u32 offset;
u32 val;
};
enum qcom_download_mode {
QCOM_DOWNLOAD_NODUMP = 0x00,
QCOM_DOWNLOAD_EDL = 0x01,
QCOM_DOWNLOAD_FULLDUMP = 0x10,
QCOM_DOWNLOAD_MINIDUMP = 0x20,
};
struct qcom_scm_hdcp_req {
u32 addr;
@@ -46,6 +60,19 @@ enum qcom_scm_sec_dev_id {
QCOM_SCM_ICE_DEV_ID = 20,
};
struct qcom_scm_current_perm_info {
__le32 vmid;
__le32 perm;
__le64 ctx;
__le32 ctx_size;
__le32 unused;
};
struct qcom_scm_mem_map_info {
__le64 mem_addr;
__le64 mem_size;
};
enum qcom_scm_ice_cipher {
QCOM_SCM_ICE_CIPHER_AES_128_XTS = 0,
QCOM_SCM_ICE_CIPHER_AES_128_CBC = 1,
@@ -56,16 +83,75 @@ enum qcom_scm_ice_cipher {
#define QCOM_SCM_PERM_READ 0x4
#define QCOM_SCM_PERM_WRITE 0x2
#define QCOM_SCM_PERM_EXEC 0x1
#define QCOM_SCM_VMID_TZ 0x1
#define QCOM_SCM_VMID_HLOS 0x3
#define QCOM_SCM_VMID_CP_TOUCH 0x8
#define QCOM_SCM_VMID_CP_BITSTREAM 0x9
#define QCOM_SCM_VMID_CP_PIXEL 0xA
#define QCOM_SCM_VMID_CP_NON_PIXEL 0xB
#define QCOM_SCM_VMID_CP_CAMERA 0xD
#define QCOM_SCM_VMID_HLOS_FREE 0xE
#define QCOM_SCM_VMID_MSS_MSA 0xF
#define QCOM_SCM_VMID_MSS_NONMSA 0x10
#define QCOM_SCM_VMID_CP_SEC_DISPLAY 0x11
#define QCOM_SCM_VMID_CP_APP 0x12
#define QCOM_SCM_VMID_LPASS 0x16
#define QCOM_SCM_VMID_WLAN 0x18
#define QCOM_SCM_VMID_WLAN_CE 0x19
#define QCOM_SCM_VMID_CP_SPSS_SP 0x1A
#define QCOM_SCM_VMID_CP_CAMERA_PREVIEW 0x1D
#define QCOM_SCM_VMID_CDSP 0x1E
#define QCOM_SCM_VMID_CP_SPSS_SP_SHARED 0x22
#define QCOM_SCM_VMID_CP_SPSS_HLOS_SHARED 0x24
#define QCOM_SCM_VMID_ADSP_HEAP 0x25
#define QCOM_SCM_VMID_CP_CDSP 0x2A
#define QCOM_SCM_VMID_NAV 0x2B
#define QCOM_SCM_VMID_TVM 0x2D
#define QCOM_SCM_VMID_OEMVM 0x31
#define QCOM_SCM_VMID_SOCCP 0x3C
#define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE)
#define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC)
static inline void qcom_scm_populate_vmperm_info(
struct qcom_scm_current_perm_info *destvm, int vmid, int perm)
{
if (!destvm)
return;
destvm->vmid = cpu_to_le32(vmid);
destvm->perm = cpu_to_le32(perm);
destvm->ctx = 0;
destvm->ctx_size = 0;
}
static inline void qcom_scm_populate_mem_map_info(
struct qcom_scm_mem_map_info *mem_to_map,
phys_addr_t mem_addr, size_t mem_size)
{
if (!mem_to_map)
return;
mem_to_map->mem_addr = cpu_to_le64(mem_addr);
mem_to_map->mem_size = cpu_to_le64(mem_size);
}
extern bool qcom_scm_is_available(void);
extern int qcom_scm_set_cold_boot_addr(void *entry);
extern int qcom_scm_set_warm_boot_addr(void *entry);
extern void qcom_scm_cpu_power_down(u32 flags);
extern int qcom_scm_sec_wdog_deactivate(void);
extern int qcom_scm_sec_wdog_trigger(void);
extern void qcom_scm_disable_sdi(void);
extern int qcom_scm_set_remote_state(u32 state, u32 id);
extern int qcom_scm_spin_cpu(void);
extern void qcom_scm_set_download_mode(enum qcom_download_mode mode);
extern int qcom_scm_get_download_mode(unsigned int *mode);
extern int qcom_scm_config_cpu_errata(void);
struct qcom_scm_pas_metadata {
void *ptr;
dma_addr_t phys;
@@ -74,16 +160,27 @@ struct qcom_scm_pas_metadata {
extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
size_t size,
struct qcom_scm_pas_metadata *ctx);
extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
struct qcom_scm_pas_metadata *ctx,
struct device *dev);
extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx,
struct device *dev);
extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
phys_addr_t size);
extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
extern int qcom_scm_pas_shutdown(u32 peripheral);
extern int qcom_scm_pas_shutdown_retry(u32 peripheral);
extern bool qcom_scm_pas_supported(u32 peripheral);
extern int qcom_scm_get_sec_dump_state(u32 *dump_state);
extern int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size);
extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
extern int qcom_scm_io_reset(void);
extern bool qcom_scm_is_secure_wdog_trigger_available(void);
extern bool qcom_scm_is_mode_switch_available(void);
extern bool qcom_scm_restore_sec_cfg_available(void);
extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
@@ -93,10 +190,39 @@ extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
u32 cp_nonpixel_start,
u32 cp_nonpixel_size);
extern int qcom_scm_mem_protect_region_id(phys_addr_t paddr, size_t size);
extern int
qcom_scm_assign_mem_regions(struct qcom_scm_mem_map_info *mem_regions,
size_t mem_regions_sz, u32 *srcvms, size_t src_sz,
struct qcom_scm_current_perm_info *newvms,
size_t newvms_sz);
extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
u64 *src,
const struct qcom_scm_vmperm *newvm,
unsigned int dest_cnt);
extern int qcom_scm_mem_protect_sd_ctrl(u32 devid, phys_addr_t mem_addr,
u64 mem_size, u32 vmid);
extern int qcom_scm_kgsl_set_smmu_aperture(
unsigned int num_context_bank);
extern int qcom_scm_kgsl_set_smmu_lpac_aperture(
unsigned int num_context_bank);
extern int qcom_scm_kgsl_init_regs(u32 gpu_req);
extern int qcom_scm_kgsl_dcvs_tuning(u32 mingap, u32 penalty, u32 numbusy);
extern int qcom_scm_enable_shm_bridge(void);
extern int qcom_scm_delete_shm_bridge(u64 handle);
extern int qcom_scm_create_shm_bridge(u64 pfn_and_ns_perm_flags,
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
u64 ns_vmids, u64 *handle);
extern bool qcom_scm_dcvs_core_available(void);
extern bool qcom_scm_dcvs_ca_available(void);
extern int qcom_scm_dcvs_reset(void);
extern int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, int *version);
extern int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size);
extern int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time);
extern int qcom_scm_dcvs_update_v2(int level, s64 total_time, s64 busy_time);
extern int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, s64 busy_time,
int context_count);
extern bool qcom_scm_ocmem_lock_available(void);
extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
@@ -104,6 +230,13 @@ extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset,
u32 size);
extern int qcom_scm_config_set_ice_key(uint32_t index, phys_addr_t paddr,
size_t size, uint32_t cipher,
unsigned int data_unit,
unsigned int ce);
extern int qcom_scm_clear_ice_key(uint32_t index, unsigned int ce);
extern int qcom_scm_derive_sw_secret(phys_addr_t paddr_key, size_t size_key,
phys_addr_t paddr_secret, size_t size_secret);
extern bool qcom_scm_ice_available(void);
extern int qcom_scm_ice_invalidate_key(u32 index);
extern int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
@@ -114,12 +247,41 @@ extern bool qcom_scm_hdcp_available(void);
extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
u32 *resp);
extern int qcom_scm_lmh_fetch_data(u32 node_id, u32 debug_type, uint32_t *peak,
uint32_t *avg);
extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
extern int qcom_scm_smmu_notify_secure_lut(u64 dev_id, bool secure);
extern int qcom_scm_camera_update_camnoc_qos(uint32_t use_case_id,
uint32_t qos_cnt, struct qcom_scm_camera_qos *scm_buf);
extern int qcom_scm_camera_protect_all(uint32_t protect, uint32_t param);
extern int qcom_scm_camera_protect_phy_lanes(bool protect, u64 regmask);
extern int qcom_scm_get_tz_log_feat_id(u64 *version);
extern int qcom_scm_get_tz_feat_id_version(u64 feat_id, u64 *version);
extern int qcom_scm_register_qsee_log_buf(phys_addr_t buf, size_t len);
extern int qcom_scm_query_encrypted_log_feature(u64 *enabled);
extern int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len,
uint32_t log_id, bool is_full_encrypted_tz_logs_supported,
bool is_full_encrypted_tz_logs_enabled);
extern int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size,
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
u64 *response_type, unsigned int *data);
extern int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size,
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
u64 *response_type, unsigned int *data);
extern int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
size_t out_buf_size, int32_t *result, u64 *response_type,
unsigned int *data);
extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
u64 limit_node, u32 node_id, u64 version);
extern int qcom_scm_lmh_profile_change(u32 profile_id);
extern bool qcom_scm_lmh_dcvsh_available(void);
extern int qcom_scm_tsens_reinit(int *tsens_ret);
#endif

View File

@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_SI_CORE_XTS_H__
#define _LINUX_SI_CORE_XTS_H__
#include <linux/firmware/qcom/si_object.h>
struct si_object *init_si_mem_object_user(struct dma_buf *dma_buf,
void (*release)(void *), void *private);
/* For 'mem_object_to_dma_buf' and 'is_mem_object' caller should own the 'object',
* (i.e. someone should have already called '__get_si_object').
*/
int is_mem_object(struct si_object *object);
struct dma_buf *mem_object_to_dma_buf(struct si_object *object);
#endif /* _LINUX_SI_CORE_XTS_H__ */

View File

@@ -0,0 +1,231 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_SI_OBJECT_H__
#define _LINUX_SI_OBJECT_H__
#include <linux/kref.h>
#include <linux/completion.h>
/* Primordial Object */
/* It is used for bootstrapping the Mink IPC connection between a VM and QTEE.
*
* Each side (both the VM and the QTEE) starts up with no object received from the
* other side. They both ''assume'' the other side implements a permanent initial
* object in the object table.
*
* QTEE's initial object is typically called the ''root client env'', and it's
* invoked by VMs when they want to get a new clientEnv. The initial object created
* by the VMs is invoked by QTEE, it's typically called the ''primordial object''.
*
* To gracefully SWITCH the primordial object, use 'init_si_object_user' with
* 'SI_OT_ROOT' type and 'put_si_object' on the previous primordial object. si-core
* will issue the release on the old primordial object if QTEE is not using it.
*/
enum si_object_type {
SI_OT_USER = 0x1, /* QTEE object. */
SI_OT_CB_OBJECT = 0x2, /* Callback Object. */
SI_OT_ROOT = 0x8, /* ''Root client env.'' or 'primordial' Object. */
SI_OT_NULL = 0x10, /* NULL object. */
};
/* Maximum number of argument that can fit in a QTEE message. */
#define MAX_ARGS 64
struct si_object;
/**
* struct si_arg - argument for QTEE object invocation.
* @type: type of argument
* @flags: extra flags.
* @b: address and size if type of argument is buffer
* @o: si_object instance if type of argument is object
*/
struct si_arg {
enum arg_type {
SI_AT_END = 0,
SI_AT_IB, /* Input Buffer. */
SI_AT_OB, /* Output Buffer. */
SI_AT_IO, /* Input Object. */
SI_AT_OO /* Output Object. */
} type;
/* 'uaddr' holds a __user address. */
#define SI_ARG_FLAGS_UADDR 1
char flags;
union {
struct si_buffer {
union {
void *addr;
void __user *uaddr;
};
size_t size;
} b;
struct si_object *o;
};
};
static inline int size_of_arg(struct si_arg u[])
{
int i = 0;
while (u[i].type != SI_AT_END)
i++;
return i;
}
/* Context ID - It is a unique ID assigned to a invocation which is in progress.
* Objects's dispatcher can use the ID to differentiate between concurrent calls.
* ID [0 .. 10) are reserved, i.e. never passed to object's dispatcher.
*/
struct si_object_invoke_ctx {
unsigned int context_id;
#define OIC_FLAG_BUSY 1 /* Context is busy. */
#define OIC_FLAG_NOTIFY 2 /* Context needs to notify the current object. */
#define OIC_FLAG_QTEE 4 /* Context has objects shared with QTEE. */
unsigned int flags;
/* Current object invoked in this callback context. */
struct si_object *object;
/* Arguments passed to dispatch callback. */
struct si_arg u[MAX_ARGS + 1];
/* Objects that are used in async buffer request on this context. */
struct list_head objects_head;
int errno;
/* inbound and outbound buffers. */
struct {
struct si_buffer msg;
phys_addr_t paddr;
/* TODO. remove after moving to tzmem allocator. */
struct qtee_shm shm;
} in, out;
};
int si_object_do_invoke(struct si_object_invoke_ctx *oic,
struct si_object *object, unsigned long op, struct si_arg u[], int *result);
/* Reserved Operations. */
#define SI_OBJECT_OP_METHOD_MASK 0x0000FFFFU
#define SI_OBJECT_OP_METHOD_ID(op) ((op) & SI_OBJECT_OP_METHOD_MASK)
#define SI_OBJECT_OP_RELEASE (SI_OBJECT_OP_METHOD_MASK - 0)
#define SI_OBJECT_OP_RETAIN (SI_OBJECT_OP_METHOD_MASK - 1)
#define SI_OBJECT_OP_NO_OP (SI_OBJECT_OP_METHOD_MASK - 2)
struct si_object_operations {
void (*release)(struct si_object *object);
/**
* @op_supported:
*
* Query made to make sure the requested operation is supported. If defined,
* it is called before marshaling of the arguments (as optimisation).
*/
int (*op_supported)(unsigned long op);
/**
* @dispatch:
*
* Object's dispatch function called on object invocation.
* Multiple operations can be dispatched concurrently.
*/
int (*dispatch)(unsigned int context_id,
struct si_object *object, unsigned long op, struct si_arg args[]);
/**
* @notify:
*
* Notify the change in status of the pervious invocation to the driver;
* i.e. transport errors or success (status is zero).
*/
void (*notify)(unsigned int context_id, struct si_object *object, int status);
/**
* @prepare:
*
* Called on object of type AT_IO on direct call (or AT_OO on callback
* response) to QTEE. The object provider can return (1) a buffer argument
* and (2) an object. @args is { { .type == AT_OB }, { .type == AT_OO },
* { .type == AT_END } }. On failour, returns SI_OBJECT_OP_NO_OP, otherwise
* an operation that provider has done on @object.
*/
unsigned long (*prepare)(struct si_object *object, struct si_arg args[]);
};
struct si_object {
const char *name;
struct kref refcount;
enum si_object_type object_type;
union object_info {
unsigned long object_ptr;
} info;
struct si_object_operations *ops;
/* see si_core_async.c. */
struct list_head node;
/* see si_core_wq.c. */
struct work_struct work;
/* Callback for any internal cleanup before the object's release. */
void (*release)(struct si_object *object);
};
#define NULL_SI_OBJECT ((struct si_object *)(0))
#define ROOT_SI_OBJECT ((struct si_object *)(1))
static inline enum si_object_type typeof_si_object(struct si_object *object)
{
if (object == NULL_SI_OBJECT)
return SI_OT_NULL;
if (object == ROOT_SI_OBJECT)
return SI_OT_ROOT;
return object->object_type;
}
static inline const char *si_object_name(struct si_object *object)
{
if (object == NULL_SI_OBJECT)
return "null";
if (object == ROOT_SI_OBJECT)
return "root";
if (!object->name)
return "noname";
return object->name;
}
#define INIT_NULL_SI_OBJECT { .object_type = SI_OT_NULL }
#define SI_OBJECT(name, ...) __SI_OBJECT(name, ##__VA_ARGS__, 1)
#define __SI_OBJECT(name, n, ...) struct si_object name[(n)] = { INIT_NULL_SI_OBJECT }
struct si_object *allocate_si_object(void);
void free_si_object(struct si_object *object);
int init_si_object_user(struct si_object *object, enum si_object_type ot,
struct si_object_operations *ops, const char *fmt, ...);
int get_si_object(struct si_object *object);
void put_si_object(struct si_object *object);
int get_async_proto_version(void);
#endif /* _LINUX_SI_OBJECT_H__ */

View File

@@ -56,11 +56,7 @@ struct fscrypt_name {
#define fname_len(p) ((p)->disk_name.len)
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */
#ifdef CONFIG_DDAR
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 44
#else
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 40
#endif
#ifdef CONFIG_FS_ENCRYPTION

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _GH_CPUSYS_VM_MEM_ACCESS_H_
#define _GH_CPUSYS_VM_MEM_ACCESS_H_
#if IS_ENABLED(CONFIG_GH_CPUSYS_VM_MEM_ACCESS)
int gh_cpusys_vm_get_share_mem_info(struct resource *res);
#else
static inline int gh_cpusys_vm_get_share_mem_info(struct resource *res)
{
return -EINVAL;
}
#endif /* CONFIG_GH_CPUSYS_VM_MEM_ACCESS */
#endif /* _GH_CPUSYS_VM_MEM_ACCESS_H_ */

View File

@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#ifndef __GH_COMMON_H
#define __GH_COMMON_H
#include <linux/types.h>
/* Common Gunyah types */
typedef u16 gh_vmid_t;
typedef u32 gh_rm_msgid_t;
typedef u32 gh_virq_handle_t;
typedef u32 gh_label_t;
typedef u32 gh_memparcel_handle_t;
typedef u64 gh_capid_t;
typedef u64 gh_dbl_flags_t;
struct gh_vminfo {
u8 *guid;
char *uri;
char *name;
char *sign_auth;
};
/* Common Gunyah macros */
#define GH_CAPID_INVAL U64_MAX
#define GH_VMID_INVAL U16_MAX
enum gh_vm_names {
/*
* GH_SELF_VM is an alias for VMID 0. Useful for RM APIs which allow
* operations on current VM such as console
*/
GH_SELF_VM,
GH_PRIMARY_VM,
GH_TRUSTED_VM,
GH_CPUSYS_VM,
GH_OEM_VM,
GH_VM_MAX
};
#endif

View File

@@ -0,0 +1,110 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_DBL_H
#define __GH_DBL_H
#include "gh_common.h"
typedef void (*dbl_rx_cb_t)(int irq, void *priv_data);
enum gh_dbl_label {
GH_DBL_TUI_LABEL,
GH_DBL_TUI_NEURON_BLK0,
GH_DBL_TUI_NEURON_BLK1,
GH_DBL_TUI_QRTR,
GH_DBL_TEST_TUIVM,
GH_DBL_TEST_OEMVM,
GH_DBL_HW_FENCE,
GH_DBL_TUI_DDUMP,
GH_DBL_OEMVM_QRTR,
GH_DBL_VM_PANIC_NOTIFY,
GH_DBL_LABEL_MAX
};
/* Possible flags to pass for send, set_mask, read, reset */
#define GH_DBL_NONBLOCK BIT(32)
#if IS_ENABLED(CONFIG_GH_DBL)
void *gh_dbl_tx_register(enum gh_dbl_label label);
void *gh_dbl_rx_register(enum gh_dbl_label label, dbl_rx_cb_t rx_cb,
void *priv);
int gh_dbl_tx_unregister(void *dbl_client_desc);
int gh_dbl_rx_unregister(void *dbl_client_desc);
int gh_dbl_send(void *dbl_client_desc, uint64_t *newflags,
const unsigned long flags);
int gh_dbl_set_mask(void *dbl_client_desc, gh_dbl_flags_t enable_mask,
gh_dbl_flags_t ack_mask, const unsigned long flags);
int gh_dbl_read_and_clean(void *dbl_client_desc, gh_dbl_flags_t *clear_flags,
const unsigned long flags);
int gh_dbl_reset(void *dbl_client_desc, const unsigned long flags);
int gh_dbl_populate_cap_info(enum gh_dbl_label label, u64 cap_id,
int direction, int rx_irq);
int gh_dbl_reset_cap_info(enum gh_dbl_label label, int direction, int *irq);
#else
static inline void *gh_dbl_tx_register(enum gh_dbl_label label)
{
return ERR_PTR(-ENODEV);
}
static inline void *gh_dbl_rx_register(enum gh_dbl_label label,
dbl_rx_cb_t rx_cb,
void *priv)
{
return ERR_PTR(-ENODEV);
}
static inline int gh_dbl_tx_unregister(void *dbl_client_desc)
{
return -EINVAL;
}
static inline int gh_dbl_rx_unregister(void *dbl_client_desc)
{
return -EINVAL;
}
static inline int gh_dbl_send(void *dbl_client_desc, uint64_t *newflags,
const unsigned long flags)
{
return -EINVAL;
}
static inline int gh_dbl_set_mask(void *dbl_client_desc,
gh_dbl_flags_t enable_mask,
gh_dbl_flags_t ack_mask,
const unsigned long flags)
{
return -EINVAL;
}
static inline int gh_dbl_read_and_clean(void *dbl_client_desc,
gh_dbl_flags_t *clear_flags,
const unsigned long flags)
{
return -EINVAL;
}
static inline int gh_dbl_reset(void *dbl_client_desc, const unsigned long flags)
{
return -EINVAL;
}
static inline int gh_dbl_populate_cap_info(enum gh_dbl_label label, u64 cap_id,
int direction, int rx_irq)
{
return -EINVAL;
}
static inline
int gh_dbl_reset_cap_info(enum gh_dbl_label label, int direction, int *irq)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#ifndef __GH_ERRNO_H
#define __GH_ERRNO_H
#include <linux/errno.h>
#define GH_ERROR_OK 0
#define GH_ERROR_UNIMPLEMENTED -1
#define GH_ERROR_RETRY -2
#define GH_ERROR_ARG_INVAL 1
#define GH_ERROR_ARG_SIZE 2
#define GH_ERROR_ARG_ALIGN 3
#define GH_ERROR_NOMEM 10
#define GH_ERROR_ADDR_OVFL 20
#define GH_ERROR_ADDR_UNFL 21
#define GH_ERROR_ADDR_INVAL 22
#define GH_ERROR_DENIED 30
#define GH_ERROR_BUSY 31
#define GH_ERROR_IDLE 32
#define GH_ERROR_IRQ_BOUND 40
#define GH_ERROR_IRQ_UNBOUND 41
#define GH_ERROR_CSPACE_CAP_NULL 50
#define GH_ERROR_CSPACE_CAP_REVOKED 51
#define GH_ERROR_CSPACE_WRONG_OBJ_TYPE 52
#define GH_ERROR_CSPACE_INSUF_RIGHTS 53
#define GH_ERROR_CSPACE_FULL 54
#define GH_ERROR_MSGQUEUE_EMPTY 60
#define GH_ERROR_MSGQUEUE_FULL 61
static inline int gh_remap_error(int gh_error)
{
switch (gh_error) {
case GH_ERROR_OK:
return 0;
case GH_ERROR_NOMEM:
return -ENOMEM;
case GH_ERROR_DENIED:
case GH_ERROR_CSPACE_CAP_NULL:
case GH_ERROR_CSPACE_CAP_REVOKED:
case GH_ERROR_CSPACE_WRONG_OBJ_TYPE:
case GH_ERROR_CSPACE_INSUF_RIGHTS:
case GH_ERROR_CSPACE_FULL:
return -EACCES;
case GH_ERROR_BUSY:
case GH_ERROR_IDLE:
return -EBUSY;
case GH_ERROR_IRQ_BOUND:
case GH_ERROR_IRQ_UNBOUND:
case GH_ERROR_MSGQUEUE_FULL:
case GH_ERROR_MSGQUEUE_EMPTY:
return -EPERM;
case GH_ERROR_UNIMPLEMENTED:
return -EOPNOTSUPP;
case GH_ERROR_ARG_INVAL:
case GH_ERROR_ARG_SIZE:
case GH_ERROR_ARG_ALIGN:
case GH_ERROR_ADDR_OVFL:
case GH_ERROR_ADDR_UNFL:
case GH_ERROR_ADDR_INVAL:
default:
return -EINVAL;
}
}
#endif

View File

@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_IRQ_LEND_H
#define __GH_IRQ_LEND_H
#include <linux/types.h>
#include "gh_common.h"
#include "gh_rm_drv.h"
enum gh_irq_label {
GH_IRQ_LABEL_SDE,
GH_IRQ_LABEL_TRUSTED_TOUCH_PRIMARY,
GH_IRQ_LABEL_TRUSTED_TOUCH_SECONDARY,
GH_IRQ_LABEL_TEST_TUIVM,
GH_IRQ_LABEL_TEST_OEMVM,
GH_IRQ_LABEL_EVA,
GH_IRQ_LABEL_MAX
};
typedef void (*gh_irq_handle_fn)(void *req, enum gh_irq_label label);
typedef void (*gh_irq_handle_fn_v2)(void *req, unsigned long notif_type,
enum gh_irq_label label);
#if IS_ENABLED(CONFIG_GH_IRQ_LEND)
int gh_irq_lend(enum gh_irq_label label, enum gh_vm_names name,
int hw_irq, gh_irq_handle_fn cb_handle, void *data);
int gh_irq_lend_v2(enum gh_irq_label label, enum gh_vm_names name,
int hw_irq, gh_irq_handle_fn_v2 cb_handle, void *data);
int gh_irq_lend_notify(enum gh_irq_label label);
int gh_irq_reclaim(enum gh_irq_label label);
int gh_irq_wait_for_lend(enum gh_irq_label label, enum gh_vm_names name,
gh_irq_handle_fn on_lend, void *data);
int gh_irq_wait_for_lend_v2(enum gh_irq_label label, enum gh_vm_names name,
gh_irq_handle_fn_v2 on_lend, void *data);
int gh_irq_accept(enum gh_irq_label label, int irq, int type);
int gh_irq_accept_notify(enum gh_irq_label label);
int gh_irq_release(enum gh_irq_label label);
int gh_irq_release_notify(enum gh_irq_label label);
#else
static inline int gh_irq_lend(enum gh_irq_label label, enum gh_vm_names name,
int hw_irq, gh_irq_handle_fn cb_handle, void *data)
{
return -EINVAL;
}
static inline int gh_irq_lend_v2(enum gh_irq_label label, enum gh_vm_names name,
int hw_irq, gh_irq_handle_fn_v2 cb_handle, void *data)
{
return -EINVAL;
}
static inline int gh_irq_lend_notify(enum gh_irq_label label)
{
return -EINVAL;
}
static inline int gh_irq_reclaim(enum gh_irq_label label)
{
return -EINVAL;
}
static inline int gh_irq_wait_for_lend(enum gh_irq_label label, enum gh_vm_names name,
gh_irq_handle_fn on_lend, void *data)
{
return -EINVAL;
}
static inline int gh_irq_wait_for_lend_v2(enum gh_irq_label label, enum gh_vm_names name,
gh_irq_handle_fn_v2 on_lend, void *data)
{
return -EINVAL;
}
static inline int gh_irq_accept(enum gh_irq_label label, int irq, int type)
{
return -EINVAL;
}
static inline int gh_irq_accept_notify(enum gh_irq_label label)
{
return -EINVAL;
}
static inline int gh_irq_release(enum gh_irq_label label)
{
return -EINVAL;
}
static inline int gh_irq_release_notify(enum gh_irq_label label)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_MEM_NOTIFIER_H
#define __GH_MEM_NOTIFIER_H
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <linux/types.h>
enum gh_mem_notifier_tag {
GH_MEM_NOTIFIER_TAG_DISPLAY,
GH_MEM_NOTIFIER_TAG_TOUCH_PRIMARY,
GH_MEM_NOTIFIER_TAG_TOUCH_SECONDARY,
GH_MEM_NOTIFIER_TAG_TLMM,
GH_MEM_NOTIFIER_TAG_TEST_TLMM,
GH_MEM_NOTIFIER_TAG_TEST_TUIVM,
GH_MEM_NOTIFIER_TAG_TEST_OEMVM,
GH_MEM_NOTIFIER_TAG_EVA,
GH_MEM_NOTIFIER_TAG_MAX
};
typedef void (*gh_mem_notifier_handler)(enum gh_mem_notifier_tag tag,
unsigned long notif_type,
void *entry_data, void *notif_msg);
#if IS_ENABLED(CONFIG_GH_MEM_NOTIFIER)
void *gh_mem_notifier_register(enum gh_mem_notifier_tag tag,
gh_mem_notifier_handler notif_handler,
void *data);
void gh_mem_notifier_unregister(void *cookie);
#else
static void __maybe_unused *gh_mem_notifier_register(enum gh_mem_notifier_tag tag,
gh_mem_notifier_handler notif_handler,
void *data)
{
return ERR_PTR(-EOPNOTSUPP);
}
static void __maybe_unused gh_mem_notifier_unregister(void *cookie)
{
}
#endif
#endif

View File

@@ -0,0 +1,98 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#ifndef __GH_MSGQ_H
#define __GH_MSGQ_H
#include <linux/types.h>
#include <linux/platform_device.h>
#include "gh_common.h"
enum gh_msgq_label {
GH_MSGQ_LABEL_RM,
GH_MSGQ_LABEL_MEMBUF,
GH_MSGQ_LABEL_DISPLAY,
GH_MSGQ_LABEL_VSOCK,
GH_MSGQ_LABEL_TEST_TUIVM,
GH_MSGQ_LABEL_TEST_OEMVM,
GH_MSGQ_LABEL_MMRM,
GH_MSGQ_LABEL_EVA,
GH_MSGQ_VCPU_SCHED_TEST,
GH_MSGQ_VCPU_SCHED_TEST_OEMVM,
GH_MSGQ_LABEL_SMMU_PROXY,
GH_MSGQ_LABEL_RESOURCE_REQUEST,
GH_MSGQ_LABEL_MEMBUF_OEMVM,
GH_MSGQ_LABEL_DMABUF_TEST_TUIVM,
GH_MSGQ_LABEL_DMABUF_TEST_OEMVM,
GH_MSGQ_LABEL_MAX
};
#define GH_MSGQ_MAX_MSG_SIZE_BYTES 240
#define GH_MSGQ_DIRECTION_TX 0
#define GH_MSGQ_DIRECTION_RX 1
/* Possible flags to pass for Tx or Rx */
#define GH_MSGQ_TX_PUSH BIT(0)
#define GH_MSGQ_NONBLOCK BIT(32)
#if IS_ENABLED(CONFIG_GH_MSGQ)
void *gh_msgq_register(int label);
int gh_msgq_unregister(void *msgq_client_desc);
int gh_msgq_send(void *msgq_client_desc,
void *buff, size_t size, unsigned long flags);
int gh_msgq_recv(void *msgq_client_desc,
void *buff, size_t buff_size,
size_t *recv_size, unsigned long flags);
int gh_msgq_populate_cap_info(int label, u64 cap_id,
int direction, int irq);
int gh_msgq_probe(struct platform_device *pdev, int label);
int gh_msgq_reset_cap_info(enum gh_msgq_label label, int direction, int *irq);
#else
static inline void *gh_msgq_register(int label)
{
return ERR_PTR(-ENODEV);
}
static inline int gh_msgq_unregister(void *msgq_client_desc)
{
return -EINVAL;
}
static inline int gh_msgq_send(void *msgq_client_desc,
void *buff, size_t size, unsigned long flags)
{
return -EINVAL;
}
static inline int gh_msgq_recv(void *msgq_client_desc,
void *buff, size_t buff_size,
size_t *recv_size, unsigned long flags)
{
return -EINVAL;
}
static inline int gh_msgq_populate_cap_info(int label, u64 cap_id,
int direction, int irq)
{
return -EINVAL;
}
static inline
int gh_msgq_reset_cap_info(enum gh_msgq_label label, int direction, int *irq)
{
return -EINVAL;
}
static inline int gh_msgq_probe(struct platform_device *pdev, int label)
{
return -ENODEV;
}
#endif
#endif

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_PANIC_NOTIFIER_H
#define __GH_PANIC_NOTIFIER_H
#if IS_ENABLED(CONFIG_GH_PANIC_NOTIFIER)
int gh_panic_notifier_register(struct notifier_block *nb);
int gh_panic_notifier_unregister(struct notifier_block *nb);
#else
static inline int gh_panic_notifier_register(struct notifier_block *nb)
{
return 0;
}
static inline int gh_panic_notifier_unregister(struct notifier_block *nb)
{
return 0;
}
#endif
#endif

View File

@@ -0,0 +1,119 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_RESOURCE_H
#define __GH_RESOURCE_H
#include <linux/notifier.h>
#include <linux/gunyah/gh_common.h>
#include <linux/gunyah/gh_rm_drv.h>
#define SUBSYS_NAME_MAX 16
#define RESOURCE_CNT_MAX 8
/* Resource type */
enum gh_res_request_type {
GH_RESOURCE_IOMEM,
GH_RESOURCE_GPIO,
GH_RESOURCE_IRQ,
};
/**
* struct gh_res_request - Define each resource in request
* @resource_type: Type of the resource
* @resource: Detailed resource information
*/
struct gh_res_request {
enum gh_res_request_type resource_type;
/**
* @irq_num: IRQ number
* @gpio_num: GPIO number
* @sgl_entry: Memory address and size
*/
union {
int irq_num;
u32 gpio_num;
struct gh_sgl_entry sgl_entry;
} resource;
};
/**
* struct gh_resource_payload - Message used to communicate between VMs
* @is_req: Represent resource need request or release
* @source_vmid: Source VMID of the message
* @subsys_name: The target subsystem name of resources
* @resource_cnt: Count of resources
* @resource: Array for resources in the message
*/
struct gh_resource_payload {
bool is_req;
gh_vmid_t source_vmid;
char subsys_name[SUBSYS_NAME_MAX];
uint8_t resource_cnt;
struct gh_res_request resource[];
};
typedef int (*gh_resource_callback)(gh_vmid_t source_vmid, bool is_req,
struct gh_res_request *resource,
int resource_cnt);
/**
* struct gh_resource_client - Client driver who is interested in request
* @list: List entry to be add in the client list
* @subsys_name: Subsystem name of resources that client is interested in
* @cb: Function to be called when request happen
*/
struct gh_resource_client {
struct list_head list;
char subsys_name[SUBSYS_NAME_MAX];
gh_resource_callback cb;
};
#if IS_ENABLED(CONFIG_GH_RES_REQUEST)
int gh_resource_register_req_client(struct gh_resource_client *client);
int gh_resource_unregister_req_client(struct gh_resource_client *client);
int gh_resource_register_release_client(struct gh_resource_client *client);
int gh_resource_unregister_release_client(struct gh_resource_client *client);
int gh_resource_request(gh_vmid_t target_vmid, const char *subsys_name,
struct gh_res_request *req_resource, int res_cnt);
int gh_resource_release(gh_vmid_t target_vmid, const char *subsys_name,
struct gh_res_request *release_resource, int res_cnt);
#else
static inline int
gh_resource_register_req_client(struct gh_resource_client *client)
{
return -ENODEV;
}
static inline int
gh_resource_unregister_req_client(struct gh_resource_client *client)
{
return -ENODEV;
}
static inline int
gh_resource_register_release_client(struct gh_resource_client *client)
{
return -EINVAL;
}
static inline int
gh_resource_unregister_release_client(struct gh_resource_client *client)
{
return -EINVAL;
}
static inline int gh_resource_request(gh_vmid_t target_vmid,
const char *subsys_name,
struct gh_res_request *req_resource,
int res_cnt)
{
return -EINVAL;
}
static inline int gh_resource_release(gh_vmid_t target_vmid,
const char *subsys_name,
struct gh_res_request *release_resource,
int res_cnt)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -0,0 +1,777 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#ifndef __GH_RM_DRV_H
#define __GH_RM_DRV_H
#include <linux/types.h>
#include <linux/notifier.h>
#include <linux/fwnode.h>
#include <linux/gunyah.h>
#include <linux/range.h>
#include "gh_common.h"
/* Notification type Message IDs */
/* Memory APIs */
#define GH_RM_NOTIF_MEM_SHARED 0x51100011
#define GH_RM_NOTIF_MEM_RELEASED 0x51100012
#define GH_RM_NOTIF_MEM_ACCEPTED 0x51100013
#define GH_RM_MEM_TYPE_NORMAL 0
#define GH_RM_MEM_TYPE_IO 1
#define GH_RM_TRANS_TYPE_DONATE 0
#define GH_RM_TRANS_TYPE_LEND 1
#define GH_RM_TRANS_TYPE_SHARE 2
#define GH_RM_ACL_X BIT(0)
#define GH_RM_ACL_W BIT(1)
#define GH_RM_ACL_R BIT(2)
#define GH_RM_MEM_RELEASE_CLEAR BIT(0)
#define GH_RM_MEM_RECLAIM_CLEAR BIT(0)
#define GH_RM_MEM_ACCEPT_VALIDATE_SANITIZED BIT(0)
#define GH_RM_MEM_ACCEPT_VALIDATE_ACL_ATTRS BIT(1)
#define GH_RM_MEM_ACCEPT_VALIDATE_LABEL BIT(2)
#define GH_RM_MEM_ACCEPT_MAP_IPA_CONTIGUOUS BIT(4)
#define GH_RM_MEM_ACCEPT_DONE BIT(7)
#define GH_RM_MEM_SHARE_SANITIZE BIT(0)
#define GH_RM_MEM_SHARE_APPEND BIT(1)
#define GH_RM_MEM_LEND_SANITIZE BIT(0)
#define GH_RM_MEM_LEND_APPEND BIT(1)
#define GH_RM_MEM_DONATE_SANITIZE BIT(0)
#define GH_RM_MEM_DONATE_APPEND BIT(1)
#define GH_RM_MEM_APPEND_END BIT(0)
#define GH_RM_MEM_NOTIFY_RECIPIENT_SHARED BIT(0)
#define GH_RM_MEM_NOTIFY_RECIPIENT GH_RM_MEM_NOTIFY_RECIPIENT_SHARED
#define GH_RM_MEM_NOTIFY_OWNER_RELEASED BIT(1)
#define GH_RM_MEM_NOTIFY_OWNER GH_RM_MEM_NOTIFY_OWNER_RELEASED
#define GH_RM_MEM_NOTIFY_OWNER_ACCEPTED BIT(2)
/* Support may vary across hardware platforms */
#define GH_RM_IPA_RESERVE_ECC BIT(0)
#define GH_RM_IPA_RESERVE_MEMTAG BIT(1)
#define GH_RM_IPA_RESERVE_NORMAL BIT(2)
#define GH_RM_IPA_RESERVE_IO BIT(3)
/* BIT(4) and BIT(5) reserved */
/* The calling VM's default memory type */
#define GH_RM_IPA_RESERVE_DEFAULT BIT(6)
#define GH_RM_IPA_RESERVE_VALID_FLAGS (GENMASK(3, 0) | BIT(6))
#define GH_RM_IPA_RESERVE_PLATFORM_ENCRYPTED BIT(0)
#define GH_RM_IPA_RESERVE_PLATFORM_AUTHENTICATED BIT(1)
#define GH_RM_IPA_RESERVE_PLATFORM_ANTI_ROLLBACK BIT(2)
#define GH_RM_IPA_RESERVE_PLATFORM_VALID_FLAGS GENMASK(2, 0)
#define MAX_EXIT_REASON_SIZE 4
struct gh_rm_notif_mem_shared_payload {
u32 mem_handle;
u8 mem_type;
u8 trans_type;
u8 flags;
u8 reserved1;
u16 owner_vmid;
u16 reserved2;
u32 label;
gh_label_t mem_info_tag;
/* TODO: How to arrange multiple variable length struct arrays? */
} __packed;
/* Compared with gh_sgl_desc, ipa_base field is not present */
struct gh_rm_notif_mem_shared_sgl_desc {
u16 n_sgl_entries;
u16 reserved;
u64 size[];
} __packed;
struct gh_rm_notif_mem_released_payload {
u32 mem_handle;
u16 participant_vmid;
u16 reserved;
gh_label_t mem_info_tag;
} __packed;
struct gh_rm_notif_mem_accepted_payload {
u32 mem_handle;
u16 participant_vmid;
u16 reserved;
gh_label_t mem_info_tag;
} __packed;
struct gh_acl_entry {
u16 vmid;
u8 perms;
u8 reserved;
} __packed;
struct gh_sgl_entry {
u64 ipa_base;
u64 size;
} __packed;
struct gh_mem_attr_entry {
u16 attr;
u16 vmid;
} __packed;
struct gh_acl_desc {
u32 n_acl_entries;
struct gh_acl_entry acl_entries[];
} __packed;
struct gh_sgl_desc {
u32 n_sgl_entries;
u16 reserved;
struct gh_sgl_entry sgl_entries[];
};
struct gh_mem_attr_desc {
u16 n_mem_attr_entries;
u16 reserved;
struct gh_mem_attr_entry attr_entries[];
} __packed;
struct gh_notify_vmid_entry {
u16 vmid;
u16 reserved;
} __packed;
struct gh_notify_vmid_desc {
u16 n_vmid_entries;
u16 reserved;
struct gh_notify_vmid_entry vmid_entries[];
} __packed;
/* VM APIs */
#define GH_RM_NOTIF_VM_EXITED 0x56100001
#define GH_RM_NOTIF_VM_SHUTDOWN 0x56100002
#define GH_RM_NOTIF_VM_STATUS 0x56100008
#define GH_RM_NOTIF_VM_IRQ_LENT 0x56100011
#define GH_RM_NOTIF_VM_IRQ_RELEASED 0x56100012
#define GH_RM_NOTIF_VM_IRQ_ACCEPTED 0x56100013
/* AUTH mechanisms */
#define GH_VM_UNAUTH 0
#define GH_VM_AUTH_PIL_ELF 1
#define GH_VM_AUTH_ANDROID_PVM 2
/* AUTH_PARAM_TYPE mechanisms */
#define GH_VM_AUTH_PARAM_PAS_ID 0 /* Used to pass peripheral auth id */
#define GH_RM_VM_STATUS_NO_STATE 0
#define GH_RM_VM_STATUS_INIT 1
#define GH_RM_VM_STATUS_READY 2
#define GH_RM_VM_STATUS_RUNNING 3
#define GH_RM_VM_STATUS_PAUSED 4
#define GH_RM_VM_STATUS_LOAD 5
#define GH_RM_VM_STATUS_AUTH 6
/* 7 is reserved */
#define GH_RM_VM_STATUS_INIT_FAILED 8
#define GH_RM_VM_STATUS_EXITED 9
#define GH_RM_VM_STATUS_RESETTING 10
#define GH_RM_VM_STATUS_RESET 11
#define GH_RM_VM_STATUS_RESET_FAILED 12
#define GH_RM_OS_STATUS_NONE 0
#define GH_RM_OS_STATUS_EARLY_BOOT 1
#define GH_RM_OS_STATUS_BOOT 2
#define GH_RM_OS_STATUS_INIT 3
#define GH_RM_OS_STATUS_RUN 4
#define GH_RM_APP_STATUS_TUI_SERVICE_BOOT 1
#define GH_RM_VM_STOP_FLAG_FORCE_STOP 0x01
#define GH_RM_VM_EXIT_TYPE_VM_EXIT 0
#define GH_RM_VM_EXIT_TYPE_SYSTEM_OFF 1
#define GH_RM_VM_EXIT_TYPE_SYSTEM_RESET 2
#define GH_RM_VM_EXIT_TYPE_SYSTEM_RESET2 3
#define GH_RM_VM_EXIT_TYPE_WDT_BITE 4
#define GH_RM_VM_EXIT_TYPE_HYP_ERROR 5
#define GH_RM_VM_EXIT_TYPE_ASYNC_EXT_ABORT 6
#define GH_RM_VM_EXIT_TYPE_VM_STOP_FORCED 7
/* GH_RM_VM_EXIT_TYPE_VM_EXIT */
struct gh_vm_exit_reason_vm_exit {
u16 exit_flags;
/* GH_VM_EXIT_EXIT_FLAG_* are bit representations */
#define GH_VM_EXIT_EXIT_FLAG_TYPE 0x1
#define GH_VM_EXIT_POWEROFF 0 /* Value at bit:0 */
#define GH_VM_EXIT_RESTART 1 /* Value at bit:0 */
#define GH_VM_EXIT_EXIT_FLAG_SYSTEM 0x2
#define GH_VM_EXIT_EXIT_FLAG_WARM 0x4
#define GH_VM_EXIT_EXIT_FLAG_DUMP 0x8
u8 exit_code;
/* Exit codes */
#define GH_VM_EXIT_CODE_NORMAL 0
#define GH_VM_EXIT_SOFTWARE_ERR 1
#define GH_VM_EXIT_BUS_ERR 2
#define GH_VM_EXIT_DEVICE_ERR 3
u8 reserved;
} __packed;
/* Reasons for VM_STOP */
#define GH_VM_STOP_SHUTDOWN 0
#define GH_VM_STOP_RESTART 1
#define GH_VM_STOP_CRASH 2
#define GH_VM_STOP_FORCE_STOP 3
#define GH_VM_STOP_MAX 4
struct gh_rm_notif_vm_exited_payload {
gh_vmid_t vmid;
u16 exit_type;
u32 exit_reason_size;
u32 exit_reason[0];
} __packed;
struct gh_rm_notif_vm_shutdown_payload {
u32 stop_reason;
} __packed;
struct gh_rm_notif_vm_status_payload {
gh_vmid_t vmid;
u16 reserved;
u8 vm_status;
u8 os_status;
u16 app_status;
} __packed;
struct gh_rm_notif_vm_irq_lent_payload {
gh_vmid_t owner_vmid;
u16 reserved;
gh_virq_handle_t virq_handle;
gh_label_t virq_label;
} __packed;
struct gh_rm_notif_vm_irq_released_payload {
gh_virq_handle_t virq_handle;
} __packed;
struct gh_rm_notif_vm_irq_accepted_payload {
gh_virq_handle_t virq_handle;
} __packed;
struct gh_vm_auth_param_entry {
u32 auth_param_type;
u32 auth_param;
} __packed;
/* Arch specific APIs */
#if IS_ENABLED(CONFIG_GH_ARM64_DRV)
/* IRQ APIs */
int gh_get_irq(u32 virq, u32 type, struct fwnode_handle *handle);
int gh_put_irq(int irq);
int gh_get_virq(int base_virq, int virq);
int gh_put_virq(int irq);
int gh_arch_validate_vm_exited_notif(size_t payload_size,
struct gh_rm_notif_vm_exited_payload *payload);
#else
static inline int gh_get_irq(u32 virq, u32 type,
struct fwnode_handle *handle)
{
return -EINVAL;
}
static inline int gh_put_irq(int irq)
{
return -EINVAL;
}
static inline int gh_get_virq(int base_virq, int virq)
{
return -EINVAL;
}
static inline int gh_put_virq(int irq)
{
return -EINVAL;
}
static inline int gh_arch_validate_vm_exited_notif(size_t payload_size,
struct gh_rm_notif_vm_exited_payload *payload)
{
return -EINVAL;
}
#endif
/* VM Services */
#define GH_RM_NOTIF_VM_CONSOLE_CHARS 0X56100080
struct gh_rm_notif_vm_console_chars {
gh_vmid_t vmid;
u16 num_bytes;
u8 bytes[0];
} __packed;
struct gh_vm_status {
u8 vm_status;
u8 os_status;
u16 app_status;
} __packed;
struct notifier_block;
typedef int (*gh_virtio_mmio_cb_t)(gh_vmid_t peer, const char *vm_name,
gh_label_t label, gh_capid_t cap_id, int linux_irq, u64 base, u64 size);
typedef int (*gh_wdog_manage_cb_t)(gh_vmid_t vmid, gh_capid_t cap_id, bool populate);
typedef int (*gh_vcpu_affinity_set_cb_t)(gh_vmid_t vmid, gh_label_t label,
gh_capid_t cap_id, int linux_irq);
typedef int (*gh_vcpu_affinity_reset_cb_t)(gh_vmid_t vmid, gh_label_t label,
gh_capid_t cap_id, int *linux_irq);
typedef int (*gh_vpm_grp_set_cb_t)(gh_vmid_t vmid, gh_capid_t cap_id, int linux_irq);
typedef int (*gh_vpm_grp_reset_cb_t)(gh_vmid_t vmid, int *linux_irq);
typedef void (*gh_all_res_populated_cb_t)(gh_vmid_t vmid, bool res_populated);
#if IS_ENABLED(CONFIG_GH_RM_DRV)
/* RM client registration APIs */
int gh_rm_register_notifier(struct notifier_block *nb);
int gh_rm_unregister_notifier(struct notifier_block *nb);
/* Client APIs for IRQ management */
int gh_rm_virq_to_irq(u32 virq, u32 type);
int gh_rm_irq_to_virq(int irq, u32 *virq);
int gh_rm_vm_irq_lend(gh_vmid_t vmid,
int virq,
int label,
gh_virq_handle_t *virq_handle);
int gh_rm_vm_irq_lend_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle);
int gh_rm_vm_irq_accept(gh_virq_handle_t virq_handle, int virq);
int gh_rm_vm_irq_accept_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle);
int gh_rm_vm_irq_release(gh_virq_handle_t virq_handle);
int gh_rm_vm_irq_release_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle);
int gh_rm_vm_irq_reclaim(gh_virq_handle_t virq_handle);
int gh_rm_set_virtio_mmio_cb(gh_virtio_mmio_cb_t fnptr);
void gh_rm_unset_virtio_mmio_cb(void);
int gh_rm_set_wdog_manage_cb(gh_wdog_manage_cb_t fnptr);
int gh_rm_set_vcpu_affinity_cb(gh_vcpu_affinity_set_cb_t fnptr);
int gh_rm_reset_vcpu_affinity_cb(gh_vcpu_affinity_reset_cb_t fnptr);
int gh_rm_set_vpm_grp_cb(gh_vpm_grp_set_cb_t fnptr);
int gh_rm_reset_vpm_grp_cb(gh_vpm_grp_reset_cb_t fnptr);
int gh_rm_all_res_populated_cb(gh_all_res_populated_cb_t fnptr);
/* Client APIs for VM management */
int gh_rm_vm_alloc_vmid(enum gh_vm_names vm_name, int *vmid);
int gh_rm_vm_dealloc_vmid(gh_vmid_t vmid);
int gh_rm_vm_config_image(gh_vmid_t vmid, u16 auth_mech, u32 mem_handle,
u64 image_offset, u64 image_size, u64 dtb_offset, u64 dtb_size);
int gh_rm_vm_auth_image(gh_vmid_t vmid, ssize_t n_entries,
struct gh_vm_auth_param_entry *entry);
int ghd_rm_vm_init(gh_vmid_t vmid);
int ghd_rm_get_vmid(enum gh_vm_names vm_name, gh_vmid_t *vmid);
int gh_rm_get_vm_id_info(gh_vmid_t vmid);
int gh_rm_get_vm_name(gh_vmid_t vmid, enum gh_vm_names *vm_name);
int gh_rm_get_vminfo(enum gh_vm_names vm_name, struct gh_vminfo *vminfo);
int ghd_rm_vm_start(int vmid);
enum gh_vm_names gh_get_image_name(const char *str);
enum gh_vm_names gh_get_vm_name(const char *str);
int gh_rm_get_this_vmid(gh_vmid_t *vmid);
int ghd_rm_vm_stop(gh_vmid_t vmid, u32 stop_reason, u8 flags);
int ghd_rm_vm_reset(gh_vmid_t vmid);
/* Client APIs for VM query */
int gh_rm_populate_hyp_res(gh_vmid_t vmid, const char *vm_name);
int gh_rm_unpopulate_hyp_res(gh_vmid_t vmid, const char *vm_name);
/* Client APIs for VM Services */
struct gh_vm_status *gh_rm_vm_get_status(gh_vmid_t vmid);
int gh_rm_vm_set_status(struct gh_vm_status gh_vm_status);
int gh_rm_vm_set_vm_status(u8 vm_status);
int gh_rm_vm_set_os_status(u8 os_status);
int gh_rm_vm_set_app_status(u16 app_status);
int gh_rm_console_open(gh_vmid_t vmid);
int gh_rm_console_close(gh_vmid_t vmid);
int gh_rm_console_write(gh_vmid_t vmid, const char *buf, size_t size);
int gh_rm_console_flush(gh_vmid_t vmid);
int gh_rm_mem_qcom_lookup_sgl(u8 mem_type, gh_label_t label,
struct gh_acl_desc *acl_desc,
struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle);
int gh_rm_mem_release(gh_memparcel_handle_t handle, u8 flags);
int ghd_rm_mem_reclaim(gh_memparcel_handle_t handle, u8 flags);
struct gh_sgl_desc *gh_rm_mem_accept(gh_memparcel_handle_t handle, u8 mem_type,
u8 trans_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc,
struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
u16 map_vmid);
int ghd_rm_mem_share(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle);
int ghd_rm_mem_lend(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle);
int gh_rm_mem_donate(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle);
int gh_rm_mem_notify(gh_memparcel_handle_t handle, u8 flags,
gh_label_t mem_info_tag,
struct gh_notify_vmid_desc *vmid_desc);
int gh_rm_ipa_reserve(u64 size, u64 align, struct range limits, u32 generic_constraints,
u32 platform_constraints, u64 *ipa);
/* API to set time base */
int gh_rm_vm_set_time_base(gh_vmid_t vmid);
/* API to set debug */
int gh_rm_vm_set_debug(gh_vmid_t vmid);
/* API for minidump support */
int gh_rm_minidump_get_info(void);
int gh_rm_minidump_register_range(phys_addr_t base_ipa, size_t region_size,
const char *name, size_t name_size);
int gh_rm_minidump_deregister_slot(uint16_t slot_num);
int gh_rm_minidump_get_slot_from_name(uint16_t starting_slot, const char *name,
size_t name_size);
#else
/* RM client register notifications APIs */
static inline int gh_rm_register_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
static inline int gh_rm_unregister_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
/* Client APIs for IRQ management */
static inline int gh_rm_virq_to_irq(u32 virq)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_lend(gh_vmid_t vmid,
int virq,
int label,
gh_virq_handle_t *virq_handle)
{
return -EINVAL;
}
static inline int gh_rm_irq_to_virq(int irq, u32 *virq)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_lend_notify(gh_vmid_t vmid,
gh_virq_handle_t virq_handle)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_accept(gh_virq_handle_t virq_handle, int virq)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_accept_notify(gh_vmid_t vmid,
gh_virq_handle_t virq_handle)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_release(gh_virq_handle_t virq_handle)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_release_notify(gh_vmid_t vmid,
gh_virq_handle_t virq_handle)
{
return -EINVAL;
}
static inline int gh_rm_vm_irq_reclaim(gh_virq_handle_t virq_handle)
{
return -EINVAL;
}
/* Client APIs for VM management */
static inline int gh_rm_vm_alloc_vmid(enum gh_vm_names vm_name, int *vmid)
{
return -EINVAL;
}
static inline int gh_rm_vm_dealloc_vmid(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int gh_rm_vm_config_image(gh_vmid_t vmid, u16 auth_mech,
u32 mem_handle, u64 image_offset, u64 image_size,
u64 dtb_offset, u64 dtb_size)
{
return -EINVAL;
}
static inline int gh_rm_vm_auth_image(gh_vmid_t vmid, ssize_t n_entries,
struct gh_vm_auth_param_entry *entry)
{
return -EINVAL;
}
static inline int ghd_rm_vm_init(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int ghd_rm_get_vmid(enum gh_vm_names vm_name, gh_vmid_t *vmid)
{
return -EINVAL;
}
static inline int gh_rm_get_vm_name(gh_vmid_t vmid, enum gh_vm_names *vm_name)
{
return -EINVAL;
}
static inline int gh_rm_get_this_vmid(gh_vmid_t *vmid)
{
return -EINVAL;
}
static inline int gh_rm_get_vminfo(enum gh_vm_names vm_name, struct gh_vminfo *vminfo)
{
return -EINVAL;
}
static inline int ghd_rm_vm_start(int vmid)
{
return -EINVAL;
}
static inline int gh_rm_get_vm_id_info(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int ghd_rm_vm_stop(gh_vmid_t vmid, u32 stop_reason, u8 flags)
{
return -EINVAL;
}
static inline int ghd_rm_vm_reset(gh_vmid_t vmid)
{
return -EINVAL;
}
/* Client APIs for VM query */
static inline int gh_rm_populate_hyp_res(gh_vmid_t vmid, const char *vm_name)
{
return -EINVAL;
}
static inline int gh_rm_unpopulate_hyp_res(gh_vmid_t vmid, const char *vm_name)
{
return -EINVAL;
}
/* Client APIs for VM Services */
static inline struct gh_vm_status *gh_rm_vm_get_status(gh_vmid_t vmid)
{
return ERR_PTR(-EINVAL);
}
static inline int gh_rm_vm_set_status(struct gh_vm_status gh_vm_status)
{
return -EINVAL;
}
static inline int gh_rm_vm_set_vm_status(u8 vm_status)
{
return -EINVAL;
}
static inline int gh_rm_vm_set_os_status(u8 os_status)
{
return -EINVAL;
}
static inline int gh_rm_vm_set_app_status(u16 app_status)
{
return -EINVAL;
}
static inline int gh_rm_console_open(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int gh_rm_console_close(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int gh_rm_console_write(gh_vmid_t vmid, const char *buf,
size_t size)
{
return -EINVAL;
}
static inline int gh_rm_console_flush(gh_vmid_t vmid)
{
return -EINVAL;
}
static inline int gh_rm_mem_qcom_lookup_sgl(u8 mem_type, gh_label_t label,
struct gh_acl_desc *acl_desc,
struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle)
{
return -EINVAL;
}
static inline int gh_rm_mem_release(gh_memparcel_handle_t handle, u8 flags)
{
return -EINVAL;
}
static inline int ghd_rm_mem_reclaim(gh_memparcel_handle_t handle, u8 flags)
{
return -EINVAL;
}
static inline struct gh_sgl_desc *gh_rm_mem_accept(gh_memparcel_handle_t handle,
u8 mem_type,
u8 trans_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc,
struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
u16 map_vmid)
{
return ERR_PTR(-EINVAL);
}
static inline int ghd_rm_mem_share(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle)
{
return -EINVAL;
}
static inline int ghd_rm_mem_lend(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle)
{
return -EINVAL;
}
static inline int gh_rm_mem_donate(u8 mem_type, u8 flags, gh_label_t label,
struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc,
struct gh_mem_attr_desc *mem_attr_desc,
gh_memparcel_handle_t *handle)
{
return -EINVAL;
}
static inline int gh_rm_mem_notify(gh_memparcel_handle_t handle, u8 flags,
gh_label_t mem_info_tag,
struct gh_notify_vmid_desc *vmid_desc)
{
return -EINVAL;
}
static inline int gh_rm_set_virtio_mmio_cb(gh_virtio_mmio_cb_t fnptr)
{
return -EINVAL;
}
static inline void gh_rm_unset_virtio_mmio_cb(void)
{
}
static inline int gh_rm_set_wdog_manage_cb(gh_wdog_manage_cb_t fnptr)
{
return -EINVAL;
}
static inline int gh_rm_set_vcpu_affinity_cb(gh_vcpu_affinity_set_cb_t fnptr)
{
return -EINVAL;
}
static inline int gh_rm_reset_vcpu_affinity_cb(gh_vcpu_affinity_reset_cb_t fnptr)
{
return -EINVAL;
}
static inline int gh_rm_set_vpm_grp_cb(gh_vpm_grp_set_cb_t fnptr)
{
return -EINVAL;
}
static inline int gh_rm_reset_vpm_grp_cb(gh_vpm_grp_reset_cb_t fnptr)
{
return -EINVAL;
}
static inline int gh_rm_all_res_populated_cb(gh_all_res_populated_cb_t fnptr)
{
return -EINVAL;
}
/* API to set time base */
static inline int gh_rm_vm_set_time_base(gh_vmid_t vmid)
{
return -EINVAL;
}
/* API to set debug */
static inline int gh_rm_vm_set_debug(gh_vmid_t vmid)
{
return -EINVAL;
}
/* API for minidump support */
static inline int gh_rm_minidump_get_info(void)
{
return -EINVAL;
}
static inline int gh_rm_minidump_register_range(phys_addr_t base_ipa,
size_t region_size, const char *name,
size_t name_size)
{
return -EINVAL;
}
static inline int gh_rm_minidump_deregister_slot(uint16_t slot_num)
{
return -EINVAL;
}
static inline int gh_rm_minidump_get_slot_from_name(uint16_t starting_slot,
const char *name,
size_t name_size)
{
return -EINVAL;
}
static inline int gh_rm_ipa_reserve(u64 size, u64 align, struct range limits,
u32 generic_constraints, u32 platform_constraints,
u64 *ipa)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _GH_VM_H
#define _GH_VM_H
/* VM power notifications */
#define GH_VM_BEFORE_POWERUP 0x1
#define GH_VM_POWERUP_FAIL 0x2
#define GH_VM_EARLY_POWEROFF 0x3
#define GH_VM_POWEROFF 0x4
#define GH_VM_EXITED 0x5
#define GH_VM_CRASH 0x6
#if IS_ENABLED(CONFIG_GH_SECURE_VM_LOADER)
int gh_register_vm_notifier(struct notifier_block *nb);
int gh_unregister_vm_notifier(struct notifier_block *nb);
#else
static inline int gh_register_vm_notifier(struct notifier_block *nb)
{
return -EINVAL;
}
static inline int gh_unregister_vm_notifier(struct notifier_block *nb)
{
return -EINVAL;
}
#endif
#if IS_ENABLED(CONFIG_GH_PROXY_SCHED)
int gh_poll_vcpu_run(gh_vmid_t vmid);
#else
static inline int gh_poll_vcpu_run(gh_vmid_t vmid)
{
return 0;
}
#endif
#endif /* _GH_VM_H */

View File

@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __GH_HCALL_COMMON_H
#define __GH_HCALL_COMMON_H
#include <linux/types.h>
struct gh_hcall_args {
unsigned long arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
};
struct gh_hcall_resp {
unsigned long resp0, resp1, resp2, resp3, resp4, resp5, resp6, resp7;
};
typedef u16 gh_hcall_fnid_t;
#endif

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2021 Samsung Electronics
*/
#ifndef __HALL_NOTIFIER_H__
#define __HALL_NOTIFIER_H__
#include <linux/notifier.h>
struct hall_notifier_context {
const char *name;
int value;
};
extern int hall_notifier_register(struct notifier_block *n);
extern int hall_notifier_unregister(struct notifier_block *nb);
extern int hall_notifier_notify(const char *hall_name, int hall_value);
#endif /* __SEC_VIB_NOTIFIER_H__ */

View File

@@ -0,0 +1,11 @@
#ifndef __SEC_HALL_DUMPKEY_H__
#define __SEC_HALL_DUMPKEY_H__
struct sec_hall_dumpkey_param {
unsigned int keycode;
int down;
};
struct hall_dump_callbacks {
void (*inform_dump)(struct device *dev);
};
#endif /* __SEC_HALL_DUMPKEY_H__ */

View File

@@ -0,0 +1,153 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __HDCP_QSEECOM_H
#define __HDCP_QSEECOM_H
#include <linux/types.h>
#define HDCP_QSEECOM_ENUM_STR(x) #x
enum hdcp2_app_cmd {
HDCP2_CMD_START,
HDCP2_CMD_START_AUTH,
HDCP2_CMD_STOP,
HDCP2_CMD_PROCESS_MSG,
HDCP2_CMD_TIMEOUT,
HDCP2_CMD_EN_ENCRYPTION,
HDCP2_CMD_QUERY_STREAM,
};
struct hdcp2_buffer {
unsigned char *data;
u32 length;
};
struct hdcp2_app_data {
u32 timeout;
bool repeater_flag;
struct hdcp2_buffer request; // requests to TA, sent from sink
struct hdcp2_buffer response; // responses from TA, sent to sink
};
struct hdcp1_topology {
uint32_t depth;
uint32_t device_count;
uint32_t max_devices_exceeded;
uint32_t max_cascade_exceeded;
uint32_t hdcp2LegacyDeviceDownstream;
uint32_t hdcp1DeviceDownstream;
};
static inline const char *hdcp2_app_cmd_str(enum hdcp2_app_cmd cmd)
{
switch (cmd) {
case HDCP2_CMD_START:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_START);
case HDCP2_CMD_START_AUTH:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_START_AUTH);
case HDCP2_CMD_STOP:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_STOP);
case HDCP2_CMD_PROCESS_MSG:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_PROCESS_MSG);
case HDCP2_CMD_TIMEOUT:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_TIMEOUT);
case HDCP2_CMD_EN_ENCRYPTION:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_EN_ENCRYPTION);
case HDCP2_CMD_QUERY_STREAM:
return HDCP_QSEECOM_ENUM_STR(HDCP2_CMD_QUERY_STREAM);
default: return "???";
}
}
#if IS_ENABLED(CONFIG_HDCP_QSEECOM)
void *hdcp1_init(void);
void hdcp1_deinit(void *data);
bool hdcp1_feature_supported(void *data);
int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb);
int hdcp1_set_enc(void *data, bool enable);
int hdcp1_ops_notify(void *data, void *topology, bool is_authenticated);
void hdcp1_stop(void *data);
void *hdcp2_init(u32 device_type);
void hdcp2_deinit(void *ctx);
bool hdcp2_feature_supported(void *ctx);
int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
struct hdcp2_app_data *app_data);
int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id,
uint8_t stream_number, uint32_t *stream_id);
int hdcp2_close_stream(void *ctx, uint32_t stream_id);
int hdcp2_force_encryption(void *ctx, uint32_t enable);
#else
static inline void *hdcp1_init(void)
{
return NULL;
}
static inline void hdcp1_deinit(void *data)
{
}
static inline bool hdcp1_feature_supported(void *data)
{
return false;
}
static inline int hdcp1_start(void *data, u32 *aksv_msb, u32 *aksv_lsb)
{
return 0;
}
static inline int hdcp1_ops_notify(void *data, void *topology, bool is_authenticated)
{
return 0;
}
static inline int hdcp1_set_enc(void *data, bool enable)
{
return 0;
}
static inline void hdcp1_stop(void *data)
{
}
static inline void *hdcp2_init(u32 device_type)
{
return NULL;
}
static inline void hdcp2_deinit(void *ctx)
{
}
static inline bool hdcp2_feature_supported(void *ctx)
{
return false;
}
static inline int hdcp2_app_comm(void *ctx, enum hdcp2_app_cmd cmd,
struct hdcp2_app_data *app_data)
{
return 0;
}
static inline int hdcp2_open_stream(void *ctx, uint8_t vc_payload_id,
uint8_t stream_number, uint32_t *stream_id)
{
return 0;
}
static inline int hdcp2_close_stream(void *ctx, uint32_t stream_id)
{
return 0;
}
static inline int hdcp2_force_encryption(void *ctx, uint32_t enable)
{
return 0;
}
#endif /* CONFIG_HDCP_QSEECOM */
#endif /* __HDCP_QSEECOM_H */

52
include/linux/hdm.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* @file hdm.h
* @brief Header file for HDM driver
* Copyright (c) 2019, Samsung Electronics Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __HDM_H__
#define __HDM_H__
#include <linux/types.h>
#ifndef __ASSEMBLY__
#define HDM_CMD_LEN ((size_t)8)
#define HDM_P_BITMASK 0x3FF
#define HDM_C_BITMASK 0xF0000
#define HDM_FLAG_UPDATE 0x10000
#define HDM_HYP_CALL 0x40000
#define HDM_HYP_INIT 0x50000
#define HDM_HYP_CLEAR 0x60000
#define HDM_HYP_CALLP 0x80000
#define HDM_CMD_MAX 0xFFFFF
#define HDM_GET_SUPPORTED_SUBSYSTEM 6
#define HDM_CAM 0x1
#define HDM_MMC 0x2
#define HDM_USB 0x4
#define HDM_WIFI 0x8
#define HDM_BT 0x10
#define HDM_GPS 0x20
#define HDM_NFC 0x40
#define HDM_AUD 0x80
#define HDM_CP 0x100
#define HDM_SPK 0x200
#define MAX_DEVICE_NUM 10
extern bool hdm_is_applied(uint32_t);
#endif //__ASSEMBLY__
#endif //__HDM_H__

View File

@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Host notify class driver
*
* Copyright (C) 2011-2023 Samsung, Inc.
* Author: Dongrak Shin <dongrak.shin@samsung.com>
*
*/
/* usb notify layer v4.0 */
#ifndef __LINUX_HOST_NOTIFY_H__
#define __LINUX_HOST_NOTIFY_H__
enum host_uevent_state {
NOTIFY_HOST_NONE,
NOTIFY_HOST_ADD,
NOTIFY_HOST_REMOVE,
NOTIFY_HOST_OVERCURRENT,
NOTIFY_HOST_LOWBATT,
NOTIFY_HOST_BLOCK,
NOTIFY_HOST_UNKNOWN,
NOTIFY_HOST_SOURCE,
NOTIFY_HOST_SINK,
};
enum host_uevent_type {
NOTIFY_UNKNOWN_STATE,
NOTIFY_HOST_STATE,
NOTIFY_POWER_STATE,
};
enum otg_hostnotify_mode {
NOTIFY_NONE_MODE,
NOTIFY_HOST_MODE,
NOTIFY_PERIPHERAL_MODE,
NOTIFY_TEST_MODE,
};
enum booster_power {
NOTIFY_POWER_OFF,
NOTIFY_POWER_ON,
};
enum set_command {
NOTIFY_SET_OFF,
NOTIFY_SET_ON,
};
struct host_notify_dev {
const char *name;
struct device *dev;
int index;
int host_state;
int host_change;
int power_state;
int power_change;
int mode;
int booster;
int (*set_mode)(bool on);
int (*set_booster)(bool on);
};
#ifdef CONFIG_USB_HOST_NOTIFY
extern int host_state_notify(struct host_notify_dev *ndev, int state);
extern int host_notify_dev_register(struct host_notify_dev *ndev);
extern void host_notify_dev_unregister(struct host_notify_dev *ndev);
#else
static inline int host_state_notify(struct host_notify_dev *ndev, int state)
{return 0; }
static inline int host_notify_dev_register(struct host_notify_dev *ndev)
{return 0; }
static inline void host_notify_dev_unregister(struct host_notify_dev *ndev) {}
#endif
#endif /* __LINUX_HOST_NOTIFY_H__ */

View File

@@ -6,6 +6,7 @@
#ifndef QCOM_VADC_COMMON_H
#define QCOM_VADC_COMMON_H
#include <linux/adc-tm-clients.h>
#include <linux/math.h>
#include <linux/types.h>
@@ -32,8 +33,9 @@
#define ADC5_DECIMATION_SHORT 250
#define ADC5_DECIMATION_MEDIUM 420
#define ADC5_DECIMATION_LONG 840
/* Default decimation - 1024 for rev2, 840 for pmic5 */
/* Default decimation - 1024 for rev2, 840 for pmic5, 1360 for adc5_gen3 and 340 for adc5_gen4 */
#define ADC5_DECIMATION_DEFAULT 2
#define ADC5_GEN4_DECIMATION_DEFAULT 1
#define ADC5_DECIMATION_SAMPLES_MAX 3
#define VADC_HW_SETTLE_DELAY_MAX 10000
@@ -44,6 +46,11 @@
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
#define PMIC5_SMB_TEMP_CONSTANT 419400
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
#define PMIC5_SMB1398_TEMP_CONSTANT 268235
#define PMIC5_SMB1398_TEMP_SCALE_FACTOR 340
#define PMIC5_PM2250_S3_DIE_TEMP_SCALE_FACTOR 187263
#define PMIC5_PM2250_S3_DIE_TEMP_CONSTANT 720100
#define PMI_CHG_SCALE_1 -138890
#define PMI_CHG_SCALE_2 391750000000LL
@@ -52,9 +59,14 @@
#define ADC5_FULL_SCALE_CODE 0x70e4
#define ADC5_USR_DATA_CHECK 0x8000
#define R_PU_10K 10000
#define R_PU_100K 100000
#define RATIO_MAX_ADC7 BIT(14)
#define PMIC5_GEN3_USB_IN_I_SCALE_FACTOR 9248
#define ADC_VDD_REF 1875000
/*
* VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
* VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for
@@ -80,6 +92,54 @@ struct vadc_linear_graph {
s32 gnd;
};
/**
* enum adc_tm_rscale_fn_type - Scaling function used to convert the
* channels input voltage/temperature to corresponding ADC code that is
* applied for thresholds. Check the corresponding channels scaling to
* determine the appropriate temperature/voltage units that are passed
* to the scaling function. Example battery follows the power supply
* framework that needs its units to be in decidegreesC so it passes
* deci-degreesC. PA_THERM clients pass the temperature in degrees.
* The order below should match the one in the driver for
* adc_tm_rscale_fn[].
*/
enum adc_tm_rscale_fn_type {
SCALE_R_ABSOLUTE = 0,
SCALE_RSCALE_NONE,
};
/**
* struct adc_tm_config - Represent ADC Thermal Monitor configuration.
* @high_thr_temp: Temperature at which high threshold notification is required.
* @low_thr_temp: Temperature at which low threshold notification is required.
* @low_thr_voltage : Low threshold voltage ADC code used for reverse
* calibration.
* @high_thr_voltage: High threshold voltage ADC code used for reverse
* calibration.
*/
struct adc_tm_config {
int high_thr_temp;
int low_thr_temp;
int64_t high_thr_voltage;
int64_t low_thr_voltage;
};
struct adc_tm_reverse_scale_fn {
int32_t (*chan)(struct adc_tm_config *tm_config);
};
struct adc_tm_client_info {
struct list_head list;
struct adc_tm_param *param;
int32_t low_thr_requested;
int32_t high_thr_requested;
bool notify_low_thr;
bool notify_high_thr;
bool high_thr_set;
bool low_thr_set;
enum adc_tm_state_request state_request;
};
/**
* enum vadc_scale_fn_type - Scaling function to convert ADC code to
* physical scaled units for the channel.
@@ -99,12 +159,48 @@ struct vadc_linear_graph {
* lookup table for PMIC7. The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* SCALE_HW_CALIB_PMIC_THERM_PM7: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code. This is for PMIC7.
* SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
* charger temperature.
* SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
* SMB1390 temperature.
* SCALE_HW_CALIB_BATT_THERM_100K: Returns battery thermistor temperature in
* decidegC using 100k pullup. The hardware applies offset/slope to adc
* code.
* SCALE_HW_CALIB_BATT_THERM_30K: Returns battery thermistor temperature in
* decidegC using 30k pullup. The hardware applies offset/slope to adc
* code.
* SCALE_HW_CALIB_BATT_THERM_400K: Returns battery thermistor temperature in
* decidegC using 400k pullup. The hardware applies offset/slope to adc
* code.
* SCALE_HW_CALIB_PM5_SMB1398_TEMP: Returns result in millidegrees for PMIC5
* SMB1398 temperature.
* SCALE_HW_CALIB_PM7_SMB_TEMP: Returns result in millidegrees for PMIC7
* SMB139x temperature.
* SCALE_HW_CALIB_PM7_CHG_TEMP: Returns result in millidegrees for PMIC7
* charger temperature.
* SCALE_HW_CALIB_CUR: Returns result in microamperes for PMIC7 channels that
* use voltage scaling.
* SCALE_HW_CALIB_CUR_RAW: Returns result in microamperes for PMIC7 channels
* that use raw ADC code.
* SCALE_HW_CALIB_PM2250_S3_DIE_TEMP: Returns result in millidegrees for
* S3 die temperature channel on PM2250.
* SCALE_HW_CALIB_PM5_CUR: Returns result in microamperes for PMIC5 channels
* that use voltage scaling.
* SCALE_HW_CALIB_PM5_GEN3_BATT_THERM_100K: Returns battery thermistor
* temperature in decidegC using 100k pullup. The hardware applies
* offset/slope to adc code.
* SCALE_HW_CALIB_PM5_GEN3_BATT_ID_100K: Returns battery ID resistance
* in ohms using 100k pullup. The hardware applies offset/slope to
* adc code.
* SCALE_HW_CALIB_PM5_GEN3_USB_IN_I: Returns USB input current in microamperes.
* SCALE_HW_CALIB_PM5_GEN4_BATT_THERM_10K: Returns battery thermistor
* temperature in decidegC using 10k pullup. The hardware applies
* offset/slope to adc code.
* SCALE_HW_CALIB_PM5_GEN4_BATT_ID_10K: Returns battery ID resistance
* in ohms using 10k pullup. The hardware applies offset/slope to
* adc code.
*/
enum vadc_scale_fn_type {
SCALE_DEFAULT = 0,
@@ -120,12 +216,34 @@ enum vadc_scale_fn_type {
SCALE_HW_CALIB_PMIC_THERM_PM7,
SCALE_HW_CALIB_PM5_CHG_TEMP,
SCALE_HW_CALIB_PM5_SMB_TEMP,
SCALE_HW_CALIB_BATT_THERM_100K,
SCALE_HW_CALIB_BATT_THERM_30K,
SCALE_HW_CALIB_BATT_THERM_400K,
SCALE_HW_CALIB_PM5_SMB1398_TEMP,
SCALE_HW_CALIB_PM7_SMB_TEMP,
SCALE_HW_CALIB_PM7_CHG_TEMP,
SCALE_HW_CALIB_CUR,
SCALE_HW_CALIB_CUR_RAW,
SCALE_HW_CALIB_PM2250_S3_DIE_TEMP,
SCALE_HW_CALIB_PM5_CUR,
SCALE_HW_CALIB_PM5_GEN3_BATT_THERM_100K,
SCALE_HW_CALIB_PM5_GEN3_BATT_ID_100K,
SCALE_HW_CALIB_PM5_GEN3_USB_IN_I,
SCALE_HW_CALIB_PM5_GEN4_BATT_THERM_10K,
SCALE_HW_CALIB_PM5_GEN4_BATT_ID_10K,
SCALE_HW_CALIB_INVALID,
};
enum vadc_generation {
ADC5_GEN3 = 0,
ADC5_GEN4,
};
struct adc5_data {
const char *name;
const u32 full_scale_code_volt;
const u32 full_scale_code_cur;
const u32 full_scale_code_raw;
const struct adc5_channels *adc_chans;
const struct iio_info *info;
unsigned int *decimation;
@@ -164,4 +282,9 @@ int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation);
int qcom_vadc_decimation_from_dt(u32 value);
void adc_tm_scale_therm_voltage_100k_gen3(struct adc_tm_config *param,
const struct adc5_data *data);
int32_t adc_tm_absolute_rthr_gen3(struct adc_tm_config *tm_config);
#endif /* QCOM_VADC_COMMON_H */

View File

@@ -19,7 +19,6 @@
#include <linux/sched/rt.h>
#include <linux/livepatch.h>
#include <linux/mm_types.h>
#include <linux/task_integrity.h>
#include <asm/thread_info.h>
@@ -36,22 +35,6 @@ extern struct cred init_cred;
#define INIT_PREV_CPUTIME(x)
#endif
#ifdef CONFIG_FIVE
# define INIT_TASK_INTEGRITY(integrity) { \
.user_value = INTEGRITY_NONE, \
.value = INTEGRITY_NONE, \
.usage_count = ATOMIC_INIT(1), \
.value_lock = __SPIN_LOCK_UNLOCKED(integrity.value_lock), \
.list_lock = __SPIN_LOCK_UNLOCKED(integrity.list_lock), \
.events = { .list = LIST_HEAD_INIT(integrity.events.list),}, \
}
# define INIT_INTEGRITY(tsk) \
.android_oem_data1[2] = (u64)&init_integrity,
#else
# define INIT_INTEGRITY(tsk)
# define INIT_TASK_INTEGRITY(integrity)
#endif
#define INIT_TASK_COMM "swapper"
/* Attach to the init_task data structure for proper alignment */

View File

@@ -0,0 +1,114 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2015, 2017-2019, 2021 The Linux Foundation.
* All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef QPNP_PON_H
#define QPNP_PON_H
#include <dt-bindings/input/qcom,qpnp-power-on.h>
#include <linux/errno.h>
#include <linux/types.h>
/**
* enum pon_trigger_source: List of PON trigger sources
* %PON_SMPL: PON triggered by Sudden Momentary Power Loss (SMPL)
* %PON_RTC: PON triggered by real-time clock (RTC) alarm
* %PON_DC_CHG: PON triggered by insertion of DC charger
* %PON_USB_CHG: PON triggered by insertion of USB
* %PON_PON1: PON triggered by other PMIC (multi-PMIC option)
* %PON_CBLPWR_N: PON triggered by power-cable insertion
* %PON_KPDPWR_N: PON triggered by long press of the power-key
*/
enum pon_trigger_source {
PON_SMPL = 1,
PON_RTC,
PON_DC_CHG,
PON_USB_CHG,
PON_PON1,
PON_CBLPWR_N,
PON_KPDPWR_N,
};
/**
* enum pon_power_off_type: Possible power off actions to perform
* %PON_POWER_OFF_RESERVED: Reserved, not used
* %PON_POWER_OFF_WARM_RESET: Reset the MSM but not all PMIC peripherals
* %PON_POWER_OFF_SHUTDOWN: Shutdown the MSM and PMIC completely
* %PON_POWER_OFF_HARD_RESET: Reset the MSM and all PMIC peripherals
* %PON_POWER_OFF_MAX_TYPE: Reserved, not used
*/
enum pon_power_off_type {
PON_POWER_OFF_RESERVED = 0x00,
PON_POWER_OFF_WARM_RESET = PON_POWER_OFF_TYPE_WARM_RESET,
PON_POWER_OFF_SHUTDOWN = PON_POWER_OFF_TYPE_SHUTDOWN,
PON_POWER_OFF_HARD_RESET = PON_POWER_OFF_TYPE_HARD_RESET,
PON_POWER_OFF_MAX_TYPE = 0x10,
};
enum pon_restart_reason {
PON_RESTART_REASON_UNKNOWN = 0x00,
PON_RESTART_REASON_RECOVERY = 0x01,
PON_RESTART_REASON_BOOTLOADER = 0x02,
PON_RESTART_REASON_RTC = 0x03,
PON_RESTART_REASON_DMVERITY_CORRUPTED = 0x04,
PON_RESTART_REASON_DMVERITY_ENFORCE = 0x05,
PON_RESTART_REASON_KEYS_CLEAR = 0x06,
PON_RESTART_REASON_SILENT = 0x0a,
PON_RESTART_REASON_NON_SILENT = 0x0b,
PON_RESTART_REASON_FORCED_SILENT = 0x0c,
PON_RESTART_REASON_FORCED_NON_SILENT = 0x0d,
};
#if IS_ENABLED(CONFIG_INPUT_QPNP_POWER_ON)
int qpnp_pon_system_pwr_off(enum pon_power_off_type type);
int qpnp_pon_is_warm_reset(void);
int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, bool enable);
int qpnp_pon_wd_config(bool enable);
int qpnp_pon_set_restart_reason(enum pon_restart_reason reason);
bool qpnp_pon_check_hard_reset_stored(void);
int qpnp_pon_modem_pwr_off(enum pon_power_off_type type);
#else
static int qpnp_pon_system_pwr_off(enum pon_power_off_type type)
{
return -ENODEV;
}
static inline int qpnp_pon_is_warm_reset(void)
{
return -ENODEV;
}
static inline int qpnp_pon_trigger_config(enum pon_trigger_source pon_src,
bool enable)
{
return -ENODEV;
}
int qpnp_pon_wd_config(bool enable)
{
return -ENODEV;
}
static inline int qpnp_pon_set_restart_reason(enum pon_restart_reason reason)
{
return -ENODEV;
}
static inline bool qpnp_pon_check_hard_reset_stored(void)
{
return false;
}
static inline int qpnp_pon_modem_pwr_off(enum pon_power_off_type type)
{
return -ENODEV;
}
#endif
#endif

View File

@@ -0,0 +1,167 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_CMD_H_
#define _SEC_CMD_H_
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/stat.h>
#include <linux/err.h>
#include <linux/input.h>
#include <linux/sched/clock.h>
#include <linux/uaccess.h>
#if IS_ENABLED(CONFIG_DRV_SAMSUNG)
#include <linux/sec_class.h>
#endif
#if !IS_ENABLED(CONFIG_SEC_FACTORY)
#define USE_SEC_CMD_QUEUE
#include <linux/kfifo.h>
#endif
#define SEC_CLASS_DEVT_TSP 10
#define SEC_CLASS_DEVT_TKEY 11
#define SEC_CLASS_DEVT_WACOM 12
#define SEC_CLASS_DEVT_SIDEKEY 13
#define SEC_CLASS_DEV_NAME_TSP "tsp"
#define SEC_CLASS_DEV_NAME_TKEY "sec_touchkey"
#define SEC_CLASS_DEV_NAME_WACOM "sec_epen"
#define SEC_CLASS_DEV_NAME_SIDEKEY "sec_sidekey"
#define SEC_CLASS_DEVT_TSP1 15
#define SEC_CLASS_DEVT_TSP2 16
#define SEC_CLASS_DEV_NAME_TSP1 "tsp1"
#define SEC_CLASS_DEV_NAME_TSP2 "tsp2"
#define SEC_CMD(name, func) .cmd_name = name, .cmd_func = func
#define SEC_CMD_H(name, func) .cmd_name = name, .cmd_func = func, .cmd_log = 1
#define SEC_CMD_V2(name, func, force_func, use_cases, wait_result) \
.cmd_name = name, .cmd_func = func, .cmd_func_forced = force_func, \
.cmd_use_cases = use_cases, .wait_read_result = wait_result
#define SEC_CMD_V2_H(name, func, force_func, use_cases, wait_result) \
.cmd_name = name, .cmd_func = func, .cmd_func_forced = force_func, \
.cmd_use_cases = use_cases, .wait_read_result = wait_result, .cmd_log = 1
#define SEC_CMD_BUF_SIZE (4096 - 1)
#define SEC_CMD_STR_LEN 256
#define SEC_CMD_RESULT_STR_LEN (4096 - 1)
#define SEC_CMD_RESULT_STR_LEN_EXPAND (SEC_CMD_RESULT_STR_LEN * 6)
#define SEC_CMD_PARAM_NUM 8
#define WAIT_RESULT true
#define EXIT_RESULT false
struct sec_cmd {
struct list_head list;
const char *cmd_name;
void (*cmd_func)(void *device_data);
int (*cmd_func_forced)(void *device_data);
/*
* cmd_use_cases using as below
* 1 : call function, 0 : no call
* first bit(1<<0) CHECK_POWEROFF
* second bit(1<<1) CHECK_LPMODE
* third bit(1<<2) CHECK_POWERON
*/
int cmd_use_cases;
bool wait_read_result;
int cmd_log;
bool not_support_cmds;
};
enum sec_cmd_status_uevent_type {
STATUS_TYPE_WET = 0,
STATUS_TYPE_NOISE,
STATUS_TYPE_FREQ,
};
enum SEC_CMD_STATUS {
SEC_CMD_STATUS_WAITING = 0,
SEC_CMD_STATUS_RUNNING, // = 1
SEC_CMD_STATUS_OK, // = 2
SEC_CMD_STATUS_FAIL, // = 3
SEC_CMD_STATUS_EXPAND, // = 4
SEC_CMD_STATUS_NOT_APPLICABLE, // = 5
};
#define INPUT_CMD_RESULT_NOT_EXIT 0
#define INPUT_CMD_RESULT_NEED_EXIT 1
#define input_cmd_result(cmd_state_parm, need_exit) \
({ \
if (need_exit == INPUT_CMD_RESULT_NEED_EXIT) { \
if (cmd_state_parm == SEC_CMD_STATUS_OK) \
snprintf(buff, sizeof(buff), "OK"); \
else if (cmd_state_parm == SEC_CMD_STATUS_FAIL) \
snprintf(buff, sizeof(buff), "NG"); \
else if (cmd_state_parm == SEC_CMD_STATUS_NOT_APPLICABLE) \
snprintf(buff, sizeof(buff), "NA"); \
} \
sec_cmd_set_cmd_result(sec, buff, strnlen(buff, sizeof(buff))); \
sec->cmd_state = cmd_state_parm; \
if (need_exit == INPUT_CMD_RESULT_NEED_EXIT) \
sec_cmd_set_cmd_exit(sec); \
input_info(true, ptsp, "%s: %s\n", __func__, buff); \
})
#ifdef USE_SEC_CMD_QUEUE
#define SEC_CMD_MAX_QUEUE 10
struct command {
char cmd[SEC_CMD_STR_LEN];
};
#endif
struct sec_cmd_data {
struct device *fac_dev;
struct device *dev;
struct list_head cmd_list_head;
u8 cmd_state;
char cmd[SEC_CMD_STR_LEN];
int cmd_param[SEC_CMD_PARAM_NUM];
char *cmd_result;
int cmd_result_expand;
int cmd_result_expand_count;
int cmd_buffer_size;
atomic_t cmd_is_running;
struct mutex cmd_lock;
struct mutex fs_lock;
struct mutex io_lock;
#ifdef USE_SEC_CMD_QUEUE
struct kfifo cmd_queue;
struct mutex fifo_lock;
struct delayed_work cmd_work;
struct mutex wait_lock;
struct completion cmd_result_done;
#endif
bool wait_cmd_result_done;
int item_count;
char cmd_result_all[SEC_CMD_RESULT_STR_LEN];
u8 cmd_all_factory_state;
struct attribute_group *vendor_attr_group;
};
void sec_cmd_set_cmd_exit(struct sec_cmd_data *data);
void sec_cmd_set_default_result(struct sec_cmd_data *data);
void sec_cmd_set_cmd_result(struct sec_cmd_data *data, char *buff, int len);
void sec_cmd_set_cmd_result_all(struct sec_cmd_data *data, char *buff, int len, char *item);
int sec_cmd_init(struct sec_cmd_data *data, struct device *dev, struct sec_cmd *cmds,
int len, int devt, struct attribute_group *vendor_attr_group);
int sec_cmd_init_without_platdata(struct sec_cmd_data *data, struct sec_cmd *cmds,
int len, int devt, struct attribute_group *vendor_attr_group);
void sec_cmd_exit(struct sec_cmd_data *data, int devt);
void sec_cmd_send_event_to_user(struct sec_cmd_data *data, char *test, char *result);
void sec_cmd_send_status_uevent(struct sec_cmd_data *data, enum sec_cmd_status_uevent_type type, int value);
void sec_cmd_send_gesture_uevent(struct sec_cmd_data *data, int type, int x, int y);
void sec_cmd_io_clear_firmware_data(struct sec_cmd_data *data);
int sec_cmd_io_init(struct sec_cmd_data *data, int devt);
#endif /* _SEC_CMD_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
#ifndef __SEC_INPUT_KUNIT_MOCK_DUMMY_H__
#define __SEC_INPUT_KUNIT_MOCK_DUMMY_H__
#define REAL_ID(func_name) __real__##func_name
#define INVOKE_ID(func_name) __invoke__##func_name
#define RETURNS(return_type) return_type
#define __mockable
#define __mockable_alias(id) __alias(id)
#define __visible_for_testing static
#ifndef PARAMS
#define PARAMS(args...) args
#endif
#define KUNIT_EXPECT_STRNE(test, left, right) EXPECT_STRNE((struct test *)test, (left), (right))
#define EXPECT_STRNE(test, left, right) do { \
struct test_stream *__stream = EXPECT_START(test); \
typeof(left) __left = (left); \
typeof(right) __right = (right); \
\
__stream->add(__stream, "Expected " #left " != " #right ", but\n"); \
__stream->add(__stream, "\t\t%s == %s\n", #left, __left); \
__stream->add(__stream, "\t\t%s == %s\n", #right, __right); \
\
EXPECT_END(test, strcmp(left, right), __stream); \
} while (0)
#define DECLARE_REDIRECT_MOCKABLE(name, return_type, param_types...) \
return_type name(param_types)
#define DEFINE_INVOKABLE(name, return_type, RETURN_ASSIGN, param_types...)
#define DEFINE_REDIRECT_MOCKABLE_COMMON(name, \
return_type, \
RETURN_ASSIGN, \
param_types...) \
return_type REAL_ID(name)(param_types); \
return_type name(param_types) __mockable_alias(REAL_ID(name)); \
DEFINE_INVOKABLE(name, return_type, RETURN_ASSIGN, param_types);
#define ASSIGN() *retval =
#define DEFINE_REDIRECT_MOCKABLE(name, return_type, param_types...) \
DEFINE_REDIRECT_MOCKABLE_COMMON(name, \
return_type, \
ASSIGN, \
param_types)
#endif /* __SEC_INPUT_KUNIT_MOCK_DUMMY_H__ */

View File

@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* drivers/input/sec_input/sec_input_multi_dev.h
*
* Core file for Samsung input device driver for multi device
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_INPUT_MULTI_DEV_H_
#define _SEC_INPUT_MULTI_DEV_H_
#include "sec_input.h"
#define MULTI_DEV_DEBUG_INFO_SIZE 256
#define MULTI_DEV_NONE 0
#define MULTI_DEV_MAIN 1
#define MULTI_DEV_SUB 2
#define FOLD_STATUS_FOLDING 1
#define FOLD_STATUS_UNFOLDING 0
#define GET_DEV_COUNT(mdev) ((mdev == NULL) ? MULTI_DEV_NONE : mdev->device_count)
#define IS_FOLD(x) (x == MULTI_DEV_MAIN || x == MULTI_DEV_SUB)
#define IS_FOLD_DEV(mdev) IS_FOLD(GET_DEV_COUNT(mdev))
#define IS_NOT_FOLD(x) !IS_FOLD(x)
#define IS_NOT_FOLD_DEV(mdev) IS_NOT_FOLD(GET_DEV_COUNT(mdev))
#define GET_FOLD_STR(x) (x == MULTI_DEV_MAIN ? "MAIN" : x == MULTI_DEV_SUB ? "SUB" : "NONE")
#define GET_SEC_CLASS_DEVT_TSP(mdev) (GET_DEV_COUNT(mdev) == MULTI_DEV_MAIN ? SEC_CLASS_DEVT_TSP1 \
: GET_DEV_COUNT(mdev) == MULTI_DEV_SUB ? SEC_CLASS_DEVT_TSP2 \
: SEC_CLASS_DEVT_TSP)
#if IS_ENABLED(CONFIG_SEC_ABC)
#define GET_INT_ABC_TYPE(mdev) (GET_DEV_COUNT(mdev) == MULTI_DEV_SUB ? SEC_ABC_SEND_EVENT_TYPE_SUB \
: SEC_ABC_SEND_EVENT_TYPE)
#endif
struct sec_input_multi_device {
struct device *dev;
int device_count;
const char *name;
bool device_ready;
int flip_status;
int flip_status_current;
int change_flip_status;
unsigned int flip_mismatch_count;
struct delayed_work switching_work;
};
#if IS_ENABLED(CONFIG_SEC_INPUT_MULTI_DEVICE)
bool sec_input_need_fold_off(struct sec_input_multi_device *mdev);
void sec_input_set_fold_state(struct sec_input_multi_device *mdev, int state);
void sec_input_multi_device_ready(struct sec_input_multi_device *mdev);
void sec_input_multi_device_create(struct device *dev);
void sec_input_multi_device_remove(struct sec_input_multi_device *mdev);
void sec_input_get_multi_device_debug_info(struct sec_input_multi_device *mdev,
char *buf, ssize_t size);
#else
static inline bool sec_input_need_fold_off(struct sec_input_multi_device *mdev) { return false; }
static inline void sec_input_set_fold_state(struct sec_input_multi_device *mdev, int state) {}
static inline void sec_input_multi_device_ready(struct sec_input_multi_device *mdev) {}
static inline void sec_input_multi_device_create(struct device *dev) {}
static inline void sec_input_multi_device_remove(struct sec_input_multi_device *mdev) {}
static inline void sec_input_get_multi_device_debug_info(struct sec_input_multi_device *mdev,
char *buf, ssize_t size) { return; }
#endif
#endif

View File

@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
//#ifndef _SEC_INPUT_RAWDATA_H_
//#define _SEC_INPUT_RAWDATA_H_
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/stat.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/input.h>
#include <linux/sysfs.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#define IOCTL_SIZE 4096
#define POSTFIX_BYTE_LENGTH (1 * 2)
#define PREFIX_BYTE_LENGTH (4 * 2)
#define RAW_VEC_NUM 3
#define IOCTL_TSP_MAP_READ _IOR(0, 0, struct raw_data)
#define IOCTL_TSP_MAP_WRITE _IOW(0, 0, struct raw_data)
#define IOCTL_TSP_MAP_WRITE_TEST_1 _IOW('T', 1, struct raw_data)
struct raw_data {
int num;
u8 data[IOCTL_SIZE];
};
struct sec_input_rawdata_device {
struct device *dev;
struct device *fac_dev;
int num;
int rawdata_len;
u8 *raw_u8;
u8 *rawdata_pool[3];
struct mutex lock;
int raw_write_index;
int raw_read_index;
};
#if IS_ENABLED(CONFIG_SEC_INPUT_RAWDATA)
void sec_input_rawdata_copy_to_user(s16 *data, int len, int press);
int sec_input_rawdata_buffer_alloc(void);
int sec_input_rawdata_init(struct device *dev, struct device *fac_dev);
#else
static inline void sec_input_rawdata_copy_to_user(s16 *data, int len, int press)
{
}
static inline int sec_input_rawdata_buffer_alloc(void)
{
return 0;
}
static inline int sec_input_rawdata_init(struct device *dev, struct device *fac_dev)
{
return 0;
}
#endif
//#endif

View File

@@ -0,0 +1,97 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_SECURE_TOUCH_H_
#define _SEC_SECURE_TOUCH_H_
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/stat.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <linux/input.h>
#include <linux/sysfs.h>
//#if defined(CONFIG_SEC_SYSFS)
//#include <linux/sec_sysfs.h>
#if IS_ENABLED(CONFIG_DRV_SAMSUNG)
#include <linux/sec_class.h>
#endif
//#else
//extern struct class *sec_class;
//#endif
#if IS_ENABLED(CONFIG_HALL_NOTIFIER)
#include <linux/hall/hall_ic_notifier.h>
#endif
#if IS_ENABLED(CONFIG_SUPPORT_SENSOR_FOLD)
#include <linux/sensor/sensors_core.h>
#endif
#define SECURE_TOUCH_DEVICE_FIRST 1
#define SECURE_TOUCH_DEVICE_SECOND 2
/*
* folder open = main screen = 0
* folder close = sub screen = 1
*/
#define SECURE_TOUCH_MAIN_DEV 0
#define SECURE_TOUCH_SUB_DEV 1
#define SECURE_TOUCH_FOLDER_OPEN 0
#define SECURE_TOUCH_FOLDER_CLOSE 1
#define SECURE_TOUCH_DEV_NAME "ss_touch"
struct sec_touch_driver {
struct list_head list;
struct device *dev;
int drv_number;
int (*enable)(void *drv_data);
int (*disable)(void *drv_data);
int (*status)(void *drv_data);
int (*irq_handle)(void *drv_data);
void *drv_data;
struct kobject *kobj;
int enabled;
int registered;
int is_running;
};
struct sec_secure_touch {
struct list_head list_head;
int secure_enabled;
void *data;
struct platform_device *pdev;
struct device *device;
#if IS_ENABLED(CONFIG_SEC_INPUT_MULTI_DEVICE)
struct delayed_work folder_work;
#endif
int hall_ic;
struct mutex lock;
struct notifier_block nb;
struct notifier_block nb_ssh;
struct sec_touch_driver touch_driver[2];
int device_number;
int current_device;
};
int sec_secure_touch_set_device(struct sec_secure_touch *data, int dev_num);
void sec_secure_touch_sysfs_notify(struct sec_secure_touch *data);
struct sec_touch_driver *sec_secure_touch_register(void *drv_data, struct device *dev, int dev_num, struct kobject *kobj);
void sec_secure_touch_unregister(int dev_num);
int sec_secure_touch_init(void);
void sec_secure_touch_exit(void);
extern void hall_ic_register_notify(struct notifier_block *nb);
extern void hall_ic_unregister_notify(struct notifier_block *nb);
#endif

View File

@@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_TCLM_H_
#define _SEC_TCLM_H_
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
/* TCLM_CONCEPT - start */
#define TCLM_LEVEL_NONE 0x00
#define TCLM_LEVEL_CLEAR_NV 0x01
#define TCLM_LEVEL_LOCKDOWN 0x02
#define TCLM_LEVEL_EVERYTIME 0x05
#define TCLM_LEVEL_NOT_SUPPORT 0xFF
#define CAL_HISTORY_QUEUE_MAX 10
#define CAL_HISTORY_QUEUE_SHORT_DISPLAY 3
#define TCLM_AMBIENT_CAL 0
#define TCLM_OFFSET_CAL_SDC 1
#define TCLM_OFFSET_CAL_SEC 2
#define SEC_TCLM_NVM_OFFSET 1
#define SEC_TCLM_NVM_OFFSET_LENGTH 4
/* [0]: tclm_level, [1] afe_base_high, [2] afe_base_low = 3byte */
#define SEC_CAL_PASS 1
enum tclm_offset {
SEC_TCLM_NVM_OFFSET_IC_FIRMWARE_VER = 1,
SEC_TCLM_NVM_ALL_DATA = 2,
SEC_TCLM_NVM_TEST = 3,
};
#define CAL_POS_CMD(full_name, short_name) .f_name = full_name, .s_name = short_name
enum tclm_root {
CALPOSITION_NONE = 0,
CALPOSITION_INITIAL = 1,
CALPOSITION_FACTORY = 2,
CALPOSITION_OUTSIDE = 3,
CALPOSITION_LCIA = 4,
CALPOSITION_SVCCENTER = 5,
CALPOSITION_ABNORMAL = 6,
CALPOSITION_FIRMUP = 7,
CALPOSITION_SPECOUT = 8,
CALPOSITION_TUNEUP = 9,
CALPOSITION_EVERYTIME = 10,
CALPOSITION_TESTMODE = 11,
CALPOSITION_UNDEFINE = 12,
CALPOSITION_MAX = 16,
};
enum tclm_result {
TCLM_RESULT_DONE = 0,
TCLM_RESULT_ABNORMAL = 1,
TCLM_RESULT_CAL_DONE = 2,
};
struct sec_cal_position {
const char *f_name;
const char s_name;
};
struct sec_tclm_nvdata {
u8 cal_count;
u16 tune_fix_ver;
u8 cal_position;
u8 cal_pos_hist_cnt;
u8 cal_pos_hist_lastp;
u8 cal_pos_hist_queue[2 * CAL_HISTORY_QUEUE_MAX];
u8 cal_fail_flag; /* pass : 1 fail : etc */
u8 cal_fail_cnt; /* history cnt */
} __attribute__ ((packed));
/* TCLM_CONCEPT - end */
struct sec_tclm_data {
int tclm_level;
int afe_base;
bool external_factory;
u8 root_of_calibration;
struct sec_cal_position *tclm_string;
u8 cal_pos_hist_last3[2 * CAL_HISTORY_QUEUE_SHORT_DISPLAY + 1]; /* 7 */
struct device *dev;
int (*tclm_read)(struct device *dev, int address);
int (*tclm_write)(struct device *dev, int address);
int (*tclm_execute_force_calibration)(struct device *dev, int cal_mode);
void (*tclm_parse_dt)(struct device *dev, struct sec_tclm_data *tdata);
struct sec_tclm_nvdata nvdata;
u8 tclm[SEC_TCLM_NVM_OFFSET_LENGTH];
bool support_tclm_test;
};
void sec_tclm_case(struct sec_tclm_data *data, int tclm_case);
int sec_tclm_get_nvm_all(struct sec_tclm_data *data);
void sec_tclm_position_history(struct sec_tclm_data *data);
void sec_tclm_root_of_cal(struct sec_tclm_data *data, int pos);
void sec_tclm_debug_info(struct sec_tclm_data *data);
void sec_tclm_reposition_history(struct sec_tclm_data *data);
int sec_execute_tclm_package(struct sec_tclm_data *data, int factory_mode);
int sec_tclm_check_cal_case(struct sec_tclm_data *data);
void sec_tclm_initialize(struct sec_tclm_data *data);
int tclm_test_command(struct sec_tclm_data *data, int test_case, int cmd_param1, int cmd_param2, char *buff);
int sec_tclm_test_on_probe(struct sec_tclm_data *data);
#endif

View File

@@ -0,0 +1,125 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* drivers/input/sec_input/sec_trusted_touch.h
*
* Core file for Samsung input device driver for multi device
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_TRUSTED_TOUCH_H_
#define _SEC_TRUSTED_TOUCH_H_
#include "sec_input.h"
#if IS_ENABLED(CONFIG_INPUT_SEC_TRUSTED_TOUCH)
#include <linux/gpio.h>
#include <linux/pinctrl/qcom-pinctrl.h>
#include <linux/gunyah/gh_msgq.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <linux/gunyah/gh_irq_lend.h>
#include <linux/gunyah/gh_mem_notifier.h>
#include <linux/atomic.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/kobject.h>
#include <linux/sort.h>
#define TRUSTED_TOUCH_MEM_LABEL 0x7
enum trusted_touch_mode_config {
TRUSTED_TOUCH_VM_MODE,
TRUSTED_TOUCH_MODE_NONE
};
enum trusted_touch_pvm_states {
TRUSTED_TOUCH_PVM_INIT,
PVM_I2C_RESOURCE_ACQUIRED,
PVM_INTERRUPT_DISABLED,
PVM_IOMEM_LENT,
PVM_IOMEM_LENT_NOTIFIED,
PVM_IRQ_LENT,
PVM_IRQ_LENT_NOTIFIED,
PVM_IOMEM_RELEASE_NOTIFIED,
PVM_IRQ_RELEASE_NOTIFIED,
PVM_ALL_RESOURCES_RELEASE_NOTIFIED,
PVM_IRQ_RECLAIMED,
PVM_IOMEM_RECLAIMED,
PVM_INTERRUPT_ENABLED,
PVM_I2C_RESOURCE_RELEASED,
TRUSTED_TOUCH_PVM_STATE_MAX
};
enum trusted_touch_tvm_states {
TRUSTED_TOUCH_TVM_INIT,
TVM_IOMEM_LENT_NOTIFIED,
TVM_IRQ_LENT_NOTIFIED,
TVM_ALL_RESOURCES_LENT_NOTIFIED,
TVM_IOMEM_ACCEPTED,
TVM_I2C_SESSION_ACQUIRED,
TVM_IRQ_ACCEPTED,
TVM_INTERRUPT_ENABLED,
TVM_INTERRUPT_DISABLED,
TVM_IRQ_RELEASED,
TVM_I2C_SESSION_RELEASED,
TVM_IOMEM_RELEASED,
TRUSTED_TOUCH_TVM_STATE_MAX
};
#define TOUCH_INTR_GPIO_BASE 0xF12E000
#define TOUCH_INTR_GPIO_SIZE 0x1000
#define TOUCH_INTR_GPIO_OFFSET 0x8
#define TRUSTED_TOUCH_EVENT_LEND_FAILURE -1
#define TRUSTED_TOUCH_EVENT_LEND_NOTIFICATION_FAILURE -2
#define TRUSTED_TOUCH_EVENT_ACCEPT_FAILURE -3
#define TRUSTED_TOUCH_EVENT_FUNCTIONAL_FAILURE -4
#define TRUSTED_TOUCH_EVENT_RELEASE_FAILURE -5
#define TRUSTED_TOUCH_EVENT_RECLAIM_FAILURE -6
#define TRUSTED_TOUCH_EVENT_I2C_FAILURE -7
#define TRUSTED_TOUCH_EVENT_NOTIFICATIONS_PENDING 5
struct trusted_touch_vm_info {
enum gh_irq_label irq_label;
enum gh_mem_notifier_tag mem_tag;
enum gh_vm_names vm_name;
const char *trusted_touch_type;
u32 hw_irq;
gh_memparcel_handle_t vm_mem_handle;
u32 *iomem_bases;
u32 *iomem_sizes;
u32 iomem_list_size;
void *mem_cookie;
atomic_t vm_state;
};
struct sec_trusted_touch {
struct device *dev;
struct trusted_touch_vm_info *vm_info;
struct mutex clk_io_ctrl_mutex;
struct mutex transition_lock;
const char *touch_environment;
struct completion trusted_touch_powerdown;
struct clk *core_clk;
struct clk *iface_clk;
atomic_t trusted_touch_initialized;
atomic_t trusted_touch_enabled;
atomic_t trusted_touch_transition;
atomic_t trusted_touch_event;
atomic_t trusted_touch_abort_status;
atomic_t delayed_vm_probe_pending;
atomic_t trusted_touch_mode;
int (*pre_func)(struct device *dev, int mode);
int (*post_func)(struct device *dev, int mode);
};
int sec_trusted_touch_init(struct device *dev);
#else
static inline int sec_trusted_touch_init(struct device *dev)
{
return 0;
}
#endif
#endif

View File

@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __SEC_TSP_DUMPKEY_H__
#define __SEC_TSP_DUMPKEY_H__
#define NUM_DEVICES 3
struct sec_tsp_dumpkey_param {
unsigned int keycode;
int down;
};
struct tsp_dump_callbacks {
void (*inform_dump)(struct device *dev);
struct device *ptsp;
};
void sec_input_dumpkey_register(int dev_id, void (*callback)(struct device *dev), struct device *dev);
void sec_input_dumpkey_unregister(int dev_id);
int sec_tsp_dumpkey_init(void);
void sec_tsp_dumpkey_exit(void);
#endif /* __SEC_TSP_DUMPKEY_H__ */

View File

@@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0
* Copyright (C) 2022 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _SEC_TSP_LOG_H_
#define _SEC_TSP_LOG_H_
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tick.h>
#include <linux/module.h>
#include <linux/memblock.h>
#include <linux/sched/clock.h>
#define SEC_TSP_LOG_BUF_SIZE (256 * 1024) /* 256 KB */
#define SEC_TSP_FAIL_HIST_BUF_SIZE (50 * 1024) /* 50 KB */
#if IS_ENABLED(CONFIG_SEC_INPUT_MULTI_DEVICE)
#define SEC_TSP_RAW_DATA_BUF_SIZE (2 * 50 * 1024) /* 100 KB */
#else
#define SEC_TSP_RAW_DATA_BUF_SIZE (50 * 1024) /* 50 KB */
#endif
#define SEC_TSP_COMMAND_HISTORY_BUF_SIZE (10 * 1024) /* 10 KB */
#define SEC_TSP_SPONGE_LOG_BUF_SIZE (128 * 1024) /* 128 KB */
#define SEC_TSP_LOG_TIMESTAMP_SIZE 50
#define SEC_TSP_LOG_EXTRA_SIZE 10
/**
* sec_debug_tsp_log : Leave tsp log in tsp_msg file.
* ( Timestamp + Tsp logs )
* sec_debug_tsp_log_msg : Leave tsp log in tsp_msg file and
* add additional message between timestamp and tsp log.
* ( Timestamp + additional Message + Tsp logs )
*/
void sec_tsp_sponge_log(char *buf);
void sec_debug_tsp_log_msg(char *msg, char *buf);
void sec_debug_tsp_fail_hist(char *msg, char *buf);
void sec_tsp_log_fix(void);
void sec_tsp_raw_data_clear(char mode);
void sec_debug_tsp_raw_data_msg(char mode, char *msg, char *buf);
void sec_debug_tsp_command_history(char *buf);
int sec_tsp_log_init(void);
#endif /* _SEC_TSP_LOG_H_ */

View File

@@ -0,0 +1,28 @@
/*
* spu-sign-verify.h
*
* Author: JJungs-lee <jhs2.lee@samsung.com>
*
*/
#ifndef _SPU_SIGN_VERIFY_H_
#define _SPU_SIGN_VERIFY_H_
#include <linux/string.h>
/* TAG NAME */
#define TSP_TAG "TSP"
#define WACOM_TAG "WACOM"
/* METADATA LEN */
#define DIGEST_LEN 32
#define SIGN_LEN 512
/* TAG LEN */
#define TAG_LEN(FW) strlen(FW##_TAG)
/* TOTAL METADATA SIZE */
#define SPU_METADATA_SIZE(FW) ((TAG_LEN(FW)) + (DIGEST_LEN) + (SIGN_LEN))
extern long spu_firmware_signature_verify(const char *fw_name, const u8 *fw_data, const long fw_size);
#endif //end _SPU_SIGN_VERIFY_H_

View File

@@ -0,0 +1,127 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_IO_PGTABLE_FAST_H
#define __LINUX_IO_PGTABLE_FAST_H
#include <linux/notifier.h>
#include <linux/io-pgtable.h>
/*
* This ought to be private to io-pgtable-fast, but dma-mapping-fast
* currently requires it for a debug usecase.
*/
typedef u64 av8l_fast_iopte;
struct io_pgtable_ops;
struct scatterlist;
struct av8l_fast_io_pgtable {
struct io_pgtable iop;
av8l_fast_iopte *pgd;
av8l_fast_iopte *puds[4];
av8l_fast_iopte *pmds;
struct page **pages; /* page table memory */
int nr_pages;
dma_addr_t base;
dma_addr_t end;
};
/* Struct accessors */
#define iof_pgtable_to_data(x) \
container_of((x), struct av8l_fast_io_pgtable, iop)
#define iof_pgtable_ops_to_pgtable(x) \
container_of((x), struct io_pgtable, ops)
#define iof_pgtable_ops_to_data(x) \
iof_pgtable_to_data(iof_pgtable_ops_to_pgtable(x))
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
int av8l_fast_map_public(struct io_pgtable_ops *ops, unsigned long iova,
phys_addr_t paddr, size_t size, int prot);
void av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
size_t size);
int av8l_fast_map_sg_public(struct io_pgtable_ops *ops,
unsigned long iova, struct scatterlist *sgl,
unsigned int nents, int prot, size_t *size);
bool av8l_fast_iova_coherent_public(struct io_pgtable_ops *ops,
unsigned long iova);
phys_addr_t av8l_fast_iova_to_phys_public(struct io_pgtable_ops *ops,
unsigned long iova);
#else
static inline int
av8l_fast_map_public(struct io_pgtable_ops *ops, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
{
return -EINVAL;
}
static inline void av8l_fast_unmap_public(struct io_pgtable_ops *ops,
unsigned long iova, size_t size)
{
}
static inline int av8l_fast_map_sg_public(struct io_pgtable_ops *ops,
unsigned long iova, struct scatterlist *sgl,
unsigned int nents, int prot, size_t *size)
{
return 0;
}
static inline bool av8l_fast_iova_coherent_public(struct io_pgtable_ops *ops,
unsigned long iova)
{
return false;
}
static inline phys_addr_t
av8l_fast_iova_to_phys_public(struct io_pgtable_ops *ops,
unsigned long iova)
{
return 0;
}
#endif /* CONFIG_IOMMU_IO_PGTABLE_FAST */
/* events for notifiers passed to av8l_register_notify */
#define MAPPED_OVER_STALE_TLB 1
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB
/*
* Doesn't matter what we use as long as bit 0 is unset. The reason why we
* need a different value at all is that there are certain hardware
* platforms with erratum that require that a PTE actually be zero'd out
* and not just have its valid bit unset.
*/
#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0xa
void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops, u64 base, u64 end,
bool skip_sync);
void av8l_register_notify(struct notifier_block *nb);
#else /* !CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */
#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0
static inline void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops,
u64 base,
u64 end,
bool skip_sync)
{
}
static inline void av8l_register_notify(struct notifier_block *nb)
{
}
#endif /* CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */
#endif /* __LINUX_IO_PGTABLE_FAST_H */

View File

@@ -41,6 +41,9 @@ struct iova_domain {
struct hlist_node cpuhp_dead;
ANDROID_VENDOR_DATA(1);
#if IS_ENABLED(CONFIG_QTVM_IOMMU_TRACE_HOOKS) && !defined(CONFIG_ANDROID_VENDOR_OEM_DATA)
u64 android_vendor_data1;
#endif
};
static inline unsigned long iova_size(struct iova *iova)

208
include/linux/ipa_usb.h Normal file
View File

@@ -0,0 +1,208 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _IPA_USB_H_
#define _IPA_USB_H_
#include <linux/if_ether.h>
#include <linux/types.h>
enum ipa_usb_teth_prot {
IPA_USB_RNDIS = 0,
IPA_USB_ECM = 1,
IPA_USB_RMNET = 2,
IPA_USB_MBIM = 3,
IPA_USB_DIAG = 4,
IPA_USB_RMNET_CV2X = 5,
IPA_USB_MAX_TETH_PROT_SIZE
};
enum teth_bridge_params {
IPA_TETH_BRIDGE_1 = 0,
IPA_TETH_BRIDGE_2 = 1,
IPA_TETH_BRIDGE_MAX
};
/**
* ipa_usb_teth_params - parameters for RDNIS/ECM initialization API
*
* @host_ethaddr: host Ethernet address in network order
* @device_ethaddr: device Ethernet address in network order
*/
struct ipa_usb_teth_params {
u8 host_ethaddr[ETH_ALEN];
u8 device_ethaddr[ETH_ALEN];
};
enum ipa_usb_notify_event {
IPA_USB_DEVICE_READY,
IPA_USB_REMOTE_WAKEUP,
IPA_USB_SUSPEND_COMPLETED
};
enum ipa_usb_max_usb_packet_size {
IPA_USB_FULL_SPEED_64B = 64,
IPA_USB_HIGH_SPEED_512B = 512,
IPA_USB_SUPER_SPEED_1024B = 1024
};
enum ipa_usb_gsi_chan_dir {
CHAN_DIR_FROM_GSI = 0x0,
CHAN_DIR_TO_GSI = 0x1
};
/**
* ipa_usb_teth_prot_params - parameters for connecting RNDIS
*
* @max_xfer_size_bytes_to_dev: max size of UL packets in bytes
* @max_packet_number_to_dev: max number of UL aggregated packets
* @max_xfer_size_bytes_to_host: max size of DL packets in bytes
*
*/
struct ipa_usb_teth_prot_params {
u32 max_xfer_size_bytes_to_dev;
u32 max_packet_number_to_dev;
u32 max_xfer_size_bytes_to_host;
};
/**
* ipa_usb_xdci_connect_params - parameters required to start IN, OUT
* channels, and connect RNDIS/ECM/teth_bridge
*
* @max_pkt_size: USB speed (full/high/super/super-speed plus)
* @ipa_to_usb_xferrscidx: Transfer Resource Index (XferRscIdx) for IN channel.
* The hardware-assigned transfer resource index for the
* transfer, which was returned in response to the
* Start Transfer command. This field is used for
* "Update Transfer" command.
* Should be 0 =< ipa_to_usb_xferrscidx <= 127.
* @ipa_to_usb_xferrscidx_valid: true if xferRscIdx should be updated for IN
* channel
* @usb_to_ipa_xferrscidx: Transfer Resource Index (XferRscIdx) for OUT channel
* Should be 0 =< usb_to_ipa_xferrscidx <= 127.
* @usb_to_ipa_xferrscidx_valid: true if xferRscIdx should be updated for OUT
* channel
* @teth_prot: tethering protocol
* @teth_prot_params: parameters for connecting the tethering protocol.
* @max_supported_bandwidth_mbps: maximum bandwidth need of the client in Mbps
*/
struct ipa_usb_xdci_connect_params {
enum ipa_usb_max_usb_packet_size max_pkt_size;
u8 ipa_to_usb_xferrscidx;
bool ipa_to_usb_xferrscidx_valid;
u8 usb_to_ipa_xferrscidx;
bool usb_to_ipa_xferrscidx_valid;
enum ipa_usb_teth_prot teth_prot;
struct ipa_usb_teth_prot_params teth_prot_params;
u32 max_supported_bandwidth_mbps;
};
/**
* ipa_usb_xdci_chan_scratch - xDCI protocol SW config area of
* channel scratch
*
* @last_trb_addr_iova: Address (iova LSB - based on alignment restrictions) of
* last TRB in queue. Used to identify roll over case
* @const_buffer_size: TRB buffer size in KB (similar to IPA aggregation
* configuration). Must be aligned to max USB Packet Size.
* Should be 1 <= const_buffer_size <= 31.
* @depcmd_low_addr: Used to generate "Update Transfer" command
* @depcmd_hi_addr: Used to generate "Update Transfer" command.
*/
struct ipa_usb_xdci_chan_scratch {
u16 last_trb_addr_iova;
u8 const_buffer_size;
u32 depcmd_low_addr;
u8 depcmd_hi_addr;
};
/**
* ipa_usb_xdci_chan_params - xDCI channel related properties
*
* @keep_ipa_awake: when true, IPA will not be clock gated
* @teth_prot: tethering protocol for which the channel is created
* @gevntcount_low_addr: GEVNCOUNT low address for event scratch
* @gevntcount_hi_addr: GEVNCOUNT high address for event scratch
* @dir: channel direction
* @xfer_ring_len: length of transfer ring in bytes (must be integral
* multiple of transfer element size - 16B for xDCI)
* @xfer_scratch: parameters for xDCI channel scratch
* @xfer_ring_base_addr_iova: IO virtual address mapped to pysical base address
* @data_buff_base_len: length of data buffer allocated by USB driver
* @data_buff_base_addr_iova: IO virtual address mapped to pysical base address
* @sgt_xfer_rings: Scatter table for Xfer rings,contains valid non NULL
* value
* when USB S1-SMMU enabed, else NULL.
* @sgt_data_buff: Scatter table for data buffs,contains valid non NULL
* value
* when USB S1-SMMU enabed, else NULL.
*
*/
struct ipa_usb_xdci_chan_params {
/* IPA EP params */
bool keep_ipa_awake;
enum ipa_usb_teth_prot teth_prot;
/* event ring params */
u32 gevntcount_low_addr;
u8 gevntcount_hi_addr;
/* transfer ring params */
enum ipa_usb_gsi_chan_dir dir;
u16 xfer_ring_len;
struct ipa_usb_xdci_chan_scratch xfer_scratch;
u64 xfer_ring_base_addr_iova;
u32 data_buff_base_len;
u64 data_buff_base_addr_iova;
struct sg_table *sgt_xfer_rings;
struct sg_table *sgt_data_buff;
};
/**
* ipa_usb_chan_out_params - out parameters for channel request
*
* @clnt_hdl: opaque client handle assigned by IPA to client
* @db_reg_phs_addr_lsb: Physical address of doorbell register where the 32
* LSBs of the doorbell value should be written
* @db_reg_phs_addr_msb: Physical address of doorbell register where the 32
* MSBs of the doorbell value should be written
*
*/
struct ipa_req_chan_out_params {
u32 clnt_hdl;
u32 db_reg_phs_addr_lsb;
u32 db_reg_phs_addr_msb;
};
struct ipa_usb_ops {
int (*init_teth_prot)(enum ipa_usb_teth_prot teth_prot,
struct ipa_usb_teth_params *teth_params,
int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *),
void *user_data);
int (*xdci_connect)
(struct ipa_usb_xdci_chan_params *ul_chan_params,
struct ipa_usb_xdci_chan_params *dl_chan_params,
struct ipa_req_chan_out_params *ul_out_params,
struct ipa_req_chan_out_params *dl_out_params,
struct ipa_usb_xdci_connect_params *connect_params);
int (*xdci_disconnect)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
enum ipa_usb_teth_prot teth_prot);
int (*deinit_teth_prot)(enum ipa_usb_teth_prot teth_prot);
int (*xdci_suspend)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
enum ipa_usb_teth_prot teth_prot,
bool with_remote_wakeup);
int (*xdci_resume)(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
enum ipa_usb_teth_prot teth_prot);
bool (*ipa_usb_is_teth_prot_connected)
(enum ipa_usb_teth_prot usb_teth_prot);
};
#if IS_ENABLED(CONFIG_USB_F_GSI)
void ipa_ready_callback(void *ops);
#else
static inline void ipa_ready_callback(void *ops)
{ }
#endif
#endif /* _IPA_USB_H_ */

295
include/linux/ipc_logging.h Normal file
View File

@@ -0,0 +1,295 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2015,2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _IPC_LOGGING_H
#define _IPC_LOGGING_H
#include <linux/errno.h>
#include <linux/types.h>
#define MAX_MSG_SIZE 255
enum {
TSV_TYPE_MSG_START = 1,
TSV_TYPE_SKB = TSV_TYPE_MSG_START,
TSV_TYPE_STRING,
TSV_TYPE_MSG_END = TSV_TYPE_STRING,
};
struct tsv_header {
unsigned char type;
unsigned char size; /* size of data field */
};
struct encode_context {
struct tsv_header hdr;
char buff[MAX_MSG_SIZE];
int offset;
};
struct decode_context {
int output_format; /* 0 = debugfs */
char *buff; /* output buffer */
int size; /* size of output buffer */
};
#if IS_ENABLED(CONFIG_IPC_LOGGING)
/*
* ipc_log_context_create: Create a debug log context
* Should not be called from atomic context
*
* @max_num_pages: Number of pages of logging space required (max. 10)
* @mod_name : Name of the directory entry under DEBUGFS
* @feature_version : First 16 bit for version number of user-defined message
* formats and next 16 bit for enabling minidump
*
* returns context id on success, NULL on failure
*/
void *ipc_log_context_create(int max_num_pages, const char *modname,
uint32_t feature_version);
/*
* msg_encode_start: Start encoding a log message
*
* @ectxt: Temporary storage to hold the encoded message
* @type: Root event type defined by the module which is logging
*/
void msg_encode_start(struct encode_context *ectxt, uint32_t type);
/*
* tsv_timestamp_write: Writes the current timestamp count
*
* @ectxt: Context initialized by calling msg_encode_start()
*/
int tsv_timestamp_write(struct encode_context *ectxt);
/*
* tsv_qtimer_write: Writes the current QTimer timestamp count
*
* @ectxt: Context initialized by calling msg_encode_start()
*/
int tsv_qtimer_write(struct encode_context *ectxt);
/*
* tsv_pointer_write: Writes a data pointer
*
* @ectxt: Context initialized by calling msg_encode_start()
* @pointer: Pointer value to write
*/
int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
/*
* tsv_int32_write: Writes a 32-bit integer value
*
* @ectxt: Context initialized by calling msg_encode_start()
* @n: Integer to write
*/
int tsv_int32_write(struct encode_context *ectxt, int32_t n);
/*
* tsv_byte_array_write: Writes a byte array
*
* @ectxt: Context initialized by calling msg_encode_start()
* @data: Pointer to byte array
* @data_size: Size of byte array
*/
int tsv_byte_array_write(struct encode_context *ectxt,
void *data, int data_size);
/*
* msg_encode_end: Complete the message encode process
*
* @ectxt: Temporary storage which holds the encoded message
*/
void msg_encode_end(struct encode_context *ectxt);
/*
* ipc_log_write: Commits message to logging ring buffer
*
* @ctxt: Logging context
* @ectxt: Temporary storage which holds the encoded message
*/
void ipc_log_write(void *ctxt, struct encode_context *ectxt);
/*
* ipc_log_string: Helper function to log a string
*
* @ilctxt: Debug Log Context created using ipc_log_context_create()
* @fmt: Data specified using format specifiers
*/
int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
/**
* ipc_log_extract - Reads and deserializes log
*
* @ilctxt: logging context
* @buff: buffer to receive the data
* @size: size of the buffer
* @returns: 0 if no data read; >0 number of bytes read; < 0 error
*
* If no data is available to be read, then the ilctxt::read_avail
* completion is reinitialized. This allows clients to block
* until new log data is save.
*/
int ipc_log_extract(void *ilctxt, char *buff, int size);
/*
* Print a string to decode context.
* @dctxt Decode context
* @args printf args
*/
#define IPC_SPRINTF_DECODE(dctxt, args...) \
do { \
int i; \
i = scnprintf(dctxt->buff, dctxt->size, args); \
dctxt->buff += i; \
dctxt->size -= i; \
} while (0)
/*
* tsv_timestamp_read: Reads a timestamp
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_timestamp_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_qtimer_read: Reads a QTimer timestamp
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_qtimer_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_pointer_read: Reads a data pointer
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_pointer_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_int32_read: Reads a 32-bit integer value
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
int32_t tsv_int32_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_byte_array_read: Reads a byte array
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_byte_array_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* add_deserialization_func: Register a deserialization function to
* unpack the subevents of a main event
*
* @ctxt: Debug log context to which the deserialization function has
* to be registered
* @type: Main/Root event, defined by the module which is logging, to
* which this deserialization function has to be registered.
* @dfune: Deserialization function to be registered
*
* return 0 on success, -ve value on FAILURE
*/
int add_deserialization_func(void *ctxt, int type,
void (*dfunc)(struct encode_context *,
struct decode_context *));
/*
* ipc_log_context_destroy: Destroy debug log context
*
* @ctxt: debug log context created by calling ipc_log_context_create API.
*/
int ipc_log_context_destroy(void *ctxt);
/*
* netlog
*/
void net_log(const char *fmt, ...);
#else
static inline void net_log(const char *fmt, ...) { }
static inline void *ipc_log_context_create(int max_num_pages,
const char *modname, uint32_t feature_version)
{ return NULL; }
static inline void msg_encode_start(struct encode_context *ectxt,
uint32_t type) { }
static inline int tsv_timestamp_write(struct encode_context *ectxt)
{ return -EINVAL; }
static inline int tsv_qtimer_write(struct encode_context *ectxt)
{ return -EINVAL; }
static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
{ return -EINVAL; }
static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
{ return -EINVAL; }
static inline int tsv_byte_array_write(struct encode_context *ectxt,
void *data, int data_size)
{ return -EINVAL; }
static inline void msg_encode_end(struct encode_context *ectxt) { }
static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
{ return -EINVAL; }
static inline int ipc_log_extract(void *ilctxt, char *buff, int size)
{ return -EINVAL; }
#define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
static inline void tsv_timestamp_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format) { }
static inline void tsv_qtimer_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format) { }
static inline void tsv_pointer_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format) { }
static inline int32_t tsv_int32_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format)
{ return 0; }
static inline void tsv_byte_array_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format) { }
static inline int add_deserialization_func(void *ctxt, int type,
void (*dfunc)(struct encode_context *,
struct decode_context *))
{ return 0; }
static inline int ipc_log_context_destroy(void *ctxt)
{ return 0; }
#endif
#endif

View File

@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016, 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LEDS_QPNP_FLASH_V2_H
#define __LEDS_QPNP_FLASH_V2_H
#include <linux/leds.h>
#include <linux/notifier.h>
enum flash_led_irq_type {
LED_FAULT_IRQ = BIT(0),
MITIGATION_IRQ = BIT(1),
FLASH_TIMER_EXP_IRQ = BIT(2),
ALL_RAMP_DOWN_DONE_IRQ = BIT(3),
ALL_RAMP_UP_DONE_IRQ = BIT(4),
LED3_RAMP_UP_DONE_IRQ = BIT(5),
LED2_RAMP_UP_DONE_IRQ = BIT(6),
LED1_RAMP_UP_DONE_IRQ = BIT(7),
INVALID_IRQ = BIT(8),
};
int qpnp_flash_led_register_irq_notifier(struct notifier_block *nb);
int qpnp_flash_led_unregister_irq_notifier(struct notifier_block *nb);
#endif

View File

@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LEDS_QPNP_FLASH_H
#define __LEDS_QPNP_FLASH_H
#include <linux/leds.h>
#define ENABLE_REGULATOR BIT(0)
#define DISABLE_REGULATOR BIT(1)
#define QUERY_MAX_AVAIL_CURRENT BIT(2)
#define QUERY_MAX_CURRENT BIT(3)
#define FLASH_LED_PREPARE_OPTIONS_MASK GENMASK(3, 0)
int qpnp_flash_register_led_prepare(struct device *dev, void *data);
#if IS_ENABLED(CONFIG_LEDS_QPNP_FLASH_V2)
int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
int *max_current);
#else
static inline int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
int *max_current)
{
return -ENODEV;
}
#endif
#if IS_ENABLED(CONFIG_BACKLIGHT_QCOM_SPMI_WLED)
int wled_flash_led_prepare(struct led_trigger *trig, int options,
int *max_current);
#else
static inline int wled_flash_led_prepare(struct led_trigger *trig, int options,
int *max_current)
{
return -EINVAL;
}
#endif
#endif

View File

@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LEDS_QTI_FLASH_H
#define __LEDS_QTI_FLASH_H
#include <linux/leds.h>
#define ENABLE_REGULATOR BIT(0)
#define DISABLE_REGULATOR BIT(1)
#define QUERY_MAX_AVAIL_CURRENT BIT(2)
/**
* struct flash_led_param: QTI flash LED parameter data
* @on_time_ms : Time to wait before strobing the switch
* @off_time_ms : Time to wait to turn off LED after strobing switch
*/
struct flash_led_param {
u64 on_time_ms;
u64 off_time_ms;
};
#if IS_ENABLED(CONFIG_LEDS_QTI_FLASH)
int qti_flash_led_prepare(struct led_trigger *trig,
int options, int *max_current);
int qti_flash_led_set_param(struct led_trigger *trig,
struct flash_led_param param);
#if IS_ENABLED(CONFIG_SENSORS_STK6D2X) || IS_ENABLED(CONFIG_SENSORS_TSL2511) || IS_ENABLED(CONFIG_SENSORS_STK6DAX)
int qti_flash_led_set_strobe_sel(struct led_trigger *trig,
int strobe_sel);
#endif
#else
static inline int qti_flash_led_prepare(struct led_trigger *trig,
int options, int *max_current)
{
return -EINVAL;
}
static inline int qti_flash_led_set_param(struct led_trigger *trig,
struct flash_led_param param);
{
return -EINVAL;
}
#if IS_ENABLED(CONFIG_SENSORS_STK6D2X) || IS_ENABLED(CONFIG_SENSORS_STK6DAX)
static inline int qti_flash_led_set_strobe_sel(struct led_trigger *trig,
int strobe_sel);
{
return -EINVAL;
}
#endif
#endif
#endif

View File

@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _QMP_H_
#define _QMP_H_
#include <linux/types.h>
/**
* struct qmp_pkt - Packet structure to be used for TX and RX with QMP
* @size size of data
* @data Buffer holding data of this packet
*/
struct qmp_pkt {
u32 size;
void *data;
};
#endif /* _QMP_H_ */

View File

@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MEM_BUF_ALTMAP_H
#define _MEM_BUF_ALTMAP_H
#include <linux/dma-buf.h>
#include <uapi/linux/mem-buf.h>
#include <linux/gunyah/gh_rm_drv.h>
#include "../../drivers/dma-buf/heaps/qcom_sg_ops.h"
extern struct gen_pool *dmabuf_mem_pool;
/*
* mem_buf_dmabuf_obj
* A dmabuf object representing memory shared/lent by another Virtual machine
* and obtained via mem_buf_retrieve().
* @buffer: data type expected by qcom_sg_buf_ops
* @pgmap: Arguments to memremap_pages
* @memmap: alternate memmap for the dmabuf if present
* @memmap_base: base ipa address of alternate memmap memory
* @memmap_size: ipa size of alternate memmap memory
*/
struct mem_buf_dmabuf_obj {
struct qcom_sg_buffer buffer;
struct dev_pagemap pgmap;
void *memmap;
unsigned long memmap_base;
size_t memmap_size;
};
int prepare_altmap(struct mem_buf_dmabuf_obj *obj,
struct gh_sgl_desc **__sgl_desc, size_t dmabuf_size);
size_t determine_memmap_size(size_t dmabuf_size);
#endif /* _MEM_BUF_ALTMAP_H */

View File

@@ -0,0 +1,120 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MEM_BUF_EXPORTER_H
#define _MEM_BUF_EXPORTER_H
#include <linux/dma-buf.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <soc/qcom/secure_buffer.h>
int mem_buf_dma_buf_attach(struct dma_buf *dmabuf,
struct dma_buf_attachment *attachment);
/* Private data for managing a dmabuf's Virtual Machine permissions. */
struct mem_buf_vmperm;
/*
* @lookup: Returns the mem_buf_vmperm data structure contained somewhere
* in the exporter's private_data, or a negative number on error.
* @attach: The exporter's normal dma_buf_attach callback
* @dma_ops: The exporter's standard dma_buf callbacks, except for
* attach which must be NULL.
*/
struct mem_buf_dma_buf_ops {
struct mem_buf_vmperm *(*lookup)(struct dma_buf *dmabuf);
int (*attach)(struct dma_buf *dmabuf, struct dma_buf_attachment *a);
struct dma_buf_ops dma_ops;
};
struct dma_buf *
mem_buf_dma_buf_export(struct dma_buf_export_info *exp_info,
struct mem_buf_dma_buf_ops *ops);
#define MEM_BUF_WRAPPER_FLAG_STATIC_VM BIT(0)
#define MEM_BUF_WRAPPER_FLAG_LENDSHARE BIT(1)
#define MEM_BUF_WRAPPER_FLAG_ACCEPT BIT(2)
#define MEM_BUF_WRAPPER_FLAG_ERR BIT(3)
/*
* A dmabuf owned by the current VM with RWX permissions.
* All variants should be free'd via mem_buf_vmperm_free().
*
* @dmabuf: value returned from dma_buf_export()
* @sgt: Reference to the exporter's internal memory descriptor.
* Will not be freed by mem_buf_vmperm_free().
*/
struct mem_buf_vmperm *mem_buf_vmperm_alloc(struct sg_table *sgt);
/*
* A dmabuf which permantently belongs to the given VMs & permissions.
*/
struct mem_buf_vmperm *mem_buf_vmperm_alloc_staticvm(struct sg_table *sgt, int *vmids, int *perms,
u32 nr_acl_entries);
/*
* A dmabuf in the "MEMACCEPT" state.
*/
struct mem_buf_vmperm *mem_buf_vmperm_alloc_accept(struct sg_table *sgt,
gh_memparcel_handle_t memparcel_hdl, int *vmids, int *perms,
unsigned int nr_acl_entries);
/*
* Performs the expected close step based on whether the dmabuf
* is of the "STATICVM" "MEMACCEPT" or "DEFAULT" type.
* Exporters should call this from dma_buf_release. If this function
* Returns an error, exporters should consider the underlying memory
* to have undefined permissions.
*/
int mem_buf_vmperm_release(struct mem_buf_vmperm *vmperm);
/*
* Pins ths permissions of the dmabuf.
* The exporter should call this from dma_buf_mmap, vm_ops->open(), and
* dma_buf_map_attachment. It must not be called from
* dma_buf_begin_cpu_access as userspace may call this function unsafely
* via DMA_BUF_IOCTL_SYNC.
*/
void mem_buf_vmperm_pin(struct mem_buf_vmperm *vmperm);
/*
* Unpins ths permissions of the dmabuf.
* The exporter should call this from vm_ops->close(), and
* dma_buf_unmap_attachment. It must not be called from
* dma_buf_end_cpu_access as userspace may call this function unsafely
* via DMA_BUF_IOCTL_SYNC.
*/
void mem_buf_vmperm_unpin(struct mem_buf_vmperm *vmperm);
/*
* Check whether the current permissions of the dmabuf allow CMO.
* Requires RW.
*
* The exporter should call this during dma_buf_map/unmap_attachment,
* and dma_buf_begin/end_cpu_access.
*/
bool mem_buf_vmperm_can_cmo(struct mem_buf_vmperm *vmperm);
/*
* Check whether the current permissions of the dmabuf allow mmap.
* Requires at minimum the permissions specified in vma.
*
* The exporter should call mem_buf_vmperm_pin() from mmap.
* The exporter should implement the open() and close() operations of
* vma->vm_ops, and call mem_buf_vmperm_pin()/unpin() respectively.
*/
bool mem_buf_vmperm_can_mmap(struct mem_buf_vmperm *vmperm, struct vm_area_struct *vma);
/*
* Check whether the current permissions of the dmabuf allow vmap.
* Requires RW.
*
* The exporter should call this during dma_buf_vmap,
*/
bool mem_buf_vmperm_can_vmap(struct mem_buf_vmperm *vmperm);
#endif /*_MEM_BUF_EXPORTER_H */

139
include/linux/mem-buf.h Normal file
View File

@@ -0,0 +1,139 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MEM_BUF_H
#define _MEM_BUF_H
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <linux/types.h>
#include <linux/dma-buf.h>
#include <uapi/linux/mem-buf.h>
/* For in-kernel use only, not allowed for userspace ioctl */
#define MEM_BUF_BUDDY_MEM_TYPE (MEM_BUF_ION_MEM_TYPE + 2)
/* Used to obtain the underlying vmperm struct of a DMA-BUF */
struct mem_buf_vmperm *to_mem_buf_vmperm(struct dma_buf *dmabuf);
/* Returns true if the local VM has exclusive access and is the owner */
bool mem_buf_dma_buf_exclusive_owner(struct dma_buf *dmabuf);
/*
* Returns the Virtual Machine vmids & permissions of the dmabuf. Can't be
* modified.
*/
int mem_buf_dma_buf_get_vmperm(struct dma_buf *dmabuf, const int **vmids,
const int **perms, int *nr_acl_entries);
/*
* Returns a copy of the Virtual Machine vmids & permissions of the dmabuf.
* The caller must kfree() when finished.
*/
int mem_buf_dma_buf_copy_vmperm(struct dma_buf *dmabuf, int **vmids, int **perms,
int *nr_acl_entries);
/*
* Returns 0 if @dmabuf has a valid memparcel handle and stores it in
* memparcel_hdl
*/
int mem_buf_dma_buf_get_memparcel_hdl(struct dma_buf *dmabuf,
gh_memparcel_handle_t *memparcel_hdl);
typedef int (*mem_buf_dma_buf_destructor)(void *dtor_data);
int mem_buf_dma_buf_set_destructor(struct dma_buf *dmabuf,
mem_buf_dma_buf_destructor dtor,
void *dtor_data);
/**
* struct mem_buf_allocation_data - Data structure that contains information
* about a memory buffer allocation request.
* @size: The size (in bytes) of the memory to be requested from a remote VM
* @nr_acl_entries: The number of ACL entries in @acl_list
* @acl_list: A list of VMID and permission pairs that describe what VMIDs will
* have access to the memory, and with what permissions
* @trans_type: One of GH_RM_TRANS_TYPE_DONATE/LEND/SHARE
* @sgl_desc: Optional. Requests a specific set of IPA addresses.
* @src_mem_type: The type of memory that the remote VM should allocate
* (e.g. ION memory)
* @src_data: A pointer to memory type specific data that the remote VM may need
* when performing an allocation (e.g. ION memory allocations require a heap ID)
* @dst_mem_type: The type of memory that the native VM wants (e.g. ION memory)
* @dst_data: A pointer to memory type specific data that the native VM may
* need when adding the memory from the remote VM (e.g. ION memory requires a
* heap ID to add the memory to).
*/
struct mem_buf_allocation_data {
size_t size;
unsigned int nr_acl_entries;
int *vmids;
int *perms;
u32 trans_type;
struct gh_sgl_desc *sgl_desc;
enum mem_buf_mem_type src_mem_type;
void *src_data;
enum mem_buf_mem_type dst_mem_type;
void *dst_data;
};
struct mem_buf_lend_kernel_arg {
unsigned int nr_acl_entries;
int *vmids;
int *perms;
gh_memparcel_handle_t memparcel_hdl;
u32 flags;
u64 label;
};
int mem_buf_lend(struct dma_buf *dmabuf,
struct mem_buf_lend_kernel_arg *arg);
/*
* mem_buf_share
* Grant the local VM, as well as one or more remote VMs access
* to the dmabuf. The permissions of the local VM default to RWX
* unless otherwise specified.
*/
int mem_buf_share(struct dma_buf *dmabuf,
struct mem_buf_lend_kernel_arg *arg);
struct mem_buf_retrieve_kernel_arg {
int sender_vmid;
unsigned int nr_acl_entries;
int *vmids;
int *perms;
gh_memparcel_handle_t memparcel_hdl;
int fd_flags;
};
struct dma_buf *mem_buf_retrieve(struct mem_buf_retrieve_kernel_arg *arg);
int mem_buf_reclaim(struct dma_buf *dmabuf);
#if IS_ENABLED(CONFIG_QCOM_MEM_BUF)
void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data);
void mem_buf_free(void *membuf);
struct gh_sgl_desc *mem_buf_get_sgl(void *membuf);
int mem_buf_current_vmid(void);
#else
static inline void *mem_buf_alloc(struct mem_buf_allocation_data *alloc_data)
{
return ERR_PTR(-ENODEV);
}
static inline void mem_buf_free(void *membuf) {}
static inline struct gh_sgl_desc *mem_buf_get_sgl(void *membuf)
{
return ERR_PTR(-EINVAL);
}
static inline int mem_buf_current_vmid(void)
{
return -EINVAL;
}
#endif /* CONFIG_QCOM_MEM_BUF */
#endif /* _MEM_BUF_H */

View File

@@ -0,0 +1,431 @@
/*
* max77775-private.h - Voltage regulator driver for the Maxim 77775
*
* Copyright (C) 2016 Samsung Electrnoics
* Insun Choi <insun77.choi@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LINUX_MFD_MAX77775_PRIV_H
#define __LINUX_MFD_MAX77775_PRIV_H
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/usb/typec/maxim/max77775.h>
#include <linux/mfd/max77775_log.h>
/* To Do : Customer Definition for product id */
#define MAX77775_USBC_PRODUCT_ID (0x75)
#define MAX77775_REG_INVALID (0xff)
#define MAX77775_IRQSRC_CHG (1 << 0)
#define MAX77775_IRQSRC_TOP (1 << 1)
#define MAX77775_IRQSRC_FG (1 << 2)
#define MAX77775_IRQSRC_USBC (1 << 3)
#define MAX77775_ELRN (1 << 0)
#define MAX77775_FILT_EMPTY (1 << 2)
enum max77775_hw_rev {
MAX77775_PASS1 = 0x1,
MAX77775_PASS2 = 0x2,
MAX77775_PASS3 = 0x3,
MAX77775_PASS4 = 0x4,
MAX77775_PASS5 = 0x5,
};
enum max77775_reg {
/* Slave addr = 0xCC */
/* PMIC Top-Level Registers */
MAX77775_PMIC_REG_PMICID = 0x00,
MAX77775_PMIC_REG_PMICREV = 0x01,
MAX77775_PMIC_REG_MAINCTRL1 = 0x02,
MAX77775_PMIC_REG_INTSRC = 0x22,
MAX77775_PMIC_REG_INTSRC_MASK = 0x23,
MAX77775_PMIC_REG_SYSTEM_INT = 0x24,
MAX77775_PMIC_REG_SYSTEM_INT_MASK = 0x26,
MAX77775_PMIC_REG_SW_RESET = 0x50,
MAX77775_CHG_REG_INT = 0xB0,
MAX77775_CHG_REG_INT_MASK = 0xB1,
MAX77775_CHG_REG_INT_OK = 0xB2,
MAX77775_CHG_REG_DETAILS_00 = 0xB3,
MAX77775_CHG_REG_DETAILS_01 = 0xB4,
MAX77775_CHG_REG_DETAILS_02 = 0xB5,
MAX77775_CHG_REG_CNFG_00 = 0xB7,
MAX77775_CHG_REG_CNFG_01 = 0xB8,
MAX77775_CHG_REG_CNFG_02 = 0xB9,
MAX77775_CHG_REG_CNFG_03 = 0xBA,
MAX77775_CHG_REG_CNFG_04 = 0xBB,
MAX77775_CHG_REG_CNFG_05 = 0xBC,
MAX77775_CHG_REG_CNFG_06 = 0xBD,
MAX77775_CHG_REG_CNFG_07 = 0xBE,
MAX77775_CHG_REG_CNFG_08 = 0xBF,
MAX77775_CHG_REG_CNFG_09 = 0xC0,
MAX77775_CHG_REG_CNFG_10 = 0xC1,
MAX77775_CHG_REG_CNFG_11 = 0xC2,
MAX77775_CHG_REG_CNFG_12 = 0xC3,
MAX77775_CHG_REG_CNFG_13 = 0xC4,
MAX77775_CHG_REG_CNFG_14 = 0xC5,
MAX77775_CHG_REG_CNFG_16 = 0xC7,
MAX77775_CHG_REG_CNFG_17 = 0xC8,
MAX77775_PMIC_REG_END,
};
/* Slave addr = 0x6C : Fuelgauge */
enum max77775_fuelgauge_reg {
MAX77775_FG_REG_STATUS = 0x00,
MAX77775_FG_REG_VALRTTH = 0x01,
MAX77775_FG_REG_TALRTTH = 0x02,
MAX77775_FG_REG_SALRTTH = 0x03,
MAX77775_FG_REG_REPCAP = 0x05,
MAX77775_FG_REG_REPSOC = 0x06,
MAX77775_FG_REG_TEMP = 0x08,
MAX77775_FG_REG_VCELL = 0x09,
MAX77775_FG_REG_CURRENT = 0x0A,
MAX77775_FG_REG_AVGCURRENT = 0x0B,
MAX77775_FG_REG_AVSOC = 0x0E,
MAX77775_FG_REG_MIXCAP = 0x0F,
MAX77775_FG_REG_FULLCAP = 0x10,
MAX77775_FG_QRTABLE00 = 0x12,
MAX77775_FG_REG_FULLSOCTHR = 0x13,
MAX77775_FG_REG_CYCLES = 0x17,
MAX77775_FG_REG_DESIGNCAP = 0x18,
MAX77775_FG_REG_AVGVCELL = 0x19,
MAX77775_FG_REG_CONFIG = 0x1D,
MAX77775_FG_REG_ICHGTERM = 0x1E,
MAX77775_FG_REG_REMCAPAV = 0x1F,
MAX77775_FG_QRTABLE10 = 0x22,
MAX77775_FG_REG_FULLCAPNOM = 0x23,
MAX77775_FG_REG_LEARNCFG = 0x28,
MAX77775_FG_REG_FILTERCFG = 0x29,
MAX77775_FG_REG_MISCCFG = 0x2B,
MAX77775_FG_REG_CGAIN = 0x2E,
MAX77775_FG_REG_COFF = 0x2F,
MAX77775_FG_QRTABLE20 = 0x32,
MAX77775_FG_REG_FULLCAPREP = 0x35,
MAX77775_FG_REG_RCOMP0 = 0x38,
MAX77775_FG_REG_TEMPCO = 0x39,
MAX77775_FG_REG_VEMPTY = 0x3A,
MAX77775_FG_QRTABLE30 = 0x42,
MAX77775_FG_REG_ISYS = 0x43,
MAX77775_FG_REG_DQACC = 0x45,
MAX77775_FG_REG_DPACC = 0x46,
MAX77775_FG_REG_AVGISYS = 0x4B,
MAX77775_FG_REG_QH = 0x4D,
MAX77775_FG_REG_VSYS = 0xB1,
MAX77775_FG_REG_TALRTTH2 = 0xB2,
/* "not used REG(0xB2)" is for checking fuelgague init result. */
MAX77775_FG_INIT_RESULT_REG = MAX77775_FG_REG_TALRTTH2,
MAX77775_FG_REG_VBYP = 0xB3,
MAX77775_FG_REG_CONFIG2 = 0xBB,
MAX77775_FG_REG_IIN = 0xD0,
MAX77775_FG_REG_VFOCV = 0xFB,
MAX77775_FG_REG_VFSOC = 0xFF,
MAX77775_FG_REG_END
};
#define MAX77775_REG_MAINCTRL1_BIASEN (1 << 7)
/* Slave addr = 0x4A: USBC */
enum max77775_usbc_reg {
MAX77775_USBC_REG_PRODUCT_ID = 0x10, /* replaced address */
MAX77775_USBC_REG_UIC_FW_REV = 0x01,
MAX77775_USBC_REG_UIC_INT = 0x02,
MAX77775_USBC_REG_CC_INT = 0x03,
MAX77775_USBC_REG_PD_INT = 0x04,
MAX77775_USBC_REG_VDM_INT = 0x05,
MAX77775_USBC_REG_SPARE_INT = 0x06,
MAX77775_USBC_REG_USBC_STATUS1 = 0x08,
MAX77775_USBC_REG_USBC_STATUS2 = 0x09,
MAX77775_USBC_REG_BC_STATUS = 0x0A,
MAX77775_USBC_REG_UIC_FW_REV2 = 0x0B,
MAX77775_USBC_REG_CC_STATUS1 = 0x0C,
MAX77775_USBC_REG_CC_STATUS2 = 0x0D,
MAX77775_USBC_REG_PD_STATUS1 = 0x0E,
MAX77775_USBC_REG_PD_STATUS2 = 0x0F,
MAX77775_USBC_REG_SPARE_STATUS1 = 0x11,
MAX77775_USBC_REG_UIC_INT_M = 0x12,
MAX77775_USBC_REG_CC_INT_M = 0x13,
MAX77775_USBC_REG_PD_INT_M = 0x14,
MAX77775_USBC_REG_VDM_INT_M = 0x15,
MAX77775_USBC_REG_SPARE_INT_M = 0x16,
MAX77775_USBC_REG_AP_DATAOUT_M1 = 0x20,
MAX77775_USBC_REG_AP_DATAOUT0 = 0x21,
MAX77775_USBC_REG_AP_DATAOUT1 = 0x22,
MAX77775_USBC_REG_AP_DATAOUT2 = 0x23,
MAX77775_USBC_REG_AP_DATAOUT3 = 0x24,
MAX77775_USBC_REG_AP_DATAOUT4 = 0x25,
MAX77775_USBC_REG_AP_DATAOUT5 = 0x26,
MAX77775_USBC_REG_AP_DATAOUT6 = 0x27,
MAX77775_USBC_REG_AP_DATAOUT7 = 0x28,
MAX77775_USBC_REG_AP_DATAOUT8 = 0x29,
MAX77775_USBC_REG_AP_DATAOUT9 = 0x2a,
MAX77775_USBC_REG_AP_DATAOUT10 = 0x2b,
MAX77775_USBC_REG_AP_DATAOUT11 = 0x2c,
MAX77775_USBC_REG_AP_DATAOUT12 = 0x2d,
MAX77775_USBC_REG_AP_DATAOUT13 = 0x2e,
MAX77775_USBC_REG_AP_DATAOUT14 = 0x2f,
MAX77775_USBC_REG_AP_DATAOUT15 = 0x30,
MAX77775_USBC_REG_AP_DATAOUT16 = 0x31,
MAX77775_USBC_REG_AP_DATAOUT17 = 0x32,
MAX77775_USBC_REG_AP_DATAOUT18 = 0x33,
MAX77775_USBC_REG_AP_DATAOUT19 = 0x34,
MAX77775_USBC_REG_AP_DATAOUT20 = 0x35,
MAX77775_USBC_REG_AP_DATAOUT21 = 0x36,
MAX77775_USBC_REG_AP_DATAOUT22 = 0x37,
MAX77775_USBC_REG_AP_DATAOUT23 = 0x38,
MAX77775_USBC_REG_AP_DATAOUT24 = 0x39,
MAX77775_USBC_REG_AP_DATAOUT25 = 0x3a,
MAX77775_USBC_REG_AP_DATAOUT26 = 0x3b,
MAX77775_USBC_REG_AP_DATAOUT27 = 0x3c,
MAX77775_USBC_REG_AP_DATAOUT28 = 0x3d,
MAX77775_USBC_REG_AP_DATAOUT29 = 0x3e,
MAX77775_USBC_REG_AP_DATAOUT30 = 0x3f,
MAX77775_USBC_REG_AP_DATAOUT31 = 0x40,
MAX77775_USBC_REG_AP_DATAOUT32 = 0x41,
MAX77775_USBC_REG_AP_DATAIN_M1 = 0x50,
MAX77775_USBC_REG_AP_DATAIN0 = 0x51,
MAX77775_USBC_REG_AP_DATAIN1 = 0x52,
MAX77775_USBC_REG_AP_DATAIN2 = 0x53,
MAX77775_USBC_REG_AP_DATAIN3 = 0x54,
MAX77775_USBC_REG_AP_DATAIN4 = 0x55,
MAX77775_USBC_REG_AP_DATAIN5 = 0x56,
MAX77775_USBC_REG_AP_DATAIN6 = 0x57,
MAX77775_USBC_REG_AP_DATAIN7 = 0x58,
MAX77775_USBC_REG_AP_DATAIN8 = 0x59,
MAX77775_USBC_REG_AP_DATAIN9 = 0x5a,
MAX77775_USBC_REG_AP_DATAIN10 = 0x5b,
MAX77775_USBC_REG_AP_DATAIN11 = 0x5c,
MAX77775_USBC_REG_AP_DATAIN12 = 0x5d,
MAX77775_USBC_REG_AP_DATAIN13 = 0x5e,
MAX77775_USBC_REG_AP_DATAIN14 = 0x5f,
MAX77775_USBC_REG_AP_DATAIN15 = 0x60,
MAX77775_USBC_REG_AP_DATAIN16 = 0x61,
MAX77775_USBC_REG_AP_DATAIN17 = 0x62,
MAX77775_USBC_REG_AP_DATAIN18 = 0x63,
MAX77775_USBC_REG_AP_DATAIN19 = 0x64,
MAX77775_USBC_REG_AP_DATAIN20 = 0x65,
MAX77775_USBC_REG_AP_DATAIN21 = 0x66,
MAX77775_USBC_REG_AP_DATAIN22 = 0x67,
MAX77775_USBC_REG_AP_DATAIN23 = 0x68,
MAX77775_USBC_REG_AP_DATAIN24 = 0x69,
MAX77775_USBC_REG_AP_DATAIN25 = 0x6a,
MAX77775_USBC_REG_AP_DATAIN26 = 0x6b,
MAX77775_USBC_REG_AP_DATAIN27 = 0x6c,
MAX77775_USBC_REG_AP_DATAIN28 = 0x6d,
MAX77775_USBC_REG_AP_DATAIN29 = 0x6e,
MAX77775_USBC_REG_AP_DATAIN30 = 0x6f,
MAX77775_USBC_REG_AP_DATAIN31 = 0x70,
MAX77775_USBC_REG_AP_DATAIN32 = 0x71,
MAX77775_USBC_REG_UIC_SWRST = 0x80,
MAX77775_USBC_REG_END,
};
enum max77775_irq_source {
SYS_INT = 0,
CHG_INT,
FUEL_INT,
USBC_INT,
CC_INT,
PD_INT,
VDM_INT,
SPARE_INT,
VIR_INT,
MAX77775_IRQ_GROUP_NR,
};
enum max77775_irq {
/* PMIC; TOPSYS */
MAX77775_SYSTEM_IRQ_SYSUVLO_INT,
MAX77775_SYSTEM_IRQ_SYSOVLO_INT,
MAX77775_SYSTEM_IRQ_TSHDN_INT,
MAX77775_SYSTEM_IRQ_SCP_INT,
/* PMIC; Charger */
MAX77775_CHG_IRQ_BYP_I,
MAX77775_CHG_IRQ_BATP_I,
MAX77775_CHG_IRQ_BAT_I,
MAX77775_CHG_IRQ_CHG_I,
MAX77775_CHG_IRQ_WCIN_I,
MAX77775_CHG_IRQ_CHGIN_I,
MAX77775_CHG_IRQ_AICL_I,
/* Fuelgauge */
MAX77775_FG_IRQ_ALERT,
/* USBC */
MAX77775_USBC_IRQ_APC_INT,
/* CC */
MAX77775_CC_IRQ_VCONNCOP_INT,
MAX77775_CC_IRQ_VSAFE0V_INT,
MAX77775_CC_IRQ_DETABRT_INT,
MAX77775_CC_IRQ_VCONNSC_INT,
MAX77775_CC_IRQ_CCPINSTAT_INT,
MAX77775_CC_IRQ_CCISTAT_INT,
MAX77775_CC_IRQ_CCVCNSTAT_INT,
MAX77775_CC_IRQ_CCSTAT_INT,
MAX77775_USBC_IRQ_VBUS_INT,
MAX77775_USBC_IRQ_VBADC_INT,
MAX77775_USBC_IRQ_DCD_INT,
MAX77775_USBC_IRQ_STOPMODE_INT,
MAX77775_USBC_IRQ_CHGT_INT,
MAX77775_USBC_IRQ_UIDADC_INT,
/*
* USBC: SYSMSG INT should be after CC INT
* because of 2 times of CC Sync INT at WDT reset
*/
MAX77775_USBC_IRQ_SYSM_INT,
/* PD */
MAX77775_PD_IRQ_PDMSG_INT,
MAX77775_PD_IRQ_PS_RDY_INT,
MAX77775_PD_IRQ_DATAROLE_INT,
MAX77775_PD_IRQ_SSACCI_INT,
MAX77775_PD_IRQ_FCTIDI_INT,
/* VDM */
MAX77775_IRQ_VDM_DISCOVER_ID_INT,
MAX77775_IRQ_VDM_DISCOVER_SVIDS_INT,
MAX77775_IRQ_VDM_DISCOVER_MODES_INT,
MAX77775_IRQ_VDM_ENTER_MODE_INT,
MAX77775_IRQ_VDM_DP_STATUS_UPDATE_INT,
MAX77775_IRQ_VDM_DP_CONFIGURE_INT,
MAX77775_IRQ_VDM_ATTENTION_INT,
/* SPARE */
MAX77775_IRQ_USBID_INT,
MAX77775_IRQ_TACONN_INT,
/* VIRTUAL */
MAX77775_VIR_IRQ_ALTERROR_INT,
MAX77775_IRQ_NR,
};
struct max77775_dev {
struct device *dev;
struct i2c_client *i2c; /* 0xCC; PMIC */
struct i2c_client *charger; /* 0xD2; Charger */
struct i2c_client *fuelgauge; /* 0x6C; Fuelgauge */
struct i2c_client *muic; /* 0x4A; MUIC */
struct i2c_client *testsid; /* 0xC4; TestSID */
struct mutex i2c_lock;
struct wakeup_source ws;
int type;
int irq;
int irq_base;
int irq_gpio;
bool blocking_waterevent;
u32 required_hw_rev;
u32 required_fw_pid;
struct mutex irqlock;
int irq_masks_cur[MAX77775_IRQ_GROUP_NR];
int irq_masks_cache[MAX77775_IRQ_GROUP_NR];
u8 FW_Revision;
u8 FW_Minor_Revision;
u8 FW_Product_ID;
u8 FW_Revision_bin;
u8 FW_Minor_Revision_bin;
u8 FW_Product_ID_bin;
struct work_struct fw_work;
struct workqueue_struct *fw_workqueue;
struct completion fw_completion;
int fw_update_state;
int fw_size;
/* For hibernation */
u8 reg_pmic_dump[MAX77775_PMIC_REG_END];
u8 reg_muic_dump[MAX77775_USBC_REG_END];
u8 pmic_id; /* pmic id. 0x75 */
u8 pmic_rev; /* pmic Rev */
u8 cc_booting_complete;
int set_altmode_en;
int enable_nested_irq;
u8 usbc_irq;
bool shutdown;
bool suspended;
wait_queue_head_t suspend_wait;
void (*check_pdmsg)(void *data, u8 pdmsg);
void *usbc_data;
struct max77775_platform_data *pdata;
};
enum max77775_types {
TYPE_MAX77775,
};
extern int max77775_irq_init(struct max77775_dev *max77775);
extern void max77775_irq_exit(struct max77775_dev *max77775);
/* MAX77775 shared i2c API function */
extern int max77775_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
extern int max77775_bulk_read(struct i2c_client *i2c, u8 reg, int count,
u8 *buf);
extern int max77775_write_reg(struct i2c_client *i2c, u8 reg, u8 value);
extern int max77775_write_reg_nolock(struct i2c_client *i2c, u8 reg, u8 value);
extern int max77775_bulk_write(struct i2c_client *i2c, u8 reg, int count,
u8 *buf);
extern int max77775_write_word(struct i2c_client *i2c, u8 reg, u16 value);
extern int max77775_read_word(struct i2c_client *i2c, u8 reg);
extern int max77775_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask);
/* MAX77775 check muic path function */
extern bool is_muic_usb_path_ap_usb(void);
extern bool is_muic_usb_path_cp_usb(void);
/* for charger api */
extern void max77775_hv_muic_charger_init(void);
extern int max77775_usbc_fw_update(struct max77775_dev *max77775, const u8 *fw_bin, int fw_bin_len, int enforce_do);
extern int max77775_usbc_fw_setting(struct max77775_dev *max77775, int enforce_do);
extern void max77775_register_pdmsg_func(struct max77775_dev *max77775,
void (*check_pdmsg)(void *, u8), void *data);
#define MAX77775_DEBUG_ENABLED
#ifdef MAX77775_DEBUG_ENABLED
#define msg_maxim(format, args...) \
md75_info_usb("max77775: %s: " format "\n", __func__, ## args)
#define err_maxim(format, args...) \
md75_err_usb("max77775: %s: " format "\n", __func__, ## args)
#else
#define msg_maxim(format, args...)
#define err_maxim(format, args...)
#endif // MAX77775_DEBUG_ENABLED
#endif /* __LINUX_MFD_MAX77775_PRIV_H */

View File

@@ -0,0 +1,121 @@
/*
* max77775.h - Driver for the Maxim 77775
*
* Copyright (C) 2016 Samsung Electrnoics
* Insun Choi <insun77.choi@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* This driver is based on max8997.h
*
* MAX77775 has Flash LED, SVC LED, Haptic, MUIC devices.
* The devices share the same I2C bus and included in
* this mfd driver.
*/
#ifndef __MAX77775_H__
#define __MAX77775_H__
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define MFD_DEV_NAME "max77775"
#define M2SH(m) ((m) & 0x0F ? ((m) & 0x03 ? ((m) & 0x01 ? 0 : 1) : ((m) & 0x04 ? 2 : 3)) : \
((m) & 0x30 ? ((m) & 0x10 ? 4 : 5) : ((m) & 0x40 ? 6 : 7)))
struct max77775_vibrator_pdata {
int gpio;
char *regulator_name;
struct pwm_device *pwm;
const char *motor_type;
int freq;
/* for multi-frequency */
int freq_nums;
u32 *freq_array;
u32 *ratio_array; /* not used now */
int normal_ratio;
int overdrive_ratio;
int high_temp_ratio;
int high_temp_ref;
int fold_open_ratio;
int fold_close_ratio;
#if defined(CONFIG_SEC_VIBRATOR)
bool calibration;
int steps;
int *intensities;
int *haptic_intensities;
#endif
};
struct max77775_regulator_data {
int id;
struct regulator_init_data *initdata;
struct device_node *reg_node;
};
struct max77775_platform_data {
/* IRQ */
int irq_base;
int irq_gpio;
bool wakeup;
bool blocking_waterevent;
bool extra_fw_enable;
int wpc_en;
u32 rev;
u32 fw_product_id;
u32 fg_resistor;
struct muic_platform_data *muic_pdata;
int num_regulators;
struct max77775_regulator_data *regulators;
struct max77775_vibrator_pdata *vibrator_data;
struct mfd_cell *sub_devices;
int num_subdevs;
bool support_audio;
char *wireless_charger_name;
};
struct max77775 {
struct regmap *regmap;
};
typedef struct {
u32 magic; /* magic number */
u8 major; /* major version */
u8 minor; /* minor version */
u8 id; /* id */
u8 rev; /* rev */
} max77775_fw_header;
#define MAX77775_SIGN 0xCEF166C1
enum {
FW_UPDATE_START = 0x00,
FW_UPDATE_WAIT_RESP_START,
FW_UPDATE_WAIT_RESP_STOP,
FW_UPDATE_DOING,
FW_UPDATE_END,
};
enum {
FW_UPDATE_FAIL = 0xF0,
FW_UPDATE_I2C_FAIL,
FW_UPDATE_TIMEOUT_FAIL,
FW_UPDATE_VERIFY_FAIL,
FW_UPDATE_CMD_FAIL,
FW_UPDATE_MAX_LENGTH_FAIL,
FW_UPDATE_ERR_CODE_FAIL,
};
#endif /* __MAX77775_H__ */

View File

@@ -0,0 +1,35 @@
/*
* max77775_log.h - Driver for the Maxim 77775
*
*/
#ifndef __MAX77775_LOG_H__
#define __MAX77775_LOG_H__
#ifdef CONFIG_USB_NOTIFY_PROC_LOG
#include <linux/usblog_proc_notify.h>
#endif
#ifdef CONFIG_USB_USING_ADVANCED_USBLOG
#define md75_info_usb(fmt, ...) \
({ \
pr_info(fmt, ##__VA_ARGS__); \
printk_usb(NOTIFY_PRINTK_USB_NORMAL, fmt, ##__VA_ARGS__); \
})
#define md75_err_usb(fmt, ...) \
({ \
pr_err(fmt, ##__VA_ARGS__); \
printk_usb(NOTIFY_PRINTK_USB_NORMAL, fmt, ##__VA_ARGS__); \
})
#else
#define md75_info_usb(fmt, ...) \
({ \
pr_info(fmt, ##__VA_ARGS__); \
})
#define md75_err_usb(fmt, ...) \
({ \
pr_err(fmt, ##__VA_ARGS__); \
})
#endif
#endif /* __MAX77775_LOG_H__ */

View File

@@ -0,0 +1,134 @@
/*
* s2mpb02-regulator.h - Voltage regulator driver for the Samsung s2mpb02
*
* Copyright (C) 2014 Samsung Electrnoics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_MFD_S2MPB02_REGULATOR_H
#define __LINUX_MFD_S2MPB02_REGULATOR_H
/* S2MPB02 registers */
enum s2mpb02_reg {
S2MPB02_REG_ID,
S2MPB02_REG_INT1,
S2MPB02_REG_INT1M,
S2MPB02_REG_ST1,
S2MPB02_REG_CTRL,
S2MPB02_REG_RSVD5,
S2MPB02_REG_RSVD6,
S2MPB02_REG_RSVD7,
S2MPB02_REG_RSVD8,
S2MPB02_REG_BBEN_DBT,
S2MPB02_REG_RSVDA,
S2MPB02_REG_B1CTRL1,
S2MPB02_REG_B1CTRL2,
S2MPB02_REG_B2CTRL1,
S2MPB02_REG_B2CTRL2,
S2MPB02_REG_BB1CTRL1,
S2MPB02_REG_BB1CTRL2,
S2MPB02_REG_BUCK_RAMP,
S2MPB02_REG_FLED_CTRL1,
S2MPB02_REG_FLED_CTRL2,
S2MPB02_REG_FLED_CUR1,
S2MPB02_REG_FLED_TIME1,
S2MPB02_REG_FLED_CUR2,
S2MPB02_REG_FLED_TIME2,
S2MPB02_REG_FLED_IRON1,
S2MPB02_REG_FLED_IRON2,
S2MPB02_REG_FLED_IRD1,
S2MPB02_REG_FLED_IRD2,
S2MPB02_REG_BST_CTRL1,
S2MPB02_REG_BST_CTRL2,
S2MPB02_REG_L1CTRL,
S2MPB02_REG_L2CTRL,
S2MPB02_REG_L3CTRL,
S2MPB02_REG_L4CTRL,
S2MPB02_REG_L5CTRL,
S2MPB02_REG_L6CTRL,
S2MPB02_REG_L7CTRL,
S2MPB02_REG_L8CTRL,
S2MPB02_REG_L9CTRL,
S2MPB02_REG_L10CTRL,
S2MPB02_REG_L11CTRL,
S2MPB02_REG_L12CTRL,
S2MPB02_REG_L13CTRL,
S2MPB02_REG_L14CTRL,
S2MPB02_REG_L15CTRL,
S2MPB02_REG_L16CTRL,
S2MPB02_REG_L17CTRL,
S2MPB02_REG_L18CTRL,
S2MPB02_REG_LDO_DSCH1,
S2MPB02_REG_LDO_DSCH2,
S2MPB02_REG_LDO_DSCH3,
};
/* S2MPB02 regulator ids */
enum S2MPB02_regulators {
S2MPB02_LDO1,
S2MPB02_LDO2,
S2MPB02_LDO3,
S2MPB02_LDO4,
S2MPB02_LDO5,
S2MPB02_LDO6,
S2MPB02_LDO7,
S2MPB02_LDO8,
S2MPB02_LDO9,
S2MPB02_LDO10,
S2MPB02_LDO11,
S2MPB02_LDO12,
S2MPB02_LDO13,
S2MPB02_LDO14,
S2MPB02_LDO15,
S2MPB02_LDO16,
S2MPB02_LDO17,
S2MPB02_LDO18,
S2MPB02_BUCK1,
S2MPB02_BUCK2,
S2MPB02_BB1,
S2MPB02_REG_MAX,
};
#define S2MPB02_BUCK_MIN1 400000
#define S2MPB02_BUCK_MIN2 2600000
#define S2MPB02_LDO_MIN1 600000
#define S2MPB02_BUCK_STEP1 6250
#define S2MPB02_BUCK_STEP2 12500
#define S2MPB02_LDO_STEP1 12500
#define S2MPB02_LDO_STEP2 25000
#define S2MPB02_LDO_VSEL_MASK 0x7F
#define S2MPB02_BUCK_VSEL_MASK 0xFF
#define S2MPB02_BUCK_ENABLE_MASK 0xC0
#define S2MPB02_LDO_ENABLE_MASK 0x80
#define S2MPB02_RAMP_DELAY 12000
#define S2MPB02_ENABLE_TIME_LDO 180
#define S2MPB02_ENABLE_TIME_BUCK 100
#define S2MPB02_ENABLE_TIME_BB 210
#define S2MPB02_BUCK_ENABLE_SHIFT 0x06
#define S2MPB02_LDO_ENABLE_SHIFT 0x07
#define S2MPB02_LDO_N_VOLTAGES (S2MPB02_LDO_VSEL_MASK + 1)
#define S2MPB02_BUCK_N_VOLTAGES (S2MPB02_BUCK_VSEL_MASK + 1)
#define S2MPB02_REGULATOR_MAX (S2MPB02_REG_MAX)
#define DVS_DEFAULT_VALUE (0x90)
#endif /* __LINUX_MFD_S2MPB02_PRIV_H */

View File

@@ -0,0 +1,121 @@
/*
* s2mpb02.h - Driver for the Samsung s2mpb02
*
* Copyright (C) 2014 Samsung Electrnoics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* S2MPB02 has Flash LED devices.
* The devices share the same I2C bus and included in
* this mfd driver.
*/
#ifndef __S2MPB02_H__
#define __S2MPB02_H__
#include <linux/i2c.h>
#define MFD_DEV_NAME "s2mpb02"
#define S2MPB02_I2C_ADDR (0xB2 >> 1)
#define S2MPB02_REG_INVALID (0xff)
#define S2MPB02_PMIC_REV(iodev) (iodev)->rev_num
enum s2mpb02_types {
TYPE_S2MPB02,
};
enum s2mpb02_reg_types {
TYPE_S2MPB02_REG_MAIN = 0,
TYPE_S2MPB02_REG_SUB,
TYPE_S2MPB02_REG_MAX
};
enum s2mpb02_irq_source {
LED_INT = 0,
S2MPB02_IRQ_GROUP_NR,
};
enum s2mpb02_irq {
/* FLASH */
S2MPB02_LED_IRQ_IRLED_END,
S2MPB02_IRQ_NR,
};
struct s2mpb02_dev {
struct device *dev;
struct i2c_client *i2c; /* 0xB2; PMIC, Flash LED */
struct mutex i2c_lock;
int type;
u8 rev_num; /* pmic Rev */
int irq;
int irq_base;
int irq_gpio;
bool wakeup;
struct mutex irqlock;
int irq_masks_cur[S2MPB02_IRQ_GROUP_NR];
int irq_masks_cache[S2MPB02_IRQ_GROUP_NR];
struct s2mpb02_platform_data *pdata;
};
#ifdef CONFIG_LEDS_S2MPB02
struct s2mpb02_led_platform_data;
#endif
struct s2mpb02_regulator_data {
int id;
struct regulator_init_data *initdata;
struct device_node *reg_node;
};
struct s2mpb02_platform_data {
/* IRQ */
int irq_base;
int irq_gpio;
bool wakeup;
bool need_recovery;;
int num_regulators;
int num_rdata;
struct s2mpb02_regulator_data *regulators;
#ifdef CONFIG_LEDS_S2MPB02
/* led (flash/torch) data */
struct s2mpb02_led_platform_data *led_data;
#endif
int devs_num;
struct mfd_cell *devs;
};
extern int s2mpb02_irq_init(struct s2mpb02_dev *s2mpb02);
extern void s2mpb02_irq_exit(struct s2mpb02_dev *s2mpb02);
extern int s2mpb02_irq_resume(struct s2mpb02_dev *s2mpb02);
/* S2MPB02 shared i2c API function */
extern int s2mpb02_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
extern int s2mpb02_bulk_read(struct i2c_client *i2c, u8 reg, int count,
u8 *buf);
extern int s2mpb02_write_reg(struct i2c_client *i2c, u8 reg, u8 value);
extern int s2mpb02_bulk_write(struct i2c_client *i2c, u8 reg, int count,
u8 *buf);
extern int s2mpb02_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask);
#endif /* __S2MPB02_H__ */

43
include/linux/mfd/sec_ap_pmic.h Executable file
View File

@@ -0,0 +1,43 @@
#ifndef __SEC_AP_PMIC_H__
#define __SEC_AP_PMIC_H__
#define SEC_PON_KEY_CNT 2
struct sec_ap_pmic_info {
struct device *dev;
struct notifier_block sec_pm_debug_nb;
struct delayed_work ws_work;
unsigned int ws_log_period;
/* ocp warn */
int ocp_warn_gpio;
int ocp_warn_irq;
int ocpw_cnt;
int ocpw_cnt_reset_offset;
ktime_t ocpw_start_time;
int ocpw_time; /* accumulated */
int ocpw_time_reset_offset;
};
enum sec_pon_type {
SEC_PON_KPDPWR = 0,
SEC_PON_RESIN,
SEC_PON_KPDPWR_RESIN,
};
/* for enable/disable manual reset, from retail group's request */
extern int sec_get_s2_reset(enum sec_pon_type type);
extern int sec_set_pm_key_wk_init(enum sec_pon_type type, int en);
extern int sec_get_pm_key_wk_init(enum sec_pon_type type);
extern void msm_gpio_print_enabled(void);
extern void pmic_gpio_sec_dbg_enabled(void);
#if IS_ENABLED(CONFIG_SEC_GPIO_DUMP)
extern void sec_ap_gpio_debug_print(void);
extern void sec_pmic_gpio_debug_print(void);
static bool gpio_dump_enabled;
#endif
#endif /* __SEC_AP_PMIC_H__ */

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
*
*/
#ifndef _MHI_H_
@@ -15,6 +15,9 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
/* MHI client drivers to set this upper bound for tx buffer */
#define MHI_MAX_MTU 0xffff
#define MHI_MAX_OEM_PK_HASH_SEGMENTS 16
struct mhi_chan;
@@ -34,6 +37,8 @@ struct mhi_buf_info;
* @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
* @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
* @MHI_CB_BW_REQ: Received a bandwidth switch request from device
* @MHI_CB_DTR_SIGNAL: DTR signaling update
* @MHI_CB_DTR_START_CHANNELS: DTR signal for client driver to start channels
*/
enum mhi_callback {
MHI_CB_IDLE,
@@ -45,6 +50,8 @@ enum mhi_callback {
MHI_CB_SYS_ERROR,
MHI_CB_FATAL_ERROR,
MHI_CB_BW_REQ,
MHI_CB_DTR_SIGNAL,
MHI_CB_DTR_START_CHANNELS,
};
/**
@@ -102,10 +109,12 @@ struct image_info {
* struct mhi_link_info - BW requirement
* target_link_speed - Link speed as defined by TLS bits in LinkControl reg
* target_link_width - Link width as defined by NLW bits in LinkStatus reg
* sequence_num - used by device to track bw requests sent to host
*/
struct mhi_link_info {
unsigned int target_link_speed;
unsigned int target_link_width;
int sequence_num;
};
/**
@@ -183,10 +192,26 @@ enum mhi_ch_ee_mask {
* enum mhi_er_data_type - Event ring data types
* @MHI_ER_DATA: Only client data over this ring
* @MHI_ER_CTRL: MHI control data and client data
* @MHI_ER_BW_SCALE: MHI controller bandwidth scale functionality
* @MHI_ER_TIMESYNC: MHI controller time synchronization DB mode functionality
*/
enum mhi_er_data_type {
MHI_ER_DATA,
MHI_ER_CTRL,
MHI_ER_BW_SCALE,
MHI_ER_TIMESYNC,
};
/**
* enum mhi_er_priority - Event ring processing priority
* @MHI_ER_PRIORITY_DEFAULT_NOSLEEP: processed by tasklet
* @MHI_ER_PRIORITY_HI_NOSLEEP: processed by hi-priority tasklet
* @MHI_ER_PRIORITY_HI_SLEEP: processed by hi-priority wq
*/
enum mhi_er_priority {
MHI_ER_PRIORITY_DEFAULT_NOSLEEP,
MHI_ER_PRIORITY_HI_NOSLEEP,
MHI_ER_PRIORITY_HI_SLEEP,
};
/**
@@ -242,7 +267,7 @@ struct mhi_channel_config {
* @irq_moderation_ms: Delay irq for additional events to be aggregated
* @irq: IRQ associated with this ring
* @channel: Dedicated channel number. U32_MAX indicates a non-dedicated ring
* @priority: Priority of this ring. Use 1 for now
* @priority: Processing priority of this ring.
* @mode: Doorbell mode
* @data_type: Type of data this ring will process
* @hardware_event: This ring is associated with hardware channels
@@ -296,6 +321,7 @@ struct mhi_controller_config {
* @bhi: Points to base of MHI BHI register space
* @bhie: Points to base of MHI BHIe register space
* @wake_db: MHI WAKE doorbell register address
* @host_notify_db: MHI host notification db address
* @iova_start: IOMMU starting address for data (required)
* @iova_stop: IOMMU stop address for data (required)
* @fw_image: Firmware image name for normal booting (optional)
@@ -310,6 +336,7 @@ struct mhi_controller_config {
* @reg_len: Length of the MHI MMIO region (required)
* @fbc_image: Points to firmware image buffer
* @rddm_image: Points to RAM dump buffer
* @tme_supported_image: Flag to make decision about firmware download start address (optional)
* @mhi_chan: Points to the channel configuration table
* @lpm_chans: List of channels that require LPM notifications
* @irq: base irq # to request (required)
@@ -336,7 +363,7 @@ struct mhi_controller_config {
* @dev_state: MHI device state
* @dev_wake: Device wakeup count
* @pending_pkts: Pending packets for the controller
* @M0, M2, M3: Counters to track number of device MHI state changes
* @M0, M2, M3, M3_fast: Counters to track number of device MHI state changes
* @transition_list: List of MHI state transitions
* @transition_lock: Lock for protecting MHI state transition list
* @wlock: Lock for protecting device wakeup
@@ -350,6 +377,7 @@ struct mhi_controller_config {
* @wake_toggle: CB function to assert and de-assert device wake (optional)
* @runtime_get: CB function to controller runtime resume (required)
* @runtime_put: CB function to decrement pm usage (required)
* @runtime_last_busy: CB function for controller to mark last busy (optional)
* @map_single: CB function to create TRE buffer
* @unmap_single: CB function to destroy TRE buffer
* @read_reg: Read a MHI register via the physical link (required)
@@ -357,6 +385,7 @@ struct mhi_controller_config {
* @reset: Controller specific reset function (optional)
* @buffer_len: Bounce buffer length
* @index: Index of the MHI controller instance
* @img_pre_alloc: allocate rddm and fbc image buffers one time
* @bounce_buf: Use of bounce buffer
* @fbc_download: MHI host needs to do complete image transfer (optional)
* @wake_set: Device wakeup set flag
@@ -384,6 +413,7 @@ struct mhi_controller {
void __iomem *bhi;
void __iomem *bhie;
void __iomem *wake_db;
void __iomem *host_notify_db;
dma_addr_t iova_start;
dma_addr_t iova_stop;
@@ -397,6 +427,7 @@ struct mhi_controller {
size_t reg_len;
struct image_info *fbc_image;
struct image_info *rddm_image;
bool tme_supported_image;
struct mhi_chan *mhi_chan;
struct list_head lpm_chans;
int *irq;
@@ -425,7 +456,7 @@ struct mhi_controller {
enum mhi_state dev_state;
atomic_t dev_wake;
atomic_t pending_pkts;
u32 M0, M2, M3;
u32 M0, M2, M3, M3_fast;
struct list_head transition_list;
spinlock_t transition_lock;
spinlock_t wlock;
@@ -441,6 +472,7 @@ struct mhi_controller {
void (*wake_toggle)(struct mhi_controller *mhi_cntrl);
int (*runtime_get)(struct mhi_controller *mhi_cntrl);
void (*runtime_put)(struct mhi_controller *mhi_cntrl);
void (*runtime_last_busy)(struct mhi_controller *mhi_cntrl);
int (*map_single)(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf);
void (*unmap_single)(struct mhi_controller *mhi_cntrl,
@@ -453,6 +485,7 @@ struct mhi_controller {
size_t buffer_len;
int index;
bool img_pre_alloc;
bool bounce_buf;
bool fbc_download;
bool wake_set;
@@ -471,8 +504,11 @@ struct mhi_controller {
* @dev: Driver model device node for the MHI device
* @dev_type: MHI device type
* @ul_chan_id: MHI channel id for UL transfer
* @ul_event_id: MHI event ring id for UL transfer
* @dl_chan_id: MHI channel id for DL transfer
* @ul_event_id: MHI event ring id for DL transfer
* @dev_wake: Device wakeup counter
* @tiocm: Device current terminal settings
*/
struct mhi_device {
const struct mhi_device_id *id;
@@ -483,8 +519,11 @@ struct mhi_device {
struct device dev;
enum mhi_device_type dev_type;
int ul_chan_id;
int ul_event_id;
int dl_chan_id;
int dl_event_id;
u32 dev_wake;
u32 tiocm;
};
/**

686
include/linux/mhi_misc.h Normal file
View File

@@ -0,0 +1,686 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */
#ifndef _MHI_MISC_H_
#define _MHI_MISC_H_
#include <linux/mhi.h>
#include <linux/ipc_logging.h>
/**
* enum MHI_DEBUG_LEVEL - various debugging levels
*/
enum MHI_DEBUG_LEVEL {
MHI_MSG_LVL_VERBOSE,
MHI_MSG_LVL_INFO,
MHI_MSG_LVL_ERROR,
MHI_MSG_LVL_CRITICAL,
MHI_MSG_LVL_MASK_ALL,
MHI_MSG_LVL_MAX,
};
/**
* struct mhi_buf - MHI Buffer description
* @node: list entry point
* @buf: Virtual address of the buffer
* @name: Buffer label. For offload channel, configurations name must be:
* ECA - Event context array data
* CCA - Channel context array data
* @dma_addr: IOMMU address of the buffer
* @phys_addr: physical address of the buffer
* @len: # of bytes
* @is_io: buffer is of IO/registesr type (resource) rather than of DDR/RAM type
*/
struct mhi_buf_extended {
struct list_head node;
void *buf;
const char *name;
dma_addr_t dma_addr;
phys_addr_t phys_addr;
size_t len;
bool is_io;
};
#ifdef CONFIG_MHI_BUS_MISC
/**
* mhi_report_error - Can be used by controller to signal error condition to the
* MHI core driver in case of any need to halt processing or incoming sideband
* signal detects an error on endpoint
* @mhi_cntrl: MHI controller
*
* Returns:
* 0 if success in reporting the error condition to MHI core
* error code on failure
*/
int mhi_report_error(struct mhi_controller *mhi_cntrl);
/**
* mhi_controller_set_privdata - Set private data for MHI controller
* @mhi_cntrl: MHI controller
* @priv: pointer to data
*/
void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv);
/**
* mhi_controller_get_privdata - Get private data from MHI controller
* @mhi_cntrl: MHI controller
*/
void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl);
/**
* mhi_bdf_to_controller - Get controller associated with given BDF values
* @domain: Domain or root complex of PCIe port
* @bus: Bus number
* @slot: PCI slot or function number
* @dev_id: Device ID of the endpoint
*
* Returns:
* MHI controller structure pointer if BDF match is found
* NULL if cookie is not found
*/
struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id);
/**
* mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
* fast/silent suspend
* @mhi_cntrl: MHI controller
* @timeout: timeout in ms
*/
void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout);
/**
* mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
* @mhi_cntrl: MHI controller
* @notify_clients: if true, clients will be notified of the resume transition
*/
int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients);
/**
* mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
* @mhi_cntrl: MHI controller
* @notify_clients: if true, clients will be notified of the suspend transition
*/
int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients);
/**
* mhi_debug_reg_dump - dump MHI registers for debug purpose
* @mhi_cntrl: MHI controller
*/
void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl);
/**
* mhi_dump_sfr - Print SFR string from RDDM table.
* @mhi_cntrl: MHI controller
*/
void mhi_dump_sfr(struct mhi_controller *mhi_cntrl);
/**
* mhi_device_configure - Allow devices with offload channels to setup their own
* channel and event ring context.
* @mhi_dev: MHI device
* @dir: direction associated with the channel needed to configure
* @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
* @elements: Number of items to iterate over from the configuration table
*/
int mhi_device_configure(struct mhi_device *mhi_dev,
enum dma_data_direction dir,
struct mhi_buf *cfg_tbl,
int elements);
/**
* mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
* registers set by device to indicate rddm readiness for debugging purposes.
* @mhi_cntrl: MHI controller
* @cookie: cookie/pattern value to match
*
* Returns:
* true if cookie is found
* false if cookie is not found
*/
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie);
/**
* mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
* @mhi_dev: Device associated with the channels
* @timeout_us: timeout, in micro-seconds
* @in_panic: If requested while kernel is in panic state and no ISRs expected
*
* The device_wake is asserted to keep device in M0 or bring it to M0.
* If device is not in M0 state, then this function will wait for device to
* move to M0, until @timeout_us elapses.
* However, if device's M1 state-change event races with this function
* then there is a possiblity of device moving from M0 to M2 and back
* to M0. That can't be avoided as host must transition device from M1 to M2
* as per the spec.
* Clients can ignore that transition after this function returns as the device
* is expected to immediately move from M2 to M0 as wake is asserted and
* wouldn't enter low power state.
* If in_panic boolean is set, no ISRs are expected, hence this API will have to
* resort to reading the MHI status register and poll on M0 state change.
*
* Returns:
* 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
* mentioned above.
* -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
* -EIO if the MHI state is one of the ERROR states.
*/
int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
bool in_panic);
/**
* mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
* @mhi_cntrl: MHI controller
* @cb_func: Callback to set for the MHI controller to receive BW scale requests
*/
void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
int (*cb_func)(struct mhi_controller *mhi_cntrl,
struct mhi_link_info *link_info));
/**
* mhi_controller_set_base - Set the controller base / resource start address
* @mhi_cntrl: MHI controller
* @base: Physical address to be set for future reference
*/
void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
phys_addr_t base);
/**
* mhi_controller_get_base - Get the controller base / resource start address
* @mhi_cntrl: MHI controller
* @base: Pointer to physical address to be populated
*/
int mhi_controller_get_base(struct mhi_controller *mhi_cntrl,
phys_addr_t *base);
/**
* mhi_controller_get_numeric_id - set numeric ID for controller
* @mhi_cntrl: MHI controller
* returns value set as ID or 0 if no value was set
*/
u32 mhi_controller_get_numeric_id(struct mhi_controller *mhi_cntrl);
/**
* mhi_get_channel_db_base - retrieve the channel doorbell base address
* @mhi_dev: Device associated with the channels
* @value: Pointer to an address value which will be populated
*/
int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
/**
* mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
* @mhi_dev: Device associated with the channels
* @value: Pointer to an address value which will be populated
*/
int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value);
/**
* mhi_get_device_for_channel - get the MHI device for a specific channel number
* @mhi_cntrl: MHI controller
* @channel - channel number
*
* Returns:
* Pointer to the MHI device associated with the channel
*/
struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
u32 channel);
/**
* mhi_device_ioctl - user space IOCTL support for MHI channels
* Native support for setting TIOCM
* @mhi_dev: Device associated with the channels
* @cmd: IOCTL cmd
* @arg: Optional parameter, iotcl cmd specific
*/
long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
unsigned long arg);
/**
* mhi_controller_set_sfr_support - Set support for subsystem failure reason
* @mhi_cntrl: MHI controller
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
size_t len);
/**
* mhi_controller_setup_timesync - Set support for time synchronization feature
* @mhi_cntrl: MHI controller
* @time_get: Callback to set for the MHI controller to receive host time
* @lpm_disable: Callback to set for the MHI controller to disable link LPM
* @lpm_enable: Callback to set for the MHI controller to enable link LPM
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
u64 (*time_get)(struct mhi_controller *c),
int (*lpm_disable)(struct mhi_controller *c),
int (*lpm_enable)(struct mhi_controller *c));
/**
* mhi_get_remote_time_sync - Get external soc time relative to local soc time
* using MMIO method.
* @mhi_dev: Device associated with the channels
* @t_host: Pointer to output local soc time
* @t_dev: Pointer to output remote soc time
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
u64 *t_host,
u64 *t_dev);
/**
* mhi_get_remote_time - Get external modem time relative to host time
* Trigger event to capture modem time, also capture host time so client
* can do a relative drift comparision.
* Recommended only tsync device calls this method and do not call this
* from atomic context
* @mhi_dev: Device associated with the channels
* @sequence:unique sequence id track event
* @cb_func: callback function to call back
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_get_remote_time(struct mhi_device *mhi_dev,
u32 sequence,
void (*cb_func)(struct mhi_device *mhi_dev,
u32 sequence,
u64 local_time,
u64 remote_time));
/**
* mhi_force_reset - does host reset request to collect device side dumps
* for debugging purpose
* @mhi_cntrl: MHI controller
*/
int mhi_force_reset(struct mhi_controller *mhi_cntrl);
/**
* mhi_controller_set_loglevel - API for controller to set a desired log level
* which will be set to VERBOSE or 0 by default
* @mhi_cntrl: MHI controller
* @lvl: Log level from MHI_DEBUG_LEVEL enumerator
*/
void mhi_controller_set_loglevel(struct mhi_controller *mhi_cntrl,
enum MHI_DEBUG_LEVEL lvl);
/**
* mhi_get_soc_info - Get SoC info before registering mhi controller
* @mhi_cntrl: MHI controller
*/
int mhi_get_soc_info(struct mhi_controller *mhi_cntrl);
/**
* mhi_host_notify_db_disable_trace - Host notification to ring channel DB
* to MHI device to stop tracing due SMMU fault
* @mhi_cntrl: MHI controller
*/
int mhi_host_notify_db_disable_trace(struct mhi_controller *mhi_cntrl);
#else
/**
* mhi_report_error - Can be used by controller to signal error condition to the
* MHI core driver in case of any need to halt processing or incoming sideband
* signal detects an error on endpoint
* @mhi_cntrl: MHI controller
*
* Returns:
* 0 if success in reporting the error condition to MHI core
* error code on failure
*/
static inline int mhi_report_error(struct mhi_controller *mhi_cntrl)
{
return -EPERM;
}
/**
* mhi_controller_set_privdata - Set private data for MHI controller
* @mhi_cntrl: MHI controller
* @priv: pointer to data
*/
void mhi_controller_set_privdata(struct mhi_controller *mhi_cntrl, void *priv)
{
}
/**
* mhi_controller_get_privdata - Get private data from MHI controller
* @mhi_cntrl: MHI controller
*/
void *mhi_controller_get_privdata(struct mhi_controller *mhi_cntrl)
{
return ERR_PTR(-EINVAL);
}
/**
* mhi_bdf_to_controller - Get controller associated with given BDF values
* @domain: Domain or root complex of PCIe port
* @bus: Bus number
* @slot: PCI slot or function number
* @dev_id: Device ID of the endpoint
*
* Returns:
* MHI controller structure pointer if BDF match is found
* NULL if cookie is not found
*/
struct mhi_controller *mhi_bdf_to_controller(u32 domain, u32 bus, u32 slot, u32 dev_id)
{
return ERR_PTR(-EINVAL);
}
/**
* mhi_set_m2_timeout_ms - Set M2 timeout in milliseconds to wait before a
* fast/silent suspend
* @mhi_cntrl: MHI controller
* @timeout: timeout in ms
*/
void mhi_set_m2_timeout_ms(struct mhi_controller *mhi_cntrl, u32 timeout)
{
}
/**
* mhi_pm_fast_resume - Resume MHI from a fast/silent suspended state
* @mhi_cntrl: MHI controller
* @notify_clients: if true, clients will be notified of the resume transition
*/
int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_clients)
{
return -EPERM;
}
/**
* mhi_pm_fast_suspend - Move MHI into a fast/silent suspended state
* @mhi_cntrl: MHI controller
* @notify_clients: if true, clients will be notified of the suspend transition
*/
int mhi_pm_fast_suspend(struct mhi_controller *mhi_cntrl, bool notify_clients)
{
return -EPERM;
}
/**
* mhi_debug_reg_dump - dump MHI registers for debug purpose
* @mhi_cntrl: MHI controller
*/
void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl)
{
}
/**
* mhi_dump_sfr - Print SFR string from RDDM table.
* @mhi_cntrl: MHI controller
*/
void mhi_dump_sfr(struct mhi_controller *mhi_cntrl)
{
}
/**
* mhi_device_configure - Allow devices with offload channels to setup their own
* channel and event ring context.
* @mhi_dev: MHI device
* @dir: direction associated with the channel needed to configure
* @cfg_tbl: Buffer with ECA/CCA information and data needed to setup context
* @elements: Number of items to iterate over from the configuration table
*/
int mhi_device_configure(struct mhi_device *mhi_dev,
enum dma_data_direction dir,
struct mhi_buf *cfg_tbl,
int elements)
{
return -EPERM;
}
/**
* mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
* registers set by device to indicate rddm readiness for debugging purposes.
* @mhi_cntrl: MHI controller
* @cookie: cookie/pattern value to match
*
* Returns:
* true if cookie is found
* false if cookie is not found
*/
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
{
return false;
}
/**
* mhi_device_get_sync_atomic - Asserts device_wait and moves device to M0
* @mhi_dev: Device associated with the channels
* @timeout_us: timeout, in micro-seconds
* @in_panic: If requested while kernel is in panic state and no ISRs expected
*
* The device_wake is asserted to keep device in M0 or bring it to M0.
* If device is not in M0 state, then this function will wait for device to
* move to M0, until @timeout_us elapses.
* However, if device's M1 state-change event races with this function
* then there is a possiblity of device moving from M0 to M2 and back
* to M0. That can't be avoided as host must transition device from M1 to M2
* as per the spec.
* Clients can ignore that transition after this function returns as the device
* is expected to immediately move from M2 to M0 as wake is asserted and
* wouldn't enter low power state.
* If in_panic boolean is set, no ISRs are expected, hence this API will have to
* resort to reading the MHI status register and poll on M0 state change.
*
* Returns:
* 0 if operation was successful (however, M0 -> M2 -> M0 is possible later) as
* mentioned above.
* -ETIMEDOUT is device faled to move to M0 before @timeout_us elapsed
* -EIO if the MHI state is one of the ERROR states.
*/
int mhi_device_get_sync_atomic(struct mhi_device *mhi_dev, int timeout_us,
bool in_panic)
{
return -EPERM;
}
/**
* mhi_controller_set_bw_scale_cb - Set the BW scale callback for MHI controller
* @mhi_cntrl: MHI controller
* @cb_func: Callback to set for the MHI controller to receive BW scale requests
*/
void mhi_controller_set_bw_scale_cb(struct mhi_controller *mhi_cntrl,
int (*cb_func)(struct mhi_controller *mhi_cntrl,
struct mhi_link_info *link_info))
{
}
/**
* mhi_controller_set_base - Set the controller base / resource start address
* @mhi_cntrl: MHI controller
* @base: Physical address to be set for future reference
*/
void mhi_controller_set_base(struct mhi_controller *mhi_cntrl,
phys_addr_t base)
{
}
/**
* mhi_controller_get_base - Get the controller base / resource start address
* @mhi_cntrl: MHI controller
* @base: Pointer to physical address to be populated
*/
int mhi_controller_get_base(struct mhi_controller *mhi_cntrl,
phys_addr_t *base)
{
return -EINVAL;
}
/**
* mhi_controller_get_numeric_id - set numeric ID for controller
* @mhi_cntrl: MHI controller
* returns value set as ID or 0 if no value was set
*/
u32 mhi_controller_get_numeric_id(struct mhi_controller *mhi_cntrl)
{
return 0;
}
/**
* mhi_get_channel_db_base - retrieve the channel doorbell base address
* @mhi_dev: Device associated with the channels
* @value: Pointer to an address value which will be populated
*/
int mhi_get_channel_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
{
return -EPERM;
}
/**
* mhi_get_event_ring_db_base - retrieve the event ring doorbell base address
* @mhi_dev: Device associated with the channels
* @value: Pointer to an address value which will be populated
*/
int mhi_get_event_ring_db_base(struct mhi_device *mhi_dev, phys_addr_t *value)
{
return -EPERM;
}
/**
* mhi_get_device_for_channel - get the MHI device for a specific channel number
* @mhi_cntrl: MHI controller
* @channel - channel number
*
* Returns:
* Pointer to the MHI device associated with the channel
*/
struct mhi_device *mhi_get_device_for_channel(struct mhi_controller *mhi_cntrl,
u32 channel)
{
return ERR_PTR(-EINVAL);
}
/**
* mhi_device_ioctl - user space IOCTL support for MHI channels
* Native support for setting TIOCM
* @mhi_dev: Device associated with the channels
* @cmd: IOCTL cmd
* @arg: Optional parameter, iotcl cmd specific
*/
long mhi_device_ioctl(struct mhi_device *mhi_dev, unsigned int cmd,
unsigned long arg)
{
return -EPERM;
}
/**
* mhi_controller_set_sfr_support - Set support for subsystem failure reason
* @mhi_cntrl: MHI controller
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_controller_set_sfr_support(struct mhi_controller *mhi_cntrl,
size_t len)
{
return -EPERM;
}
/**
* mhi_controller_setup_timesync - Set support for time synchronization feature
* @mhi_cntrl: MHI controller
* @time_get: Callback to set for the MHI controller to receive host time
* @lpm_disable: Callback to set for the MHI controller to disable link LPM
* @lpm_enable: Callback to set for the MHI controller to enable link LPM
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_controller_setup_timesync(struct mhi_controller *mhi_cntrl,
u64 (*time_get)(struct mhi_controller *c),
int (*lpm_disable)(struct mhi_controller *c),
int (*lpm_enable)(struct mhi_controller *c))
{
return -EPERM;
}
/**
* mhi_get_remote_time_sync - Get external soc time relative to local soc time
* using MMIO method.
* @mhi_dev: Device associated with the channels
* @t_host: Pointer to output local soc time
* @t_dev: Pointer to output remote soc time
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_get_remote_time_sync(struct mhi_device *mhi_dev,
u64 *t_host,
u64 *t_dev)
{
return -EPERM;
}
/**
* mhi_get_remote_time - Get external modem time relative to host time
* Trigger event to capture modem time, also capture host time so client
* can do a relative drift comparision.
* Recommended only tsync device calls this method and do not call this
* from atomic context
* @mhi_dev: Device associated with the channels
* @sequence:unique sequence id track event
* @cb_func: callback function to call back
*
* Returns:
* 0 for success, error code for failure
*/
int mhi_get_remote_time(struct mhi_device *mhi_dev,
u32 sequence,
void (*cb_func)(struct mhi_device *mhi_dev,
u32 sequence,
u64 local_time,
u64 remote_time))
{
return -EPERM;
}
/**
* mhi_force_reset - does host reset request to collect device side dumps
* for debugging purpose
* @mhi_cntrl: MHI controller
*/
int mhi_force_reset(struct mhi_controller *mhi_cntrl)
{
return -EINVAL;
}
/**
* mhi_controller_set_loglevel - API for controller to set a desired log level
* which will be set to VERBOSE or 0 by default
* @mhi_cntrl: MHI controller
* @lvl: Log level from MHI_DEBUG_LEVEL enumerator
*/
void mhi_controller_set_loglevel(struct mhi_controller *mhi_cntrl,
enum MHI_DEBUG_LEVEL lvl)
{
}
/**
* mhi_get_soc_info - Get SoC info before registering mhi controller
* @mhi_cntrl: MHI controller
*/
int mhi_get_soc_info(struct mhi_controller *mhi_cntrl)
{
return -EINVAL;
}
/**
* mhi_host_notify_db_disable_trace - Host notification to ring channel DB
* to MHI device to stop tracing due SMMU fault
* @mhi_cntrl: MHI controller
*/
int mhi_host_notify_db_disable_trace(struct mhi_controller *mhi_cntrl)
{
return -EPERM;
}
#endif /* CONFIG_MHI_BUS_MISC */
#endif /* _MHI_MISC_H_ */

1665
include/linux/msm-sps.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2016, 2018, 2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_MSM_DMA_IOMMU_MAPPING_H
#define _LINUX_MSM_DMA_IOMMU_MAPPING_H
#include <linux/device.h>
#include <linux/dma-buf.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/qcom-dma-mapping.h>
#if IS_ENABLED(CONFIG_QCOM_LAZY_MAPPING)
/*
* This function is not taking a reference to the dma_buf here. It is expected
* that clients hold reference to the dma_buf until they are done with mapping
* and unmapping.
*/
int msm_dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir, struct dma_buf *dma_buf,
unsigned long attrs);
/*
* This function takes an extra reference to the dma_buf.
* What this means is that calling msm_dma_unmap_sg will not result in buffer's
* iommu mapping being removed, which means that subsequent calls to lazy map
* will simply re-use the existing iommu mapping.
* The iommu unmapping of the buffer will occur when the ION buffer is
* destroyed.
* Using lazy mapping can provide a performance benefit because subsequent
* mappings are faster.
*
* The limitation of using this API are that all subsequent iommu mappings
* must be the same as the original mapping, ie they must map the same part of
* the buffer with the same dma data direction. Also there can't be multiple
* mappings of different parts of the buffer.
*/
static inline int msm_dma_map_sg_lazy(struct device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction dir,
struct dma_buf *dma_buf)
{
return msm_dma_map_sg_attrs(dev, sg, nents, dir, dma_buf, 0);
}
static inline int msm_dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir,
struct dma_buf *dma_buf)
{
unsigned long attrs;
attrs = DMA_ATTR_NO_DELAYED_UNMAP;
return msm_dma_map_sg_attrs(dev, sg, nents, dir, dma_buf, attrs);
}
void msm_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs);
static inline int msm_dma_map_sgtable(struct device *dev, struct sg_table *sgt,
enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs)
{
int nents;
nents = msm_dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, dma_buf, attrs);
if (nents < 0)
return nents;
else if (unlikely(nents == 0))
return -EINVAL;
sgt->nents = nents;
return 0;
}
static inline void msm_dma_unmap_sgtable(struct device *dev, struct sg_table *sgt,
enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs)
{
msm_dma_unmap_sg_attrs(dev, sgt->sgl, sgt->nents, dir, dma_buf, attrs);
}
int msm_dma_unmap_all_for_dev(struct device *dev);
/*
* Below is private function only to be called by framework (ION) and not by
* clients.
*/
void msm_dma_buf_freed(void *buffer);
#else /*CONFIG_QCOM_LAZY_MAPPING*/
static inline int msm_dma_map_sg_attrs(struct device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction dir, struct dma_buf *dma_buf,
unsigned long attrs)
{
return -EINVAL;
}
static inline void
msm_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs)
{
}
static inline int msm_dma_map_sg_lazy(struct device *dev,
struct scatterlist *sg, int nents,
enum dma_data_direction dir,
struct dma_buf *dma_buf)
{
return -EINVAL;
}
static inline int msm_dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir,
struct dma_buf *dma_buf)
{
return -EINVAL;
}
static inline int msm_dma_map_sgtable(struct device *dev, struct sg_table *sgt,
enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs)
{
return -EINVAL;
}
static inline void msm_dma_unmap_sgtable(struct device *dev, struct sg_table *sgt,
enum dma_data_direction dir,
struct dma_buf *dma_buf, unsigned long attrs)
{
}
static inline int msm_dma_unmap_all_for_dev(struct device *dev)
{
return 0;
}
static inline void msm_dma_buf_freed(void *buffer) {}
#endif /*CONFIG_QCOM_LAZY_MAPPING*/
#endif

524
include/linux/msm_gpi.h Normal file
View File

@@ -0,0 +1,524 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __MSM_GPI_H_
#define __MSM_GPI_H_
#include <linux/types.h>
struct __packed msm_gpi_tre {
u32 dword[4];
};
enum GPI_EV_TYPE {
XFER_COMPLETE_EV_TYPE = 0x22,
IMMEDIATE_DATA_EV_TYPE = 0x30,
QUP_NOTIF_EV_TYPE = 0x31,
STALE_EV_TYPE = 0xFF,
QUP_TCE_TYPE_Q2SPI_STATUS = 0x35,
QUP_TCE_TYPE_Q2SPI_CR_HEADER = 0x36,
};
enum Q2SPI_CR_HEADER_CODE {
Q2SPI_CR_CODE_SUCCESS = 0x1,
Q2SPI_CR_HEADER_LEN_ZERO = 0xB,
Q2SPI_CR_HEADER_INCORRECT = 0xC,
};
enum msm_gpi_tre_type {
MSM_GPI_TRE_INVALID = 0x00,
MSM_GPI_TRE_NOP = 0x01,
MSM_GPI_TRE_DMA_W_BUF = 0x10,
MSM_GPI_TRE_DMA_IMMEDIATE = 0x11,
MSM_GPI_TRE_DMA_W_SG_LIST = 0x12,
MSM_GPI_TRE_GO = 0x20,
MSM_GPI_TRE_CONFIG0 = 0x22,
MSM_GPI_TRE_CONFIG1 = 0x23,
MSM_GPI_TRE_CONFIG2 = 0x24,
MSM_GPI_TRE_CONFIG3 = 0x25,
MSM_GPI_TRE_LOCK = 0x30,
MSM_GPI_TRE_UNLOCK = 0x31,
};
#define MSM_GPI_TRE_TYPE(tre) ((tre->dword[3] >> 16) & 0xFF)
/* Lock TRE */
#define MSM_GPI_LOCK_TRE_DWORD0 (0)
#define MSM_GPI_LOCK_TRE_DWORD1 (0)
#define MSM_GPI_LOCK_TRE_DWORD2 (0)
#define MSM_GPI_LOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x3 << 20) | (0x0 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
/* Unlock TRE */
#define MSM_GPI_UNLOCK_TRE_DWORD0 (0)
#define MSM_GPI_UNLOCK_TRE_DWORD1 (0)
#define MSM_GPI_UNLOCK_TRE_DWORD2 (0)
#define MSM_GPI_UNLOCK_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x3 << 20) | (0x1 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
/* DMA w. Buffer TRE */
#ifdef CONFIG_ARM64
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(ptr) ((u32)ptr)
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD1(ptr) ((u32)(ptr >> 32))
#else
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD0(ptr) (ptr)
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD1(ptr) 0
#endif
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD2(length) (length & 0xFFFFFF)
#define MSM_GPI_DMA_W_BUFFER_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x1 << 20) | (0x0 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
#define MSM_GPI_DMA_W_BUFFER_TRE_GET_LEN(tre) (tre->dword[2] & 0xFFFFFF)
#define MSM_GPI_DMA_W_BUFFER_TRE_SET_LEN(tre, length) (tre->dword[2] = \
MSM_GPI_DMA_W_BUFFER_TRE_DWORD2(length))
/* DMA Immediate TRE */
#define MSM_GPI_DMA_IMMEDIATE_TRE_DWORD0(d3, d2, d1, d0) ((d3 << 24) | \
(d2 << 16) | (d1 << 8) | (d0))
#define MSM_GPI_DMA_IMMEDIATE_TRE_DWORD1(d4, d5, d6, d7) ((d7 << 24) | \
(d6 << 16) | (d5 << 8) | (d4))
#define MSM_GPI_DMA_IMMEDIATE_TRE_DWORD2(length) (length & 0xF)
#define MSM_GPI_DMA_IMMEDIATE_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x1 << 20) | (0x1 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
#define MSM_GPI_DMA_IMMEDIATE_TRE_GET_LEN(tre) (tre->dword[2] & 0xF)
/* DMA w. Scatter/Gather List TRE */
#ifdef CONFIG_ARM64
#define MSM_GPI_SG_LIST_TRE_DWORD0(ptr) ((u32)ptr)
#define MSM_GPI_SG_LIST_TRE_DWORD1(ptr) ((u32)(ptr >> 32))
#else
#define MSM_GPI_SG_LIST_TRE_DWORD0(ptr) (ptr)
#define MSM_GPI_SG_LIST_TRE_DWORD1(ptr) 0
#endif
#define MSM_GPI_SG_LIST_TRE_DWORD2(length) (length & 0xFFFF)
#define MSM_GPI_SG_LIST_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x1 << 20) \
| (0x2 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* SG Element */
#ifdef CONFIG_ARM64
#define MSM_GPI_SG_ELEMENT_DWORD0(ptr) ((u32)ptr)
#define MSM_GPI_SG_ELEMENT_DWORD1(ptr) ((u32)(ptr >> 32))
#else
#define MSM_GPI_SG_ELEMENT_DWORD0(ptr) (ptr)
#define MSM_GPI_SG_ELEMENT_DWORD1(ptr) 0
#endif
#define MSM_GSI_SG_ELEMENT_DWORD2(length) (length & 0xFFFFF)
#define MSM_GSI_SG_ELEMENT_DWORD3 (0)
/* Config2 TRE */
#define GPI_CONFIG2_TRE_DWORD0(gr, txp) ((gr << 20) | (txp))
#define GPI_CONFIG2_TRE_DWORD1(txp) (txp)
#define GPI_CONFIG2_TRE_DWORD2 (0)
#define GPI_CONFIG2_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) | \
(0x4 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* Config3 TRE */
#define GPI_CONFIG3_TRE_DWORD0(rxp) (rxp)
#define GPI_CONFIG3_TRE_DWORD1(rxp) (rxp)
#define GPI_CONFIG3_TRE_DWORD2 (0)
#define GPI_CONFIG3_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) \
| (0x5 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* SPI Go TRE */
#define MSM_GPI_SPI_GO_TRE_DWORD0(flags, cs, command) ((flags << 24) | \
(cs << 8) | command)
#define MSM_GPI_SPI_GO_TRE_DWORD1 (0)
#define MSM_GPI_SPI_GO_TRE_DWORD2(rx_len) (rx_len)
#define MSM_GPI_SPI_GO_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) | \
(0x0 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* SPI Config0 TRE */
#define MSM_GPI_SPI_CONFIG0_TRE_DWORD0(pack, flags, word_size) ((pack << 24) | \
(flags << 8) | word_size)
#define MSM_GPI_SPI_CONFIG0_TRE_DWORD1(it_del, cs_clk_del, iw_del) \
((it_del << 16) | (cs_clk_del << 8) | iw_del)
#define MSM_GPI_SPI_CONFIG0_TRE_DWORD2(clk_src, clk_div) ((clk_src << 16) | \
clk_div)
#define MSM_GPI_SPI_CONFIG0_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x2 << 20) | (0x2 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
/* UART Go TRE */
#define MSM_GPI_UART_GO_TRE_DWORD0(en_hunt, command) ((en_hunt << 8) | command)
#define MSM_GPI_UART_GO_TRE_DWORD1 (0)
#define MSM_GPI_UART_GO_TRE_DWORD2 (0)
#define MSM_GPI_UART_GO_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) \
| (0x0 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* UART Config0 TRE */
#define MSM_GPI_UART_CONFIG0_TRE_DWORD0(pack, hunt, flags, parity, sbl, size) \
((pack << 24) | (hunt << 16) | (flags << 8) | (parity << 5) | \
(sbl << 3) | size)
#define MSM_GPI_UART_CONFIG0_TRE_DWORD1(rfr_level, rx_stale) \
((rfr_level << 24) | rx_stale)
#define MSM_GPI_UART_CONFIG0_TRE_DWORD2(clk_source, clk_div) \
((clk_source << 16) | clk_div)
#define MSM_GPI_UART_CONFIG0_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x2 << 20) | (0x2 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
/* I2C GO TRE */
#define MSM_GPI_I2C_GO_TRE_DWORD0(flags, slave, opcode) \
((flags << 24) | (slave << 8) | opcode)
#define MSM_GPI_I2C_GO_TRE_DWORD1 (0)
#define MSM_GPI_I2C_GO_TRE_DWORD2(rx_len) (rx_len)
#define MSM_GPI_I2C_GO_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) | \
(0x0 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* I2C Config0 TRE */
#define MSM_GPI_I2C_CONFIG0_TRE_DWORD0(pack, t_cycle, t_high, t_low) \
((pack << 24) | (t_cycle << 16) | (t_high << 8) | t_low)
#define MSM_GPI_I2C_CONFIG0_TRE_DWORD1(inter_delay, noise_rej) \
((inter_delay << 16) | noise_rej)
#define MSM_GPI_I2C_CONFIG0_TRE_DWORD2(clk_src, clk_div) \
((clk_src << 16) | clk_div)
#define MSM_GPI_I2C_CONFIG0_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x2 << 20) | (0x2 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
/* I3C GO TRE */
#define MSM_GPI_I3C_GO_TRE_DWORD0(flags, ccc_hdr, slave, opcode) \
((flags << 24) | (ccc_hdr << 16) | (slave << 8) | opcode)
#define MSM_GPI_I3C_GO_TRE_DWORD1(flags) (flags)
#define MSM_GPI_I3C_GO_TRE_DWORD2(rx_len) (rx_len)
#define MSM_GPI_I3C_GO_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) ((0x2 << 20) | \
(0x0 << 16) | (link_rx << 11) | (bei << 10) | (ieot << 9) | \
(ieob << 8) | ch)
/* I3C Config0 TRE */
#define MSM_GPI_I3C_CONFIG0_TRE_DWORD0(pack, t_cycle, t_high, t_low) \
((pack << 24) | (t_cycle << 16) | (t_high << 8) | t_low)
#define MSM_GPI_I3C_CONFIG0_TRE_DWORD1(inter_delay, t_cycle, t_high) \
((inter_delay << 16) | (t_cycle << 8) | t_high)
#define MSM_GPI_I3C_CONFIG0_TRE_DWORD2(clk_src, clk_div) \
((clk_src << 16) | clk_div)
#define MSM_GPI_I3C_CONFIG0_TRE_DWORD3(link_rx, bei, ieot, ieob, ch) \
((0x2 << 20) | (0x2 << 16) | (link_rx << 11) | (bei << 10) | \
(ieot << 9) | (ieob << 8) | ch)
#ifdef CONFIG_ARM64
#define MSM_GPI_RING_PHYS_ADDR_UPPER(ptr) ((u32)(ptr >> 32))
#else
#define MSM_GPI_RING_PHYS_ADDR_UPPER(ptr) 0
#endif
/* Static GPII here uses bit5 bit4 bit3 bit2 bit1(xxx1 111x) */
#define STATIC_GPII_BMSK (0x1e)
#define STATIC_GPII_SHFT (0x1)
#define GPI_EV_PRIORITY_BMSK (0x1)
#define GSI_SE_ERR(log_ctx, print, dev, x...) do { \
ipc_log_string(log_ctx, x); \
if (print) { \
if (dev) \
dev_err((dev), x); \
else \
pr_err(x); \
} \
} while (0)
#define GSI_SE_DBG(log_ctx, print, dev, x...) do { \
ipc_log_string(log_ctx, x); \
if (print) { \
if (dev) \
dev_dbg((dev), x); \
else \
pr_debug(x); \
} \
} while (0)
#define LOCK_TRE_SET BIT(0)
#define CONFIG_TRE_SET BIT(1)
#define GO_TRE_SET BIT(2)
#define DMA_TRE_SET BIT(3)
#define UNLOCK_TRE_SET BIT(4)
#define GSI_MAX_TRE_TYPES (5)
#define GSI_MAX_NUM_TRE_MSGS (448)
#define GSI_MAX_IMMEDIATE_DMA_LEN (8)
/* cmds to perform by using dmaengine_slave_config() */
enum msm_gpi_ctrl_cmd {
MSM_GPI_INIT,
MSM_GPI_CMD_UART_SW_STALE,
MSM_GPI_CMD_UART_RFR_READY,
MSM_GPI_CMD_UART_RFR_NOT_READY,
};
enum msm_gpi_cb_event {
/* These events are hardware generated events */
MSM_GPI_QUP_NOTIFY,
MSM_GPI_QUP_ERROR, /* global error */
MSM_GPI_QUP_CH_ERROR, /* channel specific error */
MSM_GPI_QUP_FW_ERROR, /* unhandled error */
/* These events indicate a software bug */
MSM_GPI_QUP_PENDING_EVENT,
MSM_GPI_QUP_EOT_DESC_MISMATCH,
MSM_GPI_QUP_SW_ERROR,
MSM_GPI_QUP_CR_HEADER,
MSM_GPI_QUP_MAX_EVENT,
};
struct msm_gpi_error_log {
u32 routine;
u32 type;
u32 error_code;
};
struct __packed qup_q2spi_cr_header_event {
u8 cr_hdr[4];
u8 cr_ed_byte[4];
u32 reserved0 : 24;
u8 code : 8;
u32 byte0_len : 4;
u32 reserved1 : 3;
u32 byte0_err : 1;
u32 reserved2 : 8;
u8 type : 8;
u8 ch_id : 8;
};
struct msm_gpi_cb {
enum msm_gpi_cb_event cb_event;
u64 status;
u64 timestamp;
u64 count;
struct msm_gpi_error_log error_log;
struct __packed qup_q2spi_cr_header_event q2spi_cr_header_event;
};
static const char *const gpi_cb_event_str[MSM_GPI_QUP_MAX_EVENT] = {
[MSM_GPI_QUP_NOTIFY] = "NOTIFY",
[MSM_GPI_QUP_ERROR] = "GLOBAL ERROR",
[MSM_GPI_QUP_CH_ERROR] = "CHAN ERROR",
[MSM_GPI_QUP_FW_ERROR] = "UNHANDLED ERROR",
[MSM_GPI_QUP_PENDING_EVENT] = "PENDING EVENT",
[MSM_GPI_QUP_EOT_DESC_MISMATCH] = "EOT/DESC MISMATCH",
[MSM_GPI_QUP_SW_ERROR] = "SW ERROR",
[MSM_GPI_QUP_CR_HEADER] = "Doorbell CR EVENT"
};
#define TO_GPI_CB_EVENT_STR(event) (((event) >= MSM_GPI_QUP_MAX_EVENT) ? \
"INVALID" : gpi_cb_event_str[(event)])
struct dma_chan;
struct gpi_client_info {
/*
* memory for msm_gpi_cb is released after callback, clients shall
* save any required data for post processing after returning
* from callback
*/
void (*callback)(struct dma_chan *chan,
struct msm_gpi_cb const *msm_gpi_cb,
void *cb_param);
void *cb_param;
};
/*
* control structure to config gpi dma engine via dmaengine_slave_config()
* dma_chan.private should point to msm_gpi_ctrl structure
*/
struct msm_gpi_ctrl {
enum msm_gpi_ctrl_cmd cmd;
union {
struct gpi_client_info init;
};
};
enum msm_gpi_tce_code {
MSM_GPI_TCE_SUCCESS = 1,
MSM_GPI_TCE_EOT = 2,
MSM_GPI_TCE_EOB = 4,
MSM_GPI_TCE_UNEXP_ERR = 16,
};
/*
* gpi specific callback parameters to pass between gpi client and gpi engine.
* client shall set async_desc.callback_parm to msm_gpi_dma_async_tx_cb_param
*/
struct msm_gpi_dma_async_tx_cb_param {
u32 length;
enum msm_gpi_tce_code completion_code; /* TCE event code */
u32 status;
struct __packed msm_gpi_tre imed_tre;
void *userdata;
enum GPI_EV_TYPE tce_type;
u32 q2spi_status:8;
};
struct gsi_tre_info {
struct msm_gpi_tre lock_t;
struct msm_gpi_tre go_t;
struct msm_gpi_tre config_t;
struct msm_gpi_tre dma_t;
struct msm_gpi_tre unlock_t;
u8 flags;
};
struct gsi_tre_queue {
u32 msg_cnt;
u32 unmap_msg_cnt;
u32 freed_msg_cnt;
dma_addr_t dma_buf[GSI_MAX_NUM_TRE_MSGS];
void *virt_buf[GSI_MAX_NUM_TRE_MSGS];
u32 len[GSI_MAX_NUM_TRE_MSGS];
atomic_t irq_cnt;
};
struct gsi_xfer_param {
struct dma_async_tx_descriptor *desc;
struct msm_gpi_dma_async_tx_cb_param cb;
struct dma_chan *ch;
struct scatterlist *sg; /* lock, cfg0, go, TX, unlock */
dma_addr_t sg_dma;
struct msm_gpi_ctrl ev;
struct gsi_tre_info tre;
struct gsi_tre_queue tre_queue;
spinlock_t multi_tre_lock; /* multi tre spin lock */
void (*cb_fun)(void *ptr); /* tx or rx cb */
};
struct gsi_common {
u8 protocol;
struct completion *xfer;
struct device *dev;
void *dev_node;
struct gsi_xfer_param tx;
struct gsi_xfer_param rx;
void *ipc;
bool req_chan;
bool *err; /* For every gsi error performing gsi reset */
int *protocol_err; /* protocol specific error*/
void (*ev_cb_fun)(struct dma_chan *ch, struct msm_gpi_cb const *cb_str, void *ptr);
};
/* Client drivers of the GPI can call this function to dump the GPI registers
* whenever client met some scenario like timeout, error in GPI transfer mode.
*/
void gpi_dump_for_geni(struct dma_chan *chan);
/**
* gpi_q2spi_terminate_all() - function to stop and restart the channels
* @chan: gsi dma channel handle
*
* Return: Returns success or failure
*/
int gpi_q2spi_terminate_all(struct dma_chan *chan);
/**
* gpi_update_multi_desc_flag() - update multi descriptor flag and num of msgs for
* multi descriptor mode handling.
* @chan: Base address of dma channel
* @is_multi_descriptor: is multi descriptor flag
* @num_msgs: number of client messages
*
* Return:None
*/
void gpi_update_multi_desc_flag(struct dma_chan *chan, bool is_multi_descriptor, int num_msgs);
/**
* gsi_common_tre_process() - Process received TRE's from GSI HW
* @gsi: Base address of the gsi common structure.
* @num_xfers: number of messages count.
* @num_msg_per_irq: num of messages per irq.
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
*
* This function is used to process received TRE's from GSI HW.
* And also used for error case, it will clear and unmap all pending transfers.
*
* Return: None.
*/
void gsi_common_tre_process(struct gsi_common *gsi, u32 num_xfers, u32 num_msg_per_irq,
struct device *wrapper_dev);
/**
* gsi_common_tx_tre_optimization() - Process received TRE's from GSI HW
* @gsi: Base address of the gsi common structure.
* @num_xfers: number of messages count.
* @num_msg_per_irq: num of messages per irq.
* @xfer_timeout: xfer timeout value.
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
*
* This function is used to optimize dma tre's, it keeps always HW busy.
*
* Return: Returning timeout value
*/
int gsi_common_tx_tre_optimization(struct gsi_common *gsi, u32 num_xfers, u32 num_msg_per_irq,
u32 xfer_timeout, struct device *wrapper_dev);
/**
* geni_gsi_ch_start() - gsi channel command to start the GSI RX and TX channels
* @chan: dma channel handle
*
* Return: Returns success or failure
*/
int geni_gsi_ch_start(struct dma_chan *chan);
/**
* geni_gsi_connect_doorbell() - function to connect gsi doorbell
* @chan: dma channel handle
*
* Return: Returns success or failure
*/
int geni_gsi_connect_doorbell(struct dma_chan *chan);
/**
* geni_gsi_disconnect_doorbell_stop_ch() - function to disconnect gsi doorbell and stop channel
* @chan: dma channel handle
*
* Return: Returns success or failure
*/
int geni_gsi_disconnect_doorbell_stop_ch(struct dma_chan *chan, bool stop_ch);
/**
* geni_gsi_common_request_channel() - gsi common dma request channel
* @gsi: Base address of gsi common
* @stop_ch: stop channel if set to true
*
* Return: Returns success or failure
*/
int geni_gsi_common_request_channel(struct gsi_common *gsi);
/**
* gsi_common_prep_desc_and_submit() - gsi common prepare descriptor and gsi submit
* @gsi: Base address of gsi common
* @segs: Num of segments
* @tx_chan: dma transfer channel type
* @skip_callbacks: flag used to register callbacks
*
* Return: Returns success or failure
*/
int gsi_common_prep_desc_and_submit(struct gsi_common *gsi, int segs, bool tx_chan, bool skip_cb);
/**
* gsi_common_fill_tre_buf() - gsi common fill tre buffers
* @gsi: Base address of gsi common
* @tx_chan: dma transfer channel type
*
* Return: Returns tre count
*/
int gsi_common_fill_tre_buf(struct gsi_common *gsi, bool tx_chan);
/**
* gsi_common_clear_tre_indexes() - gsi common queue clear tre indexes
* @gsi_q: Base address of gsi common queue
*
* Return: None
*/
void gsi_common_clear_tre_indexes(struct gsi_tre_queue *gsi_q);
#endif

329
include/linux/msm_pcie.h Normal file
View File

@@ -0,0 +1,329 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */
#ifndef __MSM_PCIE_H
#define __MSM_PCIE_H
#include <linux/types.h>
#include <linux/pci.h>
enum msm_pcie_config {
MSM_PCIE_CONFIG_INVALID = 0,
MSM_PCIE_CONFIG_LINKDOWN = BIT(0),
MSM_PCIE_CONFIG_NO_RECOVERY = BIT(1),
MSM_PCIE_CONFIG_NO_L1SS_TO = BIT(2),
MSM_PCIE_CONFIG_NO_DRV_PC = BIT(3),
MSM_PCIE_CONFIG_FORCE_SUSP = BIT(4),
};
enum msm_pcie_pm_opt {
MSM_PCIE_DRV_SUSPEND = BIT(0),
MSM_PCIE_SUSPEND = BIT(1),
MSM_PCIE_RESUME = BIT(2),
MSM_PCIE_DISABLE_PC = BIT(3),
MSM_PCIE_ENABLE_PC = BIT(4),
MSM_PCIE_HANDLE_LINKDOWN = BIT(5),
MSM_PCIE_DRV_PC_CTRL = BIT(6),
};
enum msm_pcie_event {
MSM_PCIE_EVENT_INVALID = 0,
MSM_PCIE_EVENT_LINKDOWN = 0x1,
MSM_PCIE_EVENT_LINKUP = 0x2,
MSM_PCIE_EVENT_WAKEUP = 0x4,
MSM_PCIE_EVENT_L1SS_TIMEOUT = BIT(3),
MSM_PCIE_EVENT_DRV_CONNECT = BIT(4),
MSM_PCIE_EVENT_DRV_DISCONNECT = BIT(5),
MSM_PCIE_EVENT_LINK_RECOVER = BIT(6),
};
enum msm_pcie_trigger {
MSM_PCIE_TRIGGER_CALLBACK,
MSM_PCIE_TRIGGER_COMPLETION,
};
struct msm_pcie_notify {
enum msm_pcie_event event;
void *user;
void *data;
u32 options;
};
struct msm_pcie_register_event {
struct list_head node;
u32 events;
void *user;
enum msm_pcie_trigger mode;
void (*callback)(struct msm_pcie_notify *notify);
struct msm_pcie_notify notify;
struct completion *completion;
u32 options;
};
void msm_msi_config_access(struct irq_domain *domain, bool allow);
void msm_msi_config(struct irq_domain *domain);
int msm_msi_init(struct device *dev);
#if IS_ENABLED(CONFIG_PCI_MSM)
/**
* msm_pcie_set_target_link_speed - sets the upper bound of GEN speed PCIe can
* link up with
* @rc_idx: root complex port number that endpoint is connected to
* @target_link_speed: new target link speed PCIe can link up with
* @force: override DT specified link speed
*
* Provide PCIe clients the option to control upper bound of GEN speed PCIe
* can link up with. Clients may choose only GEN speed within root complex's
* controller capability or up to what is defined in devicetree,
* qcom,target-link-speed.
*
* Client may also pass 0 for target_link_speed to have PCIe root complex
* reset and use the default TLS.
*
* Return 0 on success, negative value on error
*/
int msm_pcie_set_target_link_speed(u32 rc_idx, u32 target_link_speed,
bool force);
/**
* msm_pcie_allow_l1 - allow PCIe link to re-enter L1
* @pci_dev: client's pci device structure
*
* This function gives PCIe clients the control to allow the link to re-enter
* L1. Should only be used after msm_pcie_prevent_l1 has been called.
*
* Return 0 on success, negative value on error
*/
int msm_pcie_allow_l1(struct pci_dev *pci_dev);
/**
* msm_pcie_prevent_l1 - keeps PCIe link out of L1
* @pci_dev: client's pci device structure
*
* This function gives PCIe clients the control to exit and prevent the link
* from entering L1.
*
* Return 0 on success, negative value on error
*/
int msm_pcie_prevent_l1(struct pci_dev *pci_dev);
/**
* msm_pcie_set_link_bandwidth - updates the number of lanes and speed of PCIe
* link.
* @pci_dev: client's pci device structure
* @target_link_speed: gen speed
* @target_link_width: number of lanes
*
* This function gives PCIe clients the control to update the number of lanes
* and gen speed of the link.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_set_link_bandwidth(struct pci_dev *pci_dev, u16 target_link_speed,
u16 target_link_width);
/**
* msm_pcie_l1ss_timeout_disable - disable L1ss timeout feature
* @pci_dev: client's pci device structure
*
* This function gives PCIe clients the control to disable L1ss timeout
* feature.
*/
void msm_pcie_l1ss_timeout_disable(struct pci_dev *pci_dev);
/**
* msm_pcie_l1ss_timeout_enable - enable L1ss timeout feature
* @pci_dev: client's pci device structure
*
* This function gives PCIe clients the control to enable L1ss timeout
* feature.
*/
void msm_pcie_l1ss_timeout_enable(struct pci_dev *pci_dev);
/**
* msm_pcie_pm_control - control the power state of a PCIe link.
* @pm_opt: power management operation
* @busnr: bus number of PCIe endpoint
* @user: handle of the caller
* @data: private data from the caller
* @options: options for pm control
*
* This function gives PCIe endpoint device drivers the control to change
* the power state of a PCIe link for their device.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
void *data, u32 options);
/**
* msm_pcie_register_event - register an event with PCIe bus driver.
* @reg: event structure
*
* This function gives PCIe endpoint device drivers an option to register
* events with PCIe bus driver.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_register_event(struct msm_pcie_register_event *reg);
/**
* msm_pcie_deregister_event - deregister an event with PCIe bus driver.
* @reg: event structure
*
* This function gives PCIe endpoint device drivers an option to deregister
* events with PCIe bus driver.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_deregister_event(struct msm_pcie_register_event *reg);
/**
* msm_pcie_enumerate - enumerate Endpoints.
* @rc_idx: RC that Endpoints connect to.
*
* This function enumerates Endpoints connected to RC.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_enumerate(u32 rc_idx);
/*
* msm_pcie_debug_info - run a PCIe specific debug testcase.
* @dev: pci device structure
* @option: specifies which PCIe debug testcase to execute
* @base: PCIe specific range
* @offset: offset of destination register
* @mask: mask the bit(s) of destination register
* @value: value to be written to destination register
*
* This function gives PCIe endpoint device drivers the control to
* run a debug testcase.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_debug_info(struct pci_dev *dev, u32 option, u32 base,
u32 offset, u32 mask, u32 value);
/*
* msm_pcie_reg_dump - dump pcie regsters for debug
* @pci_dev: pci device structure
* @buffer: destination buffer address
* @len: length of buffer
*
* This functions dumps PCIE registers for debug. Sould be used when
* link is already enabled
*/
int msm_pcie_reg_dump(struct pci_dev *pci_dev, u8 *buff, u32 len);
/*
* msm_pcie_fmd_enable - deassert perst and enable FMD bit
* @pci_dev: pci device structure
*
* This function will de-assert PERST if PERST is already in assert state
* and set fmd_enable bit, after that no further perst assert/de-assert
* are allowed.
*/
int msm_pcie_fmd_enable(struct pci_dev *pci_dev);
#else /* !CONFIG_PCI_MSM */
static inline int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr,
void *user, void *data, u32 options)
{
return -ENODEV;
}
static inline int msm_pcie_set_target_link_speed(u32 rc_idx,
u32 target_link_speed)
{
return -ENODEV;
}
static inline int msm_pcie_allow_l1(struct pci_dev *pci_dev)
{
return -ENODEV;
}
static inline int msm_pcie_prevent_l1(struct pci_dev *pci_dev)
{
return -ENODEV;
}
static inline int msm_pcie_l1ss_timeout_disable(struct pci_dev *pci_dev)
{
return -ENODEV;
}
static inline int msm_pcie_l1ss_timeout_enable(struct pci_dev *pci_dev)
{
return -ENODEV;
}
static inline int msm_pcie_register_event(struct msm_pcie_register_event *reg)
{
return -ENODEV;
}
static inline int msm_pcie_deregister_event(struct msm_pcie_register_event *reg)
{
return -ENODEV;
}
static inline int msm_pcie_enumerate(u32 rc_idx)
{
return -ENODEV;
}
static inline int msm_pcie_debug_info(struct pci_dev *dev, u32 option, u32 base,
u32 offset, u32 mask, u32 value)
{
return -ENODEV;
}
static inline int msm_pcie_reg_dump(struct pci_dev *pci_dev, u8 *buff, u32 len)
{
return -ENODEV;
}
static inline int msm_pcie_fmd_enable(struct pci_dev *pci_dev)
{
return -ENODEV;
}
#endif /* CONFIG_PCI_MSM */
#ifdef CONFIG_SEC_PCIE_SET_EP_STATUS
extern void sec_pcie_set_ep_enabled(struct pci_dev *dev, bool is_enabled);
#else
static inline void sec_pcie_set_ep_enabled(struct pci_dev *dev, bool is_enabled) {}
#endif
#ifdef CONFIG_SEC_PCIE_L1SS
enum l1ss_ctrl_ids {
L1SS_SYSFS,
L1SS_MST,
L1SS_AUDIO,
L1SS_MAX
};
extern void sec_pcie_set_use_ep_loaded(struct pci_dev *dev);
extern void sec_pcie_set_ep_driver_loaded(struct pci_dev *dev, bool is_loaded);
extern int sec_pcie_l1ss_enable(int ctrl_id);
extern int sec_pcie_l1ss_disable(int ctrl_id);
#else
static inline void sec_pcie_set_use_ep_loaded(dev) {}
static inline void sec_pcie_set_ep_driver_loaded(dev, is_loaded) {}
static inline int sec_pcie_l1ss_enable(int ctrl_id)
{
return -ENODEV;
}
static inline int sec_pcie_l1ss_disable(int ctrl_id)
{
return -ENODEV;
}
#endif
#endif /* __MSM_PCIE_H */

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MSM_SYSSTATS_H_
#define _MSM_SYSSTATS_H_
#include <uapi/linux/msm_sysstats.h>
#if IS_ENABLED(CONFIG_MSM_SYSSTATS)
extern void sysstats_register_kgsl_stats_cb(u64 (*cb)(pid_t pid));
extern void sysstats_unregister_kgsl_stats_cb(void);
#else
static inline void sysstats_register_kgsl_stats_cb(u64 (*cb)(pid_t pid))
{
}
static inline void sysstats_unregister_kgsl_stats_cb(void)
{
}
#endif
#endif /* _MSM_SYSSTATS_H_ */

View File

@@ -0,0 +1,711 @@
// SPDX-License-Identifier: GPL-2.0
/*
* include/linux/muic/common/muic.h
*
* header file supporting MUIC common information
*
* Copyright (C) 2022 Samsung Electronics
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __MUIC_H__
#define __MUIC_H__
#ifdef CONFIG_IFCONN_NOTIFIER
#include <linux/ifconn/ifconn_notifier.h>
#endif
#include <linux/muic/common/muic_param.h>
#include <linux/power_supply.h>
#define MUIC_CORE "MUIC_CORE"
#define SIOP (1 << 0)
#define AFC_REQUEST_CHARGER SIOP
#define FLED (1 << 1)
#define AFC_REQUEST_MST (1 << 2)
#define AFC_REQUEST_MFC (1 << 3)
#define AFC_REQUEST_DETACH_CLEAR_BIT ((SIOP))
/* Status of IF PMIC chip (suspend and resume) */
enum {
MUIC_SUSPEND = 0,
MUIC_RESUME,
};
/* MUIC Interrupt */
enum {
MUIC_INTR_DETACH = 0,
MUIC_INTR_ATTACH
};
enum muic_op_mode {
OPMODE_MUIC = 0<<0,
OPMODE_PDIC = 1<<0,
};
/* MUIC Dock Observer Callback parameter */
enum {
MUIC_DOCK_DETACHED = 0,
MUIC_DOCK_DESKDOCK = 1,
MUIC_DOCK_CARDOCK = 2,
MUIC_DOCK_AUDIODOCK = 101,
MUIC_DOCK_SMARTDOCK = 102,
MUIC_DOCK_HMT = 105,
MUIC_DOCK_ABNORMAL = 106,
MUIC_DOCK_GAMEPAD = 107,
MUIC_DOCK_GAMEPAD_WITH_EARJACK = 108,
};
/* MUIC Path */
enum {
MUIC_PATH_USB_AP = 0,
MUIC_PATH_USB_CP,
MUIC_PATH_UART_AP,
MUIC_PATH_UART_CP,
MUIC_PATH_OPEN,
MUIC_PATH_AUDIO,
};
/* bootparam SWITCH_SEL */
enum {
SWITCH_SEL_USB_MASK = 0x1,
SWITCH_SEL_UART_MASK = 0x2,
SWITCH_SEL_RUSTPROOF_MASK = 0x8,
SWITCH_SEL_AFC_DISABLE_MASK = 0x100,
};
/* bootparam CHARGING_MODE */
enum {
CH_MODE_AFC_DISABLE_VAL = 0x31, /* char '1' */
};
enum driver_probe_flag {
MUIC_PROBE_DONE = 1 << 0,
CHARGER_PROBE_DONE = 1 << 1,
};
/* MUIC ADC table */
typedef enum {
ADC_GND = 0x00,
ADC_SEND_END = 0x01, /* 0x00001 2K ohm */
ADC_REMOTE_S11 = 0x0c, /* 0x01100 20.5K ohm */
ADC_REMOTE_S12 = 0x0d, /* 0x01101 24.07K ohm */
ADC_RESERVED_VZW = 0x0e, /* 0x01110 28.7K ohm */
ADC_INCOMPATIBLE_VZW = 0x0f, /* 0x01111 34K ohm */
ADC_SMARTDOCK = 0x10, /* 0x10000 40.2K ohm */
ADC_RDU_TA = 0x10, /* 0x10000 40.2K ohm */
ADC_HMT = 0x11, /* 0x10001 49.9K ohm */
ADC_AUDIODOCK = 0x12, /* 0x10010 64.9K ohm */
ADC_USB_LANHUB = 0x13, /* 0x10011 80.07K ohm */
ADC_CHARGING_CABLE = 0x14, /* 0x10100 102K ohm */
ADC_UNIVERSAL_MMDOCK = 0x15, /* 0x10101 121K ohm */
ADC_GAMEPAD = 0x15, /* 0x10101 121K ohm */
ADC_UART_CABLE = 0x16, /* 0x10110 150K ohm */
ADC_CEA936ATYPE1_CHG = 0x17, /* 0x10111 200K ohm */
ADC_JIG_USB_OFF = 0x18, /* 0x11000 255K ohm */
ADC_JIG_USB_ON = 0x19, /* 0x11001 301K ohm */
ADC_DESKDOCK = 0x1a, /* 0x11010 365K ohm */
ADC_CEA936ATYPE2_CHG = 0x1b, /* 0x11011 442K ohm */
ADC_JIG_UART_OFF = 0x1c, /* 0x11100 523K ohm */
ADC_JIG_UART_ON = 0x1d, /* 0x11101 619K ohm */
ADC_AUDIOMODE_W_REMOTE = 0x1e, /* 0x11110 1000K ohm */
ADC_OPEN = 0x1f,
ADC_OPEN_219 = 0xfb, /* ADC open or 219.3K ohm */
ADC_219 = 0xfc, /* ADC open or 219.3K ohm */
ADC_UNDEFINED = 0xfd, /* Undefied range */
ADC_DONTCARE = 0xfe, /* ADC don't care for MHL */
ADC_ERROR = 0xff, /* ADC value read error */
} muic_adc_t;
#define IS_JIG_ADC(adc) \
(((adc == ADC_JIG_USB_OFF) \
|| (adc == ADC_JIG_USB_ON) \
|| (adc == ADC_JIG_UART_OFF) \
|| (adc == ADC_JIG_UART_ON)) ? 1 : 0)
#define ADC_WATER_THRESHOLD ADC_OPEN
/* MUIC attached device type */
typedef enum {
ATTACHED_DEV_NONE_MUIC = 0,
ATTACHED_DEV_USB_MUIC = 1,
ATTACHED_DEV_CDP_MUIC,
ATTACHED_DEV_OTG_MUIC,
ATTACHED_DEV_TA_MUIC,
ATTACHED_DEV_UNOFFICIAL_MUIC,
ATTACHED_DEV_UNOFFICIAL_TA_MUIC,
ATTACHED_DEV_UNOFFICIAL_ID_MUIC,
ATTACHED_DEV_UNOFFICIAL_ID_TA_MUIC,
ATTACHED_DEV_UNOFFICIAL_ID_ANY_MUIC,
ATTACHED_DEV_UNOFFICIAL_ID_USB_MUIC,
ATTACHED_DEV_UNOFFICIAL_ID_CDP_MUIC = 11,
ATTACHED_DEV_UNDEFINED_CHARGING_MUIC,
ATTACHED_DEV_DESKDOCK_MUIC,
ATTACHED_DEV_UNKNOWN_VB_MUIC,
ATTACHED_DEV_DESKDOCK_VB_MUIC,
ATTACHED_DEV_CARDOCK_MUIC,
ATTACHED_DEV_JIG_UART_OFF_MUIC,
ATTACHED_DEV_JIG_UART_OFF_VB_MUIC, /* VBUS enabled */
ATTACHED_DEV_JIG_UART_OFF_VB_OTG_MUIC, /* for otg test */
ATTACHED_DEV_JIG_UART_OFF_VB_FG_MUIC, /* for fuelgauge test */
ATTACHED_DEV_JIG_UART_ON_MUIC = 21,
ATTACHED_DEV_JIG_UART_ON_VB_MUIC, /* VBUS enabled */
ATTACHED_DEV_JIG_USB_OFF_MUIC,
ATTACHED_DEV_JIG_USB_ON_MUIC,
ATTACHED_DEV_SMARTDOCK_MUIC,
ATTACHED_DEV_SMARTDOCK_VB_MUIC,
ATTACHED_DEV_SMARTDOCK_TA_MUIC,
ATTACHED_DEV_SMARTDOCK_USB_MUIC,
ATTACHED_DEV_UNIVERSAL_MMDOCK_MUIC,
ATTACHED_DEV_AUDIODOCK_MUIC,
ATTACHED_DEV_MHL_MUIC = 31,
ATTACHED_DEV_CHARGING_CABLE_MUIC,
ATTACHED_DEV_AFC_CHARGER_PREPARE_MUIC,
ATTACHED_DEV_AFC_CHARGER_PREPARE_DUPLI_MUIC,
ATTACHED_DEV_AFC_CHARGER_5V_MUIC,
ATTACHED_DEV_AFC_CHARGER_5V_DUPLI_MUIC,
ATTACHED_DEV_AFC_CHARGER_9V_MUIC,
ATTACHED_DEV_AFC_CHARGER_9V_DUPLI_MUIC,
ATTACHED_DEV_AFC_CHARGER_12V_MUIC,
ATTACHED_DEV_AFC_CHARGER_12V_DUPLI_MUIC,
ATTACHED_DEV_AFC_CHARGER_ERR_V_MUIC = 41,
ATTACHED_DEV_AFC_CHARGER_ERR_V_DUPLI_MUIC,
ATTACHED_DEV_AFC_CHARGER_DISABLED_MUIC,
ATTACHED_DEV_QC_CHARGER_PREPARE_MUIC,
ATTACHED_DEV_QC_CHARGER_5V_MUIC,
ATTACHED_DEV_QC_CHARGER_ERR_V_MUIC,
ATTACHED_DEV_QC_CHARGER_9V_MUIC,
ATTACHED_DEV_HV_ID_ERR_UNDEFINED_MUIC,
ATTACHED_DEV_HV_ID_ERR_UNSUPPORTED_MUIC,
ATTACHED_DEV_HV_ID_ERR_SUPPORTED_MUIC,
ATTACHED_DEV_HMT_MUIC = 51,
ATTACHED_DEV_VZW_ACC_MUIC,
ATTACHED_DEV_VZW_INCOMPATIBLE_MUIC,
ATTACHED_DEV_USB_LANHUB_MUIC,
ATTACHED_DEV_TYPE1_CHG_MUIC,
ATTACHED_DEV_TYPE2_CHG_MUIC,
ATTACHED_DEV_TYPE3_MUIC,
ATTACHED_DEV_TYPE3_MUIC_TA,
ATTACHED_DEV_TYPE3_ADAPTER_MUIC,
ATTACHED_DEV_TYPE3_CHARGER_MUIC,
ATTACHED_DEV_NONE_TYPE3_MUIC = 61,
ATTACHED_DEV_UNSUPPORTED_ID_MUIC,
ATTACHED_DEV_UNSUPPORTED_ID_VB_MUIC,
ATTACHED_DEV_TIMEOUT_OPEN_MUIC,
ATTACHED_DEV_WIRELESS_PAD_MUIC,
ATTACHED_DEV_CARKIT_MUIC,
ATTACHED_DEV_POWERPACK_MUIC,
ATTACHED_DEV_UNDEFINED_RANGE_MUIC,
ATTACHED_DEV_HICCUP_MUIC,
ATTACHED_DEV_CHK_WATER_REQ,
ATTACHED_DEV_CHK_WATER_DRY_REQ = 71,
ATTACHED_DEV_GAMEPAD_MUIC,
ATTACHED_DEV_CHECK_OCP,
ATTACHED_DEV_RDU_TA_MUIC,
ATTACHED_DEV_FACTORY_UART_MUIC,
ATTACHED_DEV_PE_CHARGER_PREPARE_MUIC,
ATTACHED_DEV_PE_CHARGER_9V_MUIC,
ATTACHED_DEV_TURBO_CHARGER,
ATTACHED_DEV_SPECOUT_CHARGER_MUIC,
ATTACHED_DEV_UNKNOWN_MUIC,
ATTACHED_DEV_POGO_DOCK_MUIC = 81,
ATTACHED_DEV_POGO_DOCK_5V_MUIC,
ATTACHED_DEV_POGO_DOCK_9V_MUIC,
ATTACHED_DEV_POGO_DOCK_34K_MUIC,
ATTACHED_DEV_POGO_DOCK_49_9K_MUIC,
ATTACHED_DEV_ABNORMAL_OTG_MUIC,
ATTACHED_DEV_RETRY_TIMEOUT_OPEN_MUIC,
ATTACHED_DEV_RETRY_AFC_CHARGER_5V_MUIC,
ATTACHED_DEV_RETRY_AFC_CHARGER_9V_MUIC,
ATTACHED_DEV_WIRELESS_TA_MUIC,
ATTACHED_DEV_LO_TA_MUIC = 91,
ATTACHED_DEV_NUM,
} muic_attached_dev_t;
#ifdef CONFIG_MUIC_HV_FORCE_LIMIT
/* MUIC attached device type */
typedef enum {
SILENT_CHG_DONE = 0,
SILENT_CHG_CHANGING = 1,
SILENT_CHG_NUM,
} muic_silent_change_state_t;
#endif
/* MUIC HV State type */
typedef enum {
HV_STATE_INVALID = -1,
HV_STATE_IDLE = 0,
HV_STATE_DCP_CHARGER = 1,
HV_STATE_FAST_CHARGE_ADAPTOR = 2,
HV_STATE_FAST_CHARGE_COMMUNICATION = 3,
HV_STATE_AFC_5V_CHARGER = 4,
HV_STATE_AFC_9V_CHARGER = 5,
HV_STATE_QC_CHARGER = 6,
HV_STATE_QC_5V_CHARGER = 7,
HV_STATE_QC_9V_CHARGER = 8,
HV_STATE_QC_FAILED,
HV_STATE_MAX_NUM,
} muic_hv_state_t;
typedef enum {
HV_TRANS_INVALID = -1,
HV_TRANS_MUIC_DETACH = 0,
HV_TRANS_DCP_DETECTED,
HV_TRANS_NO_RESPONSE,
HV_TRANS_VDNMON_LOW,
HV_TRANS_FAST_CHARGE_PING_RESPONSE,
HV_TRANS_AFC_TA_DETECTED,
HV_TRANS_QC_TA_DETECTED,
HV_TRANS_VBUS_5V_BOOST,
HV_TRANS_VBUS_BOOST,
HV_TRANS_VBUS_REDUCE,
HV_TRANS_VBUS_UPDATE,
HV_TRANS_FAST_CHARGE_REOPEN,
HV_TRANS_MAX_NUM,
} muic_hv_transaction_t;
typedef enum {
HV_9V = 0,
HV_5V,
} muic_hv_voltage_t;
#ifdef CONFIG_MUIC_COMMON_SYSFS
struct muic_sysfs_cb {
int (*set_uart_en)(void *data, int en);
void (*set_uart_sel)(void *data);
int (*get_usb_en)(void *data);
int (*set_usb_en)(void *data, int en);
int (*get_adc)(void *data);
int (*get_mansw)(void *data, char *mesg);
int (*get_interrupt_status)(void *data, char *mesg);
int (*get_register)(void *data, char *mesg);
int (*get_attached_dev)(void *data);
int (*get_otg_test)(void *data);
int (*set_otg_test)(void *data, int en);
void (*set_audio_path)(void *data);
void (*set_apo_factory)(void *data);
int (*get_vbus_value)(void *data);
void (*set_afc_disable)(void *data);
int (*afc_set_voltage)(void *data, int vol);
int (*get_hiccup)(void *data);
int (*set_hiccup)(void *data, int en);
int (*set_overheat_hiccup)(void *data, int en);
};
#endif
/* muic common callback driver internal data structure
* that setted at muic-core.c file
*/
struct muic_platform_data {
#ifdef CONFIG_MUIC_COMMON_SYSFS
struct device *switch_device;
struct mutex sysfs_mutex;
struct muic_sysfs_cb sysfs_cb;
#endif
struct device *muic_device;
#if IS_ENABLED(CONFIG_IF_CB_MANAGER)
struct muic_dev *muic_d;
struct if_cb_manager *man;
#endif
int switch_sel;
/* muic current USB/UART path */
int usb_path;
int uart_path;
bool rustproof_on;
bool afc_disable;
int afc_disabled_updated;
enum muic_op_mode opmode;
int vbvolt;
int adc;
bool is_factory_start;
unsigned long driver_probe_flag;
/* muic switch dev register function for DockObserver */
void (*init_switch_dev_cb) (void);
void (*cleanup_switch_dev_cb) (void);
void (*jig_uart_cb)(int jig_state);
/* muic GPIO control function */
#if IS_MODULE(CONFIG_MUIC_NOTIFIER)
int (*init_gpio_cb)(int switch_sel);
#else
int (*init_gpio_cb)(void);
#endif
int (*set_gpio_usb_sel)(void *data, int usb_path);
int (*set_gpio_uart_sel)(void *data, int uart_path);
int (*set_safeout) (int safeout_path);
/* muic cable data collecting function */
void (*init_cable_data_collect_cb)(void);
/* muic AFC voltage switching function */
int (*muic_afc_set_voltage_cb)(int voltage);
/* muic AFC get voltage function */
int (*muic_afc_get_voltage_cb)(void);
/* muic hv charger disable function */
int (*muic_hv_charger_disable_cb)(bool en);
/* muic check charger init function */
int (*muic_hv_charger_init_cb)(void);
/* muic set hiccup mode function */
int (*muic_set_hiccup_mode_cb)(int on_off);
/* muic set pogo adc function */
int (*muic_set_pogo_adc_cb)(int adc);
/* muic request afc cause */
int afc_request_cause;
void *drv_data;
};
#define MUIC_PDATA_VOID_FUNC(func, param) \
{\
if (func) \
func(param); \
else \
pr_err("[muic_core] func not defined %s\n", __func__); \
}
#define MUIC_PDATA_VOID_FUNC_MULTI_PARAM(func, param1, param2) \
{\
if (func) \
func(param1, param2); \
else \
pr_err("[muic_core] func not defined %s\n", __func__); \
}
#define MUIC_PDATA_FUNC(func, param, ret) \
{\
*ret = 0; \
if (func) \
*ret = func(param); \
else \
pr_err("[muic_core] func not defined %s\n", __func__); \
}
#define MUIC_PDATA_FUNC_MULTI_PARAM(func, param1, param2, ret) \
{ \
*ret = 0; \
if (func) \
*ret = func(param1, param2); \
else \
pr_err("[muic_core] func not defined %s\n", __func__); \
}
#define MUIC_IS_ATTACHED(dev) \
(((dev != ATTACHED_DEV_UNKNOWN_MUIC) && (dev != ATTACHED_DEV_NONE_MUIC)) ? (1) : (0))
enum muic_param_en {
MUIC_DISABLE = 0,
MUIC_ENABLE
};
/* Integration */
#define ENUM_STR(x, r) { case x: r = #x; break; }
#define MASK_1b (1)
#define MASK_2b (0x3)
#define MASK_3b (0x7)
#define MASK_4b (0xf)
#define MASK_5b (0x1f)
#define MASK_6b (0x3f)
#define MASK_7b (0x7f)
#define MASK_8b (0xff)
#define IS_VCHGIN_9V(x) ((8000 <= x) && (x <= 10300))
#define IS_VCHGIN_5V(x) ((4000 <= x) && (x <= 6000))
#define AFC_MRXRDY_CNT_LIMIT (3)
#define AFC_MPING_RETRY_CNT_LIMIT (10)
#define AFC_QC_RETRY_CNT_LIMIT (3)
#define VCHGIN_CHECK_CNT_LIMIT (3)
#define AFC_QC_RETRY_WAIT_CNT_LIMIT (3)
typedef enum {
AFC_IRQ_VDNMON = 1,
AFC_IRQ_DNRES,
AFC_IRQ_MPNACK,
AFC_IRQ_MRXBUFOW,
AFC_IRQ_MRXTRF,
AFC_IRQ_MRXPERR,
AFC_IRQ_MRXRDY = 7,
} afc_int_t;
typedef enum {
AFC_NOT_MASK = 0,
AFC_MASK = 1,
} int_mask_t;
typedef enum {
QC_PROTOCOL,
AFC_PROTOCOL,
} protocol_sw_t;
typedef enum {
QC_UNKHOWN,
QC_5V,
QC_9V,
QC_12V,
} qc_2p0_type_t;
typedef enum {
VDNMON_LOW = 0x00,
VDNMON_HIGH = (0x1 << 1),
VDNMON_DONTCARE = 0xff,
} vdnmon_t;
/* MUIC afc irq type */
typedef enum {
MUIC_AFC_IRQ_VDNMON = 0,
MUIC_AFC_IRQ_MRXRDY,
MUIC_AFC_IRQ_VBADC,
MUIC_AFC_IRQ_MPNACK,
MUIC_AFC_IRQ_DONTCARE = 0xff,
} muic_afc_irq_t;
typedef enum tx_data{
MUIC_HV_5V = 0,
MUIC_HV_9V,
} muic_afc_txdata_t;
enum power_supply_lsi_property {
#if !defined(CONFIG_BATTERY_SAMSUNG) || \
IS_ENABLED(CONFIG_MFD_S2MU106) || IS_ENABLED(CONFIG_MFD_S2MF301) || defined(CONFIG_BATTERY_GKI)
POWER_SUPPLY_LSI_PROP_MIN = 10000,
#else
POWER_SUPPLY_LSI_PROP_MIN = POWER_SUPPLY_EXT_PROP_MAX + 1,
#endif
POWER_SUPPLY_LSI_PROP_POWER_ROLE,
POWER_SUPPLY_LSI_PROP_WATER_CHECK,
POWER_SUPPLY_LSI_PROP_DRY_CHECK,
POWER_SUPPLY_LSI_PROP_WATER_CHECKDONE,
POWER_SUPPLY_LSI_PROP_PM_IRQ_TIME,
POWER_SUPPLY_LSI_PROP_USBPD_OPMODE,
POWER_SUPPLY_LSI_PROP_USBPD_RPCUR,
POWER_SUPPLY_LSI_PROP_USBPD_ATTACHED,
POWER_SUPPLY_LSI_PROP_USBPD_SOURCE_ATTACH,
POWER_SUPPLY_LSI_PROP_WATER_GET_POWER_ROLE,
POWER_SUPPLY_LSI_PROP_GET_CC_STATE,
POWER_SUPPLY_LSI_PROP_WATER_STATUS,
POWER_SUPPLY_LSI_PROP_PD_PSY,
POWER_SUPPLY_LSI_PROP_HICCUP_MODE,
POWER_SUPPLY_LSI_PROP_FAC_WATER_CHECK,
POWER_SUPPLY_LSI_PROP_SET_TH,
POWER_SUPPLY_LSI_PROP_PM_VCHGIN,
POWER_SUPPLY_LSI_PROP_2LV_3LV_CHG_MODE,
POWER_SUPPLY_LSI_PROP_USBPD_RESET,
POWER_SUPPLY_LSI_PROP_PD_SUPPORT,
POWER_SUPPLY_LSI_PROP_VCHGIN,
POWER_SUPPLY_LSI_PROP_VWCIN,
POWER_SUPPLY_LSI_PROP_VBYP,
POWER_SUPPLY_LSI_PROP_VSYS,
POWER_SUPPLY_LSI_PROP_VBAT,
POWER_SUPPLY_LSI_PROP_VGPADC,
POWER_SUPPLY_LSI_PROP_VGPADC1,
POWER_SUPPLY_LSI_PROP_VGPADC2,
POWER_SUPPLY_LSI_PROP_ENABLE_WATER,
POWER_SUPPLY_LSI_PROP_VCC1,
POWER_SUPPLY_LSI_PROP_VCC2,
POWER_SUPPLY_LSI_PROP_SBU_OVP_STATE,
POWER_SUPPLY_LSI_PROP_ICHGIN,
POWER_SUPPLY_LSI_PROP_IWCIN,
POWER_SUPPLY_LSI_PROP_IOTG,
POWER_SUPPLY_LSI_PROP_ITX,
POWER_SUPPLY_LSI_PROP_CO_ENABLE,
POWER_SUPPLY_LSI_PROP_RR_ENABLE,
POWER_SUPPLY_LSI_PROP_PM_FACTORY,
POWER_SUPPLY_LSI_PROP_PCP_CLK,
POWER_SUPPLY_LSI_PROP_RID_OPS,
POWER_SUPPLY_LSI_PROP_RID_DISABLE,
POWER_SUPPLY_LSI_PROP_GET_REV,
#if IS_ENABLED(CONFIG_MFD_S2MU106) || IS_ENABLED(CONFIG_MFD_S2MF301) || defined(CONFIG_BATTERY_GKI)
POWER_SUPPLY_LSI_PROP_MAX,
#endif
};
#ifdef CONFIG_IFCONN_NOTIFIER
#define MUIC_SEND_NOTI_ATTACH(dev) \
{ \
int ret; \
struct ifconn_notifier_template template; \
template.cable_type = dev; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_MANAGER, \
IFCONN_NOTIFY_ID_ATTACH, \
IFCONN_NOTIFY_EVENT_ATTACH, \
&template); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#define MUIC_SEND_NOTI_ATTACH_ALL(dev) \
{ \
int ret; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_ALL, \
IFCONN_NOTIFY_ID_ATTACH, \
dev, \
IFCONN_NOTIFY_PARAM_DATA, \
NULL); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#define MUIC_SEND_NOTI_DETACH_ALL(dev) \
{ \
int ret; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_ALL, \
IFCONN_NOTIFY_ID_DETACH, \
dev, \
IFCONN_NOTIFY_PARAM_DATA, \
NULL); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#define MUIC_SEND_NOTI_TO_PDIC_ATTACH(dev) \
{ \
int ret; \
struct ifconn_notifier_template template; \
template.cable_type = dev; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_PDIC, \
IFCONN_NOTIFY_ID_ATTACH, \
IFCONN_NOTIFY_EVENT_ATTACH, \
IFCONN_NOTIFY_PARAM_DATA, \
&template); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#define MUIC_SEND_NOTI_TO_PDIC_DETACH(dev) \
{ \
int ret; \
struct ifconn_notifier_template template; \
template.cable_type = dev; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_PDIC, \
IFCONN_NOTIFY_ID_DETACH, \
IFCONN_NOTIFY_EVENT_DETACH, \
IFCONN_NOTIFY_PARAM_DATA, \
&template); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#define MUIC_SEND_NOTI_DETACH(dev) \
{ \
int ret; \
struct ifconn_notifier_template template; \
template.cable_type = dev; \
ret = ifconn_notifier_notify( \
IFCONN_NOTIFY_MUIC, \
IFCONN_NOTIFY_MANAGER, \
IFCONN_NOTIFY_ID_DETACH, \
IFCONN_NOTIFY_EVENT_DETACH, \
IFCONN_NOTIFY_PARAM_DATA, \
&template); \
if (ret < 0) { \
pr_err("%s: Fail to send noti\n", \
__func__); \
} \
}
#else
#define MUIC_SEND_NOTI_ATTACH(dev) \
muic_notifier_attach_attached_dev(dev)
#define MUIC_SEND_NOTI_DETACH(dev) \
muic_notifier_detach_attached_dev(dev)
#define MUIC_SEND_NOTI_TO_PDIC_ATTACH(dev) \
muic_pdic_notifier_attach_attached_dev(dev)
#define MUIC_SEND_NOTI_TO_PDIC_DETACH(dev) \
muic_pdic_notifier_detach_attached_dev(dev)
#endif
#if IS_ENABLED(CONFIG_MUIC_NOTIFIER)
extern void muic_send_lcd_on_uevent(struct muic_platform_data *muic_pdata);
extern int muic_set_hiccup_mode(int on_off);
extern int muic_hv_charger_init(void);
#if IS_ENABLED(CONFIG_MUIC_POGO)
extern int muic_set_pogo_adc(int adc);
#endif
extern int muic_afc_get_voltage(void);
extern int muic_afc_set_voltage(int voltage);
extern int muic_afc_request_voltage(int cause, int voltage);
extern int muic_afc_request_cause_clear(void);
extern int muic_afc_request_cause_clear_bit(int cause);
extern int muic_afc_get_request_cause(void);
extern bool muic_is_enable_afc_request(void);
extern int muic_hv_charger_disable(bool en);
#else
static inline void muic_send_lcd_on_uevent(struct muic_platform_data *muic_pdata)
{return; }
static inline int muic_set_hiccup_mode(int on_off) {return 0; }
static inline int muic_hv_charger_init(void) {return 0; }
static inline int muic_afc_get_voltage(void) {return 0; }
#if IS_ENABLED(CONFIG_MUIC_POGO)
static inline int muic_set_pogo_adc(int adc) {return 0};
#endif
static inline int muic_afc_set_voltage(int voltage) {return 0; }
static inline int muic_afc_request_voltage(int cause, int voltage);
static inline int muic_afc_request_cause_clear(void);
static inline int muic_afc_request_cause_clear_bit(int cause);
static inline int muic_afc_get_request_cause(void) {return 0;}
static inline bool muic_is_enable_afc_request(void) {return false;}
static inline int muic_hv_charger_disable(bool en) {return 0; }
#endif
#endif /* __MUIC_H__ */

View File

@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __MUIC_KUNIT_H__
#define __MUIC_KUNIT_H__
#if IS_ENABLED(CONFIG_SEC_KUNIT)
#include <kunit/mock.h>
#endif
#ifndef __mockable
#define __mockable
#endif
#ifndef __visible_for_testing
#define __visible_for_testing static
#endif
#ifndef EXPORT_SYMBOL_KUNIT
#define EXPORT_SYMBOL_KUNIT(sym) /* nothing */
#endif
#endif /* __MUIC_KUNIT_H__ */

View File

@@ -0,0 +1,112 @@
/*
* include/linux/muic/common/muic_notifier.h
*
* header file supporting MUIC notifier call chain information
*
* Copyright (C) 2010 Samsung Electronics
* Seung-Jin Hahn <sjin.hahn@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __MUIC_NOTIFIER_H__
#define __MUIC_NOTIFIER_H__
#include <linux/muic/common/muic.h>
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
#include <linux/usb/typec/common/pdic_notifier.h>
#endif
/* MUIC notifier call chain command */
typedef enum {
MUIC_NOTIFY_CMD_DETACH = 0,
MUIC_NOTIFY_CMD_ATTACH,
MUIC_NOTIFY_CMD_LOGICALLY_DETACH,
MUIC_NOTIFY_CMD_LOGICALLY_ATTACH,
MUIC_PDIC_NOTIFY_CMD_ATTACH,
MUIC_PDIC_NOTIFY_CMD_DETACH,
PDIC_MUIC_NOTIFY_CMD_JIG_ATTACH,
PDIC_MUIC_NOTIFY_CMD_JIG_DETACH,
} muic_notifier_cmd_t;
/* MUIC notifier call sequence,
* largest priority number device will be called first. */
typedef enum {
MUIC_NOTIFY_DEV_DOCK = 0,
MUIC_NOTIFY_DEV_MHL,
MUIC_NOTIFY_DEV_USB,
MUIC_NOTIFY_DEV_TSP,
MUIC_NOTIFY_DEV_CHARGER,
MUIC_NOTIFY_DEV_PDIC,
MUIC_NOTIFY_DEV_CPUIDLE,
MUIC_NOTIFY_DEV_CPUFREQ,
#if IS_ENABLED(CONFIG_USB_TYPEC_MANAGER_NOTIFIER)
MUIC_NOTIFY_DEV_MANAGER,
#endif
MUIC_NOTIFY_DEV_CABLE_DATA,
} muic_notifier_device_t;
struct muic_notifier_struct {
muic_attached_dev_t attached_dev;
muic_notifier_cmd_t cmd;
#if IS_ENABLED(CONFIG_PDIC_NOTIFIER)
PD_NOTI_ATTACH_TYPEDEF cxt;
#if IS_ENABLED(CONFIG_MUIC_POGO)
PD_NOTI_ATTACH_TYPEDEF pogo_cxt;
#endif /* CONFIG_MUIC_POGO */
#endif
struct blocking_notifier_head notifier_call_chain;
};
#define MUIC_NOTIFIER_BLOCK(name) \
struct notifier_block (name)
/* muic notifier init/notify function
* this function is for JUST MUIC device driver.
* DON'T use function anywhrer else!!
*/
extern struct device *switch_device;
extern void muic_notifier_attach_attached_dev(muic_attached_dev_t new_dev);
extern void muic_notifier_detach_attached_dev(muic_attached_dev_t cur_dev);
extern void muic_pdic_notifier_attach_attached_dev(muic_attached_dev_t new_dev);
extern void muic_pdic_notifier_detach_attached_dev(muic_attached_dev_t new_dev);
extern void muic_notifier_logically_attach_attached_dev(muic_attached_dev_t new_dev);
extern void muic_notifier_logically_detach_attached_dev(muic_attached_dev_t cur_dev);
#if IS_ENABLED(CONFIG_VIRTUAL_MUIC)
extern void vt_muic_notifier_attach_attached_dev(muic_attached_dev_t new_dev);
extern void vt_muic_notifier_detach_attached_dev(muic_attached_dev_t cur_dev);
#endif
#if IS_ENABLED(CONFIG_PDIC_SLSI_NON_MCU)
extern int muic_pdic_notifier_register(struct notifier_block *nb,
notifier_fn_t notifier, muic_notifier_device_t listener);
extern int muic_pdic_notifier_unregister(struct notifier_block *nb);
#endif
/* muic notifier register/unregister API
* for used any where want to receive muic attached device attach/detach. */
extern int muic_notifier_register(struct notifier_block *nb,
notifier_fn_t notifier, muic_notifier_device_t listener);
extern int muic_notifier_unregister(struct notifier_block *nb);
/* Choose a proper noti. interface for a test */
extern void muic_notifier_set_new_noti(bool flag);
#if IS_ENABLED(CONFIG_MUIC_POGO)
extern void muic_pogo_notifier_attach_attached_dev(muic_attached_dev_t new_dev);
extern void muic_pogo_notifier_detach_attached_dev(muic_attached_dev_t cur_dev);
#endif /* CONFIG_MUIC_POGO */
#endif /* __MUIC_NOTIFIER_H__ */

View File

@@ -0,0 +1,35 @@
/*
*
* Copyright (C) 2021 Samsung Electronics
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LINUX_MUIC_PARAM_H__
#define __LINUX_MUIC_PARAM_H__
#if IS_ENABLED(CONFIG_MUIC_NOTIFIER)
extern int get_switch_sel(void);
extern int get_uart_sel(void);
extern int get_afc_mode(void);
extern int get_pdic_info(void);
#else
static inline int get_switch_sel(void) {return 0; }
static inline int get_uart_sel(void) {return 0; }
static inline int get_afc_mode(void) {return 0; }
static inline int get_pdic_info(void) {return 1; }
#endif
#endif /* __LINUX_MUIC_PARAM_H__ */

View File

@@ -0,0 +1,15 @@
#ifndef MUIC_SYSFS_H
#define MUIC_SYSFS_H
#include <linux/muic/common/muic.h>
#ifdef CONFIG_MUIC_COMMON_SYSFS
extern int muic_sysfs_init(struct muic_platform_data *pdata);
extern void muic_sysfs_deinit(struct muic_platform_data *pdata);
#else
static inline int muic_sysfs_init(struct muic_platform_data *pdata)
{return 0; }
static inline void muic_sysfs_deinit(struct muic_platform_data *pdata) {}
#endif
#endif /* MUIC_SYSFS_H */

18
include/linux/ngksm.h Normal file
View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*/
#ifndef __LINUX_NGKSM_H
#define __LINUX_NGKSM_H
#include <linux/types.h>
// NGKSM Kernel Interface
extern int noinline ngksm_send_message(const char *feature_code,
const char *detail, int64_t value);
#endif /* __LINUX_NGKSM_H */

View File

@@ -206,9 +206,6 @@ enum mapping_flags {
AS_RELEASE_ALWAYS, /* Call ->release_folio(), even if no private data */
AS_STABLE_WRITES, /* must wait for writeback before modifying
folio contents */
#ifdef CONFIG_DDAR
AS_SENSITIVE = __GFP_BITS_SHIFT + 5, /* Group of sensitive pages to be cleaned up */
#endif
};
/**
@@ -406,25 +403,6 @@ static inline void filemap_nr_thps_dec(struct address_space *mapping)
#endif
}
#ifdef CONFIG_DDAR
static inline void mapping_set_sensitive(struct address_space *mapping)
{
set_bit(AS_SENSITIVE, &mapping->flags);
}
static inline void mapping_clear_sensitive(struct address_space *mapping)
{
clear_bit(AS_SENSITIVE, &mapping->flags);
}
static inline int mapping_sensitive(struct address_space *mapping)
{
if (mapping)
return test_bit(AS_SENSITIVE, &mapping->flags);
return !!mapping;
}
#endif
struct address_space *page_mapping(struct page *);
struct address_space *folio_mapping(struct folio *);
struct address_space *swapcache_mapping(struct folio *);

View File

@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013-2021, Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef PHY_QCOM_UFS_H_
#define PHY_QCOM_UFS_H_
#include "phy.h"
void ufs_qcom_phy_ctrl_rx_linecfg(struct phy *generic_phy, bool ctrl);
void ufs_qcom_phy_set_tx_lane_enable(struct phy *generic_phy, u32 tx_lanes);
int ufs_qcom_phy_get_tx_hs_equalizer(struct phy *generic_phy, u32 gear, u32 *val);
void ufs_qcom_phy_dbg_register_dump(struct phy *generic_phy);
void ufs_qcom_phy_dbg_register_save(struct phy *generic_phy);
void ufs_qcom_phy_set_src_clk_h8_enter(struct phy *generic_phy);
void ufs_qcom_phy_set_src_clk_h8_exit(struct phy *generic_phy);
void ufs_qcom_phy_save_controller_version(struct phy *generic_phy,
u8 major, u16 minor, u16 step);
#endif /* PHY_QCOM_UFS_H_ */

View File

@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __LINUX_PINCTRL_MSM_H__
#define __LINUX_PINCTRL_MSM_H__
#include <linux/types.h>
/* APIS to access qup_i3c registers */
int msm_qup_write(u32 mode, u32 val);
int msm_qup_read(u32 mode);
/* API to write to mpm_wakeup registers */
int msm_gpio_mpm_wake_set(unsigned int gpio, bool enable);
/* API to get gpio pin address */
bool msm_gpio_get_pin_address(unsigned int gpio, struct resource *res);
/* APIS to TLMM Spare registers */
int msm_spare_write(int spare_reg, u32 val);
int msm_spare_read(int spare_reg);
#endif /* __LINUX_PINCTRL_MSM_H__ */

View File

@@ -0,0 +1,39 @@
/*
* sec_thermistor.h - SEC Thermistor
*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* Minsung Kim <ms925.kim@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SEC_THERMISTOR_H
#define __LINUX_SEC_THERMISTOR_H __FILE__
/**
* struct sec_therm_adc_table - adc to temperature table for sec thermistor
* driver
* @adc: adc value
* @temperature: temperature(Celsius) * 10
*/
struct sec_therm_adc_table {
int adc;
int temperature;
};
/**
* struct sec_bat_plaform_data - init data for sec batter driver
* @adc_channel: adc channel that connected to thermistor
* @adc_table: array of adc to temperature data
* @adc_arr_size: size of adc_table
*/
struct sec_therm_platform_data {
unsigned int adc_channel;
unsigned int adc_arr_size;
bool iio_processed;
struct sec_therm_adc_table *adc_table;
};
#endif /* __LINUX_SEC_THERMISTOR_H */

View File

@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Fake platform device API for unit testing platform drivers.
*
* Copyright (C) 2018, Google LLC.
* Author: Brendan Higgins <brendanhiggins@google.com>
*/
#include <linux/platform_device.h>
#include <kunit/mock.h>
static inline struct platform_driver *platform_driver_find(const char *name)
{
struct device_driver *driver;
driver = driver_find(name, &platform_bus_type);
if (!driver)
return NULL;
return to_platform_driver(driver);
}
/**
* of_fake_node()
* @test: the test to associate node with
* @name: name of the node
*
* The &struct device_node returned is allocated as a root node with the given
* name and otherwise behaves as a real &struct device_node.
*
* Returns: the faked &struct device_node
*/
struct device_node *of_fake_node(struct kunit *test, const char *name);
/**
* of_fake_probe_platform()
* @test: the test to associate the fake platform device with
* @driver: driver to probe
* @node_name: name of the device node created
*
* Creates a &struct platform_device and an associated &struct device_node,
* probes the provided &struct platform_driver with the &struct platform_device.
*
* Returns: the &struct platform_device that was created
*/
struct platform_device *
of_fake_probe_platform(struct kunit *test,
struct platform_driver *driver,
const char *node_name);
/**
* of_fake_probe_platform_by_name()
* @test: the test to associate the fake platform device with
* @driver_name: name of the driver to probe
* @node_name: name of the device node created
*
* Same as of_fake_probe_platform() but looks up the &struct platform_driver by
* the provided name.
*
* Returns: the &struct platform_device that was created
*/
struct platform_device *of_fake_probe_platform_by_name(struct kunit *test,
const char *driver_name,
const char *node_name);

View File

@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __PMIC_VOTER_H
#define __PMIC_VOTER_H
#include <linux/mutex.h>
struct votable;
enum votable_type {
VOTE_MIN,
VOTE_MAX,
VOTE_SET_ANY,
NUM_VOTABLE_TYPES,
};
bool is_client_vote_enabled(struct votable *votable, const char *client_str);
bool is_client_vote_enabled_locked(struct votable *votable,
const char *client_str);
bool is_override_vote_enabled(struct votable *votable);
bool is_override_vote_enabled_locked(struct votable *votable);
int get_client_vote(struct votable *votable, const char *client_str);
int get_client_vote_locked(struct votable *votable, const char *client_str);
int get_effective_result(struct votable *votable);
int get_effective_result_locked(struct votable *votable);
const char *get_effective_client(struct votable *votable);
const char *get_effective_client_locked(struct votable *votable);
int vote(struct votable *votable, const char *client_str, bool state, int val);
int vote_override(struct votable *votable, const char *override_client,
bool state, int val);
int rerun_election(struct votable *votable);
struct votable *find_votable(const char *name);
struct votable *create_votable(const char *name,
int votable_type,
int (*callback)(struct votable *votable,
void *data,
int effective_result,
const char *effective_client),
void *data);
void destroy_votable(struct votable *votable);
void lock_votable(struct votable *votable);
void unlock_votable(struct votable *votable);
#endif /* __PMIC_VOTER_H */

View File

@@ -1,4 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* PROCA fnctl declarations
*

View File

@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_QCOM_CPUFREQ_HW_H
#define _LINUX_QCOM_CPUFREQ_HW_H
/*
* We can take this out if we could move the OSM cycle
* counter to WALT scheduler?
*/
#if IS_ENABLED(CONFIG_ARM_QCOM_CPUFREQ_HW)
extern u64 qcom_cpufreq_get_cpu_cycle_counter(int cpu);
#else
static inline u64 qcom_cpufreq_get_cpu_cycle_counter(int cpu)
{
return U64_MAX;
}
#endif /*CONFIG_ARM_QCOM_CPUFREQ_HW*/
#endif /* _LINUX_QCOM_CPUFREQ_HW_H */

View File

@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
& Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/*
* DMA_ATTR_NO_DELAYED_UNMAP: Used by msm specific lazy mapping to indicate
* that the mapping can be freed on unmap, rather than when the ion_buffer
* is freed.
*/
#define DMA_ATTR_NO_DELAYED_UNMAP (1UL << 13)
/*
* When passed to a DMA map call the DMA_ATTR_FORCE_COHERENT DMA
* attribute can be used to force a buffer to be mapped as IO coherent.
*/
#define DMA_ATTR_FORCE_COHERENT (1UL << 15)
/*
* When passed to a DMA map call the DMA_ATTR_FORCE_NON_COHERENT DMA
* attribute can be used to force a buffer to not be mapped as IO
* coherent.
*/
#define DMA_ATTR_FORCE_NON_COHERENT (1UL << 16)
/*
* DMA_ATTR_DELAYED_UNMAP: Used by ION, it will ensure that mappings are not
* removed on unmap but instead are removed when the ion_buffer is freed.
*/
#define DMA_ATTR_DELAYED_UNMAP (1UL << 17)
/*
* DMA_ATTR_QTI_SMMU_PROXY_MAP : Map this buffer in the TVM SMMU if supported
* on the target.
*/
#define DMA_ATTR_QTI_SMMU_PROXY_MAP (1UL << 18)
#ifndef DMA_ATTR_SYS_CACHE
/* Attributes are not supported, so render them ineffective. */
#define DMA_ATTR_SYS_CACHE (0UL)
#define DMA_ATTR_SYS_CACHE_NWA (0UL)
#endif

View File

@@ -0,0 +1,542 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _LINUX_QCOM_GENI_SE_COMMON
#define _LINUX_QCOM_GENI_SE_COMMON
#include <linux/clk.h>
#include <linux/dma-direction.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/sched/clock.h>
#include <linux/ipc_logging.h>
#ifdef CONFIG_ARM64
#define GENI_SE_DMA_PTR_L(ptr) ((u32)ptr)
#define GENI_SE_DMA_PTR_H(ptr) ((u32)(ptr >> 32))
#else
#define GENI_SE_DMA_PTR_L(ptr) ((u32)ptr)
#define GENI_SE_DMA_PTR_H(ptr) 0
#endif
#define QUPV3_TEST_BUS_EN 0x204 //write 0x11
#define QUPV3_TEST_BUS_SEL 0x200 //write 0x5 [for SE index 4)
#define QUPV3_TEST_BUS_REG 0x208 //Read only reg, to be read as part of dump
#define IPC_LOG_KPI_PAGES (4) // KPI IPC Log size
#define GENI_SE_ERR(log_ctx, print, dev, x...) do { \
ipc_log_string(log_ctx, x); \
if (print) { \
if (dev) \
dev_err((dev), x); \
else \
pr_err(x); \
} \
} while (0)
#define GENI_SE_DBG(log_ctx, print, dev, x...) do { \
ipc_log_string(log_ctx, x); \
if (print) { \
if (dev) \
dev_dbg((dev), x); \
else \
pr_debug(x); \
} \
} while (0)
#define DEFAULT_BUS_WIDTH (4)
/* In KHz */
#define DEFAULT_SE_CLK 19200
#define SPI_CORE2X_VOTE 51000
#define Q2SPI_CORE2X_VOTE 100000
#define I2C_CORE2X_VOTE 50000
#define I3C_CORE2X_VOTE 50000
#define APPS_PROC_TO_QUP_VOTE 140000
/* COMMON SE REGISTERS */
#define GENI_GENERAL_CFG (0x10)
#define GENI_CLK_CTRL_RO (0x60)
#define GENI_FW_MULTILOCK_MSA_RO (0x74)
/* SE_DMA_GENERAL_CFG */
#define DMA_IF_EN_RO (0xe20)
#define SE_GSI_EVENT_EN (0xe18)
#define SE_IRQ_EN (0xe1c)
#define DMA_GENERAL_CFG (0xe30)
#define SE_DMA_DEBUG_REG0 (0xE40)
#define SE_DMA_TX_PTR_L (0xC30)
#define SE_DMA_TX_PTR_H (0xC34)
#define SE_DMA_TX_ATTR (0xC38)
#define SE_DMA_TX_LEN (0xC3C)
#define SE_DMA_TX_IRQ_EN (0xC48)
#define SE_DMA_TX_LEN_IN (0xC54)
#define GENI_SE_DMA_EOT_BUF (BIT(0))
#define SE_DMA_RX_PTR_L (0xD30)
#define SE_DMA_RX_PTR_H (0xD34)
#define SE_DMA_RX_ATTR (0xD38)
#define SE_DMA_RX_LEN (0xD3C)
#define SE_DMA_RX_IRQ_EN (0xD48)
#define SE_DMA_TX_IRQ_EN_SET (0xC4C)
#define SE_DMA_TX_IRQ_EN_CLR (0xC50)
#define SE_DMA_RX_IRQ_EN_SET (0xD4C)
#define SE_DMA_RX_IRQ_EN_CLR (0xD50)
#define TX_GENI_CANCEL_IRQ (BIT(14))
#define SE_HW_PARAM_2 (0xE2C)
/* DMA DEBUG Register fields */
#define DMA_TX_ACTIVE (BIT(0))
#define DMA_RX_ACTIVE (BIT(1))
#define DMA_TX_STATE (GENMASK(7, 4))
#define DMA_RX_STATE (GENMASK(11, 8))
/* SE_IRQ_EN fields */
#define DMA_RX_IRQ_EN (BIT(0))
#define DMA_TX_IRQ_EN (BIT(1))
#define GENI_M_IRQ_EN (BIT(2))
#define GENI_S_IRQ_EN (BIT(3))
#define GENI_FW_S_REVISION_RO (0x6C)
#define FW_REV_VERSION_MSK (GENMASK(7, 0))
/* SE_HW_PARAM_2 fields */
#define GEN_HW_FSM_I2C (BIT(15))
/* GENI_OUTPUT_CTRL fields */
#define GENI_CFG_REG80 0x240
#define GENI_IO_MUX_0_EN BIT(0)
#define GENI_IO_MUX_1_EN BIT(2)
/* GENI_CFG_REG80 fields */
#define IO1_SEL_TX BIT(2)
#define IO2_DATA_IN_SEL_PAD2 GENMASK(11, 10)
#define IO3_DATA_IN_SEL_PAD2 BIT(15)
#define GSI_TX_PACK_EN (BIT(0))
#define GSI_RX_PACK_EN (BIT(1))
#define GSI_PRESERVE_PACK (BIT(2))
#define HW_VER_MAJOR_MASK GENMASK(31, 28)
#define HW_VER_MAJOR_SHFT 28
#define HW_VER_MINOR_MASK GENMASK(27, 16)
#define HW_VER_MINOR_SHFT 16
#define HW_VER_STEP_MASK GENMASK(15, 0)
#define OTHER_IO_OE BIT(12)
#define IO2_DATA_IN_SEL BIT(11)
#define RX_DATA_IN_SEL BIT(8)
#define IO_MACRO_IO3_SEL (GENMASK(7, 6))
#define IO_MACRO_IO2_SEL BIT(5)
#define IO_MACRO_IO0_SEL_BIT BIT(0)
/**
* struct kpi_time - Help to capture KPI information
* @len: length of the request
* @time_stamp: Time stamp of the request
*
* This struct used to hold length and time stamp of Tx/Rx request
*
*/
struct kpi_time {
unsigned int len;
unsigned long long time_stamp;
};
static inline int geni_se_common_resources_init(struct geni_se *se, u32 geni_to_core,
u32 cpu_to_geni, u32 geni_to_ddr)
{
int ret;
ret = geni_icc_get(se, "qup-memory");
if (ret)
return ret;
se->icc_paths[GENI_TO_CORE].avg_bw = geni_to_core;
se->icc_paths[CPU_TO_GENI].avg_bw = cpu_to_geni;
se->icc_paths[GENI_TO_DDR].avg_bw = geni_to_ddr;
return ret;
}
static inline int geni_se_common_get_proto(void __iomem *base)
{
int proto;
proto = ((readl_relaxed(base + GENI_FW_REVISION_RO)
& FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT);
return proto;
}
/**
* geni_se_common_get_m_fw - Read the Firmware ver for the Main sequencer engine
* @base: Base address of the serial engine's register block.
*
* Return: Firmware version for the Main sequencer engine
*/
static inline int geni_se_common_get_m_fw(void __iomem *base)
{
int fw_ver_m;
fw_ver_m = ((readl_relaxed(base + GENI_FW_REVISION_RO)
& FW_REV_VERSION_MSK));
return fw_ver_m;
}
/**
* geni_se_common_get_s_fw() - Read the Firmware ver for the Secondry sequencer engine
* @base: Base address of the serial engine's register block.
*
* Return: Firmware version for the Secondry sequencer engine
*/
static inline int geni_se_common_get_s_fw(void __iomem *base)
{
int fw_ver_s;
fw_ver_s = ((readl_relaxed(base + GENI_FW_S_REVISION_RO)
& FW_REV_VERSION_MSK));
return fw_ver_s;
}
/**
* geni_se_common_clks_off - Disabling SE clks and common clks
* @se_clk: Pointer to the SE-CLk.
* @m_ahb_clk: Pointer to the SE common m_ahb_clk.
* @s_ahb_clk: Pointer to the SE common s_ahb_clk.
*/
static inline void geni_se_common_clks_off(struct clk *se_clk, struct clk *m_ahb_clk,
struct clk *s_ahb_clk)
{
clk_disable_unprepare(se_clk);
clk_disable_unprepare(m_ahb_clk);
clk_disable_unprepare(s_ahb_clk);
}
/**
* geni_se_common_clks_on - enabling SE clks and common clks
* @se_clk: Pointer to the SE-CLk.
* @m_ahb_clk: Pointer to the SE common m_ahb_clk.
* @s_ahb_clk: Pointer to the SE common s_ahb_clk.
*/
static inline int geni_se_common_clks_on(struct clk *se_clk, struct clk *m_ahb_clk,
struct clk *s_ahb_clk)
{
int ret;
ret = clk_prepare_enable(m_ahb_clk);
if (ret)
goto clks_on_err1;
ret = clk_prepare_enable(s_ahb_clk);
if (ret)
goto clks_on_err2;
ret = clk_prepare_enable(se_clk);
if (ret)
goto clks_on_err3;
return 0;
clks_on_err3:
clk_disable_unprepare(s_ahb_clk);
clks_on_err2:
clk_disable_unprepare(m_ahb_clk);
clks_on_err1:
return ret;
}
/**
* geni_write_reg() - Helper function to write into a GENI register
* @value: Value to be written into the register.
* @base: Base address of the serial engine's register block.
* @offset: Offset within the serial engine's register block.
*/
static inline void geni_write_reg(unsigned int value, void __iomem *base, int offset)
{
return writel_relaxed(value, (base + offset));
}
/**
* geni_read_reg() - Helper function to read from a GENI register
* @base: Base address of the serial engine's register block.
* @offset: Offset within the serial engine's register block.
*
* Return: Return the contents of the register.
*/
static inline unsigned int geni_read_reg(void __iomem *base, int offset)
{
return readl_relaxed(base + offset);
}
/**
* geni_se_common_iommu_map_buf() - Map a single buffer into QUPv3 context bank
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
* @iova: Pointer in which the mapped virtual address is stored.
* @buf: Address of the buffer that needs to be mapped.
* @size: Size of the buffer.
* @dir: Direction of the DMA transfer.
*
* This function is used to map an already allocated buffer into the
* QUPv3 context bank device space.
*
* Return: 0 on success, standard Linux error codes on failure/error.
*/
static inline int geni_se_common_iommu_map_buf(struct device *wrapper_dev, dma_addr_t *iova,
void *buf, size_t size, enum dma_data_direction dir)
{
if (!wrapper_dev)
return -EINVAL;
*iova = dma_map_single(wrapper_dev, buf, size, dir);
if (dma_mapping_error(wrapper_dev, *iova))
return -EIO;
return 0;
}
/**
* geni_se_common_iommu_unmap_buf() - Unmap a single buffer from QUPv3 context bank
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
* @iova: Pointer in which the mapped virtual address is stored.
* @size: Size of the buffer.
* @dir: Direction of the DMA transfer.
*
* This function is used to unmap an already mapped buffer from the
* QUPv3 context bank device space.
*
* Return: 0 on success, standard Linux error codes on failure/error.
*/
static inline int geni_se_common_iommu_unmap_buf(struct device *wrapper_dev, dma_addr_t *iova,
size_t size, enum dma_data_direction dir)
{
if (!dma_mapping_error(wrapper_dev, *iova))
dma_unmap_single(wrapper_dev, *iova, size, dir);
return 0;
}
/**
* geni_se_common_iommu_alloc_buf() - Allocate & map a single buffer into QUPv3
* context bank
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
* @iova: Pointer in which the mapped virtual address is stored.
* @size: Size of the buffer.
*
* This function is used to allocate a buffer and map it into the
* QUPv3 context bank device space.
*
* Return: address of the buffer on success, NULL or ERR_PTR on
* failure/error.
*/
static inline void *geni_se_common_iommu_alloc_buf(struct device *wrapper_dev, dma_addr_t *iova,
size_t size)
{
void *buf = NULL;
if (!wrapper_dev || !iova || !size)
return ERR_PTR(-EINVAL);
*iova = DMA_MAPPING_ERROR;
buf = dma_alloc_coherent(wrapper_dev, size, iova, GFP_KERNEL);
return buf;
}
/**
* geni_se_common_iommu_free_buf() - Unmap & free a single buffer from QUPv3
* context bank
* @wrapper_dev: Pointer to the corresponding QUPv3 wrapper core.
* @iova: Pointer in which the mapped virtual address is stored.
* @buf: Address of the buffer.
* @size: Size of the buffer.
*
* This function is used to unmap and free a buffer from the
* QUPv3 context bank device space.
*
* Return: 0 on success, standard Linux error codes on failure/error.
*/
static inline int geni_se_common_iommu_free_buf(struct device *wrapper_dev, dma_addr_t *iova,
void *buf, size_t size)
{
if (!wrapper_dev || !iova || !buf || !size)
return -EINVAL;
dma_free_coherent(wrapper_dev, size, buf, *iova);
return 0;
}
/**
* geni_se_common_rx_dma_start() - Prepare Serial Engine registers for RX DMA
transfers.
* @base: Base address of the SE register block.
* @rx_len: Length of the RX buffer.
* @rx_dma: Pointer to store the mapped DMA address.
*
* This function is used to prepare the Serial Engine registers for DMA RX.
*
* Return: None.
*/
static inline void geni_se_common_rx_dma_start(void __iomem *base, int rx_len, dma_addr_t *rx_dma)
{
if (!*rx_dma || !base || !rx_len)
return;
geni_write_reg(7, base, SE_DMA_RX_IRQ_EN_SET);
geni_write_reg(GENI_SE_DMA_PTR_L(*rx_dma), base, SE_DMA_RX_PTR_L);
geni_write_reg(GENI_SE_DMA_PTR_H(*rx_dma), base, SE_DMA_RX_PTR_H);
/* RX does not have EOT bit */
geni_write_reg(0, base, SE_DMA_RX_ATTR);
/* Ensure that above register writes went through */
mb();
geni_write_reg(rx_len, base, SE_DMA_RX_LEN);
}
/**
* geni_se_common_get_major_minor_num() - Split qup hw_version into
major, minor and step.
* @hw_version: HW version of the qup
* @major: Buffer for Major Version field.
* @minor: Buffer for Minor Version field.
* @step: Buffer for Step Version field.
*
* Return: None
*/
static inline void geni_se_common_get_major_minor_num(u32 hw_version,
unsigned int *major, unsigned int *minor, unsigned int *step)
{
*major = (hw_version & HW_VER_MAJOR_MASK) >> HW_VER_MAJOR_SHFT;
*minor = (hw_version & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT;
*step = hw_version & HW_VER_STEP_MASK;
}
/*
* test_bus_enable_per_qupv3: enables particular test bus number.
* @wrapper_dev: QUPV3 common driver handle from SE driver
*
* Note: Need to call only once.
*
* Return: none
*/
static inline void test_bus_enable_per_qupv3(struct device *wrapper_dev, void *ipc)
{
struct geni_se *geni_se_dev;
geni_se_dev = dev_get_drvdata(wrapper_dev);
//Enablement of test bus is required only once.
//TEST_BUS_EN:4, TEST_BUS_REG_EN:0
geni_write_reg(0x11, geni_se_dev->base, QUPV3_TEST_BUS_EN);
GENI_SE_ERR(ipc, false, geni_se_dev->dev,
"%s: TEST_BUS_EN: 0x%x @address:%p\n",
__func__, geni_read_reg(geni_se_dev->base, QUPV3_TEST_BUS_EN),
(geni_se_dev->base + QUPV3_TEST_BUS_EN));
}
/*
* test_bus_select_per_qupv3: Selects the test bus as required
* @wrapper_dev: QUPV3 common driver handle from SE driver
* @test_bus_num: GENI SE number from QUPV3 core. E.g. SE0 should pass value 1.
*
* @Return: None
*/
static inline void test_bus_select_per_qupv3(struct device *wrapper_dev, u8 test_bus_num, void *ipc)
{
struct geni_se *geni_se_dev;
geni_se_dev = dev_get_drvdata(wrapper_dev);
geni_write_reg(test_bus_num, geni_se_dev->base, QUPV3_TEST_BUS_SEL);
GENI_SE_ERR(ipc, false, geni_se_dev->dev,
"%s: readback TEST_BUS_SEL: 0x%x @address:%p\n",
__func__, geni_read_reg(geni_se_dev->base, QUPV3_TEST_BUS_SEL),
(geni_se_dev->base + QUPV3_TEST_BUS_SEL));
}
/*
* test_bus_read_per_qupv3: Selects the test bus as required
* @wrapper_dev: QUPV3 common driver handle from SE driver
*
* Return: None
*/
static inline void test_bus_read_per_qupv3(struct device *wrapper_dev, void *ipc)
{
struct geni_se *geni_se_dev;
geni_se_dev = dev_get_drvdata(wrapper_dev);
GENI_SE_ERR(ipc, false, geni_se_dev->dev,
"%s: dump QUPV3_TEST_BUS_REG:0x%x\n",
__func__, geni_read_reg(geni_se_dev->base, QUPV3_TEST_BUS_REG));
}
/**
* geni_capture_start_time() - Used to capture start time of a function.
* @se: serial engine device
* @ipc: which IPC module to be used to log.
* @func: for which function start time is captured.
* @geni_kpi_capture_enabled: kpi capture enable flag to start capture the logs or not.
*
* Return: start time if kpi geni_kpi_capture_enabled flag enabled or error value.
*/
static inline unsigned long long geni_capture_start_time(struct geni_se *se, void *ipc,
const char *func,
int geni_kpi_capture_enabled)
{
struct device *dev = se->dev;
unsigned long long start_time = 0;
if (!ipc)
return -EINVAL;
if (geni_kpi_capture_enabled) {
start_time = sched_clock();
GENI_SE_ERR(ipc, false, dev,
"%s:start at %llu nsec(%llu usec)\n", func,
start_time, (start_time / 1000));
}
return start_time;
}
/**
* geni_capture_stop_time() - Logs the function execution time
* @se: serial engine device
* @ipc: which IPC module to be used to log.
* @func: for which function kpi capture is used.
* @geni_kpi_capture_enabled: kpi capture enable flag to start capture the logs or not.
* @start_time: start time of the function
* @len: Number of bytes of transfer
* @freq: frequency of operation
* Return: None
*/
static inline void geni_capture_stop_time(struct geni_se *se, void *ipc,
const char *func, int geni_kpi_capture_enabled,
unsigned long long start_time, unsigned int len,
unsigned int freq)
{
struct device *dev = se->dev;
unsigned long long exec_time = 0;
if (!ipc)
return;
if (geni_kpi_capture_enabled && start_time) {
exec_time = sched_clock() - start_time;
if (!len)
GENI_SE_ERR(ipc, false, dev,
"%s:took %llu nsec(%llu usec)\n",
func, exec_time, (exec_time / 1000));
else if (len != 0 && freq != 0)
GENI_SE_ERR(ipc, false, dev,
"%s:took %llu nsec(%llu usec) for %u bytes with freq %u\n",
func, exec_time, (exec_time / 1000), len, freq);
else
GENI_SE_ERR(ipc, false, dev,
"%s:took %llu nsec(%llu usec) for %u bytes\n", func,
exec_time, (exec_time / 1000), len);
}
}
#endif

View File

@@ -0,0 +1,99 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_QCOM_IO_PGTABLE_H
#define __QCOM_QCOM_IO_PGTABLE_H
#include <linux/io-pgtable.h>
struct qcom_iommu_pgtable_log_ops {
void (*log_new_table)(void *cookie, void *virt, unsigned long iova, size_t granule);
void (*log_remove_table)(void *cookie, void *virt, unsigned long iova, size_t granule);
};
struct qcom_iommu_flush_ops {
void (*tlb_add_walk_page)(void *cookie, void *virt);
void (*tlb_add_inv)(void *cookie);
void (*tlb_sync)(void *cookie);
};
struct qcom_io_pgtable_info {
struct io_pgtable_cfg cfg;
const struct qcom_iommu_flush_ops *iommu_tlb_ops;
const struct qcom_iommu_pgtable_log_ops *pgtable_log_ops;
/* When set to 0, all page table memory is treated as non-secure. */
u32 vmid;
dma_addr_t iova_base;
dma_addr_t iova_end;
};
#define to_qcom_io_pgtable_info(x)\
container_of((x), struct qcom_io_pgtable_info, cfg)
#define IO_PGTABLE_QUIRK_QCOM_USE_LLC_NWA BIT(31)
#define ARM_V8L_FAST ((unsigned int)-1)
#define QCOM_ARM_64_LPAE_S1 ((unsigned int)-2)
struct io_pgtable_ops *qcom_alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
struct qcom_io_pgtable_info *pgtbl_info,
void *cookie);
void qcom_free_io_pgtable_ops(struct io_pgtable_ops *ops);
static inline void
qcom_io_pgtable_tlb_add_walk_page(const struct qcom_iommu_flush_ops *tlb_ops, void *cookie,
void *virt)
{
tlb_ops->tlb_add_walk_page(cookie, virt);
}
static inline void
qcom_io_pgtable_tlb_add_inv(const struct qcom_iommu_flush_ops *tlb_ops, void *cookie)
{
tlb_ops->tlb_add_inv(cookie);
}
static inline void
qcom_io_pgtable_tlb_sync(const struct qcom_iommu_flush_ops *tlb_ops, void *cookie)
{
tlb_ops->tlb_sync(cookie);
}
static inline void
qcom_io_pgtable_log_new_table(const struct qcom_iommu_pgtable_log_ops *ops, void *cookie,
void *virt, unsigned long iova, size_t granule)
{
ops->log_new_table(cookie, virt, iova, granule);
}
static inline void
qcom_io_pgtable_log_remove_table(const struct qcom_iommu_pgtable_log_ops *ops, void *cookie,
void *virt, unsigned long iova, size_t granule)
{
ops->log_remove_table(cookie, virt, iova, granule);
}
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
extern struct io_pgtable_init_fns io_pgtable_av8l_fast_init_fns;
#endif
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
extern struct io_pgtable_init_fns qcom_io_pgtable_arm_64_lpae_s1_init_fns;
#endif
int qcom_arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
phys_addr_t paddr, size_t size, int iommu_prot, gfp_t gfp);
int qcom_arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount,
int iommu_prot, gfp_t gfp, size_t *mapped);
int qcom_arm_lpae_map_sg(struct io_pgtable_ops *ops, unsigned long iova,
struct scatterlist *sg, unsigned int nents, int prot,
gfp_t gfp, size_t *mapped);
size_t qcom_arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
size_t pgsize, size_t pgcount,
struct iommu_iotlb_gather *gather);
size_t qcom_arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
size_t size, struct iommu_iotlb_gather *gather);
#endif /* __QCOM_QCOM_IO_PGTABLE_H */

View File

@@ -0,0 +1,155 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_IOMMU_UTIL_H
#define __QCOM_IOMMU_UTIL_H
#include <linux/iommu.h>
#include <linux/dma-mapping.h>
#include <linux/iova.h>
#include <soc/qcom/secure_buffer.h>
/* IOMMU fault behaviors */
#define QCOM_IOMMU_FAULT_MODEL_NON_FATAL BIT(0)
#define QCOM_IOMMU_FAULT_MODEL_NO_CFRE BIT(1)
#define QCOM_IOMMU_FAULT_MODEL_NO_STALL BIT(2)
#define QCOM_IOMMU_FAULT_MODEL_HUPCF BIT(3)
/* IOMMU mapping configurations */
#define QCOM_IOMMU_MAPPING_CONF_S1_BYPASS BIT(0)
#define QCOM_IOMMU_MAPPING_CONF_ATOMIC BIT(1)
#define QCOM_IOMMU_MAPPING_CONF_FAST BIT(2)
/* iommu transaction flags */
/* 1 Write, 0 Read */
#define QCOM_IOMMU_ATOS_TRANS_WRITE BIT(0)
/* 1 Privileged, 0 Unprivileged */
#define QCOM_IOMMU_ATOS_TRANS_PRIV BIT(1)
/* 1 Instruction fetch, 0 Data access */
#define QCOM_IOMMU_ATOS_TRANS_INST BIT(2)
/* Non secure unprivileged Data read operation */
#define QCOM_IOMMU_ATOS_TRANS_DEFAULT (0U)
#ifndef IOMMU_SYS_CACHE
/* Attributes are not supported, so render them ineffective. */
#define IOMMU_SYS_CACHE (0)
#define IOMMU_SYS_CACHE_NWA (0)
#endif
/* vendor iommu fault flags */
#define IOMMU_FAULT_TRANSLATION (1 << 2)
#define IOMMU_FAULT_PERMISSION (1 << 3)
#define IOMMU_FAULT_EXTERNAL (1 << 4)
#define IOMMU_FAULT_TRANSACTION_STALLED (1 << 5)
/* iommu transaction flags */
#define IOMMU_TRANS_WRITE BIT(0) /* 1 Write, 0 Read */
#define IOMMU_TRANS_PRIV BIT(1) /* 1 Privileged, 0 Unprivileged */
#define IOMMU_TRANS_INST BIT(2) /* 1 Instruction fetch, 0 Data access */
#define IOMMU_TRANS_SEC BIT(3) /* 1 Secure, 0 Non-secure access*/
/* Non secure unprivileged Data read operation */
#define IOMMU_TRANS_DEFAULT (0U)
typedef void (*fault_handler_irq_t)(struct iommu_domain *, void *);
struct iommu_pgtbl_info {
void *ops;
};
struct qcom_iommu_atos_txn {
u64 addr;
u32 flags;
u32 id;
};
enum sid_switch_direction {
SID_ACQUIRE,
SID_RELEASE,
};
struct qcom_iommu_fault_ids {
u32 bid;
u32 pid;
u32 mid;
};
/*
* @sid_switch: add/remove all SIDS in the iommu domain containing dev from
* iommu registers.
*/
struct qcom_iommu_ops {
phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
struct qcom_iommu_atos_txn *txn);
int (*sid_switch)(struct device *dev, enum sid_switch_direction dir);
int (*get_fault_ids)(struct iommu_domain *domain,
struct qcom_iommu_fault_ids *ids);
int (*get_context_bank_nr)(struct iommu_domain *domain);
int (*get_asid_nr)(struct iommu_domain *domain);
int (*set_secure_vmid)(struct iommu_domain *domain, enum vmid vmid);
int (*set_fault_model)(struct iommu_domain *domain, int fault_model);
void (*set_fault_handler_irq)(struct iommu_domain *domain,
fault_handler_irq_t handler_irq, void *token);
void (*register_device_fault_handler_irq)(struct device *dev,
fault_handler_irq_t handler, void *token);
int (*enable_s1_translation)(struct iommu_domain *domain);
int (*get_mappings_configuration)(struct iommu_domain *domain);
void (*skip_tlb_management)(struct iommu_domain *domain, bool skip);
struct iommu_ops iommu_ops;
struct iommu_domain_ops domain_ops;
};
#define to_qcom_iommu_ops(x) (container_of(x, struct qcom_iommu_ops, domain_ops))
struct device_node *qcom_iommu_group_parse_phandle(struct device *dev);
int qcom_iommu_generate_dma_regions(struct device *dev,
struct list_head *head);
void qcom_iommu_generate_resv_regions(struct device *dev,
struct list_head *list);
int qcom_iommu_get_fast_iova_range(struct device *dev,
dma_addr_t *ret_iova_base,
dma_addr_t *ret_iova_end);
/* Remove once this function is exported by upstream kernel */
void qcom_iommu_get_resv_regions(struct device *dev, struct list_head *list);
phys_addr_t qcom_iommu_iova_to_phys_hard(struct iommu_domain *domain,
struct qcom_iommu_atos_txn *txn);
int qcom_iommu_sid_switch(struct device *dev, enum sid_switch_direction dir);
int qcom_skip_tlb_management(struct device *dev, bool skip);
extern int qcom_iommu_get_fault_ids(struct iommu_domain *domain,
struct qcom_iommu_fault_ids *f_ids);
extern int qcom_iommu_get_msi_size(struct device *dev, u32 *msi_size);
int qcom_iommu_get_context_bank_nr(struct iommu_domain *domain);
int qcom_iommu_get_asid_nr(struct iommu_domain *domain);
int qcom_iommu_set_secure_vmid(struct iommu_domain *domain, enum vmid vmid);
int qcom_iommu_set_fault_model(struct iommu_domain *domain, int fault_model);
int qcom_iommu_set_fault_handler_irq(struct iommu_domain *domain,
fault_handler_irq_t handler_irq, void *token);
int qcom_iommu_register_device_fault_handler_irq(struct device *dev,
fault_handler_irq_t handler, void *token);
int qcom_iommu_enable_s1_translation(struct iommu_domain *domain);
int qcom_iommu_get_mappings_configuration(struct iommu_domain *domain);
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
int __init qcom_arm_lpae_do_selftests(void);
#else
static inline int __init qcom_arm_lpae_do_selftests(void)
{
return 0;
}
#endif
#endif /* __QCOM_IOMMU_UTIL_H */

View File

@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _QCOM_DMA_HEAP_H
#define _QCOM_DMA_HEAP_H
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/dma-buf.h>
#include <linux/qcom_dma_heap_dt_constants.h>
#include <linux/err.h>
/* Heap flags */
#define QCOM_DMA_HEAP_FLAG_CACHED BIT(1)
#define QCOM_DMA_HEAP_FLAG_CP_TRUSTED_VM BIT(15)
#define QCOM_DMA_HEAP_FLAG_CP_TZ BIT(16)
#define QCOM_DMA_HEAP_FLAG_CP_TOUCH BIT(17)
#define QCOM_DMA_HEAP_FLAG_CP_BITSTREAM BIT(18)
#define QCOM_DMA_HEAP_FLAG_CP_PIXEL BIT(19)
#define QCOM_DMA_HEAP_FLAG_CP_NON_PIXEL BIT(20)
#define QCOM_DMA_HEAP_FLAG_CP_CAMERA BIT(21)
#define QCOM_DMA_HEAP_FLAG_CP_HLOS BIT(22)
#define QCOM_DMA_HEAP_FLAG_CP_SPSS_SP BIT(23)
#define QCOM_DMA_HEAP_FLAG_CP_SPSS_SP_SHARED BIT(24)
#define QCOM_DMA_HEAP_FLAG_CP_SEC_DISPLAY BIT(25)
#define QCOM_DMA_HEAP_FLAG_CP_APP BIT(26)
#define QCOM_DMA_HEAP_FLAG_CP_CAMERA_PREVIEW BIT(27)
#define QCOM_DMA_HEAP_FLAG_CP_MSS_MSA BIT(28)
#define QCOM_DMA_HEAP_FLAG_CP_CDSP BIT(29)
#define QCOM_DMA_HEAP_FLAG_CP_SPSS_HLOS_SHARED BIT(30)
#define QCOM_DMA_HEAP_FLAGS_CP_MASK GENMASK(30, 15)
#define QCOM_DMA_HEAP_FLAG_SECURE BIT(31)
bool qcom_is_dma_buf_file(struct file *file);
struct dma_buf_heap_prefetch_region {
u64 size;
struct dma_heap *heap;
};
int qcom_secure_system_heap_prefetch(struct dma_buf_heap_prefetch_region *regions,
size_t nr_regions);
int qcom_secure_system_heap_drain(struct dma_buf_heap_prefetch_region *regions,
size_t nr_regions);
/**
* dma_buf_heap_hyp_assign - wrapper function for hyp-assigning a dma_buf
* @buf: dma_buf to hyp-assign away from HLOS
* @dest_vmids: array of QCOM_DMA_HEAP_FLAG VMIDs (as defined above)
* @dest_perms: array of PERM_READ/PERM_WRITE/PERM_EXEC permission bits (as
* defined in include/soc/qcom/secure_buffer.h), such that
* dest_perms[i] specifies the permissions for VMID dest_vmids[i]
* @dest_nelems: number of elements in dest_vmids and dest_perms
*
* Return: Temporarily return -EINVAL whilst the functon isn't present. Otherwise, return
* 0 on success, or a negative value returned by hyp_assign_table() on failure.
*/
static inline int dma_buf_heap_hyp_assign(struct dma_buf *buf, int *dest_vmids, int *dest_perms,
int dest_nelems)
{
return -EINVAL;
}
/**
* dma_buf_heap_hyp_unassign - wrapper function that hyp-assigns a dma_buf back to HLOS
* @buf: dma_buf to hyp-assign back to HLOS
*
* This function takes a dma_buf, and re-assigns it to HLOS with RWX permissions (at the
* S2 level). The end-points to which the buffer was assigned to are tracked by the flags
* kept in the msm_heap_helper_buffer->flags field (the helper_buffer is accesed through
* dma_buf->priv), so the corresponding VMIDs don't need to be supplied as arguments.
*
* Return: Temporarily return -EINVAL whilst the functon isn't present. Otherwise, return
* 0 on success, or a negative value returned by hyp_assign_table() on failure.
*/
static inline int dma_buf_heap_hyp_unassign(struct dma_buf *buf)
{
return -EINVAL;
}
#endif /* _QCOM_DMA_HEAP_H */

Some files were not shown because too many files have changed in this diff Show More