diff options
Diffstat (limited to 'include/linux')
297 files changed, 39227 insertions, 593 deletions
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 52f3b7da4f2d..9333ae59c8c8 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -55,5 +55,8 @@ ktime_t alarm_expires_remaining(const struct alarm *alarm); /* Provide way to access the rtc device being used by alarmtimers */ struct rtc_device *alarmtimer_get_rtcdev(void); +#ifdef CONFIG_RTC_DRV_QPNP +extern bool poweron_alarm; +#endif #endif diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 9006c4e75cf7..3d8dcdd1aeae 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -163,4 +163,13 @@ struct amba_device name##_device = { \ #define module_amba_driver(__amba_drv) \ module_driver(__amba_drv, amba_driver_register, amba_driver_unregister) +/* + * builtin_amba_driver() - Helper macro for drivers that don't do anything + * special in driver initcall. This eliminates a lot of boilerplate. Each + * driver may only use this macro once, and calling it replaces the instance + * device_initcall(). + */ +#define builtin_amba_driver(__amba_drv) \ + builtin_driver(__amba_drv, amba_driver_register) + #endif diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index c1e6d3830c94..7a66e5699bae 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -125,6 +125,27 @@ asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a5, unsigned long a6, unsigned long a7, struct arm_smccc_res *res); + +static inline unsigned long __invoke_psci_fn_hvc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res.a0; +} + +static inline unsigned long __invoke_psci_fn_smc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res.a0; +} + /* SMCCC v1.1 implementation madness follows */ #ifdef CONFIG_ARM64 diff --git a/include/linux/avtimer_kernel.h b/include/linux/avtimer_kernel.h new file mode 100644 index 000000000000..e5a12559f1ba --- /dev/null +++ b/include/linux/avtimer_kernel.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 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 _AVTIMER_H +#define _AVTIMER_H + +#include <uapi/linux/avtimer.h> + +int avcs_core_open(void); +int avcs_core_disable_power_collapse(int disable);/* true or flase */ +int avcs_core_query_timer(uint64_t *avtimer_tick); + +#endif diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index dfa6d4f08b99..b90dff08edb0 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -10,6 +10,7 @@ #include <linux/flex_proportions.h> #include <linux/timer.h> #include <linux/workqueue.h> +#include <linux/kref.h> struct page; struct device; @@ -136,11 +137,13 @@ struct bdi_writeback { struct backing_dev_info { struct list_head bdi_list; unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */ + unsigned long io_pages; /* max allowed IO size */ unsigned int capabilities; /* Device capabilities */ congested_fn *congested_fn; /* Function pointer if device is md/dm */ void *congested_data; /* Pointer to aux data for congested func */ char *name; + struct kref refcnt; /* Reference counter for the structure */ unsigned int min_ratio; unsigned int max_ratio, max_prop_frac; diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 361274ce5815..4bc6540d426b 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -18,7 +18,14 @@ #include <linux/slab.h> int __must_check bdi_init(struct backing_dev_info *bdi); -void bdi_exit(struct backing_dev_info *bdi); + +static inline struct backing_dev_info *bdi_get(struct backing_dev_info *bdi) +{ + kref_get(&bdi->refcnt); + return bdi; +} + +void bdi_put(struct backing_dev_info *bdi); __printf(3, 4) int bdi_register(struct backing_dev_info *bdi, struct device *parent, @@ -29,6 +36,7 @@ void bdi_unregister(struct backing_dev_info *bdi); int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); void bdi_destroy(struct backing_dev_info *bdi); +struct backing_dev_info *bdi_alloc_node(gfp_t gfp_mask, int node_id); void wb_start_writeback(struct bdi_writeback *wb, long nr_pages, bool range_cyclic, enum wb_reason reason); diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h index 9b0a15d06a4f..79542b2698ec 100644 --- a/include/linux/balloon_compaction.h +++ b/include/linux/balloon_compaction.h @@ -48,6 +48,7 @@ #include <linux/migrate.h> #include <linux/gfp.h> #include <linux/err.h> +#include <linux/fs.h> /* * Balloon device information descriptor. @@ -62,6 +63,7 @@ struct balloon_dev_info { struct list_head pages; /* Pages enqueued & handled to Host */ int (*migratepage)(struct balloon_dev_info *, struct page *newpage, struct page *page, enum migrate_mode mode); + struct inode *inode; }; extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info); @@ -73,45 +75,19 @@ static inline void balloon_devinfo_init(struct balloon_dev_info *balloon) spin_lock_init(&balloon->pages_lock); INIT_LIST_HEAD(&balloon->pages); balloon->migratepage = NULL; + balloon->inode = NULL; } #ifdef CONFIG_BALLOON_COMPACTION -extern bool balloon_page_isolate(struct page *page); +extern const struct address_space_operations balloon_aops; +extern bool balloon_page_isolate(struct page *page, + isolate_mode_t mode); extern void balloon_page_putback(struct page *page); -extern int balloon_page_migrate(struct page *newpage, +extern int balloon_page_migrate(struct address_space *mapping, + struct page *newpage, struct page *page, enum migrate_mode mode); /* - * __is_movable_balloon_page - helper to perform @page PageBalloon tests - */ -static inline bool __is_movable_balloon_page(struct page *page) -{ - return PageBalloon(page); -} - -/* - * balloon_page_movable - test PageBalloon to identify balloon pages - * and PagePrivate to check that the page is not - * isolated and can be moved by compaction/migration. - * - * As we might return false positives in the case of a balloon page being just - * released under us, this need to be re-tested later, under the page lock. - */ -static inline bool balloon_page_movable(struct page *page) -{ - return PageBalloon(page) && PagePrivate(page); -} - -/* - * isolated_balloon_page - identify an isolated balloon page on private - * compaction/migration page lists. - */ -static inline bool isolated_balloon_page(struct page *page) -{ - return PageBalloon(page); -} - -/* * balloon_page_insert - insert a page into the balloon's page list and make * the page->private assignment accordingly. * @balloon : pointer to balloon device @@ -124,7 +100,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, struct page *page) { __SetPageBalloon(page); - SetPagePrivate(page); + __SetPageMovable(page, balloon->inode->i_mapping); set_page_private(page, (unsigned long)balloon); list_add(&page->lru, &balloon->pages); } @@ -140,11 +116,14 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, static inline void balloon_page_delete(struct page *page) { __ClearPageBalloon(page); + __ClearPageMovable(page); set_page_private(page, 0); - if (PagePrivate(page)) { - ClearPagePrivate(page); + /* + * No touch page.lru field once @page has been isolated + * because VM is using the field. + */ + if (!PageIsolated(page)) list_del(&page->lru); - } } /* diff --git a/include/linux/batterydata-interface.h b/include/linux/batterydata-interface.h new file mode 100644 index 000000000000..9c234ac4211d --- /dev/null +++ b/include/linux/batterydata-interface.h @@ -0,0 +1,15 @@ +/* Copyright (c) 2014-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. + */ + +#include <uapi/linux/batterydata-interface.h> + +int config_battery_data(struct bms_battery_data *profile); diff --git a/include/linux/batterydata-lib.h b/include/linux/batterydata-lib.h new file mode 100644 index 000000000000..48ff621c6713 --- /dev/null +++ b/include/linux/batterydata-lib.h @@ -0,0 +1,173 @@ +/* Copyright (c) 2012-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 __BMS_BATTERYDATA_H +#define __BMS_BATTERYDATA_H + +#include <linux/errno.h> + +#define FCC_CC_COLS 5 +#define FCC_TEMP_COLS 8 + +#define PC_CC_ROWS 31 +#define PC_CC_COLS 13 + +#define PC_TEMP_ROWS 31 +#define PC_TEMP_COLS 8 + +#define ACC_IBAT_ROWS 4 +#define ACC_TEMP_COLS 3 + +#define MAX_SINGLE_LUT_COLS 20 + +#define MAX_BATT_ID_NUM 4 +#define DEGC_SCALE 10 + +struct single_row_lut { + int x[MAX_SINGLE_LUT_COLS]; + int y[MAX_SINGLE_LUT_COLS]; + int cols; +}; + +/** + * struct sf_lut - + * @rows: number of percent charge entries should be <= PC_CC_ROWS + * @cols: number of charge cycle entries should be <= PC_CC_COLS + * @row_entries: the charge cycles/temperature at which sf data + * is available in the table. + * The charge cycles must be in increasing order from 0 to rows. + * @percent: the percent charge at which sf data is available in the table + * The percentcharge must be in decreasing order from 0 to cols. + * @sf: the scaling factor data + */ +struct sf_lut { + int rows; + int cols; + int row_entries[PC_CC_COLS]; + int percent[PC_CC_ROWS]; + int sf[PC_CC_ROWS][PC_CC_COLS]; +}; + +/** + * struct pc_temp_ocv_lut - + * @rows: number of percent charge entries should be <= PC_TEMP_ROWS + * @cols: number of temperature entries should be <= PC_TEMP_COLS + * @temp: the temperatures at which ocv data is available in the table + * The temperatures must be in increasing order from 0 to rows. + * @percent: the percent charge at which ocv data is available in the table + * The percentcharge must be in decreasing order from 0 to cols. + * @ocv: the open circuit voltage + */ +struct pc_temp_ocv_lut { + int rows; + int cols; + int temp[PC_TEMP_COLS]; + int percent[PC_TEMP_ROWS]; + int ocv[PC_TEMP_ROWS][PC_TEMP_COLS]; +}; + +struct ibat_temp_acc_lut { + int rows; + int cols; + int temp[ACC_TEMP_COLS]; + int ibat[ACC_IBAT_ROWS]; + int acc[ACC_IBAT_ROWS][ACC_TEMP_COLS]; +}; + +struct batt_ids { + int kohm[MAX_BATT_ID_NUM]; + int num; +}; + +enum battery_type { + BATT_UNKNOWN = 0, + BATT_PALLADIUM, + BATT_DESAY, + BATT_OEM, + BATT_QRD_4V35_2000MAH, + BATT_QRD_4V2_1300MAH, +}; + +/** + * struct bms_battery_data - + * @fcc: full charge capacity (mAmpHour) + * @fcc_temp_lut: table to get fcc at a given temp + * @pc_temp_ocv_lut: table to get percent charge given batt temp and cycles + * @pc_sf_lut: table to get percent charge scaling factor given cycles + * and percent charge + * @rbatt_sf_lut: table to get battery resistance scaling factor given + * temperature and percent charge + * @default_rbatt_mohm: the default value of battery resistance to use when + * readings from bms are not available. + * @delta_rbatt_mohm: the resistance to be added towards lower soc to + * compensate for battery capacitance. + * @rbatt_capacitve_mohm: the resistance to be added to compensate for + * battery capacitance + * @flat_ocv_threshold_uv: the voltage where the battery's discharge curve + * starts flattening out. + * @max_voltage_uv: max voltage of the battery + * @cutoff_uv: cutoff voltage of the battery + * @iterm_ua: termination current of the battery when charging + * to 100% + * @batt_id_kohm: the best matched battery id resistor value + * @fastchg_current_ma: maximum fast charge current + * @fg_cc_cv_threshold_mv: CC to CV threashold voltage + */ + +struct bms_battery_data { + unsigned int fcc; + struct single_row_lut *fcc_temp_lut; + struct single_row_lut *fcc_sf_lut; + struct pc_temp_ocv_lut *pc_temp_ocv_lut; + struct ibat_temp_acc_lut *ibat_acc_lut; + struct sf_lut *pc_sf_lut; + struct sf_lut *rbatt_sf_lut; + int default_rbatt_mohm; + int delta_rbatt_mohm; + int rbatt_capacitive_mohm; + int flat_ocv_threshold_uv; + int max_voltage_uv; + int cutoff_uv; + int iterm_ua; + int batt_id_kohm; + int fastchg_current_ma; + int fg_cc_cv_threshold_mv; + const char *battery_type; +}; + +#define is_between(left, right, value) \ + (((left) >= (right) && (left) >= (value) \ + && (value) >= (right)) \ + || ((left) <= (right) && (left) <= (value) \ + && (value) <= (right))) + +extern struct bms_battery_data palladium_1500_data; +extern struct bms_battery_data desay_5200_data; +extern struct bms_battery_data oem_batt_data; +extern struct bms_battery_data QRD_4v35_2000mAh_data; +extern struct bms_battery_data qrd_4v2_1300mah_data; + +int interpolate_fcc(struct single_row_lut *fcc_temp_lut, int batt_temp); +int interpolate_scalingfactor(struct sf_lut *sf_lut, int row_entry, int pc); +int interpolate_scalingfactor_fcc(struct single_row_lut *fcc_sf_lut, + int cycles); +int interpolate_pc(struct pc_temp_ocv_lut *pc_temp_ocv, + int batt_temp_degc, int ocv); +int interpolate_ocv(struct pc_temp_ocv_lut *pc_temp_ocv, + int batt_temp_degc, int pc); +int interpolate_slope(struct pc_temp_ocv_lut *pc_temp_ocv, + int batt_temp, int pc); +int interpolate_acc(struct ibat_temp_acc_lut *ibat_acc_lut, + int batt_temp, int ibat); +int linear_interpolate(int y0, int x0, int y1, int x1, int x); + +#endif diff --git a/include/linux/bif/consumer.h b/include/linux/bif/consumer.h new file mode 100644 index 000000000000..a4579dbb35ac --- /dev/null +++ b/include/linux/bif/consumer.h @@ -0,0 +1,728 @@ +/* Copyright (c) 2013, 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 _LINUX_BIF_CONSUMER_H_ +#define _LINUX_BIF_CONSUMER_H_ + +#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/notifier.h> + +#define BIF_DEVICE_ID_BYTE_LENGTH 8 +#define BIF_UNIQUE_ID_BYTE_LENGTH 10 +#define BIF_UNIQUE_ID_BIT_LENGTH 80 + +#define BIF_PRIMARY_SLAVE_DEV_ADR 0x01 + +/** + * enum bif_transaction - BIF master bus transaction types + * %BIF_TRANS_WD: Write data + * %BIF_TRANS_ERA: Extended register address + * %BIF_TRANS_WRA: Write register address + * %BIF_TRANS_RRA: Read register address + * %BIF_TRANS_BC: Bus command + * %BIF_TRANS_EDA: Extended device address + * %BIF_TRANS_SDA: Slave device address + * + * These values correspond to BIF word bits: BCF, bit 9, bit 8. + * BCF_n bit is inserted automatically. + */ +enum bif_transaction { + BIF_TRANS_WD = 0x00, + BIF_TRANS_ERA = 0x01, + BIF_TRANS_WRA = 0x02, + BIF_TRANS_RRA = 0x03, + BIF_TRANS_BC = 0x04, + BIF_TRANS_EDA = 0x05, + BIF_TRANS_SDA = 0x06, +}; + +/* BIF slave response components */ +#define BIF_SLAVE_RD_ACK 0x200 +#define BIF_SLAVE_RD_EOT 0x100 +#define BIF_SLAVE_RD_DATA 0x0FF +#define BIF_SLAVE_RD_ERR 0x0FF +#define BIF_SLAVE_TACK_ACK 0x200 +#define BIF_SLAVE_TACK_WCNT 0x0FF +#define BIF_SLAVE_TACK_ERR 0x0FF + +/** + * enum bif_bus_command - MIPI defined bus commands to use in BC transaction + * %BIF_CMD_BRES: Bus reset of all slaves + * %BIF_CMD_PDWN: Put all slaves into power down mode + * %BIF_CMD_STBY: Put all slaves into standby mode + * %BIF_CMD_EINT: Enable interrupts for all slaves + * %BIF_CMD_ISTS: Poll interrupt status for all slaves. Expects BQ + * response if any slave has a pending interrupt. + * %BIF_CMD_RBL: Specify the burst read length for the next read + * transaction. Bits 3 to 0 should also be ORed on in + * order to specify the number of bytes to read. + * %BIF_CMD_RBE: Specify the extended burst read length for the next read + * transaction. Bits 3 to 0 should also be ORed on in + * order to specify the number of bytes to read. The burst + * read length for RBEy and RBLx = 16 * y + x. + * %BIF_CMD_DASM: Device activation stick mode. This keeps a slave + * selected if it would otherwise become unselected by the + * next transaction. + * %BIF_CMD_DISS: UID search start + * %BIF_CMD_DILC: UID length check. Expects BQ response if all 80 UID + * bits for a given slave have been entered. + * %BIF_CMD_DIE0: UID search enter 0 + * %BIF_CMD_DIE1: UID search enter 1 + * %BIF_CMD_DIP0: UID search probe 0 + * %BIF_CMD_DIP1: UID search probe 1 + * %BIF_CMD_DRES: Device reset of selected slaves + * %BIF_CMD_TQ: Transaction query; expects TACK response + * %BIF_CMD_AIO: Address increment off for the next transaction + * + * These values correspond to BIF word bits 7 to 0. + */ +enum bif_bus_command { + BIF_CMD_BRES = 0x00, + BIF_CMD_PDWN = 0x02, + BIF_CMD_STBY = 0x03, + BIF_CMD_EINT = 0x10, + BIF_CMD_ISTS = 0x11, + BIF_CMD_RBL = 0x20, + BIF_CMD_RBE = 0x30, + BIF_CMD_DASM = 0x40, + BIF_CMD_DISS = 0x80, + BIF_CMD_DILC = 0x81, + BIF_CMD_DIE0 = 0x84, + BIF_CMD_DIE1 = 0x85, + BIF_CMD_DIP0 = 0x86, + BIF_CMD_DIP1 = 0x87, + BIF_CMD_DRES = 0xC0, + BIF_CMD_TQ = 0xC2, + BIF_CMD_AIO = 0xC4, +}; + +/** + * struct bif_ddb_l1_data - MIPI defined L1 DDB data structure + * @revision: DDB version; should be 0x10 for DDB v1.0 + * @level: DDB level support; should be 0x03 for DDB L1 and L2 + * @device_class: MIPI device class; should be 0x0800 + * @manufacturer_id: Manufacturer ID number allocated by MIPI + * @product_id: Manufacturer specified product ID number + * @length: Size of L2 function directory in bytes + */ +struct bif_ddb_l1_data { + u8 revision; + u8 level; + u16 device_class; + u16 manufacturer_id; + u16 product_id; + u16 length; +}; + +/** + * struct bif_ddb_l2_data - MIPI defined L2 DDB function data structure + * @function_type: Defines the type of the function. The type may be + * either MIPI or manufacturer defined. + * @function_version: Defines the version of the function. The version may + * be either MIPI or manufacturer defined. + * @function_pointer: Address in BIF slave memory where the register map for + * the function begins. + */ +struct bif_ddb_l2_data { + u8 function_type; + u8 function_version; + u16 function_pointer; +}; + +/** + * enum bif_mipi_function_type - MIPI defined DDB L2 function types + * %BIF_FUNC_PROTOCOL: Protocol function which provides access to core + * BIF communication features. + * %BIF_FUNC_SLAVE_CONTROL: Slave control function which provides control + * for BIF slave interrupts and tasks. + * %BIF_FUNC_TEMPERATURE: Temperature sensor function which provides a + * means to accurately read the battery temperature + * in a single-shot or periodic fashion. + * %BIF_FUNC_NVM: Non-volatile memory function which provides a + * means to store data onto a BIF slave that is + * non-volatile. Secondary slave objects are also + * found through the NVM function. + * %BIF_FUNC_AUTHENTICATION: Authentication function which provides a means + * to authenticate batteries. This function does + * not have a MIPI defined implimentation. Instead + * all aspects of the authentication function are + * left to the discretion of the manufacturer. + */ +enum bif_mipi_function_type { + BIF_FUNC_PROTOCOL = 0x01, + BIF_FUNC_SLAVE_CONTROL = 0x02, + BIF_FUNC_TEMPERATURE = 0x03, + BIF_FUNC_NVM = 0x04, + BIF_FUNC_AUTHENTICATION = 0x05, +}; + +#define BIF_DDB_L1_BASE_ADDR 0x0000 +#define BIF_DDB_L2_BASE_ADDR 0x000A + +/** + * enum bif_slave_error_code - MIPI defined BIF slave error codes + * %BIF_ERR_NONE: No error occurred + * %BIF_ERR_GENERAL: An unenumerated error occurred + * %BIF_ERR_PARITY: A Hamming-15 parity check failed for a word + * sent on the bus + * %BIF_ERR_INVERSION: More than 8 bits in a word were 1 + * %BIF_ERR_BAD_LENGTH: Word had more or less than 17 bits + * %BIF_ERR_TIMING: Bit timing was violated in a word + * %BIF_ERR_UNKNOWN_CMD: Bus command was unknown to the slave + * %BIF_ERR_CMD_SEQ: Commands with ordering dependency were not + * sent in the right order + * %BIF_ERR_BUS_COLLISION: BCL was already low at the beginning of a new + * transaction + * %BIF_ERR_SLAVE_BUSY: Slave is busy and cannot respond + * %BIF_ERR_FATAL: Slave is in an unrecoverable error state and + * must be reset + * + * These values are present in the ERR portion of an RD or TACK slave response + * word. These values can also be found in the ERR_CODE register of the + * protocol function. + */ +enum bif_slave_error_code { + BIF_ERR_NONE = 0x00, + BIF_ERR_GENERAL = 0x10, + BIF_ERR_PARITY = 0x11, + BIF_ERR_INVERSION = 0x12, + BIF_ERR_BAD_LENGTH = 0x13, + BIF_ERR_TIMING = 0x14, + BIF_ERR_UNKNOWN_CMD = 0x15, + BIF_ERR_CMD_SEQ = 0x16, + BIF_ERR_BUS_COLLISION = 0x1F, + BIF_ERR_SLAVE_BUSY = 0x20, + BIF_ERR_FATAL = 0x7F, +}; + +/** + * struct bif_protocol_function - constant data present in protocol function + * @l2_entry: Pointer to protocol function L2 DDB data struct + * @protocol_pointer: BIF slave address where protocol registers begin + * @device_id_pointer: BIF slave address where device ID begins + * @device_id: The 8-byte unique device ID in MSB to LSB order + */ +struct bif_protocol_function { + struct bif_ddb_l2_data *l2_entry; + u16 protocol_pointer; + u16 device_id_pointer; + u8 device_id[BIF_DEVICE_ID_BYTE_LENGTH]; /* Unique ID */ +}; + +#define PROTOCOL_FUNC_DEV_ADR_ADDR(protocol_pointer) ((protocol_pointer) + 0) +#define PROTOCOL_FUNC_ERR_CODE_ADDR(protocol_pointer) ((protocol_pointer) + 2) +#define PROTOCOL_FUNC_ERR_CNT_ADDR(protocol_pointer) ((protocol_pointer) + 3) +#define PROTOCOL_FUNC_WORD_CNT_ADDR(protocol_pointer) ((protocol_pointer) + 4) + +/** + * struct bif_slave_control_function - constant data present in slave control + * function as well internal software state parameters + * @l2_entry: Pointer to slave control function L2 DDB data struct + * @slave_ctrl_pointer: BIF slave address where slave control registers begin + * @task_count: Number of tasks supported by the slave + * @irq_notifier_list: List of notifiers for consumers drivers that wish to be + * notified when any given interrupt triggers. This list + * is dynamically allocated with length task_count. + */ +struct bif_slave_control_function { + struct bif_ddb_l2_data *l2_entry; + u16 slave_ctrl_pointer; + unsigned int task_count; + struct blocking_notifier_head *irq_notifier_list; +}; + +#define SLAVE_CTRL_TASKS_PER_SET 8 + +/** + * bif_slave_control_task_is_valid() - returns true if the specified task + * is supported by the slave or false if it isn't + * @func: Pointer to slave's slave control function structure + * @task: Slave task number to check + */ +static inline bool +bif_slave_control_task_is_valid(struct bif_slave_control_function *func, + unsigned int task) +{ + return func ? task < func->task_count : false; +} + +#define SLAVE_CTRL_FUNC_IRQ_EN_ADDR(slave_ctrl_pointer, task) \ + ((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 0) + +#define SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task) \ + ((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 1) +#define SLAVE_CTRL_FUNC_IRQ_CLEAR_ADDR(slave_ctrl_pointer, task) \ + SLAVE_CTRL_FUNC_IRQ_STATUS_ADDR(slave_ctrl_pointer, task) + +#define SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task) \ + ((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 2) +#define SLAVE_CTRL_FUNC_TASK_BUSY_ADDR(slave_ctrl_pointer, task) \ + SLAVE_CTRL_FUNC_TASK_TRIGGER_ADDR(slave_ctrl_pointer, task) + +#define SLAVE_CTRL_FUNC_TASK_AUTO_TRIGGER_ADDR(slave_ctrl_pointer, task) \ + ((slave_ctrl_pointer) + 4 * ((task) / SLAVE_CTRL_TASKS_PER_SET) + 3) + +/** + * struct bif_temperature_function - constant data present in temperature + * sensor function + * @temperatuer_pointer: BIF slave address where temperature sensor + * control registers begin + * @slave_control_channel: Slave control channel associated with the + * temperature sensor function. This channel is + * also the task number. + * @accuracy_pointer: BIF slave address where temperature accuracy + * registers begin + */ +struct bif_temperature_function { + u16 temperature_pointer; + u8 slave_control_channel; + u16 accuracy_pointer; +}; + +/** + * enum bif_mipi_object_type - MIPI defined BIF object types + * %BIF_OBJ_END_OF_LIST: Indicates that the end of the object list in + * NVM has been reached + * %BIF_OBJ_SEC_SLAVE: Specifies the UIDs of secondary slaves found + * inside of the battery pack + * %BIF_OBJ_BATT_PARAM: Specifies some variety of battery parameter. + * There is no MIPI defined format for this object + * type so parsing is manufacturer specific. + */ +enum bif_mipi_object_type { + BIF_OBJ_END_OF_LIST = 0x00, + BIF_OBJ_SEC_SLAVE = 0x01, + BIF_OBJ_BATT_PARAM = 0x02, +}; + +/** + * struct bif_object - contains all header and data information for a slave + * data object + * @type: Object type + * @version: Object version + * @manufacturer_id: Manufacturer ID number allocated by MIPI + * @length: Length of the entire object including header and CRC; + * data length == total length - 8. + * @data: Raw byte data found in the object + * @crc: CRC of the object calculated using CRC-CCITT + * @list: Linked-list connection parameter; internal use only + * @addr: BIF slave address correspond to the start of the object + * + * manufacturer_id == 0x0000 if MIPI type and version. + */ +struct bif_object { + u8 type; + u8 version; + u16 manufacturer_id; + u16 length; + u8 *data; + u16 crc; + struct list_head list; + u16 addr; +}; + +/** + * struct bif_nvm_function - constant data present in non-volatile memory + * function as well internal software state + * parameters + * @nvm_pointer: BIF slave address where NVM registers begin + * @slave_control_channel: Slave control channel associated with the + * NVM function. This channel is also the task + * number. + * @write_buffer_size: Size in bytes of the NVM write buffer. 0x00 + * is used to denote a 256 byte buffer. + * @nvm_base_address: BIF slave address where NVM begins + * @nvm_size: NVM size in bytes + * @nvm_lock_offset: Offset from the beginning of NVM of the first + * writable address + * @object_count: Number of BIF objects read from NVM + * @object_list: List of BIF objects read from NVM + */ +struct bif_nvm_function { + u16 nvm_pointer; + u8 slave_control_channel; + u8 write_buffer_size; + u16 nvm_base_address; + u16 nvm_size; + u16 nvm_lock_offset; + int object_count; + struct list_head object_list; +}; + +/** + * struct bif_ctrl - Opaque handle for a BIF controller to be used in bus + * oriented BIF function calls. + */ +struct bif_ctrl; + +/** + * struct bif_slave - Opaque handle for a BIF slave to be used in slave oriented + * BIF function calls. + */ +struct bif_slave; + +/** + * enum bif_bus_state - indicates the current or desired state of the BIF bus + * %BIF_BUS_STATE_MASTER_DISABLED: BIF host hardware is disabled + * %BIF_BUS_STATE_POWER_DOWN: BIF bus is in power down state and + * BCL is not being pulled high + * %BIF_BUS_STATE_STANDBY: BIF slaves are in standby state in which + * less power is drawn + * %BIF_BUS_STATE_ACTIVE: BIF slaves are ready for immediate + * communications + * %BIF_BUS_STATE_INTERRUPT: BIF bus is active, but no communication + * is possible. Instead, either one of the + * slaves or the master must transition to + * active state by pulling BCL low for 1 + * tau bif period. + */ +enum bif_bus_state { + BIF_BUS_STATE_MASTER_DISABLED, + BIF_BUS_STATE_POWER_DOWN, + BIF_BUS_STATE_STANDBY, + BIF_BUS_STATE_ACTIVE, + BIF_BUS_STATE_INTERRUPT, +}; + +/** + * enum bif_bus_event - events that the BIF framework may send to BIF consumers + * %BIF_BUS_EVENT_BATTERY_INSERTED: Indicates that a battery was just + * inserted physically or that the BIF + * host controller for the battery just + * probed and a battery was already + * present. + * %BIF_BUS_EVENT_BATTERY_REMOVED: Indicates that a battery was just + * removed and thus its slaves are no + * longer accessible. + */ +enum bif_bus_event { + BIF_BUS_EVENT_BATTERY_INSERTED, + BIF_BUS_EVENT_BATTERY_REMOVED, +}; + +/* Mask values to be ORed together for use in bif_match_criteria.match_mask. */ +#define BIF_MATCH_MANUFACTURER_ID BIT(0) +#define BIF_MATCH_PRODUCT_ID BIT(1) +#define BIF_MATCH_FUNCTION_TYPE BIT(2) +#define BIF_MATCH_FUNCTION_VERSION BIT(3) +#define BIF_MATCH_IGNORE_PRESENCE BIT(4) +#define BIF_MATCH_OBJ_TYPE BIT(5) +#define BIF_MATCH_OBJ_VERSION BIT(6) +#define BIF_MATCH_OBJ_MANUFACTURER_ID BIT(7) + +/** + * struct bif_match_criteria - specifies the matching criteria that a BIF + * consumer uses to find an appropriate BIF slave + * @match_mask: Mask value specifying which parameters to match upon. + * This value should be some ORed combination of + * BIF_MATCH_* specified above. + * @manufacturer_id: Manufacturer ID number allocated by MIPI + * @product_id: Manufacturer specified product ID number + * @function_type: Defines the type of the function. The type may be + * either MIPI or manufacturer defined. + * @function_version: Defines the version of the function. The version may + * be either MIPI or manufacturer defined. + * @ignore_presence: If true, then slaves that are currently not present + * will be successfully matched against. By default, only + * present slaves can be matched. + * @obj_type: Defines the type of a BIF object found in the + * non-volatile memory of a slave. + * @obj_version: Defines the version of a BIF object found in the + * non-volatile memory of a slave. + * @obj_manufacturer_id: Manufacturer ID of a BIF object found in the + * non-volatile memory of a slave. + * + * If function_type and function_verion are both specified, then they must both + * match for a single BIF function. If obj_type and obj_version or + * obj_manufacturer_id are specified, then all must match for a single BIF + * object. + */ +struct bif_match_criteria { + u32 match_mask; + u16 manufacturer_id; + u16 product_id; + u8 function_type; + u8 function_version; + bool ignore_presence; + u8 obj_type; + u8 obj_version; + u16 obj_manufacturer_id; +}; + +/* Mask values to be ORed for use in bif_obj_match_criteria.match_mask. */ +#define BIF_OBJ_MATCH_TYPE BIT(0) +#define BIF_OBJ_MATCH_VERSION BIT(1) +#define BIF_OBJ_MATCH_MANUFACTURER_ID BIT(2) + +/** + * struct bif_obj_match_criteria - specifies the matching criteria that a BIF + * consumer uses to find an appropriate BIF data object + * within a slave + * @match_mask: Mask value specifying which parameters to match upon. + * This value should be some ORed combination of + * BIF_OBJ_MATCH_* specified above. + * @type: Defines the type of the object. The type may be either + * MIPI or manufacturer defined. + * @version: Defines the version of the object. The version may be + * either MIPI or manufacturer defined. + * @manufacturer_id: Manufacturer ID number allocated by MIPI. + */ +struct bif_obj_match_criteria { + u32 match_mask; + u8 type; + u8 version; + u16 manufacturer_id; +}; + +/** + * bif_battery_rid_ranges - MIPI-BIF defined Rid battery pack resistance ranges + * %BIF_BATT_RID_SPECIAL1_MIN: Minimum Rid for special case 1 + * %BIF_BATT_RID_SPECIAL1_MAX: Maximum Rid for special case 1 + * %BIF_BATT_RID_SPECIAL2_MIN: Minimum Rid for special case 2 + * %BIF_BATT_RID_SPECIAL2_MAX: Maximum Rid for special case 2 + * %BIF_BATT_RID_SPECIAL3_MIN: Minimum Rid for special case 3 + * %BIF_BATT_RID_SPECIAL3_MAX: Maximum Rid for special case 3 + * %BIF_BATT_RID_LOW_COST_MIN: Minimum Rid for a low cost battery pack + * %BIF_BATT_RID_LOW_COST_MAX: Maximum Rid for a low cost battery pack + * %BIF_BATT_RID_SMART_MIN: Minimum Rid for a smart battery pack + * %BIF_BATT_RID_SMART_MAX: Maximum Rid for a smart battery pack + */ +enum bif_battery_rid_ranges { + BIF_BATT_RID_SPECIAL1_MIN = 0, + BIF_BATT_RID_SPECIAL1_MAX = 1, + BIF_BATT_RID_SPECIAL2_MIN = 7350, + BIF_BATT_RID_SPECIAL2_MAX = 7650, + BIF_BATT_RID_SPECIAL3_MIN = 12740, + BIF_BATT_RID_SPECIAL3_MAX = 13260, + BIF_BATT_RID_LOW_COST_MIN = 19600, + BIF_BATT_RID_LOW_COST_MAX = 140000, + BIF_BATT_RID_SMART_MIN = 240000, + BIF_BATT_RID_SMART_MAX = 450000, +}; + +#ifdef CONFIG_BIF + +int bif_request_irq(struct bif_slave *slave, unsigned int task, + struct notifier_block *nb); +int bif_free_irq(struct bif_slave *slave, unsigned int task, + struct notifier_block *nb); + +int bif_trigger_task(struct bif_slave *slave, unsigned int task); +int bif_enable_auto_task(struct bif_slave *slave, unsigned int task); +int bif_disable_auto_task(struct bif_slave *slave, unsigned int task); +int bif_task_is_busy(struct bif_slave *slave, unsigned int task); + +int bif_ctrl_count(void); +struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id); +struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev); +void bif_ctrl_put(struct bif_ctrl *ctrl); + +int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl); + +int bif_slave_match_count(struct bif_ctrl *ctrl, + const struct bif_match_criteria *match_criteria); + +struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl, + unsigned int id, const struct bif_match_criteria *match_criteria); + +void bif_slave_put(struct bif_slave *slave); + +int bif_ctrl_notifier_register(struct bif_ctrl *ctrl, + struct notifier_block *nb); + +int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl, + struct notifier_block *nb); + +struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave); + +int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version, + u16 *function_pointer); + +int bif_object_match_count(struct bif_slave *slave, + const struct bif_obj_match_criteria *match_criteria); + +struct bif_object *bif_object_match_get(struct bif_slave *slave, + unsigned int id, const struct bif_obj_match_criteria *match_criteria); + +void bif_object_put(struct bif_object *object); + +int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len); +int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len); + +int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset, u8 *buf, + int len); +int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, u8 *buf, + int len); + +int bif_object_write(struct bif_slave *slave, u8 type, u8 version, u16 + manufacturer_id, const u8 *data, int data_len); + +int bif_object_overwrite(struct bif_slave *slave, + struct bif_object *object, u8 type, u8 version, + u16 manufacturer_id, const u8 *data, int data_len); + +int bif_object_delete(struct bif_slave *slave, const struct bif_object *object); + +int bif_slave_is_present(struct bif_slave *slave); + +int bif_slave_is_selected(struct bif_slave *slave); +int bif_slave_select(struct bif_slave *slave); + +int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, int transaction, u8 data); +int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, int transaction, + u8 data, int *response); +int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, int transaction, + u8 data, bool *query_response); + +void bif_ctrl_bus_lock(struct bif_ctrl *ctrl); +void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl); + +u16 bif_crc_ccitt(const u8 *buffer, unsigned int len); + +int bif_ctrl_measure_rid(struct bif_ctrl *ctrl); +int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl); +int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns); +int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl); +int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, enum bif_bus_state state); + +#else + +static inline int bif_request_irq(struct bif_slave *slave, unsigned int task, + struct notifier_block *nb) { return -EPERM; } +static inline int bif_free_irq(struct bif_slave *slave, unsigned int task, + struct notifier_block *nb) { return -EPERM; } + +static inline int bif_trigger_task(struct bif_slave *slave, unsigned int task) +{ return -EPERM; } +static inline int bif_enable_auto_task(struct bif_slave *slave, + unsigned int task) +{ return -EPERM; } +static inline int bif_disable_auto_task(struct bif_slave *slave, + unsigned int task) +{ return -EPERM; } +static inline int bif_task_is_busy(struct bif_slave *slave, unsigned int task) +{ return -EPERM; } + +static inline int bif_ctrl_count(void) { return -EPERM; } +static inline struct bif_ctrl *bif_ctrl_get_by_id(unsigned int id) +{ return ERR_PTR(-EPERM); } +struct bif_ctrl *bif_ctrl_get(struct device *consumer_dev) +{ return ERR_PTR(-EPERM); } +static inline void bif_ctrl_put(struct bif_ctrl *ctrl) { return; } + +static inline int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl) +{ return -EPERM; } + +static inline int bif_slave_match_count(struct bif_ctrl *ctrl, + const struct bif_match_criteria *match_criteria) +{ return -EPERM; } + +static inline struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl, + unsigned int id, const struct bif_match_criteria *match_criteria) +{ return ERR_PTR(-EPERM); } + +static inline void bif_slave_put(struct bif_slave *slave) { return; } + +static inline int bif_ctrl_notifier_register(struct bif_ctrl *ctrl, + struct notifier_block *nb) +{ return -EPERM; } + +static inline int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl, + struct notifier_block *nb) +{ return -EPERM; } + +static inline struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave) +{ return ERR_PTR(-EPERM); } + +static inline int bif_slave_find_function(struct bif_slave *slave, u8 function, + u8 *version, u16 *function_pointer) +{ return -EPERM; } + +static inline int bif_object_match_count(struct bif_slave *slave, + const struct bif_obj_match_criteria *match_criteria) +{ return -EPERM; } + +static inline struct bif_object *bif_object_match_get(struct bif_slave *slave, + unsigned int id, const struct bif_obj_match_criteria *match_criteria) +{ return ERR_PTR(-EPERM); } + +static inline void bif_object_put(struct bif_object *object) +{} + +static inline int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, + int len) +{ return -EPERM; } +static inline int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, + int len) +{ return -EPERM; } + +static inline int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset, + u8 *buf, int len) +{ return -EPERM; } +static inline int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, + u8 *buf, int len) +{ return -EPERM; } + +static inline int bif_object_write(struct bif_slave *slave, u8 type, u8 version, + u16 manufacturer_id, const u8 *data, int data_len) +{ return -EPERM; } + +static inline int bif_object_overwrite(struct bif_slave *slave, + struct bif_object *object, u8 type, u8 version, + u16 manufacturer_id, const u8 *data, int data_len) +{ return -EPERM; } + +static inline int bif_object_delete(struct bif_slave *slave, + const struct bif_object *object) +{ return -EPERM; } + +static inline int bif_slave_is_present(struct bif_slave *slave) +{ return -EPERM; } + +static inline int bif_slave_is_selected(struct bif_slave *slave) +{ return -EPERM; } +static inline int bif_slave_select(struct bif_slave *slave) +{ return -EPERM; } + +static inline int bif_ctrl_raw_transaction(struct bif_ctrl *ctrl, + int transaction, u8 data) +{ return -EPERM; } +static inline int bif_ctrl_raw_transaction_read(struct bif_ctrl *ctrl, + int transaction, u8 data, int *response) +{ return -EPERM; } +static inline int bif_ctrl_raw_transaction_query(struct bif_ctrl *ctrl, + int transaction, u8 data, bool *query_response) +{ return -EPERM; } + +static inline void bif_ctrl_bus_lock(struct bif_ctrl *ctrl) +{ return -EPERM; } +static inline void bif_ctrl_bus_unlock(struct bif_ctrl *ctrl) +{ return -EPERM; } + +static inline u16 bif_crc_ccitt(const u8 *buffer, unsigned int len) +{ return 0; } + +static inline int bif_ctrl_measure_rid(struct bif_ctrl *ctrl) { return -EPERM; } +static inline int bif_ctrl_get_bus_period(struct bif_ctrl *ctrl) +{ return -EPERM; } +static inline int bif_ctrl_set_bus_period(struct bif_ctrl *ctrl, int period_ns) +{ return -EPERM; } +static inline int bif_ctrl_get_bus_state(struct bif_ctrl *ctrl) +{ return -EPERM; } +static inline int bif_ctrl_set_bus_state(struct bif_ctrl *ctrl, + enum bif_bus_state state) +{ return -EPERM; } + +#endif + +#endif diff --git a/include/linux/bif/driver.h b/include/linux/bif/driver.h new file mode 100644 index 000000000000..184d46f72022 --- /dev/null +++ b/include/linux/bif/driver.h @@ -0,0 +1,161 @@ +/* Copyright (c) 2013, 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 _LINUX_BIF_DRIVER_H_ +#define _LINUX_BIF_DRIVER_H_ + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/types.h> +#include <linux/bif/consumer.h> + +/** + * struct bif_ctrl_dev - opaque handle used to identify a given BIF controller + * device + */ +struct bif_ctrl_dev; + +/** + * struct bif_ctrl_ops - BIF operations which may be implemented by BIF + * controller drivers + * @bus_transaction: Perform the specified BIF transaction which does + * not result in any slave response. + * @bus_transaction_query: Perform the specified BIF transaction which + * expects a BQ response in the case of slave + * positive acknowledgement. + * @bus_transaction_read: Perform the specified BIF transaction which + * expects an RD or TACK response from the selected + * slave. + * @read_slave_registers: Perform all BIF transactions necessary to read + * the specified set of contiguous registers from + * the previously selected slave. This operation + * is used to optimize the common case of slave + * register reads since the a BIF controller driver + * can take advantage of BIF burst reads while the + * BIF core driver cannot due to the inherient + * tight timing requirements. + * @write_slave_registers: Perform all BIF transactions necessary to write + * the specified set of contiguous registers to + * the previously selected slave. This operation + * is used to optimize the common case of slave + * register writes since the a BIF controller + * driver can remove redundant steps when + * performing several WD commands in a row. + * @get_bus_period: Return the tau_bif BIF bus clock period in + * nanoseconds. + * @set_bus_period: Set the tau_bif BIF bus clock period in + * nanoseconds. If the exact period is not + * supported by the BIF controller hardware, then + * the next larger supported period should be used. + * @get_battery_presence: Return the current state of the battery pack. + * If a battery pack is present, then return >= 1. + * If a battery pack is not present, then return 0. + * If an error occurs during presence detection, + * then return errno. + * @get_battery_rid: Return the measured value of the Rid battery + * pack pull-down resistor in ohms. + * @get_bus_state: Return the current bus state as defined by one + * of the enum bif_bus_state values. + * @set_bus_state: Set the BIF bus state to the specified enum + * bif_bus_state value. + * + * The following operations must be defined by every BIF controller driver in + * order to ensure baseline functionality: + * bus_transaction, bus_transaction_query, get_bus_state, and set_bus_state. + * + * The BIF core driver is unaware of BIF transaction timing constraints. A + * given BIF controller driver must ensure that all timing constraints in the + * MIPI-BIF specification are met as transactions are carried out. + * + * Conversion between 11-bit and 17-bit BIF words (i.e. the insertion of BCF_n, + * parity bits, and the inversion bit) must be handled inside of the BIF + * controller driver (either in software or hardware). This guarantees maximum + * performance if hardware support is available. + * + * The bus_transaction_read operation must return -ETIMEDOUT in the case of no + * RD or TACK word received. This allows the transaction query, TQ, command + * to be used for slave selection verification. + * + * It is acceptable for the BIF bus state to be changed autonomously by a BIF + * controller driver in response to low level bus actions without a call to + * set_bus_state. One example is the case of receiving a slave interrupt + * while in interrupt state as this intrinsically causes the bus to enter the + * active communication state. + */ +struct bif_ctrl_ops { + int (*bus_transaction) (struct bif_ctrl_dev *bdev, int transaction, + u8 data); + int (*bus_transaction_query) (struct bif_ctrl_dev *bdev, + int transaction, u8 data, + bool *query_response); + int (*bus_transaction_read) (struct bif_ctrl_dev *bdev, + int transaction, u8 data, + int *response); + int (*read_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr, + u8 *data, int len); + int (*write_slave_registers) (struct bif_ctrl_dev *bdev, u16 addr, + const u8 *data, int len); + int (*get_bus_period) (struct bif_ctrl_dev *bdev); + int (*set_bus_period) (struct bif_ctrl_dev *bdev, int period_ns); + int (*get_battery_presence) (struct bif_ctrl_dev *bdev); + int (*get_battery_rid) (struct bif_ctrl_dev *bdev); + int (*get_bus_state) (struct bif_ctrl_dev *bdev); + int (*set_bus_state) (struct bif_ctrl_dev *bdev, int state); +}; + +/** + * struct bif_ctrl_desc - BIF bus controller descriptor + * @name: Name used to identify the BIF controller + * @ops: BIF operations supported by the BIF controller + * @bus_clock_min_ns: Minimum tau_bif BIF bus clock period supported by the + * BIF controller + * @bus_clock_max_ns: Maximum tau_bif BIF bus clock period supported by the + * BIF controller + * + * Each BIF controller registered with the BIF core is described with a + * structure of this type. + */ +struct bif_ctrl_desc { + const char *name; + struct bif_ctrl_ops *ops; + int bus_clock_min_ns; + int bus_clock_max_ns; +}; + +#ifdef CONFIG_BIF + +struct bif_ctrl_dev *bif_ctrl_register(struct bif_ctrl_desc *bif_desc, + struct device *dev, void *driver_data, struct device_node *of_node); + +void bif_ctrl_unregister(struct bif_ctrl_dev *bdev); + +void *bdev_get_drvdata(struct bif_ctrl_dev *bdev); + +int bif_ctrl_notify_battery_changed(struct bif_ctrl_dev *bdev); +int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev); + +#else + +static inline struct bif_ctrl_dev *bif_ctrl_register( + struct bif_ctrl_desc *bif_desc, struct device *dev, void *driver_data, + struct device_node *of_node) +{ return ERR_PTR(-EINVAL); } + +static inline void bif_ctrl_unregister(struct bif_ctrl_dev *bdev) { } + +static inline void *bdev_get_drvdata(struct bif_ctrl_dev *bdev) { return NULL; } + +int bif_ctrl_notify_slave_irq(struct bif_ctrl_dev *bdev) { return -EINVAL; } + +#endif + +#endif diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index f0942a82bb20..e7fd9490bcf6 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -39,6 +39,15 @@ struct bvec_iter { current bvec */ }; +#ifdef CONFIG_BLOCK_PERF_FRAMEWORK +/* Double declaration from ktime.h so as to not break the include dependency + * chain. Should be kept up to date. + */ +union blk_ktime { + s64 tv64; +}; +#endif + /* * main unit of I/O for the block layer and lower layers (ie drivers and * stacking drivers) @@ -55,6 +64,10 @@ struct bio { struct bvec_iter bi_iter; +#ifdef CONFIG_BLOCK_PERF_FRAMEWORK + union blk_ktime submit_time; + unsigned int blk_sector_count; +#endif /* Number of segments in this BIO after * physical address coalescing is performed. */ @@ -89,6 +102,13 @@ struct bio { unsigned short bi_vcnt; /* how many bio_vec's */ /* + * When using dircet-io (O_DIRECT), we can't get the inode from a bio + * by walking bio->bi_io_vec->bv_page->mapping->host + * since the page is anon. + */ + struct inode *bi_dio_inode; + + /* * Everything starting with bi_max_vecs will be preserved by bio_reset() */ @@ -128,6 +148,13 @@ struct bio { */ #define BIO_RESET_BITS 13 #define BIO_OWNS_VEC 13 /* bio_free() should free bvec */ +/* + * Added for Req based dm which need to perform post processing. This flag + * ensures blk_update_request does not free the bios or request, this is done + * at the dm level + */ +#define BIO_DONTFREE 14 +#define BIO_INLINECRYPT 15 /* * top 4 bits of bio flags indicate the pool this bio came from @@ -162,6 +189,8 @@ enum rq_flag_bits { __REQ_INTEGRITY, /* I/O includes block integrity payload */ __REQ_FUA, /* forced unit access */ __REQ_FLUSH, /* request for cache flush */ + __REQ_POST_FLUSH_BARRIER,/* cache barrier after a data req */ + __REQ_BARRIER, /* marks flush req as barrier */ /* bio only flags */ __REQ_RAHEAD, /* read ahead, can fail anytime */ @@ -169,7 +198,7 @@ enum rq_flag_bits { * throttling rules. Don't do it again. */ /* request only flags */ - __REQ_SORTED, /* elevator knows about this request */ + __REQ_SORTED = __REQ_RAHEAD, /* elevator knows about this request */ __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ __REQ_NOMERGE, /* don't touch this for merging */ __REQ_STARTED, /* drive already may have started this one */ @@ -190,6 +219,7 @@ enum rq_flag_bits { __REQ_HASHED, /* on IO scheduler merge hash */ __REQ_MQ_INFLIGHT, /* track inflight for MQ */ __REQ_NO_TIMEOUT, /* requests may never expire */ + __REQ_URGENT, /* urgent request */ __REQ_NR_BITS, /* stops here */ }; @@ -202,6 +232,7 @@ enum rq_flag_bits { #define REQ_PRIO (1ULL << __REQ_PRIO) #define REQ_DISCARD (1ULL << __REQ_DISCARD) #define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME) +#define REQ_URGENT (1ULL << __REQ_URGENT) #define REQ_NOIDLE (1ULL << __REQ_NOIDLE) #define REQ_INTEGRITY (1ULL << __REQ_INTEGRITY) @@ -210,7 +241,7 @@ enum rq_flag_bits { #define REQ_COMMON_MASK \ (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ - REQ_SECURE | REQ_INTEGRITY) + REQ_SECURE | REQ_INTEGRITY | REQ_BARRIER) #define REQ_CLONE_MASK REQ_COMMON_MASK #define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) @@ -225,6 +256,7 @@ enum rq_flag_bits { #define REQ_SORTED (1ULL << __REQ_SORTED) #define REQ_SOFTBARRIER (1ULL << __REQ_SOFTBARRIER) #define REQ_FUA (1ULL << __REQ_FUA) +#define REQ_BARRIER (1ULL << __REQ_BARRIER) #define REQ_NOMERGE (1ULL << __REQ_NOMERGE) #define REQ_STARTED (1ULL << __REQ_STARTED) #define REQ_DONTPREP (1ULL << __REQ_DONTPREP) @@ -236,6 +268,7 @@ enum rq_flag_bits { #define REQ_ALLOCED (1ULL << __REQ_ALLOCED) #define REQ_COPY_USER (1ULL << __REQ_COPY_USER) #define REQ_FLUSH (1ULL << __REQ_FLUSH) +#define REQ_POST_FLUSH_BARRIER (1ULL << __REQ_POST_FLUSH_BARRIER) #define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ) #define REQ_IO_STAT (1ULL << __REQ_IO_STAT) #define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 28c7776cf3ef..f00c4221685b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -44,7 +44,7 @@ struct pr_ops; * Maximum number of blkcg policies allowed to be registered concurrently. * Defined here to simplify include dependency. */ -#define BLKCG_MAX_POLS 2 +#define BLKCG_MAX_POLS 3 struct request; typedef void (rq_end_io_fn)(struct request *, int); @@ -337,7 +337,7 @@ struct request_queue { */ struct delayed_work delay_work; - struct backing_dev_info backing_dev_info; + struct backing_dev_info *backing_dev_info; /* * The queue owner gets to use this for whatever they like. @@ -497,6 +497,7 @@ struct request_queue { #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ #define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ #define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ +#define QUEUE_FLAG_FAST 23 /* fast block device (e.g. ram based) */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_STACKABLE) | \ @@ -585,6 +586,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) #define blk_queue_secdiscard(q) (blk_queue_discard(q) && \ test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags)) +#define blk_queue_fast(q) test_bit(QUEUE_FLAG_FAST, &(q)->queue_flags) #define blk_noretry_request(rq) \ ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \ @@ -803,6 +805,7 @@ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, struct scsi_ioctl_command __user *); +extern void blk_recalc_rq_segments(struct request *rq); extern int blk_queue_enter(struct request_queue *q, gfp_t gfp); extern void blk_queue_exit(struct request_queue *q); extern void blk_start_queue(struct request_queue *q); @@ -1015,6 +1018,8 @@ extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); +extern int blk_rq_map_sg_no_cluster + (struct request_queue *, struct request *, struct scatterlist *); extern void blk_dump_rq_flags(struct request *, char *); extern long nr_blockdev_pages(void); @@ -1127,6 +1132,7 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, #define BLKDEV_DISCARD_SECURE 0x01 /* secure discard */ extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); +extern int blkdev_issue_barrier(struct block_device *, gfp_t, sector_t *); extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, diff --git a/include/linux/bluetooth-power.h b/include/linux/bluetooth-power.h new file mode 100644 index 000000000000..a822ba8c07d1 --- /dev/null +++ b/include/linux/bluetooth-power.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2016, 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 __LINUX_BLUETOOTH_POWER_H +#define __LINUX_BLUETOOTH_POWER_H + +/* + * voltage regulator information required for configuring the + * bluetooth chipset + */ +struct bt_power_vreg_data { + /* voltage regulator handle */ + struct regulator *reg; + /* regulator name */ + const char *name; + /* voltage levels to be set */ + unsigned int low_vol_level; + unsigned int high_vol_level; + /* current level to be set */ + unsigned int load_uA; + /* + * is set voltage supported for this regulator? + * false => set voltage is not supported + * true => set voltage is supported + * + * Some regulators (like gpio-regulators, LVS (low voltage swtiches) + * PMIC regulators) dont have the capability to call + * regulator_set_voltage or regulator_set_optimum_mode + * Use this variable to indicate if its a such regulator or not + */ + bool set_voltage_sup; + /* is this regulator enabled? */ + bool is_enabled; +}; + +struct bt_power_clk_data { + /* clock regulator handle */ + struct clk *clk; + /* clock name */ + const char *name; + /* is this clock enabled? */ + bool is_enabled; +}; + +/* + * Platform data for the bluetooth power driver. + */ +struct bluetooth_power_platform_data { + /* Bluetooth reset gpio */ + int bt_gpio_sys_rst; + struct device *slim_dev; + /* VDDIO voltage regulator */ + struct bt_power_vreg_data *bt_vdd_io; + /* VDD_PA voltage regulator */ + struct bt_power_vreg_data *bt_vdd_pa; + /* VDD_LDOIN voltage regulator */ + struct bt_power_vreg_data *bt_vdd_ldo; + /* VDD_XTAL voltage regulator */ + struct bt_power_vreg_data *bt_vdd_xtal; + /* VDD_CORE voltage regulator */ + struct bt_power_vreg_data *bt_vdd_core; + /* Optional: chip power down gpio-regulator + * chip power down data is required when bluetooth module + * and other modules like wifi co-exist in a single chip and + * shares a common gpio to bring chip out of reset. + */ + struct bt_power_vreg_data *bt_chip_pwd; + /* bluetooth reference clock */ + struct bt_power_clk_data *bt_chip_clk; + /* Optional: Bluetooth power setup function */ + int (*bt_power_setup)(int); +}; + +int bt_register_slimdev(struct device *dev); + +#define BT_CMD_SLIM_TEST 0xbfac +#define BT_CMD_PWR_CTRL 0xbfad +#endif /* __LINUX_BLUETOOTH_POWER_H */ diff --git a/include/linux/bug.h b/include/linux/bug.h index 581a53dfbd31..bcfd70c217a3 100644 --- a/include/linux/bug.h +++ b/include/linux/bug.h @@ -114,4 +114,29 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr, } #endif /* CONFIG_GENERIC_BUG */ + +#ifdef CONFIG_PANIC_ON_DATA_CORRUPTION +#define PANIC_CORRUPTION 1 +#else +#define PANIC_CORRUPTION 0 +#endif /* CONFIG_PANIC_ON_DATA_CORRUPTION */ + +/* + * Since detected data corruption should stop operation on the affected + * structures. Return value must be checked and sanely acted on by caller. + */ +static inline __must_check bool check_data_corruption(bool v) { return v; } +#define CHECK_DATA_CORRUPTION(condition, fmt, ...) \ + check_data_corruption(({ \ + bool corruption = unlikely(condition); \ + if (corruption) { \ + if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \ + pr_err(fmt, ##__VA_ARGS__); \ + BUG(); \ + } else \ + WARN(1, fmt, ##__VA_ARGS__); \ + } \ + corruption; \ + })) + #endif /* _LINUX_BUG_H */ diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 8da263299754..4cd5c95d1ca0 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -66,7 +66,6 @@ enum { /* cgroup_root->flags */ enum { - CGRP_ROOT_SANE_BEHAVIOR = (1 << 0), /* __DEVEL__sane_behavior specified */ CGRP_ROOT_NOPREFIX = (1 << 1), /* mounted subsystems have no named prefix */ CGRP_ROOT_XATTR = (1 << 2), /* supports extended attributes */ }; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7cd0171963ae..f91991b97888 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -13,6 +13,7 @@ #include <linux/io.h> #include <linux/of.h> +#include <linux/mutex.h> #ifdef CONFIG_COMMON_CLK @@ -31,6 +32,11 @@ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ #define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ +#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ +#define CLK_ENABLE_HAND_OFF BIT(12) /* enable clock when registered. + hand-off enable_count & prepare_count + to first consumer that enables clk */ +#define CLK_IS_MEASURE BIT(14) /* measure clock */ struct clk; struct clk_hw; @@ -173,6 +179,16 @@ struct clk_rate_request { * directory is provided as an argument. Called with * prepare_lock held. Returns 0 on success, -EERROR otherwise. * + * @set_flags: Set custom flags which deals with hardware specifics. Returns 0 + * on success, -EEROR otherwise. + * + * @list_registers: Queries the hardware to get the current register contents. + * This callback is optional and required clocks could + * add this callback. + * + * @list_rate: Return the nth supported frequency for a given clock which is + * below rate_max on success and -ENXIO in case of no frequency + * table. * * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow * implementations to split any work between atomic (enable) and sleepable @@ -213,6 +229,11 @@ struct clk_ops { int (*set_phase)(struct clk_hw *hw, int degrees); void (*init)(struct clk_hw *hw); int (*debug_init)(struct clk_hw *hw, struct dentry *dentry); + int (*set_flags)(struct clk_hw *hw, unsigned flags); + void (*list_registers)(struct seq_file *f, + struct clk_hw *hw); + long (*list_rate)(struct clk_hw *hw, unsigned n, + unsigned long rate_max); }; /** @@ -224,6 +245,9 @@ struct clk_ops { * @parent_names: array of string names for all possible parents * @num_parents: number of possible parents * @flags: framework-level hints and quirks + * @vdd_class: voltage scaling requirement class + * @rate_max: maximum clock rate in Hz supported at each voltage level + * @num_rate_max: number of maximum voltage level supported */ struct clk_init_data { const char *name; @@ -231,8 +255,73 @@ struct clk_init_data { const char * const *parent_names; u8 num_parents; unsigned long flags; + struct clk_vdd_class *vdd_class; + unsigned long *rate_max; + int num_rate_max; +}; + +struct regulator; + +/** + * struct clk_vdd_class - Voltage scaling class + * @class_name: name of the class + * @regulator: array of regulators + * @num_regulators: size of regulator array. Standard regulator APIs will be + used if this field > 0 + * @set_vdd: function to call when applying a new voltage setting + * @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then + regulator + * @level_votes: array of votes for each level + * @num_levels: specifies the size of level_votes array + * @skip_handoff: do not vote for the max possible voltage during init + * @use_max_uV: use INT_MAX for max_uV when calling regulator_set_voltage + * @cur_level: the currently set voltage level + * @lock: lock to protect this struct + */ +struct clk_vdd_class { + const char *class_name; + struct regulator **regulator; + int num_regulators; + int (*set_vdd)(struct clk_vdd_class *v_class, int level); + int *vdd_uv; + int *level_votes; + int num_levels; + bool skip_handoff; + bool use_max_uV; + unsigned long cur_level; + struct mutex lock; }; +#define DEFINE_VDD_CLASS(_name, _set_vdd, _num_levels) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .set_vdd = _set_vdd, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .vdd_uv = _vdd_uv, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGS_INIT(_name, _num_regulators) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + /** * struct clk_hw - handle for traversing from a struct clk to its corresponding * hardware-specific structure. struct clk_hw should be declared within struct @@ -667,6 +756,9 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, unsigned long max_rate); +unsigned long clk_aggregate_rate(struct clk_hw *hw, + const struct clk_core *parent); + static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src) { dst->clk = src->clk; @@ -704,7 +796,8 @@ int of_clk_get_parent_count(struct device_node *np); int of_clk_parent_fill(struct device_node *np, const char **parents, unsigned int size); const char *of_clk_get_parent_name(struct device_node *np, int index); - +int of_clk_detect_critical(struct device_node *np, int index, + unsigned long *flags); void of_clk_init(const struct of_device_id *matches); #else /* !CONFIG_OF */ @@ -742,6 +835,13 @@ static inline const char *of_clk_get_parent_name(struct device_node *np, { return NULL; } + +static inline int of_clk_detect_critical(struct device_node *np, int index, + unsigned long *flags) +{ + return 0; +} + #define of_clk_init(matches) \ { while (0); } #endif /* CONFIG_OF */ @@ -781,6 +881,13 @@ static inline void clk_writel(u32 val, u32 __iomem *reg) struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode, void *data, const struct file_operations *fops); #endif +#else +struct of_device_id; + +static inline void __init of_clk_init(const struct of_device_id *matches) +{ + return; +} #endif /* CONFIG_COMMON_CLK */ #endif /* CLK_PROVIDER_H */ diff --git a/include/linux/clk.h b/include/linux/clk.h index 0df4a51e1a78..76708a7c46c0 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -408,6 +408,16 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); +/** + * clk_set_flags - set the custom specific flags for this clock + * @clk: clock source + * @flags: custom flags which would be hardware specific, defined for specific + * hardware. + * + * Returns success 0 or negative errno. + */ +int clk_set_flags(struct clk *clk, unsigned long flags); + #else /* !CONFIG_HAVE_CLK */ static inline struct clk *clk_get(struct device *dev, const char *id) @@ -488,7 +498,7 @@ static inline void clk_disable_unprepare(struct clk *clk) struct device_node; struct of_phandle_args; -#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) +#if defined(CONFIG_OF) struct clk *of_clk_get(struct device_node *np, int index); struct clk *of_clk_get_by_name(struct device_node *np, const char *name); struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec); diff --git a/include/linux/clk/gdsc.h b/include/linux/clk/gdsc.h new file mode 100644 index 000000000000..b012ed06d3f4 --- /dev/null +++ b/include/linux/clk/gdsc.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 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 __GDSC_H +#define __GDSC_H + +#include <linux/regulator/consumer.h> + +/* Allow the clock memories to be turned off */ +void gdsc_allow_clear_retention(struct regulator *regulator); + +#endif diff --git a/include/linux/clk/msm-clk-provider.h b/include/linux/clk/msm-clk-provider.h new file mode 100644 index 000000000000..2fa8916ad356 --- /dev/null +++ b/include/linux/clk/msm-clk-provider.h @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2007-2016, The Linux Foundation. All rights reserved. + * + * 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 __MSM_CLK_PROVIDER_H +#define __MSM_CLK_PROVIDER_H + +#include <linux/types.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/device.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/mutex.h> +#include <linux/regulator/consumer.h> +#include <linux/seq_file.h> +#include <linux/clk/msm-clk.h> + +#if defined(CONFIG_COMMON_CLK_MSM) +/* + * Bit manipulation macros + */ +#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) + +/* + * Halt/Status Checking Mode Macros + */ +#define HALT 0 /* Bit pol: 1 = halted */ +#define NOCHECK 1 /* No bit to check, do nothing */ +#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */ +#define ENABLE 3 /* Bit pol: 1 = running */ +#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */ +#define DELAY 5 /* No bit to check, just delay */ + +struct clk_register_data { + char *name; + u32 offset; +}; +#ifdef CONFIG_DEBUG_FS +void clk_debug_print_hw(struct clk *clk, struct seq_file *f); +#else +static inline void clk_debug_print_hw(struct clk *clk, struct seq_file *f) {} +#endif + +#define CLK_WARN(clk, cond, fmt, ...) do { \ + clk_debug_print_hw(clk, NULL); \ + WARN(cond, "%s: " fmt, clk_name(clk), ##__VA_ARGS__); \ +} while (0) + +/** + * struct clk_vdd_class - Voltage scaling class + * @class_name: name of the class + * @regulator: array of regulators. + * @num_regulators: size of regulator array. Standard regulator APIs will be + used if this field > 0. + * @set_vdd: function to call when applying a new voltage setting. + * @vdd_uv: sorted 2D array of legal voltage settings. Indexed by level, then + regulator. + * @vdd_ua: sorted 2D array of legal cureent settings. Indexed by level, then + regulator. Optional parameter. + * @level_votes: array of votes for each level. + * @num_levels: specifies the size of level_votes array. + * @skip_handoff: do not vote for the max possible voltage during init + * @use_max_uV: use INT_MAX for max_uV when calling regulator_set_voltage + * This is useful when different vdd_class share same regulator. + * @cur_level: the currently set voltage level + * @lock: lock to protect this struct + */ +struct clk_vdd_class { + const char *class_name; + struct regulator **regulator; + int num_regulators; + int (*set_vdd)(struct clk_vdd_class *v_class, int level); + int *vdd_uv; + int *vdd_ua; + int *level_votes; + int num_levels; + bool skip_handoff; + bool use_max_uV; + unsigned long cur_level; + struct mutex lock; +}; + +#define DEFINE_VDD_CLASS(_name, _set_vdd, _num_levels) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .set_vdd = _set_vdd, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGULATORS(_name, _num_levels, _num_regulators, _vdd_uv, \ + _vdd_ua) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .vdd_uv = _vdd_uv, \ + .vdd_ua = _vdd_ua, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .level_votes = (int [_num_levels]) {}, \ + .num_levels = _num_levels, \ + .cur_level = _num_levels, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +#define DEFINE_VDD_REGS_INIT(_name, _num_regulators) \ + struct clk_vdd_class _name = { \ + .class_name = #_name, \ + .regulator = (struct regulator * [_num_regulators]) {}, \ + .num_regulators = _num_regulators, \ + .lock = __MUTEX_INITIALIZER(_name.lock) \ + } + +enum handoff { + HANDOFF_ENABLED_CLK, + HANDOFF_DISABLED_CLK, +}; + +struct clk_ops { + int (*prepare)(struct clk *clk); + int (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + void (*unprepare)(struct clk *clk); + void (*enable_hwcg)(struct clk *clk); + void (*disable_hwcg)(struct clk *clk); + int (*in_hwcg_mode)(struct clk *clk); + enum handoff (*handoff)(struct clk *clk); + int (*reset)(struct clk *clk, enum clk_reset_action action); + int (*pre_set_rate)(struct clk *clk, unsigned long new_rate); + int (*set_rate)(struct clk *clk, unsigned long rate); + void (*post_set_rate)(struct clk *clk, unsigned long old_rate); + int (*set_max_rate)(struct clk *clk, unsigned long rate); + int (*set_flags)(struct clk *clk, unsigned flags); + unsigned long (*get_rate)(struct clk *clk); + long (*list_rate)(struct clk *clk, unsigned n); + int (*is_enabled)(struct clk *clk); + long (*round_rate)(struct clk *clk, unsigned long rate); + int (*set_parent)(struct clk *clk, struct clk *parent); + struct clk *(*get_parent)(struct clk *clk); + bool (*is_local)(struct clk *clk); + void __iomem *(*list_registers)(struct clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +/** + * struct clk + * @prepare_count: prepare refcount + * @prepare_lock: protects clk_prepare()/clk_unprepare() path and @prepare_count + * @count: enable refcount + * @lock: protects clk_enable()/clk_disable() path and @count + * @depends: non-direct parent of clock to enable when this clock is enabled + * @vdd_class: voltage scaling requirement class + * @fmax: maximum frequency in Hz supported at each voltage level + * @parent: the current source of this clock + * @opp_table_populated: tracks if the OPP table of this clock has been filled + */ +struct clk { + uint32_t flags; + struct clk_ops *ops; + const char *dbg_name; + struct clk *depends; + struct clk_vdd_class *vdd_class; + unsigned long *fmax; + int num_fmax; + unsigned long rate; + struct clk *parent; + struct clk_src *parents; + unsigned int num_parents; + + struct list_head children; + struct list_head siblings; + struct list_head list; + + unsigned count; + unsigned notifier_count; + spinlock_t lock; + unsigned prepare_count; + struct mutex prepare_lock; + + unsigned long init_rate; + bool always_on; + bool opp_table_populated; + + struct dentry *clk_dir; +}; + +#define CLK_INIT(name) \ + .lock = __SPIN_LOCK_UNLOCKED((name).lock), \ + .prepare_lock = __MUTEX_INITIALIZER((name).prepare_lock), \ + .children = LIST_HEAD_INIT((name).children), \ + .siblings = LIST_HEAD_INIT((name).siblings), \ + .list = LIST_HEAD_INIT((name).list) + +bool is_rate_valid(struct clk *clk, unsigned long rate); +int vote_vdd_level(struct clk_vdd_class *vdd_class, int level); +int unvote_vdd_level(struct clk_vdd_class *vdd_class, int level); +int __clk_pre_reparent(struct clk *c, struct clk *new, unsigned long *flags); +void __clk_post_reparent(struct clk *c, struct clk *old, unsigned long *flags); + +/* Register clocks with the MSM clock driver */ +int msm_clock_register(struct clk_lookup *table, size_t size); +int of_msm_clock_register(struct device_node *np, struct clk_lookup *table, + size_t size); + +int clock_rcgwr_init(struct platform_device *pdev); +int clock_rcgwr_disable(struct platform_device *pdev); + +extern struct clk dummy_clk; +extern struct clk_ops clk_ops_dummy; + +#define CLK_DUMMY(clk_name, clk_id, clk_dev, flags) { \ + .con_id = clk_name, \ + .dev_id = clk_dev, \ + .clk = &dummy_clk, \ + } + +#define DEFINE_CLK_DUMMY(name, _rate) \ + static struct fixed_clk name = { \ + .c = { \ + .dbg_name = #name, \ + .rate = _rate, \ + .ops = &clk_ops_dummy, \ + CLK_INIT(name.c), \ + }, \ + }; + +#define CLK_LOOKUP(con, c, dev) { .con_id = con, .clk = &c, .dev_id = dev } +#define CLK_LOOKUP_OF(con, _c, dev) { .con_id = con, .clk = &(&_c)->c, \ + .dev_id = dev, .of_idx = clk_##_c } +#define CLK_LIST(_c) { .clk = &(&_c)->c, .of_idx = clk_##_c } + +static inline bool is_better_rate(unsigned long req, unsigned long best, + unsigned long new) +{ + if (IS_ERR_VALUE(new)) + return false; + + return (req <= new && new < best) || (best < req && best < new); +} + +extern int of_clk_add_provider(struct device_node *np, + struct clk *(*clk_src_get)(struct of_phandle_args *args, + void *data), + void *data); +extern void of_clk_del_provider(struct device_node *np); + +static inline const char *clk_name(struct clk *c) +{ + if (IS_ERR_OR_NULL(c)) + return "(null)"; + return c->dbg_name; +}; +#endif /* CONFIG_COMMON_CLK_MSM */ +#endif diff --git a/include/linux/clk/msm-clk.h b/include/linux/clk/msm-clk.h new file mode 100644 index 000000000000..8455fd776246 --- /dev/null +++ b/include/linux/clk/msm-clk.h @@ -0,0 +1,138 @@ +/* Copyright (c) 2009, 2012-2016, 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 __MACH_CLK_H +#define __MACH_CLK_H + +#include <linux/notifier.h> + +#if defined(CONFIG_COMMON_CLK_QCOM) +enum branch_mem_flags { + CLKFLAG_RETAIN_PERIPH, + CLKFLAG_NORETAIN_PERIPH, + CLKFLAG_RETAIN_MEM, + CLKFLAG_NORETAIN_MEM, + CLKFLAG_PERIPH_OFF_SET, + CLKFLAG_PERIPH_OFF_CLEAR, +}; + +#include <linux/clk.h> + +#elif defined(CONFIG_COMMON_CLK_MSM) +#define CLKFLAG_INVERT 0x00000001 +#define CLKFLAG_NOINVERT 0x00000002 +#define CLKFLAG_NONEST 0x00000004 +#define CLKFLAG_NORESET 0x00000008 +#define CLKFLAG_RETAIN_PERIPH 0x00000010 +#define CLKFLAG_NORETAIN_PERIPH 0x00000020 +#define CLKFLAG_RETAIN_MEM 0x00000040 +#define CLKFLAG_NORETAIN_MEM 0x00000080 +#define CLKFLAG_SKIP_HANDOFF 0x00000100 +#define CLKFLAG_MIN 0x00000400 +#define CLKFLAG_MAX 0x00000800 +#define CLKFLAG_INIT_DONE 0x00001000 +#define CLKFLAG_INIT_ERR 0x00002000 +#define CLKFLAG_NO_RATE_CACHE 0x00004000 +#define CLKFLAG_MEASURE 0x00008000 +#define CLKFLAG_EPROBE_DEFER 0x00010000 +#define CLKFLAG_PERIPH_OFF_SET 0x00020000 +#define CLKFLAG_PERIPH_OFF_CLEAR 0x00040000 + +struct clk_lookup; +struct clk; + +enum clk_reset_action { + CLK_RESET_DEASSERT = 0, + CLK_RESET_ASSERT = 1 +}; + +struct clk_src { + struct clk *src; + int sel; +}; + +/* Rate is maximum clock rate in Hz */ +int clk_set_max_rate(struct clk *clk, unsigned long rate); + +/* Assert/Deassert reset to a hardware block associated with a clock */ +int clk_reset(struct clk *clk, enum clk_reset_action action); + +/* Set clock-specific configuration parameters */ +int clk_set_flags(struct clk *clk, unsigned long flags); + +/* returns the mux selection index associated with a particular parent */ +int parent_to_src_sel(struct clk_src *parents, int num_parents, struct clk *p); + +/* returns the mux selection index associated with a particular parent */ +int clk_get_parent_sel(struct clk *c, struct clk *parent); + +/** + * DOC: clk notifier callback types + * + * PRE_RATE_CHANGE - called immediately before the clk rate is changed, + * to indicate that the rate change will proceed. Drivers must + * immediately terminate any operations that will be affected by the + * rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK, + * NOTIFY_STOP or NOTIFY_BAD. + * + * ABORT_RATE_CHANGE: called if the rate change failed for some reason + * after PRE_RATE_CHANGE. In this case, all registered notifiers on + * the clk will be called with ABORT_RATE_CHANGE. Callbacks must + * always return NOTIFY_DONE or NOTIFY_OK. + * + * POST_RATE_CHANGE - called after the clk rate change has successfully + * completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK. + * + */ +#define PRE_RATE_CHANGE BIT(0) +#define POST_RATE_CHANGE BIT(1) +#define ABORT_RATE_CHANGE BIT(2) + +/** + * struct msm_clk_notifier - associate a clk with a notifier + * @clk: struct clk * to associate the notifier with + * @notifier_head: a blocking_notifier_head for this clk + * @node: linked list pointers + * + * A list of struct clk_notifier is maintained by the notifier code. + * An entry is created whenever code registers the first notifier on a + * particular @clk. Future notifiers on that @clk are added to the + * @notifier_head. + */ +struct msm_clk_notifier { + struct clk *clk; + struct srcu_notifier_head notifier_head; + struct list_head node; +}; + +/** + * struct msm_clk_notifier_data - rate data to pass to the notifier callback + * @clk: struct clk * being changed + * @old_rate: previous rate of this clk + * @new_rate: new rate of this clk + * + * For a pre-notifier, old_rate is the clk's rate before this rate + * change, and new_rate is what the rate will be in the future. For a + * post-notifier, old_rate and new_rate are both set to the clk's + * current rate (this was done to optimize the implementation). + */ +struct msm_clk_notifier_data { + struct clk *clk; + unsigned long old_rate; + unsigned long new_rate; +}; + +int msm_clk_notif_register(struct clk *clk, struct notifier_block *nb); + +int msm_clk_notif_unregister(struct clk *clk, struct notifier_block *nb); + +#endif /* CONFIG_COMMON_CLK_MSM */ +#endif diff --git a/include/linux/clk/msm-clock-generic.h b/include/linux/clk/msm-clock-generic.h new file mode 100644 index 000000000000..cb2d8787b84f --- /dev/null +++ b/include/linux/clk/msm-clock-generic.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2013-2018, 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 __MSM_CLOCK_GENERIC_H +#define __MSM_CLOCK_GENERIC_H + +#include <linux/clk/msm-clk-provider.h> +#include <linux/of.h> + +/** + * struct fixed_clk - fixed rate clock + * @c: clk + */ +struct fixed_clk { + struct clk c; +}; + +/* ==================== Mux clock ==================== */ + +struct mux_clk; + +struct clk_mux_ops { + int (*set_mux_sel)(struct mux_clk *clk, int sel); + int (*get_mux_sel)(struct mux_clk *clk); + + /* Optional */ + bool (*is_enabled)(struct mux_clk *clk); + int (*enable)(struct mux_clk *clk); + void (*disable)(struct mux_clk *clk); + void __iomem *(*list_registers)(struct mux_clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +#define MUX_SRC_LIST(...) \ + .parents = (struct clk_src[]){__VA_ARGS__}, \ + .num_parents = ARRAY_SIZE(((struct clk_src[]){__VA_ARGS__})) + +#define MUX_REC_SRC_LIST(...) \ + .rec_parents = (struct clk * []){__VA_ARGS__}, \ + .num_rec_parents = ARRAY_SIZE(((struct clk * []){__VA_ARGS__})) + +struct mux_clk { + /* Parents in decreasing order of preference for obtaining rates. */ + struct clk_src *parents; + int num_parents; + /* Recursively search for the requested parent in rec_parents. */ + struct clk **rec_parents; + int num_rec_parents; + struct clk *safe_parent; + int safe_sel; + unsigned long safe_freq; + /* + * Before attempting a clk_round_rate on available sources, attempt a + * clk_get_rate on all those sources. If one of them is already at the + * necessary rate, that source will be used. + */ + bool try_get_rate; + struct clk_mux_ops *ops; + /* + * Set if you need the mux to try a new parent before falling back to + * the current parent. If the safe_parent field above is set, then the + * safe_sel intermediate source will only be used if we fall back to + * to the current parent during mux_set_rate. + */ + bool try_new_parent; + + /* Fields not used by helper function. */ + void *const __iomem *base; + u32 offset; + u32 en_offset; + u32 mask; + u32 shift; + u32 en_mask; + /* + * Set post divider for debug mux in order to divide the clock + * by post_div + 1. + */ + u32 post_div; + int low_power_sel; + void *priv; + + struct clk c; +}; + +static inline struct mux_clk *to_mux_clk(struct clk *c) +{ + return container_of(c, struct mux_clk, c); +} + +extern struct clk_ops clk_ops_gen_mux; + +/* ==================== Divider clock ==================== */ + +struct div_clk; + +struct clk_div_ops { + int (*set_div)(struct div_clk *clk, int div); + int (*get_div)(struct div_clk *clk); + bool (*is_enabled)(struct div_clk *clk); + int (*enable)(struct div_clk *clk); + void (*disable)(struct div_clk *clk); + void __iomem *(*list_registers)(struct div_clk *clk, int n, + struct clk_register_data **regs, u32 *size); +}; + +struct div_data { + unsigned int div; + unsigned int min_div; + unsigned int max_div; + unsigned long rate_margin; + /* + * Indicate whether this divider clock supports half-interger divider. + * If it is, all the min_div and max_div have been doubled. It means + * they are 2*N. + */ + bool is_half_divider; + /* + * Skip odd dividers since the hardware may not support them. + */ + bool skip_odd_div; + bool skip_even_div; + bool allow_div_one; + unsigned int cached_div; +}; + +struct div_clk { + struct div_data data; + + /* + * Some implementations may require the divider to be set to a "safe" + * value that allows reprogramming of upstream clocks without violating + * voltage constraints. + */ + unsigned long safe_freq; + + /* Optional */ + struct clk_div_ops *ops; + + /* Fields not used by helper function. */ + void *const __iomem *base; + u32 offset; + u32 mask; + u32 shift; + u32 en_mask; + void *priv; + struct clk c; +}; + +static inline struct div_clk *to_div_clk(struct clk *c) +{ + return container_of(c, struct div_clk, c); +} + +extern struct clk_ops clk_ops_div; +extern struct clk_ops clk_ops_slave_div; + +struct ext_clk { + struct clk c; + struct device *dev; + char *clk_id; +}; + +long parent_round_rate(struct clk *c, unsigned long rate); +unsigned long parent_get_rate(struct clk *c); +int parent_set_rate(struct clk *c, unsigned long rate); + +static inline struct ext_clk *to_ext_clk(struct clk *c) +{ + return container_of(c, struct ext_clk, c); +} + +extern struct clk_ops clk_ops_ext; + +#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \ +static struct div_clk clk_name = { \ + .data = { \ + .max_div = _div, \ + .min_div = _div, \ + .div = _div, \ + }, \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_div, \ + CLK_INIT(clk_name.c), \ + } \ +} + +#define DEFINE_FIXED_SLAVE_DIV_CLK(clk_name, _div, _parent) \ +static struct div_clk clk_name = { \ + .data = { \ + .max_div = _div, \ + .min_div = _div, \ + .div = _div, \ + }, \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_slave_div, \ + CLK_INIT(clk_name.c), \ + } \ +} + +#define DEFINE_EXT_CLK(clk_name, _parent) \ +static struct ext_clk clk_name = { \ + .c = { \ + .parent = _parent, \ + .dbg_name = #clk_name, \ + .ops = &clk_ops_ext, \ + CLK_INIT(clk_name.c), \ + } \ +} + +/* ==================== Mux Div clock ==================== */ + +struct mux_div_clk; + +/* + * struct mux_div_ops + * the enable and disable ops are optional. + */ + +struct mux_div_ops { + int (*set_src_div)(struct mux_div_clk *, u32 src_sel, u32 div); + void (*get_src_div)(struct mux_div_clk *, u32 *src_sel, u32 *div); + int (*enable)(struct mux_div_clk *); + void (*disable)(struct mux_div_clk *); + bool (*is_enabled)(struct mux_div_clk *); + void __iomem *(*list_registers)(struct mux_div_clk *md, int n, + struct clk_register_data **regs, u32 *size); +}; + +/* + * struct mux_div_clk - combined mux/divider clock + * @priv + parameters needed by ops + * @safe_freq + when switching rates from A to B, the mux div clock will + instead switch from A -> safe_freq -> B. This allows the + mux_div clock to change rates while enabled, even if this + behavior is not supported by the parent clocks. + + If changing the rate of parent A also causes the rate of + parent B to change, then safe_freq must be defined. + + safe_freq is expected to have a source clock which is always + on and runs at only one rate. + * @parents + list of parents and mux indicies + * @ops + function pointers for hw specific operations + * @src_sel + the mux index which will be used if the clock is enabled. + * @try_get_rate + Set if you need the mux to directly jump to a source + that is at the desired rate currently. + * @force_enable_md + Set if the mux-div needs to be force enabled/disabled during + clk_enable/disable. + */ + +struct mux_div_clk { + /* Required parameters */ + struct mux_div_ops *ops; + struct div_data data; + struct clk_src *parents; + u32 num_parents; + + struct clk c; + + /* Internal */ + u32 src_sel; + + /* Optional parameters */ + void *priv; + void __iomem *base; + u32 div_mask; + u32 div_offset; + u32 div_shift; + u32 src_mask; + u32 src_offset; + u32 src_shift; + u32 en_mask; + u32 en_offset; + + u32 safe_div; + struct clk *safe_parent; + unsigned long safe_freq; + bool try_get_rate; + bool force_enable_md; +}; + +static inline struct mux_div_clk *to_mux_div_clk(struct clk *clk) +{ + return container_of(clk, struct mux_div_clk, c); +} + +extern struct clk_ops clk_ops_mux_div_clk; + +/* ==================== Virtual clock ==================== */ +struct virtclk_front { + int id; + struct clk c; + u32 flag; +}; + +extern struct clk_ops virtclk_front_ops; + +int msm_virtclk_front_probe(struct platform_device *pdev, + struct clk_lookup *table, + size_t size); + +#endif diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index 08bffcc466de..0422183013ae 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -21,6 +21,7 @@ struct clk_lookup { struct list_head node; const char *dev_id; const char *con_id; + int of_idx; struct clk *clk; struct clk_hw *clk_hw; }; diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 071146169dfd..d282307214ac 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -186,6 +186,7 @@ extern void clocksource_suspend(void); extern void clocksource_resume(void); extern struct clocksource * __init clocksource_default_clock(void); extern void clocksource_mark_unstable(struct clocksource *cs); +extern void clocksource_select_force(void); extern u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cycles); diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 4cd4ddf64cc7..e864751d870a 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -52,6 +52,10 @@ extern void compaction_defer_reset(struct zone *zone, int order, bool alloc_success); extern bool compaction_restarting(struct zone *zone, int order); +extern int kcompactd_run(int nid); +extern void kcompactd_stop(int nid); +extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx); + #else static inline unsigned long try_to_compact_pages(gfp_t gfp_mask, unsigned int order, int alloc_flags, @@ -84,9 +88,22 @@ static inline bool compaction_deferred(struct zone *zone, int order) return true; } +static inline int kcompactd_run(int nid) +{ + return 0; +} +static inline void kcompactd_stop(int nid) +{ +} + +static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx) +{ +} + #endif /* CONFIG_COMPACTION */ #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) +struct node; extern int compaction_register_node(struct node *node); extern void compaction_unregister_node(struct node *node); diff --git a/include/linux/coresight-cti.h b/include/linux/coresight-cti.h new file mode 100644 index 000000000000..73f56b76cc18 --- /dev/null +++ b/include/linux/coresight-cti.h @@ -0,0 +1,93 @@ +/* Copyright (c) 2013-2014, 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 _LINUX_CORESIGHT_CTI_H +#define _LINUX_CORESIGHT_CTI_H + +#include <linux/list.h> + +struct coresight_cti_data { + int nr_ctis; + const char **names; +}; + +struct coresight_cti { + const char *name; + struct list_head link; +}; + +#ifdef CONFIG_CORESIGHT_CTI +extern struct coresight_cti *coresight_cti_get(const char *name); +extern void coresight_cti_put(struct coresight_cti *cti); +extern int coresight_cti_map_trigin( + struct coresight_cti *cti, int trig, int ch); +extern int coresight_cti_map_trigout( + struct coresight_cti *cti, int trig, int ch); +extern void coresight_cti_unmap_trigin( + struct coresight_cti *cti, int trig, int ch); +extern void coresight_cti_unmap_trigout( + struct coresight_cti *cti, int trig, int ch); +extern void coresight_cti_reset(struct coresight_cti *cti); +extern int coresight_cti_set_trig(struct coresight_cti *cti, int ch); +extern void coresight_cti_clear_trig(struct coresight_cti *cti, int ch); +extern int coresight_cti_pulse_trig(struct coresight_cti *cti, int ch); +extern int coresight_cti_enable_gate(struct coresight_cti *cti, int ch); +extern void coresight_cti_disable_gate(struct coresight_cti *cti, int ch); +extern void coresight_cti_ctx_save(void); +extern void coresight_cti_ctx_restore(void); +extern int coresight_cti_ack_trig(struct coresight_cti *cti, int trig); +#else +static inline struct coresight_cti *coresight_cti_get(const char *name) +{ + return NULL; +} +static inline void coresight_cti_put(struct coresight_cti *cti) {} +static inline int coresight_cti_map_trigin( + struct coresight_cti *cti, int trig, int ch) +{ + return -ENOSYS; +} +static inline int coresight_cti_map_trigout( + struct coresight_cti *cti, int trig, int ch) +{ + return -ENOSYS; +} +static inline void coresight_cti_unmap_trigin( + struct coresight_cti *cti, int trig, int ch) {} +static inline void coresight_cti_unmap_trigout( + struct coresight_cti *cti, int trig, int ch) {} +static inline void coresight_cti_reset(struct coresight_cti *cti) {} +static inline int coresight_cti_set_trig(struct coresight_cti *cti, int ch) +{ + return -ENOSYS; +} +static inline void coresight_cti_clear_trig(struct coresight_cti *cti, int ch) +{} +static inline int coresight_cti_pulse_trig(struct coresight_cti *cti, int ch) +{ + return -ENOSYS; +} +static inline int coresight_cti_enable_gate(struct coresight_cti *cti, int ch) +{ + return -ENOSYS; +} +static inline void coresight_cti_disable_gate(struct coresight_cti *cti, int ch) +{} +static inline void coresight_cti_ctx_save(void){} +static inline void coresight_cti_ctx_restore(void){} +static inline int coresight_cti_ack_trig(struct coresight_cti *cti, int trig) +{ + return -ENOSYS; +} +#endif + +#endif diff --git a/include/linux/coresight-stm.h b/include/linux/coresight-stm.h new file mode 100644 index 000000000000..375d96666f91 --- /dev/null +++ b/include/linux/coresight-stm.h @@ -0,0 +1,35 @@ +#ifndef __LINUX_CORESIGHT_STM_H_ +#define __LINUX_CORESIGHT_STM_H_ + +#include <uapi/linux/coresight-stm.h> + +#define stm_log_inv(entity_id, proto_id, data, size) \ + stm_trace(STM_OPTION_NONE, entity_id, proto_id, data, size) + +#define stm_log_inv_ts(entity_id, proto_id, data, size) \ + stm_trace(STM_OPTION_TIMESTAMPED, entity_id, proto_id, \ + data, size) + +#define stm_log_gtd(entity_id, proto_id, data, size) \ + stm_trace(STM_OPTION_GUARANTEED, entity_id, proto_id, \ + data, size) + +#define stm_log_gtd_ts(entity_id, proto_id, data, size) \ + stm_trace(STM_OPTION_GUARANTEED | STM_OPTION_TIMESTAMPED, \ + entity_id, proto_id, data, size) + +#define stm_log(entity_id, data, size) \ + stm_log_inv_ts(entity_id, 0, data, size) + +#ifdef CONFIG_CORESIGHT_STM +extern int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id, + const void *data, uint32_t size); +#else +static inline int stm_trace(uint32_t options, uint8_t entity_id, + uint8_t proto_id, const void *data, uint32_t size) +{ + return 0; +} +#endif + +#endif diff --git a/include/linux/coresight.h b/include/linux/coresight.h index a7cabfa23b55..66bf56640fe1 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2016 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 @@ -40,6 +40,13 @@ extern struct bus_type coresight_bustype; +enum coresight_clk_rate { + CORESIGHT_CLK_RATE_OFF, + CORESIGHT_CLK_RATE_TRACE = 1000, + CORESIGHT_CLK_RATE_HSTRACE = 2000, + CORESIGHT_CLK_RATE_FIXED = 3000, +}; + enum coresight_dev_type { CORESIGHT_DEV_TYPE_NONE, CORESIGHT_DEV_TYPE_SINK, @@ -94,6 +101,7 @@ struct coresight_dev_subtype { connected to. * @nr_outport: number of output ports for this component. * @clk: The clock this component is associated to. + * @default_sink: Flag to set default sink */ struct coresight_platform_data { int cpu; @@ -104,6 +112,7 @@ struct coresight_platform_data { int *child_ports; int nr_outport; struct clk *clk; + bool default_sink; }; /** @@ -185,10 +194,12 @@ struct coresight_device { * Operations available for sinks * @enable: enables the sink. * @disable: disables the sink. + * @abort: captures sink trace on abort */ struct coresight_ops_sink { int (*enable)(struct coresight_device *csdev); void (*disable)(struct coresight_device *csdev); + void (*abort)(struct coresight_device *csdev); }; /** @@ -230,6 +241,7 @@ extern int coresight_enable(struct coresight_device *csdev); extern void coresight_disable(struct coresight_device *csdev); extern int coresight_timeout(void __iomem *addr, u32 offset, int position, int value); +extern void coresight_abort(void); #else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } @@ -239,14 +251,19 @@ coresight_enable(struct coresight_device *csdev) { return -ENOSYS; } static inline void coresight_disable(struct coresight_device *csdev) {} static inline int coresight_timeout(void __iomem *addr, u32 offset, int position, int value) { return 1; } +static inline void coresight_abort(void) {} #endif -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_CORESIGHT) extern struct coresight_platform_data *of_get_coresight_platform_data( struct device *dev, struct device_node *node); +extern struct coresight_cti_data *of_get_coresight_cti_data( + struct device *dev, struct device_node *node); #else static inline struct coresight_platform_data *of_get_coresight_platform_data( struct device *dev, struct device_node *node) { return NULL; } +static inline struct coresight_cti_data *of_get_coresight_cti_data( + struct device *dev, struct device_node *node) { return NULL; } #endif #ifdef CONFIG_PID_NS diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 0628343928ca..1945aa03a52a 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -27,6 +27,19 @@ struct cpu { struct device dev; }; +struct cpu_pstate_pwr { + unsigned int freq; + uint32_t power; +}; + +struct cpu_pwr_stats { + int cpu; + long temp; + struct cpu_pstate_pwr *ptable; + bool throttling; + int len; +}; + extern int register_cpu(struct cpu *cpu, int num); extern struct device *get_cpu_device(unsigned cpu); extern bool cpu_is_hotpluggable(unsigned cpu); @@ -239,6 +252,7 @@ extern struct bus_type cpu_subsys; extern void cpu_hotplug_begin(void); extern void cpu_hotplug_done(void); extern void get_online_cpus(void); +extern void cpu_hotplug_mutex_held(void); extern void put_online_cpus(void); extern void cpu_hotplug_disable(void); extern void cpu_hotplug_enable(void); @@ -261,6 +275,7 @@ static inline void cpu_hotplug_done(void) {} #define cpu_hotplug_enable() do { } while (0) #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) #define __hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) +#define cpu_hotplug_mutex_held() do { } while (0) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) #define __register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) @@ -276,6 +291,9 @@ static inline int disable_nonboot_cpus(void) { return 0; } static inline void enable_nonboot_cpus(void) {} #endif /* !CONFIG_PM_SLEEP_SMP */ +struct cpu_pwr_stats *get_cpu_pwr_stats(void); +void trigger_cpu_pwr_stats_calc(void); + enum cpuhp_state { CPUHP_OFFLINE, CPUHP_ONLINE, diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index c156f5082758..e221494fb7a0 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -31,6 +31,11 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval, unsigned long voltage, u32 *power); +struct cpu_cooling_ops { + int (*ceil_limit)(int, u32); + int (*get_cur_state)(int, unsigned long *); +}; + #ifdef CONFIG_CPU_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. @@ -43,6 +48,10 @@ struct thermal_cooling_device * cpufreq_power_cooling_register(const struct cpumask *clip_cpus, u32 capacitance, get_static_t plat_static_func); +struct thermal_cooling_device * +cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, + struct cpu_cooling_ops *ops); + /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. * @np: a valid struct device_node to the cooling device device tree node. @@ -112,6 +121,13 @@ of_cpufreq_power_cooling_register(struct device_node *np, return NULL; } +static inline struct thermal_cooling_device * +cpufreq_platform_cooling_register(const struct cpumask *clip_cpus, + struct cpu_cooling_ops *ops) +{ + return NULL; +} + static inline void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { diff --git a/include/linux/cpu_pm.h b/include/linux/cpu_pm.h index 455b233dd3b1..91117bcc665a 100644 --- a/include/linux/cpu_pm.h +++ b/include/linux/cpu_pm.h @@ -71,8 +71,8 @@ int cpu_pm_register_notifier(struct notifier_block *nb); int cpu_pm_unregister_notifier(struct notifier_block *nb); int cpu_pm_enter(void); int cpu_pm_exit(void); -int cpu_cluster_pm_enter(void); -int cpu_cluster_pm_exit(void); +int cpu_cluster_pm_enter(unsigned long aff_level); +int cpu_cluster_pm_exit(unsigned long aff_level); #else @@ -96,12 +96,12 @@ static inline int cpu_pm_exit(void) return 0; } -static inline int cpu_cluster_pm_enter(void) +static inline int cpu_cluster_pm_enter(unsigned long aff_level) { return 0; } -static inline int cpu_cluster_pm_exit(void) +static inline int cpu_cluster_pm_exit(unsigned long aff_level) { return 0; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 23015c3a377b..0c84c69d54f8 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -386,6 +386,7 @@ static inline void cpufreq_resume(void) {} #define CPUFREQ_TRANSITION_NOTIFIER (0) #define CPUFREQ_POLICY_NOTIFIER (1) +#define CPUFREQ_GOVINFO_NOTIFIER (2) /* Transition notifiers */ #define CPUFREQ_PRECHANGE (0) @@ -398,6 +399,9 @@ static inline void cpufreq_resume(void) {} #define CPUFREQ_CREATE_POLICY (3) #define CPUFREQ_REMOVE_POLICY (4) +/* Govinfo Notifiers */ +#define CPUFREQ_LOAD_CHANGE (0) + #ifdef CONFIG_CPU_FREQ int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); @@ -406,6 +410,16 @@ void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs); void cpufreq_freq_transition_end(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs, int transition_failed); +/* + * Governor specific info that can be passed to modules that subscribe + * to CPUFREQ_GOVINFO_NOTIFIER + */ +struct cpufreq_govinfo { + unsigned int cpu; + unsigned int load; + unsigned int sampling_rate_us; +}; +extern struct atomic_notifier_head cpufreq_govinfo_notifier_list; #else /* CONFIG_CPU_FREQ */ static inline int cpufreq_register_notifier(struct notifier_block *nb, diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index bb3a4bb35183..e0bfecde4e7b 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -53,6 +53,7 @@ extern int nr_cpu_ids; * cpu_present_mask - has bit 'cpu' set iff cpu is populated * cpu_online_mask - has bit 'cpu' set iff cpu available to scheduler * cpu_active_mask - has bit 'cpu' set iff cpu available to migration + * cpu_isolated_mask- has bit 'cpu' set iff cpu isolated * * If !CONFIG_HOTPLUG_CPU, present == possible, and active == online. * @@ -89,25 +90,38 @@ extern const struct cpumask *const cpu_possible_mask; extern const struct cpumask *const cpu_online_mask; extern const struct cpumask *const cpu_present_mask; extern const struct cpumask *const cpu_active_mask; +extern const struct cpumask *const cpu_isolated_mask; #if NR_CPUS > 1 #define num_online_cpus() cpumask_weight(cpu_online_mask) #define num_possible_cpus() cpumask_weight(cpu_possible_mask) #define num_present_cpus() cpumask_weight(cpu_present_mask) #define num_active_cpus() cpumask_weight(cpu_active_mask) +#define num_isolated_cpus() cpumask_weight(cpu_isolated_mask) +#define num_online_uniso_cpus() \ +({ \ + cpumask_t mask; \ + \ + cpumask_andnot(&mask, cpu_online_mask, cpu_isolated_mask); \ + cpumask_weight(&mask); \ +}) #define cpu_online(cpu) cpumask_test_cpu((cpu), cpu_online_mask) #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask) #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask) #define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask) +#define cpu_isolated(cpu) cpumask_test_cpu((cpu), cpu_isolated_mask) #else #define num_online_cpus() 1U #define num_possible_cpus() 1U #define num_present_cpus() 1U #define num_active_cpus() 1U +#define num_isolated_cpus() 0U +#define num_online_uniso_cpus() 1U #define cpu_online(cpu) ((cpu) == 0) #define cpu_possible(cpu) ((cpu) == 0) #define cpu_present(cpu) ((cpu) == 0) #define cpu_active(cpu) ((cpu) == 0) +#define cpu_isolated(cpu) ((cpu) != 0) #endif /* verify cpu argument to cpumask_* operators */ @@ -724,12 +738,14 @@ extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); #define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask) #define for_each_online_cpu(cpu) for_each_cpu((cpu), cpu_online_mask) #define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask) +#define for_each_isolated_cpu(cpu) for_each_cpu((cpu), cpu_isolated_mask) /* Wrappers for arch boot code to manipulate normally-constant masks */ void set_cpu_possible(unsigned int cpu, bool possible); void set_cpu_present(unsigned int cpu, bool present); void set_cpu_online(unsigned int cpu, bool online); void set_cpu_active(unsigned int cpu, bool active); +void set_cpu_isolated(unsigned int cpu, bool isolated); void init_cpu_present(const struct cpumask *src); void init_cpu_possible(const struct cpumask *src); void init_cpu_online(const struct cpumask *src); diff --git a/include/linux/crypto.h b/include/linux/crypto.h index b7c1e1a7ebac..d7c8b37b2e95 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -48,6 +48,7 @@ #define CRYPTO_ALG_TYPE_AEAD 0x00000003 #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 #define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005 +#define CRYPTO_ALG_TYPE_SKCIPHER 0x00000005 #define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006 #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 #define CRYPTO_ALG_TYPE_HASH 0x00000008 diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 9df992b818a4..c066f6b56e58 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -238,7 +238,6 @@ extern seqlock_t rename_lock; * These are the low-level FS interfaces to the dcache.. */ extern void d_instantiate(struct dentry *, struct inode *); -extern void d_instantiate_new(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 68030e22af35..b54b1a748d83 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -52,6 +52,10 @@ struct devfreq_dev_status { */ #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 +#define DEVFREQ_FLAG_WAKEUP_MAXFREQ 0x2 +#define DEVFREQ_FLAG_FAST_HINT 0x4 +#define DEVFREQ_FLAG_SLOW_HINT 0x8 + /** * struct devfreq_dev_profile - Devfreq's user device profile * @initial_freq: The operating frequency when devfreq_add_device() is @@ -114,7 +118,8 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; - int (*get_target_freq)(struct devfreq *this, unsigned long *freq); + int (*get_target_freq)(struct devfreq *this, unsigned long *freq, + u32 *flag); int (*event_handler)(struct devfreq *devfreq, unsigned int event, void *data); }; @@ -231,6 +236,9 @@ static inline int devfreq_update_stats(struct devfreq *df) * the governor may consider slowing the frequency down. * Specify 0 to use the default. Valid value = 0 to 100. * downdifferential < upthreshold must hold. + * @simple_scaling: Setting this flag will scale the clocks up only if the + * load is above @upthreshold and will scale the clocks + * down only if the load is below @downdifferential. * * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor, * the governor uses the default values. @@ -238,6 +246,7 @@ static inline int devfreq_update_stats(struct devfreq *df) struct devfreq_simple_ondemand_data { unsigned int upthreshold; unsigned int downdifferential; + unsigned int simple_scaling; }; #endif diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 4a08fef28acc..b393ab66073a 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -616,4 +616,11 @@ static inline unsigned long to_bytes(sector_t n) return (n << SECTOR_SHIFT); } +/*----------------------------------------------------------------- + * Helper for block layer and dm core operations + *----------------------------------------------------------------- + */ +void dm_dispatch_request(struct request *rq); +void dm_kill_unmapped_request(struct request *rq, int error); +void dm_end_request(struct request *clone, int error); #endif /* _LINUX_DEVICE_MAPPER_H */ diff --git a/include/linux/device.h b/include/linux/device.h index eb891c9c4b62..21722b8509ce 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -684,6 +684,18 @@ void __iomem *devm_ioremap_resource(struct device *dev, int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); +static inline int devm_add_action_or_reset(struct device *dev, + void (*action)(void *), void *data) +{ + int ret; + + ret = devm_add_action(dev, action, data); + if (ret) + action(data); + + return ret; +} + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about @@ -818,6 +830,7 @@ struct device { struct cma *cma_area; /* contiguous memory area for dma allocations */ #endif + struct removed_region *removed_mem; /* arch specific additions */ struct dev_archdata archdata; @@ -1013,6 +1026,7 @@ static inline bool device_supports_offline(struct device *dev) extern void lock_device_hotplug(void); extern void unlock_device_hotplug(void); extern int lock_device_hotplug_sysfs(void); +extern void lock_device_hotplug_assert(void); extern int device_offline(struct device *dev); extern int device_online(struct device *dev); extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h new file mode 100644 index 000000000000..d931f9690e2f --- /dev/null +++ b/include/linux/diagchar.h @@ -0,0 +1,939 @@ +/* Copyright (c) 2008-2019, 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 DIAGCHAR_SHARED +#define DIAGCHAR_SHARED + +#define MSG_MASKS_TYPE 0x00000001 +#define LOG_MASKS_TYPE 0x00000002 +#define EVENT_MASKS_TYPE 0x00000004 +#define PKT_TYPE 0x00000008 +#define DEINIT_TYPE 0x00000010 +#define USER_SPACE_DATA_TYPE 0x00000020 +#define DCI_DATA_TYPE 0x00000040 +#define USER_SPACE_RAW_DATA_TYPE 0x00000080 +#define DCI_LOG_MASKS_TYPE 0x00000100 +#define DCI_EVENT_MASKS_TYPE 0x00000200 +#define DCI_PKT_TYPE 0x00000400 +#define HDLC_SUPPORT_TYPE 0x00001000 + +#define USB_MODE 1 +#define MEMORY_DEVICE_MODE 2 +#define NO_LOGGING_MODE 3 +#define UART_MODE 4 +#define SOCKET_MODE 5 +#define CALLBACK_MODE 6 + +/* different values that go in for diag_data_type */ + +#define DATA_TYPE_EVENT 0 +#define DATA_TYPE_F3 1 +#define DATA_TYPE_LOG 2 +#define DATA_TYPE_RESPONSE 3 +#define DATA_TYPE_DELAYED_RESPONSE 4 +#define DATA_TYPE_DCI_LOG 0x00000100 +#define DATA_TYPE_DCI_EVENT 0x00000200 + +/* Different IOCTL values */ +#define DIAG_IOCTL_COMMAND_REG 0 +#define DIAG_IOCTL_COMMAND_DEREG 1 +#define DIAG_IOCTL_SWITCH_LOGGING 7 +#define DIAG_IOCTL_GET_DELAYED_RSP_ID 8 +#define DIAG_IOCTL_LSM_DEINIT 9 +#define DIAG_IOCTL_DCI_INIT 20 +#define DIAG_IOCTL_DCI_DEINIT 21 +#define DIAG_IOCTL_DCI_SUPPORT 22 +#define DIAG_IOCTL_DCI_REG 23 +#define DIAG_IOCTL_DCI_STREAM_INIT 24 +#define DIAG_IOCTL_DCI_HEALTH_STATS 25 +#define DIAG_IOCTL_DCI_LOG_STATUS 26 +#define DIAG_IOCTL_DCI_EVENT_STATUS 27 +#define DIAG_IOCTL_DCI_CLEAR_LOGS 28 +#define DIAG_IOCTL_DCI_CLEAR_EVENTS 29 +#define DIAG_IOCTL_REMOTE_DEV 32 +#define DIAG_IOCTL_VOTE_REAL_TIME 33 +#define DIAG_IOCTL_GET_REAL_TIME 34 +#define DIAG_IOCTL_PERIPHERAL_BUF_CONFIG 35 +#define DIAG_IOCTL_PERIPHERAL_BUF_DRAIN 36 +#define DIAG_IOCTL_REGISTER_CALLBACK 37 +#define DIAG_IOCTL_HDLC_TOGGLE 38 +#define DIAG_IOCTL_QUERY_PD_LOGGING 39 + +/* PC Tools IDs */ +#define APQ8060_TOOLS_ID 4062 +#define AO8960_TOOLS_ID 4064 +#define APQ8064_TOOLS_ID 4072 +#define MSM8625_TOOLS_ID 4075 +#define MSM8930_TOOLS_ID 4076 +#define MSM8630_TOOLS_ID 4077 +#define MSM8230_TOOLS_ID 4078 +#define APQ8030_TOOLS_ID 4079 +#define MSM8627_TOOLS_ID 4080 +#define MSM8227_TOOLS_ID 4081 +#define MSM8974_TOOLS_ID 4083 +#define APQ8074_TOOLS_ID 4090 +#define MSM8916_TOOLS_ID 4094 +#define APQ8084_TOOLS_ID 4095 +#define MSM8994_TOOLS_ID 4097 +#define MSM8939_TOOLS_ID 4103 +#define APQ8026_TOOLS_ID 4104 +#define MSM8909_TOOLS_ID 4108 +#define MSM8992_TOOLS_ID 4111 +#define MSM8952_TOOLS_ID 4110 +#define MSM_8996_TOOLS_ID 4112 + +#define MSG_MASK_0 (0x00000001) +#define MSG_MASK_1 (0x00000002) +#define MSG_MASK_2 (0x00000004) +#define MSG_MASK_3 (0x00000008) +#define MSG_MASK_4 (0x00000010) +#define MSG_MASK_5 (0x00000020) +#define MSG_MASK_6 (0x00000040) +#define MSG_MASK_7 (0x00000080) +#define MSG_MASK_8 (0x00000100) +#define MSG_MASK_9 (0x00000200) +#define MSG_MASK_10 (0x00000400) +#define MSG_MASK_11 (0x00000800) +#define MSG_MASK_12 (0x00001000) +#define MSG_MASK_13 (0x00002000) +#define MSG_MASK_14 (0x00004000) +#define MSG_MASK_15 (0x00008000) +#define MSG_MASK_16 (0x00010000) +#define MSG_MASK_17 (0x00020000) +#define MSG_MASK_18 (0x00040000) +#define MSG_MASK_19 (0x00080000) +#define MSG_MASK_20 (0x00100000) +#define MSG_MASK_21 (0x00200000) +#define MSG_MASK_22 (0x00400000) +#define MSG_MASK_23 (0x00800000) +#define MSG_MASK_24 (0x01000000) +#define MSG_MASK_25 (0x02000000) +#define MSG_MASK_26 (0x04000000) +#define MSG_MASK_27 (0x08000000) +#define MSG_MASK_28 (0x10000000) +#define MSG_MASK_29 (0x20000000) +#define MSG_MASK_30 (0x40000000) +#define MSG_MASK_31 (0x80000000) + +/* These masks are to be used for support of all legacy messages in the sw. +The user does not need to remember the names as they will be embedded in +the appropriate macros. */ +#define MSG_LEGACY_LOW MSG_MASK_0 +#define MSG_LEGACY_MED MSG_MASK_1 +#define MSG_LEGACY_HIGH MSG_MASK_2 +#define MSG_LEGACY_ERROR MSG_MASK_3 +#define MSG_LEGACY_FATAL MSG_MASK_4 + +/* Legacy Message Priorities */ +#define MSG_LVL_FATAL (MSG_LEGACY_FATAL) +#define MSG_LVL_ERROR (MSG_LEGACY_ERROR | MSG_LVL_FATAL) +#define MSG_LVL_HIGH (MSG_LEGACY_HIGH | MSG_LVL_ERROR) +#define MSG_LVL_MED (MSG_LEGACY_MED | MSG_LVL_HIGH) +#define MSG_LVL_LOW (MSG_LEGACY_LOW | MSG_LVL_MED) + +#define MSG_LVL_NONE 0 + +/* This needs to be modified manually now, when we add + a new RANGE of SSIDs to the msg_mask_tbl */ +#define MSG_MASK_TBL_CNT 26 +#define APPS_EVENT_LAST_ID 0xCB7 + +#define MSG_SSID_0 0 +#define MSG_SSID_0_LAST 131 +#define MSG_SSID_1 500 +#define MSG_SSID_1_LAST 506 +#define MSG_SSID_2 1000 +#define MSG_SSID_2_LAST 1007 +#define MSG_SSID_3 2000 +#define MSG_SSID_3_LAST 2008 +#define MSG_SSID_4 3000 +#define MSG_SSID_4_LAST 3014 +#define MSG_SSID_5 4000 +#define MSG_SSID_5_LAST 4010 +#define MSG_SSID_6 4500 +#define MSG_SSID_6_LAST 4584 +#define MSG_SSID_7 4600 +#define MSG_SSID_7_LAST 4616 +#define MSG_SSID_8 5000 +#define MSG_SSID_8_LAST 5036 +#define MSG_SSID_9 5500 +#define MSG_SSID_9_LAST 5517 +#define MSG_SSID_10 6000 +#define MSG_SSID_10_LAST 6081 +#define MSG_SSID_11 6500 +#define MSG_SSID_11_LAST 6521 +#define MSG_SSID_12 7000 +#define MSG_SSID_12_LAST 7003 +#define MSG_SSID_13 7100 +#define MSG_SSID_13_LAST 7111 +#define MSG_SSID_14 7200 +#define MSG_SSID_14_LAST 7201 +#define MSG_SSID_15 8000 +#define MSG_SSID_15_LAST 8000 +#define MSG_SSID_16 8500 +#define MSG_SSID_16_LAST 8532 +#define MSG_SSID_17 9000 +#define MSG_SSID_17_LAST 9008 +#define MSG_SSID_18 9500 +#define MSG_SSID_18_LAST 9521 +#define MSG_SSID_19 10200 +#define MSG_SSID_19_LAST 10210 +#define MSG_SSID_20 10251 +#define MSG_SSID_20_LAST 10255 +#define MSG_SSID_21 10300 +#define MSG_SSID_21_LAST 10300 +#define MSG_SSID_22 10350 +#define MSG_SSID_22_LAST 10377 +#define MSG_SSID_23 10400 +#define MSG_SSID_23_LAST 10416 +#define MSG_SSID_24 10500 +#define MSG_SSID_24_LAST 10505 +#define MSG_SSID_25 0xC000 +#define MSG_SSID_25_LAST 0xC063 + +static const uint32_t msg_bld_masks_0[] = { + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_ERROR, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_ERROR, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_ERROR, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_MED | MSG_MASK_5 | MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8, + MSG_LVL_LOW, + MSG_LVL_ERROR, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED|MSG_MASK_7 | \ + MSG_MASK_8|MSG_MASK_9|MSG_MASK_10|MSG_MASK_11|MSG_MASK_12 | \ + MSG_MASK_13|MSG_MASK_14|MSG_MASK_15|MSG_MASK_16 | \ + MSG_MASK_17|MSG_MASK_18|MSG_MASK_19|MSG_MASK_20|MSG_MASK_21, + MSG_LVL_MED|MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10| \ + MSG_MASK_11|MSG_MASK_12|MSG_MASK_13|MSG_MASK_14| \ + MSG_MASK_15|MSG_MASK_16|MSG_MASK_17, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED|MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_MED, + MSG_LVL_MED|MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10| \ + MSG_MASK_11|MSG_MASK_12|MSG_MASK_13|MSG_MASK_14|MSG_MASK_15| \ + MSG_MASK_16|MSG_MASK_17|MSG_MASK_18|MSG_MASK_19|MSG_MASK_20| \ + MSG_MASK_21|MSG_MASK_22|MSG_MASK_23|MSG_MASK_24|MSG_MASK_25, + MSG_LVL_MED|MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW | MSG_MASK_5 | \ + MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8, + MSG_LVL_LOW | MSG_MASK_5 | \ + MSG_MASK_6, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_MED | MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10| \ + MSG_MASK_11|MSG_MASK_12|MSG_MASK_13|MSG_MASK_14|MSG_MASK_15 | \ + MSG_MASK_16|MSG_MASK_17|MSG_MASK_18|MSG_MASK_19|MSG_MASK_20, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_HIGH | MSG_MASK_21, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR, + MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR, + MSG_LVL_MED|MSG_LVL_HIGH, + MSG_LVL_MED|MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_HIGH, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR +}; + +static const uint32_t msg_bld_masks_1[] = { + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH +}; + +static const uint32_t msg_bld_masks_2[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED|MSG_MASK_5, + MSG_LVL_MED, + MSG_LVL_MED +}; + +static const uint32_t msg_bld_masks_3[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7| + MSG_MASK_8|MSG_MASK_9|MSG_MASK_10, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED +}; + +static const uint32_t msg_bld_masks_4[] = { + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_5[] = { + MSG_LVL_HIGH, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED|MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7| \ + MSG_MASK_8|MSG_MASK_9, + MSG_LVL_MED +}; + +static const uint32_t msg_bld_masks_6[] = { + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, + MSG_LVL_LOW | MSG_MASK_5, +}; + +static const uint32_t msg_bld_masks_7[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_8[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_HIGH +}; + +static const uint32_t msg_bld_masks_9[] = { + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_10[] = { + MSG_LVL_MED, + MSG_LVL_ERROR, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_MASK_5 | \ + MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10| \ + MSG_MASK_11|MSG_MASK_12|MSG_MASK_13|MSG_MASK_14|MSG_MASK_15| \ + MSG_MASK_16|MSG_MASK_17|MSG_MASK_18|MSG_MASK_19|MSG_MASK_20| \ + MSG_MASK_21|MSG_MASK_22, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW|MSG_MASK_5, + MSG_LVL_LOW|MSG_MASK_0 | MSG_MASK_1 | MSG_MASK_2 | \ + MSG_MASK_3 | MSG_MASK_4 | MSG_MASK_5 | MSG_MASK_6, + MSG_LVL_HIGH, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED +}; + +static const uint32_t msg_bld_masks_11[] = { + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, +}; + +static const uint32_t msg_bld_masks_12[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, +}; + +static const uint32_t msg_bld_masks_13[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, +}; + +static const uint32_t msg_bld_masks_14[] = { + MSG_LVL_MED, + MSG_LVL_MED, +}; + +static const uint32_t msg_bld_masks_15[] = { + MSG_LVL_MED +}; + +static const uint32_t msg_bld_masks_16[] = { + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR | + MSG_LVL_FATAL, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_17[] = { + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED, + MSG_LVL_MED | MSG_MASK_6 | \ + MSG_MASK_7 | MSG_MASK_8 | MSG_MASK_9, + MSG_LVL_MED | MSG_MASK_5 | \ + MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8 | MSG_MASK_9 | \ + MSG_MASK_10 | MSG_MASK_11 | MSG_MASK_12 | MSG_MASK_13 | \ + MSG_MASK_14 | MSG_MASK_15 | MSG_MASK_16 | MSG_MASK_17, + MSG_LVL_MED, + MSG_LVL_MED | MSG_MASK_5 | \ + MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8 | MSG_MASK_9 | \ + MSG_MASK_10 | MSG_MASK_11 | MSG_MASK_12 | MSG_MASK_13 | \ + MSG_MASK_14 | MSG_MASK_15 | MSG_MASK_16 | MSG_MASK_17 | \ + MSG_MASK_18 | MSG_MASK_19 | MSG_MASK_20 | MSG_MASK_21 | \ + MSG_MASK_22, + MSG_LVL_MED, + MSG_LVL_MED, +}; + +static const uint32_t msg_bld_masks_18[] = { + MSG_LVL_LOW, + MSG_LVL_MED | MSG_MASK_8 | MSG_MASK_9 | MSG_MASK_10 | MSG_MASK_11 | + MSG_MASK_12 | MSG_MASK_13 | MSG_MASK_14 | MSG_MASK_15 | + MSG_MASK_16 | MSG_MASK_17 | MSG_MASK_18 | MSG_MASK_19 | + MSG_MASK_20, + MSG_LVL_MED | MSG_MASK_5 | MSG_MASK_6, + MSG_LVL_MED | MSG_MASK_5, + MSG_LVL_MED | MSG_MASK_5 | MSG_MASK_6, + MSG_LVL_LOW, + MSG_LVL_MED | MSG_MASK_5 | MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8 | + MSG_MASK_9, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_MED | MSG_MASK_5 | MSG_MASK_6 | MSG_MASK_7 | MSG_MASK_8 | + MSG_MASK_9 | MSG_MASK_10 | MSG_MASK_11 | MSG_MASK_12 | + MSG_MASK_13 | MSG_MASK_14 | MSG_MASK_15 | MSG_MASK_16 | + MSG_MASK_20 | MSG_MASK_21 | MSG_MASK_22, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_19[] = { + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_20[] = { + MSG_LVL_LOW | MSG_MASK_5 | MSG_MASK_6 | MSG_MASK_7 | + MSG_MASK_8 | MSG_MASK_9 | MSG_MASK_10 | MSG_MASK_11 | + MSG_MASK_12, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_21[] = { + MSG_LVL_HIGH +}; + +static const uint32_t msg_bld_masks_22[] = { + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_23[] = { + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW, + MSG_LVL_LOW +}; + +static const uint32_t msg_bld_masks_24[] = { + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH, + MSG_LVL_HIGH +}; + +static const uint32_t msg_bld_masks_25[] = { + MSG_LVL_LOW +}; + +/* LOG CODES */ +static const uint32_t log_code_last_tbl[] = { + 0x0, /* EQUIP ID 0 */ + 0x1CC0, /* EQUIP ID 1 */ + 0x0, /* EQUIP ID 2 */ + 0x0, /* EQUIP ID 3 */ + 0x4910, /* EQUIP ID 4 */ + 0x5420, /* EQUIP ID 5 */ + 0x0, /* EQUIP ID 6 */ + 0x74FF, /* EQUIP ID 7 */ + 0x0, /* EQUIP ID 8 */ + 0x0, /* EQUIP ID 9 */ + 0xA38A, /* EQUIP ID 10 */ + 0xB9FF, /* EQUIP ID 11 */ + 0x0, /* EQUIP ID 12 */ + 0xD1FF, /* EQUIP ID 13 */ + 0x0, /* EQUIP ID 14 */ + 0x0, /* EQUIP ID 15 */ +}; + +#define LOG_GET_ITEM_NUM(xx_code) (xx_code & 0x0FFF) +#define LOG_GET_EQUIP_ID(xx_code) ((xx_code & 0xF000) >> 12) +#define LOG_ITEMS_TO_SIZE(num_items) ((num_items+7)/8) +#define LOG_SIZE_TO_ITEMS(size) ((8*size) - 7) +#define EVENT_COUNT_TO_BYTES(count) ((count/8) + 1) + +#endif diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index c8e1831d7572..4c86e4483e0d 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h @@ -18,6 +18,12 @@ enum dma_attr { DMA_ATTR_NO_KERNEL_MAPPING, DMA_ATTR_SKIP_CPU_SYNC, DMA_ATTR_FORCE_CONTIGUOUS, + DMA_ATTR_STRONGLY_ORDERED, + DMA_ATTR_SKIP_ZEROING, + DMA_ATTR_NO_DELAYED_UNMAP, + DMA_ATTR_EXEC_MAPPING, + DMA_ATTR_FORCE_COHERENT, + DMA_ATTR_FORCE_NON_COHERENT, DMA_ATTR_MAX, }; diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index 19baa7f4f403..eecc7240ddfc 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h @@ -60,7 +60,6 @@ void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs); void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs); -int iommu_dma_supported(struct device *dev, u64 mask); int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); #else diff --git a/include/linux/dma-mapping-fast.h b/include/linux/dma-mapping-fast.h new file mode 100644 index 000000000000..560f04736c1d --- /dev/null +++ b/include/linux/dma-mapping-fast.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2016, 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 __LINUX_DMA_MAPPING_FAST_H +#define __LINUX_DMA_MAPPING_FAST_H + +#include <linux/iommu.h> +#include <linux/io-pgtable-fast.h> + +struct dma_iommu_mapping; + +struct dma_fast_smmu_mapping { + struct device *dev; + struct iommu_domain *domain; + dma_addr_t base; + size_t size; + size_t num_4k_pages; + + unsigned int bitmap_size; + unsigned long *bitmap; + unsigned long next_start; + unsigned long upcoming_stale_bit; + bool have_stale_tlbs; + + dma_addr_t pgtbl_dma_handle; + av8l_fast_iopte *pgtbl_pmds; + + spinlock_t lock; + struct notifier_block notifier; + + int is_smmu_pt_coherent; +}; + +#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST +int fast_smmu_attach_device(struct device *dev, + struct dma_iommu_mapping *mapping); +void fast_smmu_detach_device(struct device *dev, + struct dma_iommu_mapping *mapping); +#else +static inline int fast_smmu_attach_device(struct device *dev, + struct dma_iommu_mapping *mapping) +{ + return -ENODEV; +} + +static inline void fast_smmu_detach_device(struct device *dev, + struct dma_iommu_mapping *mapping) +{ +} +#endif + +#endif /* __LINUX_DMA_MAPPING_FAST_H */ diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 62dd6676b7cc..1d4cb72f7fd7 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -61,6 +61,10 @@ struct dma_map_ops { int (*mapping_error)(struct device *dev, dma_addr_t dma_addr); int (*dma_supported)(struct device *dev, u64 mask); int (*set_dma_mask)(struct device *dev, u64 mask); + void *(*remap)(struct device *dev, void *cpu_addr, dma_addr_t handle, + size_t size, struct dma_attrs *attrs); + void (*unremap)(struct device *dev, void *remapped_address, + size_t size); #ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK u64 (*get_required_mask)(struct device *dev); #endif @@ -89,6 +93,40 @@ static inline int is_device_dma_capable(struct device *dev) #include <asm-generic/dma-mapping-broken.h> #endif +#ifndef CONFIG_NO_DMA +static inline void *dma_remap(struct device *dev, void *cpu_addr, + dma_addr_t dma_handle, size_t size, struct dma_attrs *attrs) +{ + const struct dma_map_ops *ops = get_dma_ops(dev); + BUG_ON(!ops); + + if (!ops->remap) { + WARN_ONCE(1, "Remap function not implemented for %pS\n", + ops->remap); + return NULL; + } + + return ops->remap(dev, cpu_addr, dma_handle, size, attrs); +} + + +static inline void dma_unremap(struct device *dev, void *remapped_addr, + size_t size) +{ + const struct dma_map_ops *ops = get_dma_ops(dev); + BUG_ON(!ops); + + if (!ops->unremap) { + WARN_ONCE(1, "unremap function not implemented for %pS\n", + ops->unremap); + return; + } + + return ops->unremap(dev, remapped_addr, size); +} +#endif + + static inline u64 dma_get_mask(struct device *dev) { if (dev && dev->dma_mask && *dev->dma_mask) diff --git a/include/linux/ecm_ipa.h b/include/linux/ecm_ipa.h new file mode 100644 index 000000000000..6d30af8bbc9f --- /dev/null +++ b/include/linux/ecm_ipa.h @@ -0,0 +1,95 @@ +/* Copyright (c) 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 _ECM_IPA_H_ +#define _ECM_IPA_H_ + +#include <linux/ipa.h> + +/* + * @priv: private data given upon ipa_connect + * @evt: event enum, should be IPA_WRITE_DONE + * @data: for tx path the data field is the sent socket buffer. + */ +typedef void (*ecm_ipa_callback)(void *priv, + enum ipa_dp_evt_type evt, + unsigned long data); + +/* + * struct ecm_ipa_params - parameters for ecm_ipa initialization API + * + * @device_ready_notify: callback supplied by USB core driver. + * This callback shall be called by the Netdev once the device + * is ready to recieve data from tethered PC. + * @ecm_ipa_rx_dp_notify: ecm_ipa will set this callback (out parameter). + * this callback shall be supplied for ipa_connect upon pipe + * connection (USB->IPA), once IPA driver receive data packets + * from USB pipe destined for Apps this callback will be called. + * @ecm_ipa_tx_dp_notify: ecm_ipa will set this callback (out parameter). + * this callback shall be supplied for ipa_connect upon pipe + * connection (IPA->USB), once IPA driver send packets destined + * for USB, IPA BAM will notify for Tx-complete. + * @priv: ecm_ipa will set this pointer (out parameter). + * This pointer will hold the network device for later interaction + * with ecm_ipa APIs + * @host_ethaddr: host Ethernet address in network order + * @device_ethaddr: device Ethernet address in network order + * @skip_ep_cfg: boolean field that determines if Apps-processor + * should or should not configure this end-point. + */ +struct ecm_ipa_params { + void (*device_ready_notify)(void); + ecm_ipa_callback ecm_ipa_rx_dp_notify; + ecm_ipa_callback ecm_ipa_tx_dp_notify; + u8 host_ethaddr[ETH_ALEN]; + u8 device_ethaddr[ETH_ALEN]; + void *private; + bool skip_ep_cfg; +}; + + +#ifdef CONFIG_ECM_IPA + +int ecm_ipa_init(struct ecm_ipa_params *params); + +int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl, + void *priv); + +int ecm_ipa_disconnect(void *priv); + +void ecm_ipa_cleanup(void *priv); + +#else /* CONFIG_ECM_IPA*/ + +static inline int ecm_ipa_init(struct ecm_ipa_params *params) +{ + return 0; +} + +static inline int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl, + void *priv) +{ + return 0; +} + +static inline int ecm_ipa_disconnect(void *priv) +{ + return 0; +} + +static inline void ecm_ipa_cleanup(void *priv) +{ + +} +#endif /* CONFIG_ECM_IPA*/ + +#endif /* _ECM_IPA_H_ */ diff --git a/include/linux/ecryptfs.h b/include/linux/ecryptfs.h index 8d5ab998a222..0f0b66491940 100644 --- a/include/linux/ecryptfs.h +++ b/include/linux/ecryptfs.h @@ -1,6 +1,9 @@ #ifndef _LINUX_ECRYPTFS_H #define _LINUX_ECRYPTFS_H +struct inode; +struct page; + /* Version verification for shared data structures w/ userspace */ #define ECRYPTFS_VERSION_MAJOR 0x00 #define ECRYPTFS_VERSION_MINOR 0x04 @@ -41,6 +44,7 @@ #define RFC2440_CIPHER_AES_256 0x09 #define RFC2440_CIPHER_TWOFISH 0x0a #define RFC2440_CIPHER_CAST_6 0x0b +#define RFC2440_CIPHER_AES_XTS_256 0x0c #define RFC2440_CIPHER_RSA 0x01 @@ -102,4 +106,101 @@ struct ecryptfs_auth_tok { } token; } __attribute__ ((packed)); +#define ECRYPTFS_INVALID_EVENTS_HANDLE -1 + +/** + * ecryptfs_events struct represents a partial interface + * towards ecryptfs module. If registered to ecryptfs events, + * one can receive push notifications. + * A first callback received from ecryptfs will probably be + * about file opening (open_cb), + * in which ecryptfs passes its ecryptfs_data for future usage. + * This data represents a file and must be passed in every query functions + * such as ecryptfs_get_key_size(), ecryptfs_get_cipher() etc. + */ +struct ecryptfs_events { + bool (*is_cipher_supported_cb)(const void *ecrytpfs_data); + void (*open_cb)(struct inode *inode, void *ecrytpfs_data); + void (*release_cb)(struct inode *inode); + int (*encrypt_cb)(struct page *in_page, struct page *out_page, + struct inode *inode, unsigned long extent_offset); + int (*decrypt_cb)(struct page *in_page, struct page *out_page, + struct inode *inode, unsigned long extent_offset); + bool (*is_hw_crypt_cb)(void); + size_t (*get_salt_key_size_cb)(const void *ecrytpfs_data); +}; + +#ifdef CONFIG_ECRYPT_FS +int ecryptfs_register_to_events(const struct ecryptfs_events *ops); + +int ecryptfs_unregister_from_events(int user_handle); + +const unsigned char *ecryptfs_get_key(const void *ecrytpfs_data); + +size_t ecryptfs_get_key_size(const void *ecrytpfs_data); + +const unsigned char *ecryptfs_get_salt(const void *ecrytpfs_data); + +size_t ecryptfs_get_salt_size(const void *ecrytpfs_data); + +bool ecryptfs_cipher_match(const void *ecrytpfs_data, + const unsigned char *cipher, size_t cipher_size); + +bool ecryptfs_is_page_in_metadata(const void *ecrytpfs_data, pgoff_t offset); + +bool ecryptfs_is_data_equal(const void *ecrytpfs_data1, + const void *ecrytpfs_data2); + +#else +static inline int ecryptfs_register_to_events( + const struct ecryptfs_events *ops) +{ + return 1; /* dummy handle */ +} + +static inline int ecryptfs_unregister_from_events(int user_handle) +{ + return 0; +} + +static inline const unsigned char *ecryptfs_get_key(const void *ecrytpfs_data) +{ + return NULL; +} + +static inline size_t ecryptfs_get_key_size(const void *ecrytpfs_data) +{ + return 0; +} + +static inline const unsigned char *ecryptfs_get_salt(const void *ecrytpfs_data) +{ + return NULL; +} + +static inline size_t ecryptfs_get_salt_size(const void *ecrytpfs_data) +{ + return 0; +} + +static inline bool ecryptfs_cipher_match(const void *ecrytpfs_data, + const unsigned char *cipher, size_t cipher_size) +{ + return false; +} + +static inline bool ecryptfs_is_page_in_metadata(const void *ecrytpfs_data, + pgoff_t offset) +{ + return false; +} + +static inline bool ecryptfs_is_data_equal(const void *ecrytpfs_data1, + const void *ecrytpfs_data2) +{ + return false; +} + +#endif /* CONFIG_ECRYPT_FS */ + #endif /* _LINUX_ECRYPTFS_H */ diff --git a/include/linux/epm_adc.h b/include/linux/epm_adc.h new file mode 100644 index 000000000000..0a19c5ec3e88 --- /dev/null +++ b/include/linux/epm_adc.h @@ -0,0 +1,17 @@ +#ifndef __EPM_ADC_H +#define __EPM_ADC_H + +#include <linux/i2c.h> +#include <uapi/linux/epm_adc.h> + +struct epm_adc_platform_data { + struct epm_chan_properties *channel; + uint32_t num_channels; + uint32_t num_adc; + uint32_t chan_per_adc; + uint32_t chan_per_mux; + struct i2c_board_info epm_i2c_board_info; + uint32_t bus_id; + uint32_t gpio_expander_base_addr; +}; +#endif /* __EPM_ADC_H */ diff --git a/include/linux/esoc_client.h b/include/linux/esoc_client.h new file mode 100644 index 000000000000..8d13c88eda81 --- /dev/null +++ b/include/linux/esoc_client.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2014, 2017, 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 __ESOC_CLIENT_H_ +#define __ESOC_CLIENT_H_ + +#include <linux/device.h> +#include <linux/esoc_ctrl.h> +#include <linux/notifier.h> + +/* + * 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; +}; + +#ifdef CONFIG_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); +#else +static inline struct esoc_desc *devm_register_esoc_client(struct device *dev, + const char *name) +{ + return NULL; +} +static inline void devm_unregister_esoc_client(struct device *dev, + struct esoc_desc *esoc_desc) +{ + return; +} +static inline int esoc_register_client_notifier(struct notifier_block *nb) +{ + return -EIO; +} +#endif +#endif diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 7abf674c388c..081afbe982c0 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -55,6 +55,15 @@ #define EXTCON_JACK_SPDIF_IN 26 /* Sony Philips Digital InterFace */ #define EXTCON_JACK_SPDIF_OUT 27 +/* connector orientation 0 - CC1, 1 - CC2 */ +#define EXTCON_USB_CC 28 + +/* connector speed 0 - High Speed, 1 - super speed */ +#define EXTCON_USB_SPEED 29 + +/* connector type C current 0 - default current, 1 - medium or high current */ +#define EXTCON_USB_TYPEC_MED_HIGH_CURRENT 30 + /* Display external connector */ #define EXTCON_DISP_HDMI 40 /* High-Definition Multimedia Interface */ #define EXTCON_DISP_MHL 41 /* Mobile High-Definition Link */ diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 2ebfa01b7091..de8f11461536 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /** * include/linux/f2fs_fs.h * * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.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_F2FS_FS_H #define _LINUX_F2FS_FS_H @@ -112,12 +109,16 @@ struct f2fs_super_block { struct f2fs_device devs[MAX_DEVICES]; /* device list */ __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */ __u8 hot_ext_count; /* # of hot file extension */ - __u8 reserved[314]; /* valid reserved region */ + __u8 reserved[310]; /* valid reserved region */ + __le32 crc; /* checksum of superblock */ } __packed; /* * For checkpoint */ +#define CP_DISABLED_QUICK_FLAG 0x00002000 +#define CP_DISABLED_FLAG 0x00001000 +#define CP_QUOTA_NEED_FSCK_FLAG 0x00000800 #define CP_LARGE_NAT_BITMAP_FLAG 0x00000400 #define CP_NOCRC_RECOVERY_FLAG 0x00000200 #define CP_TRIMMED_FLAG 0x00000100 @@ -163,6 +164,10 @@ struct f2fs_checkpoint { unsigned char sit_nat_version_bitmap[1]; } __packed; +#define CP_CHKSUM_OFFSET 4092 /* default chksum offset in checkpoint */ +#define CP_MIN_CHKSUM_OFFSET \ + (offsetof(struct f2fs_checkpoint, sit_nat_version_bitmap)) + /* * For orphan inode management */ @@ -186,7 +191,7 @@ struct f2fs_orphan_block { struct f2fs_extent { __le32 fofs; /* start file offset of the extent */ __le32 blk; /* start block address of the extent */ - __le32 len; /* lengh of the extent */ + __le32 len; /* length of the extent */ } __packed; #define F2FS_NAME_LEN 255 @@ -197,11 +202,12 @@ struct f2fs_extent { get_extra_isize(inode)) #define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ #define ADDRS_PER_INODE(inode) addrs_per_inode(inode) -#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ +#define DEF_ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ +#define ADDRS_PER_BLOCK(inode) addrs_per_block(inode) #define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ #define ADDRS_PER_PAGE(page, inode) \ - (IS_INODE(page) ? ADDRS_PER_INODE(inode) : ADDRS_PER_BLOCK) + (IS_INODE(page) ? ADDRS_PER_INODE(inode) : ADDRS_PER_BLOCK(inode)) #define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) #define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) @@ -266,7 +272,7 @@ struct f2fs_inode { } __packed; struct direct_node { - __le32 addr[ADDRS_PER_BLOCK]; /* array of data block address */ + __le32 addr[DEF_ADDRS_PER_BLOCK]; /* array of data block address */ } __packed; struct indirect_node { @@ -284,7 +290,7 @@ enum { struct node_footer { __le32 nid; /* node id */ - __le32 ino; /* inode nunmber */ + __le32 ino; /* inode number */ __le32 flag; /* include cold/fsync/dentry marks and offset */ __le64 cp_ver; /* checkpoint version */ __le32 next_blkaddr; /* next node page block address */ @@ -304,11 +310,6 @@ struct f2fs_node { * For NAT entries */ #define NAT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_nat_entry)) -#define NAT_ENTRY_BITMAP_SIZE ((NAT_ENTRY_PER_BLOCK + 7) / 8) -#define NAT_ENTRY_BITMAP_SIZE_ALIGNED \ - ((NAT_ENTRY_BITMAP_SIZE + BITS_PER_LONG - 1) / \ - BITS_PER_LONG * BITS_PER_LONG) - struct f2fs_nat_entry { __u8 version; /* latest version of cached nat entry */ @@ -494,12 +495,12 @@ typedef __le32 f2fs_hash_t; /* * space utilization of regular dentry and inline dentry (w/o extra reservation) - * regular dentry inline dentry - * bitmap 1 * 27 = 27 1 * 23 = 23 - * reserved 1 * 3 = 3 1 * 7 = 7 - * dentry 11 * 214 = 2354 11 * 182 = 2002 - * filename 8 * 214 = 1712 8 * 182 = 1456 - * total 4096 3488 + * regular dentry inline dentry (def) inline dentry (min) + * bitmap 1 * 27 = 27 1 * 23 = 23 1 * 1 = 1 + * reserved 1 * 3 = 3 1 * 7 = 7 1 * 1 = 1 + * dentry 11 * 214 = 2354 11 * 182 = 2002 11 * 2 = 22 + * filename 8 * 214 = 1712 8 * 182 = 1456 8 * 2 = 16 + * total 4096 3488 40 * * Note: there are more reserved space in inline dentry than in regular * dentry, when converting inline dentry we should handle this carefully. @@ -511,12 +512,13 @@ typedef __le32 f2fs_hash_t; #define SIZE_OF_RESERVED (PAGE_SIZE - ((SIZE_OF_DIR_ENTRY + \ F2FS_SLOT_LEN) * \ NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) +#define MIN_INLINE_DENTRY_SIZE 40 /* just include '.' and '..' entries */ /* One directory entry slot representing F2FS_SLOT_LEN-sized file name */ struct f2fs_dir_entry { __le32 hash_code; /* hash code of file name */ __le32 ino; /* inode number */ - __le16 name_len; /* lengh of file name */ + __le16 name_len; /* length of file name */ __u8 file_type; /* file type */ } __packed; diff --git a/include/linux/fb.h b/include/linux/fb.h index b48a14e5424e..479d6640cc6e 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -288,10 +288,18 @@ struct fb_ops { int (*fb_ioctl)(struct fb_info *info, unsigned int cmd, unsigned long arg); + /* perform fb specific ioctl v2 (optional) - provides file param */ + int (*fb_ioctl_v2)(struct fb_info *info, unsigned int cmd, + unsigned long arg, struct file *file); + /* Handle 32bit compat ioctl (optional) */ int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd, unsigned long arg); + /* Handle 32bit compat ioctl (optional) */ + int (*fb_compat_ioctl_v2)(struct fb_info *info, unsigned cmd, + unsigned long arg, struct file *file); + /* perform fb specific mmap */ int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); @@ -460,17 +468,8 @@ struct fb_info { struct fb_cmap cmap; /* Current cmap */ struct list_head modelist; /* mode list */ struct fb_videomode *mode; /* current mode */ + struct file *file; /* current file node */ -#ifdef CONFIG_FB_BACKLIGHT - /* assigned backlight device */ - /* set before framebuffer registration, - remove after unregister */ - struct backlight_device *bl_dev; - - /* Backlight level curve */ - struct mutex bl_curve_mutex; - u8 bl_curve[FB_BACKLIGHT_LEVELS]; -#endif #ifdef CONFIG_FB_DEFERRED_IO struct delayed_work deferred_work; struct fb_deferred_io *fbdefio; diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 5c41c5e75b5c..8ddd41a5ff2c 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -48,6 +48,20 @@ int request_firmware_nowait( int request_firmware_direct(const struct firmware **fw, const char *name, struct device *device); +int request_firmware_into_buf(const char *name, struct device *device, + phys_addr_t dest_addr, size_t dest_size, + void * (*map_fw_mem)(phys_addr_t phys, + size_t size, void *data), + void (*unmap_fw_mem)(void *virt, size_t size, + void *data), + void *data); +int request_firmware_nowait_into_buf( + struct module *module, bool uevent, + const char *name, struct device *device, gfp_t gfp, void *context, + void (*cont)(const struct firmware *fw, void *context), + phys_addr_t dest_addr, size_t dest_size, + void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data), + void (*unmap_fw_mem)(void *virt, size_t size, void *data), void *data); void release_firmware(const struct firmware *fw); #else static inline int request_firmware(const struct firmware **fw, @@ -56,6 +70,19 @@ static inline int request_firmware(const struct firmware **fw, { return -EINVAL; } +static inline int request_firmware_into_buf(const char *name, + struct device *device, + phys_addr_t dest_addr, + size_t dest_size, + void * (*map_fw_mem)(phys_addr_t phys, + size_t size, void *data), + void (*unmap_fw_mem)(void *virt, + size_t size, + void *data), + void *data) +{ + return -EINVAL; +} static inline int request_firmware_nowait( struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, @@ -63,7 +90,16 @@ static inline int request_firmware_nowait( { return -EINVAL; } - +static inline int request_firmware_nowait_into_buf( + struct module *module, bool uevent, + const char *name, struct device *device, gfp_t gfp, void *context, + void (*cont)(const struct firmware *fw, void *context), + phys_addr_t dest_addr, size_t dest_size, + void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data), + void (*unmap_fw_mem)(void *virt, size_t size, void *data), void *data) +{ + return -EINVAL; +} static inline void release_firmware(const struct firmware *fw) { } diff --git a/include/linux/fs.h b/include/linux/fs.h index 4ed68f9d0da3..cb599dd90018 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -213,8 +213,15 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE) #define WRITE_ODIRECT (WRITE | REQ_SYNC) #define WRITE_FLUSH (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH) +#define WRITE_FLUSH_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | \ + REQ_BARRIER) #define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA) #define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) +#define WRITE_POST_FLUSH_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | \ + REQ_POST_FLUSH_BARRIER | REQ_BARRIER) +#define WRITE_ORDERED_FLUSH_BARRIER (WRITE | REQ_SYNC | REQ_NOIDLE | \ + REQ_FLUSH | REQ_POST_FLUSH_BARRIER | \ + REQ_BARRIER) /* * Attribute flags. These should be or-ed together to figure out what @@ -423,6 +430,8 @@ struct address_space_operations { */ int (*migratepage) (struct address_space *, struct page *, struct page *, enum migrate_mode); + bool (*isolate_page)(struct page *, isolate_mode_t); + void (*putback_page)(struct page *); int (*launder_page) (struct page *); int (*is_partially_uptodate) (struct page *, unsigned long, unsigned long); @@ -495,6 +504,7 @@ struct block_device { int bd_invalidated; struct gendisk * bd_disk; struct request_queue * bd_queue; + struct backing_dev_info *bd_bdi; struct list_head bd_list; /* * Private data. You must have bd_claim'ed the block_device @@ -933,6 +943,10 @@ struct file { struct list_head f_tfile_llink; #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; + +#ifdef CONFIG_FILE_TABLE_DEBUG + struct hlist_node f_hash; +#endif /* #ifdef CONFIG_FILE_TABLE_DEBUG */ } __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ struct file_handle { @@ -2344,6 +2358,7 @@ extern struct kmem_cache *names_cachep; #ifdef CONFIG_BLOCK extern int register_blkdev(unsigned int, const char *); extern void unregister_blkdev(unsigned int, const char *); +extern void bdev_unhash_inode(dev_t dev); extern struct block_device *bdget(dev_t); extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); @@ -2675,6 +2690,7 @@ static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { }; #endif extern void unlock_new_inode(struct inode *); extern unsigned int get_next_ino(void); +extern void evict_inodes(struct super_block *sb); extern void __iget(struct inode * inode); extern void iget_failed(struct inode *); @@ -2824,6 +2840,8 @@ static inline void inode_dio_end(struct inode *inode) wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); } +struct inode *dio_bio_get_inode(struct bio *bio); + extern void inode_set_flags(struct inode *inode, unsigned int flags, unsigned int mask); @@ -3124,4 +3142,7 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); extern void inode_nohighmem(struct inode *inode); +int vfs_ioc_setflags_prepare(struct inode *inode, unsigned int oldflags, + unsigned int flags); + #endif /* _LINUX_FS_H */ diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h index 44bd4fbd3ec5..e2729c6d9829 100644 --- a/include/linux/fscrypt_notsupp.h +++ b/include/linux/fscrypt_notsupp.h @@ -67,16 +67,6 @@ static inline void fscrypt_restore_control_page(struct page *page) return; } -static inline void fscrypt_set_d_op(struct dentry *dentry) -{ - return; -} - -static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry) -{ - return; -} - /* policy.c */ static inline int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg) diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h index 9d1857302b73..46b62d82b6d6 100644 --- a/include/linux/fscrypt_supp.h +++ b/include/linux/fscrypt_supp.h @@ -28,7 +28,7 @@ struct fscrypt_operations { int (*set_context)(struct inode *, const void *, size_t, void *); bool (*dummy_context)(struct inode *); bool (*empty_dir)(struct inode *); - unsigned (*max_namelen)(struct inode *); + unsigned int max_namelen; }; struct fscrypt_ctx { @@ -74,20 +74,6 @@ static inline struct page *fscrypt_control_page(struct page *page) extern void fscrypt_restore_control_page(struct page *); -extern const struct dentry_operations fscrypt_d_ops; - -static inline void fscrypt_set_d_op(struct dentry *dentry) -{ - d_set_d_op(dentry, &fscrypt_d_ops); -} - -static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry) -{ - spin_lock(&dentry->d_lock); - dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY; - spin_unlock(&dentry->d_lock); -} - /* policy.c */ extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); extern int fscrypt_ioctl_get_policy(struct file *, void __user *); diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h new file mode 100644 index 000000000000..e6e53a36104b --- /dev/null +++ b/include/linux/fscrypto.h @@ -0,0 +1,411 @@ +/* + * General per-file encryption definition + * + * Copyright (C) 2015, Google, Inc. + * + * Written by Michael Halcrow, 2015. + * Modified by Jaegeuk Kim, 2015. + */ + +#ifndef _LINUX_FSCRYPTO_H +#define _LINUX_FSCRYPTO_H + +#include <linux/key.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/bio.h> +#include <linux/dcache.h> +#include <crypto/skcipher.h> +#include <uapi/linux/fs.h> + +#define FS_KEY_DERIVATION_NONCE_SIZE 16 +#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1 + +#define FS_POLICY_FLAGS_PAD_4 0x00 +#define FS_POLICY_FLAGS_PAD_8 0x01 +#define FS_POLICY_FLAGS_PAD_16 0x02 +#define FS_POLICY_FLAGS_PAD_32 0x03 +#define FS_POLICY_FLAGS_PAD_MASK 0x03 +#define FS_POLICY_FLAGS_VALID 0x03 + +/* Encryption algorithms */ +#define FS_ENCRYPTION_MODE_INVALID 0 +#define FS_ENCRYPTION_MODE_AES_256_XTS 1 +#define FS_ENCRYPTION_MODE_AES_256_GCM 2 +#define FS_ENCRYPTION_MODE_AES_256_CBC 3 +#define FS_ENCRYPTION_MODE_AES_256_CTS 4 + +/** + * Encryption context for inode + * + * Protector format: + * 1 byte: Protector format (1 = this version) + * 1 byte: File contents encryption mode + * 1 byte: File names encryption mode + * 1 byte: Flags + * 8 bytes: Master Key descriptor + * 16 bytes: Encryption Key derivation nonce + */ +struct fscrypt_context { + u8 format; + u8 contents_encryption_mode; + u8 filenames_encryption_mode; + u8 flags; + u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; + u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; +} __packed; + +/* Encryption parameters */ +#define FS_XTS_TWEAK_SIZE 16 +#define FS_AES_128_ECB_KEY_SIZE 16 +#define FS_AES_256_GCM_KEY_SIZE 32 +#define FS_AES_256_CBC_KEY_SIZE 32 +#define FS_AES_256_CTS_KEY_SIZE 32 +#define FS_AES_256_XTS_KEY_SIZE 64 +#define FS_MAX_KEY_SIZE 64 + +#define FS_KEY_DESC_PREFIX "fscrypt:" +#define FS_KEY_DESC_PREFIX_SIZE 8 + +/* This is passed in from userspace into the kernel keyring */ +struct fscrypt_key { + u32 mode; + u8 raw[FS_MAX_KEY_SIZE]; + u32 size; +} __packed; + +struct fscrypt_info { + u8 ci_data_mode; + u8 ci_filename_mode; + u8 ci_flags; + struct crypto_skcipher *ci_ctfm; + struct key *ci_keyring_key; + u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE]; +}; + +#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 +#define FS_WRITE_PATH_FL 0x00000002 + +struct fscrypt_ctx { + union { + struct { + struct page *bounce_page; /* Ciphertext page */ + struct page *control_page; /* Original page */ + } w; + struct { + struct bio *bio; + struct work_struct work; + } r; + struct list_head free_list; /* Free list */ + }; + u8 flags; /* Flags */ + u8 mode; /* Encryption mode for tfm */ +}; + +struct fscrypt_completion_result { + struct completion completion; + int res; +}; + +#define DECLARE_FS_COMPLETION_RESULT(ecr) \ + struct fscrypt_completion_result ecr = { \ + COMPLETION_INITIALIZER((ecr).completion), 0 } + +#define FS_FNAME_NUM_SCATTER_ENTRIES 4 +#define FS_CRYPTO_BLOCK_SIZE 16 +#define FS_FNAME_CRYPTO_DIGEST_SIZE 32 + +/** + * For encrypted symlinks, the ciphertext length is stored at the beginning + * of the string in little-endian format. + */ +struct fscrypt_symlink_data { + __le16 len; + char encrypted_path[1]; +} __packed; + +/** + * This function is used to calculate the disk space required to + * store a filename of length l in encrypted symlink format. + */ +static inline u32 fscrypt_symlink_data_len(u32 l) +{ + if (l < FS_CRYPTO_BLOCK_SIZE) + l = FS_CRYPTO_BLOCK_SIZE; + return (l + sizeof(struct fscrypt_symlink_data) - 1); +} + +struct fscrypt_str { + unsigned char *name; + u32 len; +}; + +struct fscrypt_name { + const struct qstr *usr_fname; + struct fscrypt_str disk_name; + u32 hash; + u32 minor_hash; + struct fscrypt_str crypto_buf; +}; + +#define FSTR_INIT(n, l) { .name = n, .len = l } +#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len) +#define fname_name(p) ((p)->disk_name.name) +#define fname_len(p) ((p)->disk_name.len) + +/* + * crypto opertions for filesystems + */ +struct fscrypt_operations { + int (*get_context)(struct inode *, void *, size_t); + int (*key_prefix)(struct inode *, u8 **); + int (*prepare_context)(struct inode *); + int (*set_context)(struct inode *, const void *, size_t, void *); + int (*dummy_context)(struct inode *); + bool (*is_encrypted)(struct inode *); + bool (*empty_dir)(struct inode *); + unsigned (*max_namelen)(struct inode *); +}; + +static inline bool fscrypt_dummy_context_enabled(struct inode *inode) +{ + if (inode->i_sb->s_cop->dummy_context && + inode->i_sb->s_cop->dummy_context(inode)) + return true; + return false; +} + +static inline bool fscrypt_valid_contents_enc_mode(u32 mode) +{ + return (mode == FS_ENCRYPTION_MODE_AES_256_XTS); +} + +static inline bool fscrypt_valid_filenames_enc_mode(u32 mode) +{ + return (mode == FS_ENCRYPTION_MODE_AES_256_CTS); +} + +static inline bool fscrypt_is_dot_dotdot(const struct qstr *str) +{ + if (str->len == 1 && str->name[0] == '.') + return true; + + if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.') + return true; + + return false; +} + +static inline struct page *fscrypt_control_page(struct page *page) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + return ((struct fscrypt_ctx *)page_private(page))->w.control_page; +#else + WARN_ON_ONCE(1); + return ERR_PTR(-EINVAL); +#endif +} + +static inline int fscrypt_has_encryption_key(struct inode *inode) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + return (inode->i_crypt_info != NULL); +#else + return 0; +#endif +} + +static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + spin_lock(&dentry->d_lock); + dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY; + spin_unlock(&dentry->d_lock); +#endif +} + +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) +extern const struct dentry_operations fscrypt_d_ops; +#endif + +static inline void fscrypt_set_d_op(struct dentry *dentry) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + d_set_d_op(dentry, &fscrypt_d_ops); +#endif +} + +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) +/* crypto.c */ +extern struct kmem_cache *fscrypt_info_cachep; +int fscrypt_initialize(void); + +extern struct fscrypt_ctx *fscrypt_get_ctx(struct inode *, gfp_t); +extern void fscrypt_release_ctx(struct fscrypt_ctx *); +extern struct page *fscrypt_encrypt_page(struct inode *, struct page *, gfp_t); +extern int fscrypt_decrypt_page(struct page *); +extern void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *, struct bio *); +extern void fscrypt_pullback_bio_page(struct page **, bool); +extern void fscrypt_restore_control_page(struct page *); +extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t, + unsigned int); +/* policy.c */ +extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); +extern int fscrypt_ioctl_get_policy(struct file *, void __user *); +extern int fscrypt_has_permitted_context(struct inode *, struct inode *); +extern int fscrypt_inherit_context(struct inode *, struct inode *, + void *, bool); +/* keyinfo.c */ +extern int get_crypt_info(struct inode *); +extern int fscrypt_get_encryption_info(struct inode *); +extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *); + +/* fname.c */ +extern int fscrypt_setup_filename(struct inode *, const struct qstr *, + int lookup, struct fscrypt_name *); +extern void fscrypt_free_filename(struct fscrypt_name *); +extern u32 fscrypt_fname_encrypted_size(struct inode *, u32); +extern int fscrypt_fname_alloc_buffer(struct inode *, u32, + struct fscrypt_str *); +extern void fscrypt_fname_free_buffer(struct fscrypt_str *); +extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32, + const struct fscrypt_str *, struct fscrypt_str *); +extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *, + struct fscrypt_str *); +#endif + +/* crypto.c */ +static inline struct fscrypt_ctx *fscrypt_notsupp_get_ctx(struct inode *i, + gfp_t f) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c) +{ + return; +} + +static inline struct page *fscrypt_notsupp_encrypt_page(struct inode *i, + struct page *p, gfp_t f) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int fscrypt_notsupp_decrypt_page(struct page *p) +{ + return -EOPNOTSUPP; +} + +static inline void fscrypt_notsupp_decrypt_bio_pages(struct fscrypt_ctx *c, + struct bio *b) +{ + return; +} + +static inline void fscrypt_notsupp_pullback_bio_page(struct page **p, bool b) +{ + return; +} + +static inline void fscrypt_notsupp_restore_control_page(struct page *p) +{ + return; +} + +static inline int fscrypt_notsupp_zeroout_range(struct inode *i, pgoff_t p, + sector_t s, unsigned int f) +{ + return -EOPNOTSUPP; +} + +/* policy.c */ +static inline int fscrypt_notsupp_ioctl_set_policy(struct file *f, + const void __user *arg) +{ + return -EOPNOTSUPP; +} + +static inline int fscrypt_notsupp_ioctl_get_policy(struct file *f, + void __user *arg) +{ + return -EOPNOTSUPP; +} + +static inline int fscrypt_notsupp_has_permitted_context(struct inode *p, + struct inode *i) +{ + return 0; +} + +static inline int fscrypt_notsupp_inherit_context(struct inode *p, + struct inode *i, void *v, bool b) +{ + return -EOPNOTSUPP; +} + +/* keyinfo.c */ +static inline int fscrypt_notsupp_get_encryption_info(struct inode *i) +{ + return -EOPNOTSUPP; +} + +static inline void fscrypt_notsupp_put_encryption_info(struct inode *i, + struct fscrypt_info *f) +{ + return; +} + + /* fname.c */ +static inline int fscrypt_notsupp_setup_filename(struct inode *dir, + const struct qstr *iname, + int lookup, struct fscrypt_name *fname) +{ + if (dir->i_sb->s_cop->is_encrypted(dir)) + return -EOPNOTSUPP; + + memset(fname, 0, sizeof(struct fscrypt_name)); + fname->usr_fname = iname; + fname->disk_name.name = (unsigned char *)iname->name; + fname->disk_name.len = iname->len; + return 0; +} + +static inline void fscrypt_notsupp_free_filename(struct fscrypt_name *fname) +{ + return; +} + +static inline u32 fscrypt_notsupp_fname_encrypted_size(struct inode *i, u32 s) +{ + /* never happens */ + WARN_ON(1); + return 0; +} + +static inline int fscrypt_notsupp_fname_alloc_buffer(struct inode *inode, + u32 ilen, struct fscrypt_str *crypto_str) +{ + return -EOPNOTSUPP; +} + +static inline void fscrypt_notsupp_fname_free_buffer(struct fscrypt_str *c) +{ + return; +} + +static inline int fscrypt_notsupp_fname_disk_to_usr(struct inode *inode, + u32 hash, u32 minor_hash, + const struct fscrypt_str *iname, + struct fscrypt_str *oname) +{ + return -EOPNOTSUPP; +} + +static inline int fscrypt_notsupp_fname_usr_to_disk(struct inode *inode, + const struct qstr *iname, + struct fscrypt_str *oname) +{ + return -EOPNOTSUPP; +} +#endif /* _LINUX_FSCRYPTO_H */ diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 824bd16ae408..a5f251d76018 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -36,6 +36,7 @@ struct vm_area_struct; #define ___GFP_OTHER_NODE 0x800000u #define ___GFP_WRITE 0x1000000u #define ___GFP_KSWAPD_RECLAIM 0x2000000u +#define ___GFP_CMA 0x4000000u /* If the above are modified, __GFP_BITS_SHIFT may need updating */ /* @@ -50,8 +51,9 @@ struct vm_area_struct; #define __GFP_DMA32 ((__force gfp_t)___GFP_DMA32) #define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* Page is movable */ #define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) /* ZONE_MOVABLE allowed */ -#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) - +#define __GFP_CMA ((__force gfp_t)___GFP_CMA) +#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE| \ + __GFP_CMA) /* * Page mobility and placement hints * @@ -183,7 +185,7 @@ struct vm_area_struct; #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* Room for N __GFP_FOO bits */ -#define __GFP_BITS_SHIFT 26 +#define __GFP_BITS_SHIFT 27 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* @@ -264,7 +266,12 @@ static inline int gfpflags_to_migratetype(const gfp_t gfp_flags) return MIGRATE_UNMOVABLE; /* Group based on mobility */ +#ifndef CONFIG_CMA return (gfp_flags & GFP_MOVABLE_MASK) >> GFP_MOVABLE_SHIFT; +#else + return ((gfp_flags & GFP_MOVABLE_MASK) >> GFP_MOVABLE_SHIFT) | + ((gfp_flags & __GFP_CMA) != 0); +#endif } #undef GFP_MOVABLE_MASK #undef GFP_MOVABLE_SHIFT diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index ee2d8c6f9130..6eb18a6d4e72 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -1,6 +1,8 @@ #ifndef _GPIO_KEYS_H #define _GPIO_KEYS_H +#define GPIO_KEYS_DEV_NAME "gpio-keys" + struct device; struct gpio_desc; @@ -52,7 +54,8 @@ struct gpio_keys_platform_data { unsigned int rep:1; int (*enable)(struct device *dev); void (*disable)(struct device *dev); - const char *name; + const char *name; /* input device name */ + bool use_syscore; }; #endif diff --git a/include/linux/habmm.h b/include/linux/habmm.h new file mode 100644 index 000000000000..34ba1083a554 --- /dev/null +++ b/include/linux/habmm.h @@ -0,0 +1,371 @@ +/* Copyright (c) 2016-2018, 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 HABMM_H +#define HABMM_H + +#include "linux/habmmid.h" + +#define HAB_API_VER_DEF(_MAJOR_, _MINOR_) \ + ((_MAJOR_&0xFF)<<16 | (_MINOR_&0xFFF)) +#define HAB_API_VER HAB_API_VER_DEF(1, 0) + +#include <linux/types.h> + +/* habmm_socket_open + * + * Description: + * + * Establish a communication channel between Virtual Machines. Blocks + * until the connection is established between sender and receiver. + * Client can call this APImultiple times with the same name to connect + * to the same communication channel, the function returns a different context + * for every open for proper resource allocation and client identification. + * + * Params: + * out handle - An opaque handle associated with a successful virtual channel + * creation in MM_ID - multimedia ID used to allocate the physical channels to + * service all the virtual channels created through this open + * in timeout - timeout value specified by the client to avoid forever block + * in flags - future extension + * + * Return: + * status (success/failure/timeout) + * + */ + +/* single FE-BE connection multi-to-multi point to point matching (default) */ +#define HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE 0x00000000 +/* one BE for one domU */ +#define HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_DOMU 0x00000001 +/* one BE for all the domUs */ +#define HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_MULTI_DOMUS 0x00000002 + +int32_t habmm_socket_open(int32_t *handle, uint32_t mm_ip_id, + uint32_t timeout, uint32_t flags); + +/* habmm_socket_close + * + * Description: + * + * Tear down the virtual channel that was established through habmm_socket_open + * and release all resources associated with it. + * + * Params: + * + * in handle - handle to the virtual channel created by habmm_socket_open + * + * Return: + * status - (success/failure) + * + * + */ + +int32_t habmm_socket_close(int32_t handle); + + +/* habmm_socket_send + * + * Description: + * + * Send data over the virtual channel + * + * Params: + * + * in handle - handle created by habmm_socket_open + * in src_buff - data to be send across the virtual channel + * inout size_bytes - size of the data to be send. Either the whole packet is + * sent or not + * in flags - future extension + * + * Return: + * status (success/fail/disconnected) + * + */ + +/* Non-blocking mode: function will return immediately with HAB_AGAIN + * if the send operation cannot be completed without blocking. + */ +#define HABMM_SOCKET_SEND_FLAGS_NON_BLOCKING 0x00000001 + +/* Collect cross-VM stats: client provides stat-buffer large enough to allow 2 + * sets of a 2-uint64_t pair to collect seconds and nano-seconds at the + * beginning of the stat-buffer. Stats are collected when the stat-buffer leaves + * VM1, then enters VM2 + */ +#define HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT 0x00000002 + +/* start to measure cross-vm schedule latency: VM1 send msg with this flag + * to VM2 to kick off the measurement. In the hab driver level, the VM1 hab + * driver shall record the time of schdule out with mpm_timer, and buffer + * it for later usage. The VM2 hab driver shall record the time of schedule + * in with mpm_timer and pass it to "habtest" application. + */ +#define HABMM_SOCKET_XVM_SCHE_TEST 0x00000004 + +/* VM2 responds this message to VM1 for HABMM_SOCKET_XVM_SCHE_TEST. + * In the hab driver level, the VM2 hab driver shall record the time of schedule + * out with mpm_timer, and buffer it for later usage; the VM1 hab driver + * shall record the time of schedule in with mpm_timer and pass it to "habtest" + * application. + */ +#define HABMM_SOCKET_XVM_SCHE_TEST_ACK 0x00000008 + +/* VM1 sends this message to VM2 asking for collect all the mpm_timer values + * to calculate the latency of schduling between VM1 and VM2. In the hab driver + * level, the VM1 hab driver shall save the previous restored schduling out + * time to the message buffer + */ +#define HABMM_SOCKET_XVM_SCHE_RESULT_REQ 0x00000010 + +/* VM2 responds this message to VM2 for HABMM_SOCKET_XVM_SCHE_RESULT_REQ. + * In the habtest application level, VM2 shall save the previous restored + * scheduling in time into message buffer, in the hab driver level, VM2 + * shall save the previous restored scheduling out time to the message + * buffer. + */ +#define HABMM_SOCKET_XVM_SCHE_RESULT_RSP 0x00000020 + +struct habmm_xing_vm_stat { + uint64_t tx_sec; + uint64_t tx_usec; + uint64_t rx_sec; + uint64_t rx_usec; +}; + +int32_t habmm_socket_send(int32_t handle, void *src_buff, uint32_t size_bytes, + uint32_t flags); + + +/* habmm_socket_recv + * + * Description: + * + * Receive data over the virtual channel created by habmm_socket_open. + * Blocking until actual data is received or timeout value expires + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * inout dst_buff - buffer pointer to store received data + * inout size_bytes - size of the dst_buff. returned value shows the actual + * bytes received. + * in timeout - timeout value specified by the client to avoid forever block + * in flags - future extension + * + * + * Return: + * status (success/failure/timeout/disconnected) + * + */ + +/* Non-blocking mode: function will return immediately if there is no data + * available. Supported only for kernel clients. + */ +#define HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING 0x00000001 + +/* In the blocking mode, this flag is used to indicate it is an + * uninterruptbile blocking call. + */ +#define HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE 0x00000002 + +int32_t habmm_socket_recv(int32_t handle, void *dst_buff, uint32_t *size_bytes, + uint32_t timeout, uint32_t flags); + +/* habmm_socket_sendto + * + * Description: + * + * This is for backend only. Send data over the virtual channel to remote + * frontend virtual channel for multi-FEs-to-single-BE model when + * the BE virtual channel is created using + * HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_DOMU or + * HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_MULTI_DOMUS + * + * Params: + * + * in handle - handle created by habmm_socket_open + * in src_buff - data to be send across the virtual channel + * inout size_bytes - size of the data to be send. The packet is fully sent on + * success,or not sent at all upon any failure + * in remote_handle - the destination of this send using remote FE's virtual + * channel handle + * in flags - future extension + * + * Return: + * status (success/fail/disconnected) + */ +int32_t habmm_socket_sendto(int32_t handle, void *src_buff, uint32_t size_bytes, + int32_t remote_handle, uint32_t flags); + + +/* habmm_socket_recvfrom + * + * Description: + * + * Receive data over the virtual channel created by habmm_socket_open. + * Returned is the remote FE's virtual channel handle to be used for sendto. + * Blocking until actual data is received or timeout value expires. This is for + * BE running in multi-FEs-to-single-BE model when the BE virtual channel is + * created using HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_DOMU or + * HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_MULTI_DOMUS. + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * inout dst_buff - buffer pointer to store received data + * inout size_bytes - size of the dst_buff. returned value shows the actual + * bytes received. + * in timeout - timeout value specified by the client to avoid forever block + * in remote_handle - the FE who sent this message through the + * connected virtual channel to BE. + * in flags - future extension + * + * Return: + * status (success/failure/timeout/disconnected) + * + */ +int32_t habmm_socket_recvfrom(int32_t handle, void *dst_buff, + uint32_t *size_bytes, uint32_t timeout, + int32_t *remote_handle, uint32_t flags); + +/* exporting memory type DMA : This is platform dependent for user mode. If it + * does exist, HAB needs to use DMA method to retrieve the memory for exporting. + * If it does not exist, this flag is ignored. + */ +#define HABMM_EXP_MEM_TYPE_DMA 0x00000001 + +/* + * this flag is used for export from dma_buf fd or import to dma_buf fd + */ +#define HABMM_EXPIMP_FLAGS_FD 0x00010000 + +#define HAB_MAX_EXPORT_SIZE 0x8000000 + +/* + * Description: + * + * Prepare the sharing of the buffer on the exporter side. The returned + * reference ID needs to be sent to importer separately. + * During sending the HAB will attach the actual exporting buffer information. + * The exporting is per process space. + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * in buff_to_share - buffer to be exported + * in size_bytes - size of the exporting buffer in bytes + * out export_id - to be returned by this call upon success + * in flags - future extension + * + * Return: + * status (success/failure) + * + */ +int32_t habmm_export(int32_t handle, void *buff_to_share, uint32_t size_bytes, + uint32_t *export_id, uint32_t flags); + +/* + * Description: + * + * Free any allocated resource associated with this export IDin on local side. + * Params: + * + * in handle - communication channel created by habmm_socket_open + * in export_id - all resource allocated with export_id are to be freed + * in flags - future extension + * + * Return: + * status (success/failure) + * + */ +int32_t habmm_unexport(int32_t handle, uint32_t export_id, uint32_t flags); + +/* + * Description: + * + * Import the exporter's shared reference ID. + * The importing is per process space. + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * out buff_shared - buffer to be imported. returned upon success + * in size_bytes - size of the imported buffer in bytes. It should match the + * original exported buffer size + * in export_id - received when exporter sent its exporting ID through + * habmm_socket_send() previously + * in flags - future extension + * + * Return: + * status (success/failure) + * + */ + +/* Non-blocking mode: function will return immediately if there is no data + * available. Supported only for kernel clients. + */ +#define HABMM_IMPORT_FLAGS_CACHED 0x00000001 + +int32_t habmm_import(int32_t handle, void **buff_shared, uint32_t size_bytes, + uint32_t export_id, uint32_t flags); + +/* + * Description: + * + * Release any resource associated with the export ID on the importer side. + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * in export_id - received when exporter sent its exporting ID through + * habmm_socket_send() previously + * in buff_shared - received from habmm_import() together with export_id + * in flags - future extension + * + * Return: + * status (success/failure) + * + */ +int32_t habmm_unimport(int32_t handle, uint32_t export_id, void *buff_shared, + uint32_t flags); + +/* + * Description: + * + * Query various information of the opened hab socket. + * + * Params: + * + * in handle - communication channel created by habmm_socket_open + * in habmm_socket_info - retrieve socket information regarding local and remote + * VMs + * in flags - future extension + * + * Return: + * status (success/failure) + * + */ + +struct hab_socket_info { + int32_t vmid_remote; /* habmm's vmid */ + int32_t vmid_local; + /* name from hypervisor framework if available */ + char vmname_remote[12]; + char vmname_local[12]; +}; + +int32_t habmm_socket_query(int32_t handle, struct hab_socket_info *info, + uint32_t flags); + +#endif /* HABMM_H */ diff --git a/include/linux/hash.h b/include/linux/hash.h index 79c52fa81cac..a75b1009d3f7 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h @@ -15,6 +15,7 @@ */ #include <asm/types.h> +#include <asm/hash.h> #include <linux/compiler.h> /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ @@ -99,4 +100,38 @@ static inline u32 hash32_ptr(const void *ptr) return (u32)val; } +struct fast_hash_ops { + u32 (*hash)(const void *data, u32 len, u32 seed); + u32 (*hash2)(const u32 *data, u32 len, u32 seed); +}; + +/** + * arch_fast_hash - Caclulates a hash over a given buffer that can have + * arbitrary size. This function will eventually use an + * architecture-optimized hashing implementation if + * available, and trades off distribution for speed. + * + * @data: buffer to hash + * @len: length of buffer in bytes + * @seed: start seed + * + * Returns 32bit hash. + */ +extern u32 arch_fast_hash(const void *data, u32 len, u32 seed); + +/** + * arch_fast_hash2 - Caclulates a hash over a given buffer that has a + * size that is of a multiple of 32bit words. This + * function will eventually use an architecture- + * optimized hashing implementation if available, + * and trades off distribution for speed. + * + * @data: buffer to hash (must be 32bit padded) + * @len: number of 32bit words + * @seed: start seed + * + * Returns 32bit hash. + */ +extern u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed); + #endif /* _LINUX_HASH_H */ diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h new file mode 100644 index 000000000000..1ff11e4e33db --- /dev/null +++ b/include/linux/hdcp_qseecom.h @@ -0,0 +1,166 @@ +/* Copyright (c) 2015-2018, 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 __HDCP_QSEECOM_H +#define __HDCP_QSEECOM_H +#include <linux/types.h> + +#define HDCP_MAX_MESSAGE_PARTS 4 +#define RECV_ID_SIZE 5 +#define MAX_DEVICES_SUPPORTED 127 + +enum hdcp_lib_wakeup_cmd { + HDCP_LIB_WKUP_CMD_INVALID, + HDCP_LIB_WKUP_CMD_START, + HDCP_LIB_WKUP_CMD_STOP, + HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS, + HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED, + HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS, + HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED, + HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT, + HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE, + HDCP_LIB_WKUP_CMD_LINK_FAILED, +}; + +enum hdmi_hdcp_wakeup_cmd { + HDMI_HDCP_WKUP_CMD_INVALID, + HDMI_HDCP_WKUP_CMD_SEND_MESSAGE, + HDMI_HDCP_WKUP_CMD_RECV_MESSAGE, + HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS, + HDMI_HDCP_WKUP_CMD_STATUS_FAILED, + HDMI_HDCP_WKUP_CMD_LINK_POLL, + HDMI_HDCP_WKUP_CMD_AUTHENTICATE +}; + +struct hdcp_lib_wakeup_data { + enum hdcp_lib_wakeup_cmd cmd; + void *context; + char *recvd_msg_buf; + uint32_t recvd_msg_len; + uint32_t timeout; +}; + +struct hdcp_msg_part { + char *name; + uint32_t offset; + uint32_t length; +}; + +struct hdcp_msg_data { + uint32_t num_messages; + struct hdcp_msg_part messages[HDCP_MAX_MESSAGE_PARTS]; + uint8_t rx_status; +}; + +struct hdmi_hdcp_wakeup_data { + enum hdmi_hdcp_wakeup_cmd cmd; + void *context; + char *send_msg_buf; + uint32_t send_msg_len; + uint32_t timeout; + uint8_t abort_mask; + const struct hdcp_msg_data *message_data; +}; + +static inline char *hdmi_hdcp_cmd_to_str(uint32_t cmd) +{ + switch (cmd) { + case HDMI_HDCP_WKUP_CMD_SEND_MESSAGE: + return "HDMI_HDCP_WKUP_CMD_SEND_MESSAGE"; + case HDMI_HDCP_WKUP_CMD_RECV_MESSAGE: + return "HDMI_HDCP_WKUP_CMD_RECV_MESSAGE"; + case HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS: + return "HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS"; + case HDMI_HDCP_WKUP_CMD_STATUS_FAILED: + return "HDMI_HDCP_WKUP_CMD_STATUS_FAIL"; + case HDMI_HDCP_WKUP_CMD_LINK_POLL: + return "HDMI_HDCP_WKUP_CMD_LINK_POLL"; + case HDMI_HDCP_WKUP_CMD_AUTHENTICATE: + return "HDMI_HDCP_WKUP_CMD_AUTHENTICATE"; + default: + return "???"; + } +} + +static inline char *hdcp_lib_cmd_to_str(uint32_t cmd) +{ + switch (cmd) { + case HDCP_LIB_WKUP_CMD_START: + return "HDCP_LIB_WKUP_CMD_START"; + case HDCP_LIB_WKUP_CMD_STOP: + return "HDCP_LIB_WKUP_CMD_STOP"; + case HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS: + return "HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS"; + case HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED: + return "HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED"; + case HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS: + return "HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS"; + case HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED: + return "HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED"; + case HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT: + return "HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT"; + case HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE: + return "HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE"; + case HDCP_LIB_WKUP_CMD_LINK_FAILED: + return "HDCP_LIB_WKUP_CMD_LINK_FAILED"; + default: + return "???"; + } +} + +struct hdcp_srm_device_id_t { + uint8_t data[RECV_ID_SIZE]; +}; + +struct hdcp_txmtr_ops { + int (*wakeup)(struct hdcp_lib_wakeup_data *data); + bool (*feature_supported)(void *phdcpcontext); + void (*update_exec_type)(void *ctx, bool tethered); + int (*hdcp_txmtr_get_state)(void *phdcpcontext, + uint32_t *state); +}; + +struct hdcp_client_ops { + int (*wakeup)(struct hdmi_hdcp_wakeup_data *data); + void (*notify_lvl_change)(void *client_ctx, int min_lvl); + void (*srm_cb)(void *client_ctx); + void (*mute_sink)(void *client_ctx); +}; + +enum hdcp_device_type { + HDCP_TXMTR_HDMI = 0x8001, + HDCP_TXMTR_DP = 0x8002 +}; + +struct hdcp_register_data { + struct hdcp_client_ops *client_ops; + struct hdcp_txmtr_ops *txmtr_ops; + enum hdcp_device_type device_type; + void *client_ctx; + void **hdcp_ctx; + bool tethered; +}; + +int hdcp_library_register(struct hdcp_register_data *data); +void hdcp_library_deregister(void *phdcpcontext); +bool hdcp1_check_if_supported_load_app(void); +int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb); +int hdcp1_set_enc(bool enable); +int hdcp1_validate_receiver_ids(struct hdcp_srm_device_id_t *device_ids, +uint32_t device_id_cnt); +void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp); +void hdcp1_notify_topology(void); +void hdcp1_client_register(void *client_ctx, +struct hdcp_client_ops *ops); +void hdcp1_client_unregister(void); + +#endif /* __HDCP_QSEECOM_H */ diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index e9744202fa29..bc38b99a9fc9 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -35,6 +35,7 @@ enum hdmi_infoframe_type { }; #define HDMI_IEEE_OUI 0x000c03 +#define HDMI_IEEE_OUI_HF 0xc45dd8 #define HDMI_INFOFRAME_HEADER_SIZE 4 #define HDMI_AVI_INFOFRAME_SIZE 13 #define HDMI_SPD_INFOFRAME_SIZE 25 @@ -78,6 +79,8 @@ enum hdmi_picture_aspect { HDMI_PICTURE_ASPECT_NONE, HDMI_PICTURE_ASPECT_4_3, HDMI_PICTURE_ASPECT_16_9, + HDMI_PICTURE_ASPECT_64_27, + HDMI_PICTURE_ASPECT_256_135, HDMI_PICTURE_ASPECT_RESERVED, }; diff --git a/include/linux/hid.h b/include/linux/hid.h index ee5378eacda6..645172ce4cc5 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -346,6 +346,12 @@ struct hid_item { #define HID_GROUP_STEAM 0x0103 /* + * HID protocol status + */ +#define HID_REPORT_PROTOCOL 1 +#define HID_BOOT_PROTOCOL 0 + +/* * This is the global environment of the parser. This information is * persistent for main-items. The global environment can be saved and * restored with PUSH/POP statements. diff --git a/include/linux/highmem.h b/include/linux/highmem.h index bb3f3297062a..61aff324bd5e 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -39,6 +39,12 @@ extern unsigned long totalhigh_pages; void kmap_flush_unused(void); +#ifdef CONFIG_ARCH_WANT_KMAP_ATOMIC_FLUSH +void kmap_atomic_flush_unused(void); +#else +static inline void kmap_atomic_flush_unused(void) { } +#endif + struct page *kmap_to_page(void *addr); #else /* CONFIG_HIGHMEM */ @@ -80,6 +86,7 @@ static inline void __kunmap_atomic(void *addr) #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn)) #define kmap_flush_unused() do {} while(0) +#define kmap_atomic_flush_unused() do {} while (0) #endif #endif /* CONFIG_HIGHMEM */ @@ -180,9 +187,24 @@ static inline struct page * alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, unsigned long vaddr) { +#ifndef CONFIG_CMA return __alloc_zeroed_user_highpage(__GFP_MOVABLE, vma, vaddr); +#else + return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma, + vaddr); +#endif } +#ifdef CONFIG_CMA +static inline struct page * +alloc_zeroed_user_highpage_movable_cma(struct vm_area_struct *vma, + unsigned long vaddr) +{ + return __alloc_zeroed_user_highpage(__GFP_MOVABLE|__GFP_CMA, vma, + vaddr); +} +#endif + static inline void clear_highpage(struct page *page) { void *kaddr = kmap_atomic(page); diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index a875dcf0044a..a72ce396bb7d 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -53,6 +53,7 @@ enum hrtimer_restart { * * 0x00 inactive * 0x01 enqueued into rbtree + * 0x02 timer is pinned to a cpu * * The callback state is not part of the timer->state because clearing it would * mean touching the timer after the callback, this makes it impossible to free @@ -72,6 +73,8 @@ enum hrtimer_restart { */ #define HRTIMER_STATE_INACTIVE 0x00 #define HRTIMER_STATE_ENQUEUED 0x01 +#define HRTIMER_PINNED_SHIFT 1 +#define HRTIMER_STATE_PINNED (1 << HRTIMER_PINNED_SHIFT) /** * struct hrtimer - the basic hrtimer structure @@ -88,12 +91,6 @@ enum hrtimer_restart { * @base: pointer to the timer base (per cpu and per clock) * @state: state information (See bit values above) * @is_rel: Set if the timer was armed relative - * @start_pid: timer statistics field to store the pid of the task which - * started the timer - * @start_site: timer statistics field to store the site where the timer - * was started - * @start_comm: timer statistics field to store the name of the process which - * started the timer * * The hrtimer structure must be initialized by hrtimer_init() */ @@ -104,11 +101,6 @@ struct hrtimer { struct hrtimer_clock_base *base; u8 state; u8 is_rel; -#ifdef CONFIG_TIMER_STATS - int start_pid; - void *start_site; - char start_comm[16]; -#endif }; /** @@ -357,6 +349,9 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device); /* Exported timer functions: */ +/* To be used from cpusets, only */ +extern void hrtimer_quiesce_cpu(void *cpup); + /* Initialize timers: */ extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode); @@ -424,18 +419,12 @@ extern u64 hrtimer_get_next_event(void); extern bool hrtimer_active(const struct hrtimer *timer); -/** - * hrtimer_is_queued = check, whether the timer is on one of the queues - * @timer: Timer to check - * - * Returns: True if the timer is queued, false otherwise - * - * The function can be used lockless, but it gives only a current snapshot. +/* + * Helper function to check, whether the timer is on one of the queues */ -static inline bool hrtimer_is_queued(struct hrtimer *timer) +static inline int hrtimer_is_queued(struct hrtimer *timer) { - /* The READ_ONCE pairs with the update functions of timer->state */ - return !!(READ_ONCE(timer->state) & HRTIMER_STATE_ENQUEUED); + return timer->state & HRTIMER_STATE_ENQUEUED; } /* diff --git a/include/linux/i2c/i2c-msm-v2.h b/include/linux/i2c/i2c-msm-v2.h new file mode 100644 index 000000000000..cf695beaa4a3 --- /dev/null +++ b/include/linux/i2c/i2c-msm-v2.h @@ -0,0 +1,666 @@ +/* Copyright (c) 2014-2015,2017-2018, 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. + * + */ +/* + * I2C controller driver for Qualcomm Technologies Inc platforms + */ + +#ifndef _I2C_MSM_V2_H +#define _I2C_MSM_V2_H + +#include <linux/bitops.h> +#include <linux/dmaengine.h> + +enum msm_i2_debug_level { + MSM_ERR, /* Error messages only. Always on */ + MSM_PROF, /* High level events. Use for profiling */ + MSM_DBG, /* Low level details. Use for debugging */ +}; + +#define i2c_msm_dbg(ctrl, dbg_level, fmt, ...) do {\ + if (ctrl->dbgfs.dbg_lvl >= dbg_level)\ + dev_info(ctrl->dev, pr_fmt(fmt), ##__VA_ARGS__);\ + } while (0) + +#define BIT_IS_SET(val, idx) ((val >> idx) & 0x1) +#define BITS_AT(val, idx, n_bits)(((val) & (((1 << n_bits) - 1) << idx)) >> idx) +#define MASK_IS_SET(val, mask) ((val & mask) == mask) +#define MASK_IS_SET_BOOL(val, mask) (MASK_IS_SET(val, mask) ? 1 : 0) +#define KHz(freq) (1000 * freq) +#define I2C_MSM_CLK_FAST_PLUS_FREQ (1000000) +#define I2C_MSM_MAX_RETRIES 5 + +/* QUP Registers */ +enum { + QUP_CONFIG = 0x0, + QUP_STATE = 0x4, + QUP_IO_MODES = 0x8, + QUP_SW_RESET = 0xC, + QUP_OPERATIONAL = 0x18, + QUP_ERROR_FLAGS = 0x1C, + QUP_ERROR_FLAGS_EN = 0x20, + QUP_TEST_CTRL = 0x24, + QUP_OPERATIONAL_MASK = 0x28, + QUP_HW_VERSION = 0x30, + QUP_MX_READ_COUNT = 0x208, + QUP_MX_WRITE_COUNT = 0x150, + QUP_MX_OUTPUT_COUNT = 0x100, + QUP_MX_INPUT_COUNT = 0x200, + QUP_MX_WR_CNT = 0x100, + QUP_OUT_DEBUG = 0x108, + QUP_OUT_FIFO_CNT = 0x10C, + QUP_OUT_FIFO_BASE = 0x110, + QUP_IN_READ_CUR = 0x20C, + QUP_IN_DEBUG = 0x210, + QUP_IN_FIFO_CNT = 0x214, + QUP_IN_FIFO_BASE = 0x218, + QUP_I2C_MASTER_CLK_CTL = 0x400, + QUP_I2C_STATUS = 0x404, + QUP_I2C_MASTER_CONFIG = 0x408, + QUP_I2C_MASTER_BUS_CLR = 0x40C, +}; + +/* Register:QUP_STATE state field values */ +enum i2c_msm_qup_state { + QUP_STATE_RESET = 0, + QUP_STATE_RUN = 1U, + QUP_STATE_PAUSE = 3U, +}; + +/* Register:QUP_STATE fields */ +enum { + QUP_STATE_MASK = 3U, + QUP_STATE_VALID = BIT(2), + QUP_I2C_MAST_GEN = BIT(4), + QUP_I2C_FLUSH = BIT(6), + QUP_I2C_STATUS_RESET = 0x42, +}; + + +/* Register:QUP_CONFIG fields */ +enum { + QUP_MINI_CORE_MASK = 0xF00, + QUP_MINI_CORE_I2C_VAL = 0x200, + QUP_N_MASK = 0x1F, + QUP_N_VAL = 0x7, /* 0xF for A family */ + QUP_NO_OUPUT = BIT(6), + QUP_NO_INPUT = BIT(7), + QUP_APP_CLK_ON_EN = BIT(12), + QUP_CORE_CLK_ON_EN = BIT(13), + QUP_FIFO_CLK_GATE_EN = BIT(14), +}; + +/* Register:QUP_OPERATIONAL fields */ +enum { + QUP_INPUT_FIFO_NOT_EMPTY = BIT(5), + QUP_OUTPUT_SERVICE_FLAG = BIT(8), + QUP_INPUT_SERVICE_FLAG = BIT(9), + QUP_MAX_OUTPUT_DONE_FLAG = BIT(10), + QUP_MAX_INPUT_DONE_FLAG = BIT(11), + QUP_OUT_BLOCK_WRITE_REQ = BIT(12), + QUP_IN_BLOCK_READ_REQ = BIT(13), +}; + +/* Register:QUP_OPERATIONAL_MASK fields */ +enum { + QUP_INPUT_SERVICE_MASK = BIT(9), + QUP_OUTPUT_SERVICE_MASK = BIT(8), +}; + +/* Register:QUP_IO_MODES fields */ +enum { + QUP_OUTPUT_MODE = BIT(10) | BIT(11), + QUP_INPUT_MODE = BIT(12) | BIT(13), + QUP_UNPACK_EN = BIT(14), + QUP_PACK_EN = BIT(15), + QUP_OUTPUT_BIT_SHIFT_EN = BIT(16), +}; + +/* Register:QUP_I2C_STATUS (a.k.a I2C_MASTER_STATUS) fields */ +enum { + QUP_BUS_ERROR = BIT(2), + QUP_PACKET_NACKED = BIT(3), + QUP_ARB_LOST = BIT(4), + QUP_INVALID_WRITE = BIT(5), + QUP_FAILED = BIT(6), + QUP_BUS_ACTIVE = BIT(8), + QUP_BUS_MASTER = BIT(9), + QUP_INVALID_TAG = BIT(23), + QUP_INVALID_READ_ADDR = BIT(24), + QUP_INVALID_READ_SEQ = BIT(25), + QUP_I2C_SDA = BIT(26), + QUP_I2C_SCL = BIT(27), + QUP_MSTR_STTS_ERR_MASK = 0x380003C, +}; + +/* Register:QUP_I2C_MASTER_CONFIG fields */ +enum { + QUP_EN_VERSION_TWO_TAG = 1U, +}; + +/* Register:QUP_I2C_MASTER_CLK_CTL field setters */ +#define I2C_MSM_SCL_NOISE_REJECTION(reg_val, noise_rej_val) \ + (((reg_val) & ~(0x3 << 24)) | (((noise_rej_val) & 0x3) << 24)) +#define I2C_MSM_SDA_NOISE_REJECTION(reg_val, noise_rej_val) \ + (((reg_val) & ~(0x3 << 26)) | (((noise_rej_val) & 0x3) << 26)) + +/* Register:QUP_ERROR_FLAGS_EN flags */ +enum { + QUP_OUTPUT_OVER_RUN_ERR_EN = BIT(5), + QUP_INPUT_UNDER_RUN_ERR_EN = BIT(4), + QUP_OUTPUT_UNDER_RUN_ERR_EN = BIT(3), + QUP_INPUT_OVER_RUN_ERR_EN = BIT(2), +}; + +/* Status, Error flags */ +enum { + I2C_STATUS_WR_BUFFER_FULL = BIT(0), + I2C_STATUS_BUS_ACTIVE = BIT(8), + I2C_STATUS_BUS_MASTER = BIT(9), + I2C_STATUS_ERROR_MASK = 0x38000FC, + QUP_I2C_NACK_FLAG = BIT(3), + QUP_IN_NOT_EMPTY = BIT(5), + QUP_ERR_FLGS_MASK = 0x3C, +}; + +/* Master status clock states */ +enum { + I2C_CLK_RESET_BUSIDLE_STATE = 0, + I2C_CLK_FORCED_LOW_STATE = 5, +}; + +/* Controller's power state */ +enum i2c_msm_power_state { + I2C_MSM_PM_RT_ACTIVE, + I2C_MSM_PM_RT_SUSPENDED, + I2C_MSM_PM_SYS_SUSPENDED +}; + +/* + * The max buffer size required for tags is for holding the following sequence: + * [start] + [start | slv-addr] + [ rd/wr | len] + * which sum up to 6 bytes. However, we use u64 to hold the value, thus we say + * that max length is 8 bytes. + */ +#define I2C_MSM_TAG2_MAX_LEN (4) +#define I2C_MSM_DMA_TX_SZ (64) /* tx chan n entries */ +#define I2C_MSM_DMA_RX_SZ (32) /* rx chan n entries */ +#define I2C_MSM_DMA_DESC_ARR_SIZ (I2C_MSM_DMA_TX_SZ + I2C_MSM_DMA_RX_SZ) +#define I2C_MSM_REG_2_STR_BUF_SZ (128) +/* Optimal value to hold the error strings */ +#define I2C_MSM_MAX_ERR_BUF_SZ (256) +#define I2C_MSM_BUF_DUMP_MAX_BC (20) +#define I2C_MSM_MAX_POLL_MSEC (100) +#define I2C_MSM_TIMEOUT_SAFTY_COEF (10) +#define I2C_MSM_TIMEOUT_MIN_USEC (500000) + +/* QUP v2 tags */ +#define QUP_TAG2_DATA_WRITE (0x82ULL) +#define QUP_TAG2_DATA_WRITE_N_STOP (0x83ULL) +#define QUP_TAG2_DATA_READ (0x85ULL) +#define QUP_TAG2_DATA_READ_N_STOP (0x87ULL) +#define QUP_TAG2_START (0x81ULL) +#define QUP_TAG2_DATA_READ_N_NACK (0x86ULL) +#define QUP_TAG2_START_STOP (0x8AULL) +#define QUP_TAG2_INPUT_EOT (0x93ULL) +#define QUP_TAG2_FLUSH_STOP (0x96ULL) +#define QUP_BUF_OVERHD_BC (2) +#define QUP_MAX_BUF_SZ (256) + +enum i2c_msm_clk_path_vec_idx { + I2C_MSM_CLK_PATH_SUSPEND_VEC, + I2C_MSM_CLK_PATH_RESUME_VEC, +}; +#define I2C_MSM_CLK_PATH_AVRG_BW(ctrl) (0) +#define I2C_MSM_CLK_PATH_BRST_BW(ctrl) (ctrl->rsrcs.clk_freq_in * 8) + +enum i2c_msm_gpio_name_idx { + I2C_MSM_GPIO_SCL, + I2C_MSM_GPIO_SDA, +}; + +extern const char * const i2c_msm_mode_str_tbl[]; + +struct i2c_msm_ctrl; + +/* + * i2c_msm_dma_mem: utility struct which holds both physical and virtual addr + */ +struct i2c_msm_dma_mem { + dma_addr_t phy_addr; + void *vrtl_addr; +}; + +/* + * i2c_msm_tag: tag's data and its length. + * + * @len tag len can be two, four or six bytes. + */ +struct i2c_msm_tag { + u64 val; + int len; +}; + +/* + * i2c_msm_dma_tag: similar to struct i2c_msm_tag but holds physical address. + * + * @buf physical address of entry in the tag_arr of + * struct i2c_msm_xfer_mode_dma + * @len tag len. + * + * Hold the information from i2c_msm_dma_xfer_prepare() which is used by + * i2c_msm_dma_xfer_process() and freed by i2c_msm_dma_xfer_unprepare() + */ +struct i2c_msm_dma_tag { + dma_addr_t buf; + size_t len; +}; + +/* + * i2c_msm_dma_buf: dma mapped pointer to i2c_msg data buffer and related tag + * @vir_addr ptr to i2c_msg buf beginning or with offset (when buf len > 256) + */ +struct i2c_msm_dma_buf { + struct i2c_msm_dma_mem ptr; + enum dma_data_direction dma_dir; + size_t len; + bool is_rx; + bool is_last; + struct i2c_msm_dma_tag tag; + /* DMA API */ + struct scatterlist sg_list[2]; +}; + +/* + * i2c_msm_dma_chan: per channel info + * + * @is_init true when the channel is initialized and requires eventual teardown. + * @name channel name (tx/rx) for debugging. + * @desc_cnt_cur number of occupied descriptors + */ +struct i2c_msm_dma_chan { + bool is_init; + const char *name; + size_t desc_cnt_cur; + struct dma_chan *dma_chan; + enum dma_transfer_direction dir; +}; + +enum i2c_msm_dma_chan_dir { + I2C_MSM_DMA_TX, + I2C_MSM_DMA_RX, + I2C_MSM_DMA_CNT, +}; + +enum i2c_msm_dma_state { + I2C_MSM_DMA_INIT_NONE, /* Uninitialized DMA */ + I2C_MSM_DMA_INIT_CORE, /* Core init not channels, memory Allocated */ + I2C_MSM_DMA_INIT_CHAN, /* Both Core and channels are init */ +}; + +/* + * struct i2c_msm_xfer_mode_dma: DMA mode configuration and work space + * + * @state specifies the DMA core and channel initialization states. + * @buf_arr_cnt current number of valid buffers in buf_arr. The valid buffers + * are at index 0..buf_arr_cnt excluding buf_arr_cnt. + * @buf_arr array of descriptors which point to the user's buffer + * virtual and physical address, and hold meta data about the buffer + * and respective tag. + * @tag_arr array of tags in DMAable memory. Holds a tag per buffer of the same + * index, that is tag_arr[i] is related to buf_arr[i]. Also, tag_arr[i] + * is queued in the tx channel just befor buf_arr[i] is queued in + * the tx (output buf) or rx channel (input buffer). + * @eot_n_flush_stop_tags EOT and flush-stop tags to be queued to the tx + * DMA channel after the last transfer when it is a read. + * @input_tag hw is placing input tags in the rx channel on read operations. + * The value of these tags is "don't care" from DMA transfer + * perspective. Thus, this single buffer is used for all the input + * tags. The field is used as write only. + */ +struct i2c_msm_xfer_mode_dma { + enum i2c_msm_dma_state state; + size_t buf_arr_cnt; + struct i2c_msm_dma_buf buf_arr[I2C_MSM_DMA_DESC_ARR_SIZ]; + struct i2c_msm_dma_mem tag_arr; + struct i2c_msm_dma_mem eot_n_flush_stop_tags; + struct i2c_msm_dma_mem input_tag; + struct i2c_msm_dma_chan chan[I2C_MSM_DMA_CNT]; +}; + +/* + * I2C_MSM_DMA_TAG_MEM_SZ includes the following fields of + * struct i2c_msm_xfer_mode_dma (in order): + * + * Buffer of DMA memory: + * +-----------+---------+-----------+-----------+----+-----------+ + * | input_tag | eot_... | tag_arr 0 | tag_arr 1 | .. | tag_arr n | + * +-----------+---------+-----------+-----------+----+-----------+ + * + * Why +2? + * One tag buffer for the input tags. This is a write only buffer for DMA, it is + * used to read the tags of the input fifo. We let them overwrite each other, + * since it is a throw-away from the driver's perspective. + * Second tag buffer for the EOT and flush-stop tags. This is a read only + * buffer (from DMA perspective). It is used to put EOT and flush-stop at the + * end of every transaction. + */ +#define I2C_MSM_DMA_TAG_MEM_SZ \ + ((I2C_MSM_DMA_DESC_ARR_SIZ + 2) * I2C_MSM_TAG2_MAX_LEN) + +/* + * i2c_msm_xfer_mode_fifo: operations and state of FIFO mode + * + * @ops "base class" of i2c_msm_xfer_mode_dma. Contains the operations while + * the rest of the fields contain the data. + * @input_fifo_sz input fifo size in bytes + * @output_fifo_sz output fifo size in bytes + * @in_rem remaining u32 entries in input FIFO before empty + * @out_rem remaining u32 entries in output FIFO before full + * @out_buf buffer for collecting bytes to four bytes groups (u32) before + * writing them to the output fifo. + * @out_buf_idx next free index in out_buf. 0..3 + */ +struct i2c_msm_xfer_mode_fifo { + size_t input_fifo_sz; + size_t output_fifo_sz; + size_t in_rem; + size_t out_rem; + u8 out_buf[4]; + int out_buf_idx; +}; + +/* i2c_msm_xfer_mode_blk: operations and state of Block mode + * + * @is_init when true, struct is initialized and requires mem free on exit + * @in_blk_sz size of input/rx block + * @out_blk_sz size of output/tx block + * @tx_cache internal buffer to store tx data + * @rx_cache internal buffer to store rx data + * @rx_cache_idx points to the next unread index in rx cache + * @tx_cache_idx points to the next unwritten index in tx cache + * @wait_rx_blk completion object to wait on for end of blk rx transfer. + * @wait_tx_blk completion object to wait on for end of blk tx transfer. + * @complete_mask applied to QUP_OPERATIONAL to determine when blk + * xfer is complete. + */ +struct i2c_msm_xfer_mode_blk { + bool is_init; + size_t in_blk_sz; + size_t out_blk_sz; + u8 *tx_cache; + u8 *rx_cache; + int rx_cache_idx; + int tx_cache_idx; + struct completion wait_rx_blk; + struct completion wait_tx_blk; + u32 complete_mask; +}; + +/* INPUT_MODE and OUTPUT_MODE filds of QUP_IO_MODES register */ +enum i2c_msm_xfer_mode_id { + I2C_MSM_XFER_MODE_FIFO, + I2C_MSM_XFER_MODE_BLOCK, + I2C_MSM_XFER_MODE_DMA, + I2C_MSM_XFER_MODE_NONE, /* keep last as a counter */ +}; + + +struct i2c_msm_dbgfs { + struct dentry *root; + enum msm_i2_debug_level dbg_lvl; + enum i2c_msm_xfer_mode_id force_xfer_mode; +}; + +/* + * qup_i2c_clk_path_vote: data to use bus scaling driver for clock path vote + * + * @mstr_id master id number of the i2c core or its wrapper (BLSP/GSBI). + * When zero, clock path voting is disabled. + * @client_hdl when zero, client is not registered with the bus scaling driver, + * and bus scaling functionality should not be used. When non zero, it + * is a bus scaling client id and may be used to vote for clock path. + * @reg_err when true, registration error was detected and an error message was + * logged. i2c will attempt to re-register but will log error only once. + * once registration succeed, the flag is set to false. + * @actv_only when set, votes when system active and removes the vote when + * system goes idle (optimises for performance). When unset, voting using + * runtime pm (optimizes for power). + */ +struct qup_i2c_clk_path_vote { + u32 mstr_id; + u32 client_hdl; + struct msm_bus_scale_pdata *pdata; + bool reg_err; + bool actv_only; +}; + +/* + * i2c_msm_resources: OS resources + * + * @mem I2C controller memory resource from platform data. + * @base I2C controller virtual base address + * @clk_freq_in core clock frequency in Hz + * @clk_freq_out bus clock frequency in Hz + */ +struct i2c_msm_resources { + struct resource *mem; + void __iomem *base; /* virtual */ + struct clk *core_clk; + struct clk *iface_clk; + int clk_freq_in; + int clk_freq_out; + struct qup_i2c_clk_path_vote clk_path_vote; + int irq; + bool disable_dma; + struct pinctrl *pinctrl; + struct pinctrl_state *gpio_state_active; + struct pinctrl_state *gpio_state_suspend; +}; + +#define I2C_MSM_PINCTRL_ACTIVE "i2c_active" +#define I2C_MSM_PINCTRL_SUSPEND "i2c_sleep" + +/* + * i2c_msm_xfer_buf: current xfer position and preprocessed tags + * + * @is_init the buf is marked initialized by the first call to + * i2c_msm_xfer_next_buf() + * @msg_idx index of the message that the buffer is pointing to + * @byte_idx index of first byte in the current buffer + * @end_idx count of bytes processed from the current message. This value + * is compared against len to find out if buffer is done processing. + * @len number of bytes in current buffer. + * @is_rx when true, current buffer is pointing to a i2c read operation. + * @slv_addr 8 bit address. This is the i2c_msg->addr + rd/wr bit. + * + * Keep track of current position in the client's transfer request and + * pre-process a transfer's buffer and tags. + */ +struct i2c_msm_xfer_buf { + bool is_init; + int msg_idx; + int byte_idx; + int end_idx; + int len; + bool is_rx; + bool is_last; + u16 slv_addr; + struct i2c_msm_tag in_tag; + struct i2c_msm_tag out_tag; +}; + +#ifdef DEBUG +#define I2C_MSM_PROF_MAX_EVNTS (64) +#else +#define I2C_MSM_PROF_MAX_EVNTS (16) +#endif + +/* + * i2c_msm_prof_event: profiling event + * + * @data Additional data about the event. The interpretation of the data is + * dependant on the type field. + * @type event type (see enum i2c_msm_prof_event_type) + */ +struct i2c_msm_prof_event { + struct timespec time; + u64 data0; + u32 data1; + u32 data2; + u8 type; + u8 dump_func_id; +}; + +enum i2c_msm_err { + I2C_MSM_NO_ERR = 0, + I2C_MSM_ERR_NACK, + I2C_MSM_ERR_ARB_LOST, + I2C_MSM_ERR_BUS_ERR, + I2C_MSM_ERR_TIMEOUT, + I2C_MSM_ERR_CORE_CLK, + I2C_MSM_ERR_OVR_UNDR_RUN, +}; + +/* + * i2c_msm_xfer: A client transfer request. A list of one or more i2c messages + * + * @msgs NULL when no active xfer. Points to array of i2c_msgs + * given by the client. + * @msg_cnt number of messages in msgs array. + * @complete completion object to wait on for end of transfer. + * @rx_cnt number of input bytes in the client's request. + * @tx_cnt number of output bytes in the client's request. + * @rx_ovrhd_cnt number of input bytes due to tags. + * @tx_ovrhd_cnt number of output bytes due to tags. + * @event profiling data. An array of timestamps of transfer events + * @event_cnt number of items in event array. + * @is_active true during xfer process and false after xfer end + * @mtx mutex to solve multithreaded problem in xfer + */ +struct i2c_msm_xfer { + struct i2c_msg *msgs; + int msg_cnt; + enum i2c_msm_xfer_mode_id mode_id; + struct completion complete; + struct completion rx_complete; + size_t rx_cnt; + size_t tx_cnt; + size_t rx_ovrhd_cnt; + size_t tx_ovrhd_cnt; + struct i2c_msm_xfer_buf cur_buf; + u32 timeout; + bool last_is_rx; + enum i2c_msm_err err; + struct i2c_msm_prof_event event[I2C_MSM_PROF_MAX_EVNTS]; + atomic_t event_cnt; + atomic_t is_active; + struct mutex mtx; + struct i2c_msm_xfer_mode_fifo fifo; + struct i2c_msm_xfer_mode_blk blk; + struct i2c_msm_xfer_mode_dma dma; +}; + +/* + * i2c_msm_ctrl: the driver's main struct + * + * @is_init true when + * @ver info that is different between i2c controller versions + * @ver_num ha + * @xfer state of the currently processed transfer. + * @dbgfs debug-fs root and values that may be set via debug-fs. + * @rsrcs resources from platform data including clocks, gpios, irqs, and + * memory regions. + * @mstr_clk_ctl cached value for programming to mstr_clk_ctl register + * @i2c_sts_reg status of QUP_I2C_MASTER_STATUS register. + * @qup_op_reg status of QUP_OPERATIONAL register. + */ +struct i2c_msm_ctrl { + struct device *dev; + struct i2c_adapter adapter; + struct i2c_msm_xfer xfer; + struct i2c_msm_dbgfs dbgfs; + struct i2c_msm_resources rsrcs; + u32 mstr_clk_ctl; + u32 i2c_sts_reg; + u32 qup_op_reg; + enum i2c_msm_power_state pwr_state; +}; + +/* Enum for the profiling event types */ +enum i2c_msm_prof_evnt_type { + I2C_MSM_VALID_END, + I2C_MSM_PIP_DSCN, + I2C_MSM_PIP_CNCT, + I2C_MSM_ACTV_END, + I2C_MSM_IRQ_BGN, + I2C_MSM_IRQ_END, + I2C_MSM_XFER_BEG, + I2C_MSM_XFER_END, + I2C_MSM_SCAN_SUM, + I2C_MSM_NEXT_BUF, + I2C_MSM_COMPLT_OK, + I2C_MSM_COMPLT_FL, + I2C_MSM_PROF_RESET, +}; + +#ifdef CONFIG_I2C_MSM_PROF_DBG +void i2c_msm_dbgfs_init(struct i2c_msm_ctrl *ctrl); + +void i2c_msm_dbgfs_teardown(struct i2c_msm_ctrl *ctrl); + +/* diagonisis the i2c registers and dump the errors accordingly */ +const char *i2c_msm_dbg_tag_to_str(const struct i2c_msm_tag *tag, + char *buf, size_t buf_len); + +void i2c_msm_prof_evnt_dump(struct i2c_msm_ctrl *ctrl); + +/* function definitions to be used from the i2c-msm-v2-debug file */ +void i2c_msm_prof_evnt_add(struct i2c_msm_ctrl *ctrl, + enum msm_i2_debug_level dbg_level, + enum i2c_msm_prof_evnt_type event, + u64 data0, u32 data1, u32 data2); + +int i2c_msm_dbg_qup_reg_dump(struct i2c_msm_ctrl *ctrl); + +const char * +i2c_msm_dbg_dma_tag_to_str(const struct i2c_msm_dma_tag *dma_tag, char *buf, + size_t buf_len); +#else +/* use dummy functions */ +static inline void i2c_msm_dbgfs_init(struct i2c_msm_ctrl *ctrl) {} +static inline void i2c_msm_dbgfs_teardown(struct i2c_msm_ctrl *ctrl) {} + +static inline const char *i2c_msm_dbg_tag_to_str(const struct i2c_msm_tag *tag, + char *buf, size_t buf_len) +{ + return NULL; +} +static inline void i2c_msm_prof_evnt_dump(struct i2c_msm_ctrl *ctrl) {} + +/* function definitions to be used from the i2c-msm-v2-debug file */ +static inline void i2c_msm_prof_evnt_add(struct i2c_msm_ctrl *ctrl, + enum msm_i2_debug_level dbg_level, + enum i2c_msm_prof_evnt_type event, + u64 data0, u32 data1, u32 data2) {} + +static inline int i2c_msm_dbg_qup_reg_dump(struct i2c_msm_ctrl *ctrl) +{ + return true; +} +static inline const char *i2c_msm_dbg_dma_tag_to_str(const struct + i2c_msm_dma_tag * dma_tag, char *buf, size_t buf_len) +{ + return NULL; +} +#endif /* I2C_MSM_V2_PROF_DBG */ +#endif /* _I2C_MSM_V2_H */ diff --git a/include/linux/idr.h b/include/linux/idr.h index 013fd9bc4cb6..0708f79f32f6 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -181,6 +181,11 @@ static inline int ida_get_new(struct ida *ida, int *p_id) return ida_get_new_above(ida, 0, p_id); } +static inline bool ida_is_empty(struct ida *ida) +{ + return idr_is_empty(&ida->idr); +} + void __init idr_init_cache(void); #endif /* __IDR_H__ */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 149a7a6687e9..c2f46cffaab4 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1535,6 +1535,9 @@ struct ieee80211_vht_operation { #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_FT 2 #define WLAN_AUTH_SAE 3 +#define WLAN_AUTH_FILS_SK 4 +#define WLAN_AUTH_FILS_SK_PFS 5 +#define WLAN_AUTH_FILS_PK 6 #define WLAN_AUTH_LEAP 128 #define WLAN_AUTH_CHALLENGE_LEN 128 @@ -1674,6 +1677,9 @@ enum ieee80211_statuscode { WLAN_STATUS_REJECT_DSE_BAND = 96, WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ + WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, + WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, }; @@ -2032,6 +2038,15 @@ enum ieee80211_key_len { #define IEEE80211_GCMP_MIC_LEN 16 #define IEEE80211_GCMP_PN_LEN 6 +#define FILS_NONCE_LEN 16 +#define FILS_MAX_KEK_LEN 64 + +#define FILS_ERP_MAX_USERNAME_LEN 16 +#define FILS_ERP_MAX_REALM_LEN 253 +#define FILS_ERP_MAX_RRK_LEN 64 + +#define PMK_MAX_LEN 48 + /* Public action codes */ enum ieee80211_pub_actioncode { WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4, @@ -2245,31 +2260,37 @@ enum ieee80211_sa_query_action { }; +#define SUITE(oui, id) (((oui) << 8) | (id)) + /* cipher suite selectors */ -#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 -#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 -#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 -/* reserved: 0x000FAC03 */ -#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 -#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 -#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 -#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08 -#define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09 -#define WLAN_CIPHER_SUITE_CCMP_256 0x000FAC0A -#define WLAN_CIPHER_SUITE_BIP_GMAC_128 0x000FAC0B -#define WLAN_CIPHER_SUITE_BIP_GMAC_256 0x000FAC0C -#define WLAN_CIPHER_SUITE_BIP_CMAC_256 0x000FAC0D - -#define WLAN_CIPHER_SUITE_SMS4 0x00147201 +#define WLAN_CIPHER_SUITE_USE_GROUP SUITE(0x000FAC, 0) +#define WLAN_CIPHER_SUITE_WEP40 SUITE(0x000FAC, 1) +#define WLAN_CIPHER_SUITE_TKIP SUITE(0x000FAC, 2) +/* reserved: SUITE(0x000FAC, 3) */ +#define WLAN_CIPHER_SUITE_CCMP SUITE(0x000FAC, 4) +#define WLAN_CIPHER_SUITE_WEP104 SUITE(0x000FAC, 5) +#define WLAN_CIPHER_SUITE_AES_CMAC SUITE(0x000FAC, 6) +#define WLAN_CIPHER_SUITE_GCMP SUITE(0x000FAC, 8) +#define WLAN_CIPHER_SUITE_GCMP_256 SUITE(0x000FAC, 9) +#define WLAN_CIPHER_SUITE_CCMP_256 SUITE(0x000FAC, 10) +#define WLAN_CIPHER_SUITE_BIP_GMAC_128 SUITE(0x000FAC, 11) +#define WLAN_CIPHER_SUITE_BIP_GMAC_256 SUITE(0x000FAC, 12) +#define WLAN_CIPHER_SUITE_BIP_CMAC_256 SUITE(0x000FAC, 13) + +#define WLAN_CIPHER_SUITE_SMS4 SUITE(0x001472, 1) /* AKM suite selectors */ -#define WLAN_AKM_SUITE_8021X 0x000FAC01 -#define WLAN_AKM_SUITE_PSK 0x000FAC02 -#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05 -#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06 -#define WLAN_AKM_SUITE_TDLS 0x000FAC07 -#define WLAN_AKM_SUITE_SAE 0x000FAC08 -#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09 +#define WLAN_AKM_SUITE_8021X SUITE(0x000FAC, 1) +#define WLAN_AKM_SUITE_PSK SUITE(0x000FAC, 2) +#define WLAN_AKM_SUITE_8021X_SHA256 SUITE(0x000FAC, 5) +#define WLAN_AKM_SUITE_PSK_SHA256 SUITE(0x000FAC, 6) +#define WLAN_AKM_SUITE_TDLS SUITE(0x000FAC, 7) +#define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8) +#define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9) +#define WLAN_AKM_SUITE_FILS_SHA256 SUITE(0x000FAC, 14) +#define WLAN_AKM_SUITE_FILS_SHA384 SUITE(0x000FAC, 15) +#define WLAN_AKM_SUITE_FT_FILS_SHA256 SUITE(0x000FAC, 16) +#define WLAN_AKM_SUITE_FT_FILS_SHA384 SUITE(0x000FAC, 17) #define WLAN_MAX_KEY_LEN 32 diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index fad58671c49e..62acf17a894b 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -161,6 +161,16 @@ int iio_read_channel_processed(struct iio_channel *chan, int *val); int iio_write_channel_raw(struct iio_channel *chan, int val); /** + * iio_write_channel_processed() - write to a given channel + * @chan: The channel being queried. + * @val: Value being written. + * + * Note processed writes to iio channels are converted to raw + * values before being written. + */ +int iio_write_channel_processed(struct iio_channel *chan, int val); + +/** * iio_get_channel_type() - get the type of a channel * @channel: The channel being queried. * @type: The type of the channel. diff --git a/include/linux/iio/imu/mpu.h b/include/linux/iio/imu/mpu.h new file mode 100644 index 000000000000..4dbb86cad6d1 --- /dev/null +++ b/include/linux/iio/imu/mpu.h @@ -0,0 +1,124 @@ +/* +* Copyright (C) 2012-2017 InvenSense, 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 __MPU_H_ +#define __MPU_H_ + +#ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/ioctl.h> +#endif + +enum secondary_slave_type { + SECONDARY_SLAVE_TYPE_NONE, + SECONDARY_SLAVE_TYPE_ACCEL, + SECONDARY_SLAVE_TYPE_COMPASS, + SECONDARY_SLAVE_TYPE_PRESSURE, + SECONDARY_SLAVE_TYPE_ALS, + + SECONDARY_SLAVE_TYPE_TYPES +}; + +enum ext_slave_id { + ID_INVALID = 0, + GYRO_ID_MPU3050, + GYRO_ID_MPU6050A2, + GYRO_ID_MPU6050B1, + GYRO_ID_MPU6050B1_NO_ACCEL, + GYRO_ID_ITG3500, + + ACCEL_ID_LIS331, + ACCEL_ID_LSM303DLX, + ACCEL_ID_LIS3DH, + ACCEL_ID_KXSD9, + ACCEL_ID_KXTF9, + ACCEL_ID_BMA150, + ACCEL_ID_BMA222, + ACCEL_ID_BMA250, + ACCEL_ID_ADXL34X, + ACCEL_ID_MMA8450, + ACCEL_ID_MMA845X, + ACCEL_ID_MPU6050, + + COMPASS_ID_AK8963, + COMPASS_ID_AK8975, + COMPASS_ID_AK8972, + COMPASS_ID_AMI30X, + COMPASS_ID_AMI306, + COMPASS_ID_YAS529, + COMPASS_ID_YAS530, + COMPASS_ID_HMC5883, + COMPASS_ID_LSM303DLH, + COMPASS_ID_LSM303DLM, + COMPASS_ID_MMC314X, + COMPASS_ID_HSCDTD002B, + COMPASS_ID_HSCDTD004A, + COMPASS_ID_MLX90399, + COMPASS_ID_AK09911, + COMPASS_ID_AK09912, + COMPASS_ID_AK09916, + + PRESSURE_ID_BMP085, + PRESSURE_ID_BMP280, + + ALS_ID_APDS_9900, + ALS_ID_APDS_9930, + ALS_ID_TSL_2772, +}; + +#define INV_PROD_KEY(ver, rev) (ver * 100 + rev) +/** + * struct mpu_platform_data - Platform data for the mpu driver + * @int_config: Bits [7:3] of the int config register. + * @level_shifter: 0: VLogic, 1: VDD + * @orientation: Orientation matrix of the gyroscope + * @sec_slave_type: secondary slave device type, can be compass, accel, etc + * @sec_slave_id: id of the secondary slave device + * @secondary_i2c_address: secondary device's i2c address + * @secondary_orientation: secondary device's orientation matrix + * @aux_slave_type: auxiliary slave. Another slave device type + * @aux_slave_id: auxiliary slave ID. + * @aux_i2c_addr: auxiliary device I2C address. + * @read_only_slave_type: read only slave type. + * @read_only_slave_id: read only slave device ID. + * @read_only_i2c_addr: read only slave device address. + * + * Contains platform specific information on how to configure the MPU3050 to + * work on this platform. The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct mpu_platform_data { + __u8 int_config; + __u8 level_shifter; + __s8 orientation[9]; + enum secondary_slave_type sec_slave_type; + enum ext_slave_id sec_slave_id; + __u16 secondary_i2c_addr; + __s8 secondary_orientation[9]; + enum secondary_slave_type aux_slave_type; + enum ext_slave_id aux_slave_id; + __u16 aux_i2c_addr; + enum secondary_slave_type read_only_slave_type; + enum ext_slave_id read_only_slave_id; + __u16 read_only_i2c_addr; +#ifdef CONFIG_OF + int (*power_on)(struct mpu_platform_data *); + int (*power_off)(struct mpu_platform_data *); + struct regulator *vdd_ana; + struct regulator *vdd_i2c; +#endif +}; + +#endif /* __MPU_H_ */ diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h index 9a715cfa1fe3..365fb3be7ee7 100644 --- a/include/linux/inet_lro.h +++ b/include/linux/inet_lro.h @@ -81,6 +81,7 @@ struct net_lro_mgr { #define LRO_F_EXTRACT_VLAN_ID 2 /* Set flag if VLAN IDs are extracted from received packets and eth protocol is still ETH_P_8021Q */ +#define LRO_F_NI 4 /* If not NAPI, Pass packets to stack via NI */ /* * Set for generated SKBs that are not added to @@ -122,6 +123,50 @@ struct net_lro_mgr { }; /* + * Large Receive Offload (LRO) information provided by the driver + * + * Fields must be set by driver when using the lro_receive_skb_ext() + */ +struct net_lro_info { + /* bitmask indicating the supported fields */ + unsigned long valid_fields; + /* + * Driver has checked the LRO eligibilty of the skb + */ + #define LRO_ELIGIBILITY_CHECKED (1 << 0) + /* + * Driver has provided the TCP payload checksum + */ + #define LRO_TCP_DATA_CSUM (1 << 1) + /* + * Driver has extracted the TCP window from the skb + * The value is in network format + */ + #define LRO_TCP_WIN (1 << 2) + /* + * Driver has extracted the TCP sequence number from skb + * The value is in network format + */ + #define LRO_TCP_SEQ_NUM (1 << 3) + /* + * Driver has extracted the TCP ack number from the skb + * The value is in network format + */ + #define LRO_TCP_ACK_NUM (1 << 4) + /* + * Driver has provided the LRO descriptor + */ + #define LRO_DESC (1 << 5) + + bool lro_eligible; + __wsum tcp_data_csum; + __be16 tcp_win; + __be32 tcp_seq_num; + __be32 tcp_ack_num; + struct net_lro_desc *lro_desc; +}; + +/* * Processes a SKB * * @lro_mgr: LRO manager to use @@ -133,10 +178,54 @@ struct net_lro_mgr { void lro_receive_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, void *priv); + +/* + * Processes an SKB + * + * This API provides means to pass any LRO information that has already + * been extracted by the driver + * + * @lro_mgr: LRO manager to use + * @skb: SKB to aggregate + * @priv: Private data that may be used by driver functions + * (for example get_tcp_ip_hdr) + * @lro_info: LRO information extracted by the driver + */ + +void lro_receive_skb_ext(struct net_lro_mgr *lro_mgr, + struct sk_buff *skb, + void *priv, + struct net_lro_info *lro_info); + +/* + * Processes a fragment list + * + * This functions aggregate fragments and generate SKBs do pass + * the packets to the stack. + * + * @lro_mgr: LRO manager to use + * @frags: Fragment to be processed. Must contain entire header in first + * element. + * @len: Length of received data + * @true_size: Actual size of memory the fragment is consuming + * @priv: Private data that may be used by driver functions + * (for example get_tcp_ip_hdr) + */ + +void lro_receive_frags(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, void *priv, __wsum sum); + /* * Forward all aggregated SKBs held by lro_mgr to network stack */ void lro_flush_all(struct net_lro_mgr *lro_mgr); +void lro_flush_pkt(struct net_lro_mgr *lro_mgr, + struct iphdr *iph, struct tcphdr *tcph); + +void lro_flush_desc(struct net_lro_mgr *lro_mgr, + struct net_lro_desc *lro_desc); + #endif diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index ee971f335a8b..7118876e9896 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -128,6 +128,8 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY) +#define IN_DEV_NF_IPV4_DEFRAG_SKIP(in_dev) \ + IN_DEV_ORCONF((in_dev), NF_IPV4_DEFRAG_SKIP) struct in_ifaddr { struct hlist_node hash; diff --git a/include/linux/input/atmel_maxtouch_ts.h b/include/linux/input/atmel_maxtouch_ts.h new file mode 100755 index 000000000000..adc359008c42 --- /dev/null +++ b/include/linux/input/atmel_maxtouch_ts.h @@ -0,0 +1,61 @@ +/* + * Atmel maXTouch Touchscreen driver + * + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Linux foundation chooses to take subject only to the GPLv2 license terms, + * and distributes only under these terms. + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@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. + */ + +#ifndef __LINUX_ATMEL_MAXTOUCH_TS_H +#define __LINUX_ATMEL_MAXTOUCH_TS_H + +#include <linux/types.h> + +/* The platform data for the Atmel maXTouch touchscreen driver */ +struct mxt_platform_data { + unsigned long irqflags; + unsigned long resetflags; + int gpio_reset; + int gpio_irq; + int gpio_i2cmode; + u8 t19_num_keys; + const unsigned int *t19_keymap; + int t15_num_keys; + const unsigned int *t15_keymap; + const char *cfg_name; + const char *fw_name; + bool ignore_crc; + + const struct mxt_config_info *config_array; + size_t config_array_size; + + /* touch panel's minimum and maximum coordinates */ + u32 panel_minx; + u32 panel_maxx; + u32 panel_miny; + u32 panel_maxy; + + /* display's minimum and maximum coordinates */ + u32 disp_minx; + u32 disp_maxx; + u32 disp_miny; + u32 disp_maxy; + + int *key_codes; + u8 bl_addr; + + u8(*read_chg) (void); + int (*init_hw) (bool); + int (*power_on) (bool); +}; + +#endif /* __LINUX_ATMEL_MAXTOUCH_TS_H */ diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h new file mode 100644 index 000000000000..ad95957d9189 --- /dev/null +++ b/include/linux/input/ft5x06_ts.h @@ -0,0 +1,77 @@ +/* + * + * FocalTech ft5x06 TouchScreen driver header file. + * + * Copyright (c) 2010 Focal tech Ltd. + * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. + * + * 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 __LINUX_FT5X06_TS_H__ +#define __LINUX_FT5X06_TS_H__ + +#define FT5X06_ID 0x55 +#define FT5X16_ID 0x0A +#define FT5X36_ID 0x14 +#define FT6X06_ID 0x06 +#define FT6X36_ID 0x36 + +struct fw_upgrade_info { + bool auto_cal; + u16 delay_aa; + u16 delay_55; + u8 upgrade_id_1; + u8 upgrade_id_2; + u16 delay_readid; + u16 delay_erase_flash; +}; + +struct ft5x06_gesture_platform_data { + int gesture_enable_to_set; /* enable/disable gesture */ + int in_pocket; /* whether in pocket mode or not */ + struct device *dev; + struct class *gesture_class; + struct ft5x06_ts_data *data; +}; + +struct ft5x06_ts_platform_data { + struct fw_upgrade_info info; + const char *name; + const char *fw_name; + u32 irqflags; + u32 irq_gpio; + u32 irq_gpio_flags; + u32 reset_gpio; + u32 reset_gpio_flags; + u32 family_id; + u32 x_max; + u32 y_max; + u32 x_min; + u32 y_min; + u32 panel_minx; + u32 panel_miny; + u32 panel_maxx; + u32 panel_maxy; + u32 group_id; + u32 hard_rst_dly; + u32 soft_rst_dly; + u32 num_max_touches; + bool fw_vkey_support; + bool no_force_update; + bool i2c_pull_up; + bool ignore_id_check; + bool gesture_support; + bool resume_in_workqueue; + int (*power_init)(bool); + int (*power_on)(bool); +}; + +#endif diff --git a/include/linux/input/gen_vkeys.h b/include/linux/input/gen_vkeys.h new file mode 100644 index 000000000000..a58158d703bd --- /dev/null +++ b/include/linux/input/gen_vkeys.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2013, 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 __GEN_VKEYS_ +struct vkeys_platform_data { + const char *name; + int disp_maxx; + int disp_maxy; + int panel_maxx; + int panel_maxy; + int *keycodes; + int num_keys; + int y_offset; +}; +#endif diff --git a/include/linux/input/qpnp-power-on.h b/include/linux/input/qpnp-power-on.h new file mode 100644 index 000000000000..5944f0fd3414 --- /dev/null +++ b/include/linux/input/qpnp-power-on.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2012-2015, 2017, 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 QPNP_PON_H +#define QPNP_PON_H + +#include <linux/errno.h> + +/** + * enum pon_trigger_source: List of PON trigger sources + * %PON_SMPL: PON triggered by SMPL - Sudden Momentary Power Loss + * %PON_RTC: PON triggered by 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 + */ +enum pon_power_off_type { + PON_POWER_OFF_RESERVED = 0x00, + PON_POWER_OFF_WARM_RESET = 0x01, + PON_POWER_OFF_SHUTDOWN = 0x04, + PON_POWER_OFF_HARD_RESET = 0x07, + PON_POWER_OFF_MAX_TYPE = 0x10, +}; + +enum pon_restart_reason { + /* 0 ~ 31 for common defined features */ + 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, + + /* 32 ~ 63 for OEMs/ODMs secific features */ + PON_RESTART_REASON_OEM_MIN = 0x20, + PON_RESTART_REASON_OEM_MAX = 0x3f, +}; + +#ifdef 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); + +#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; +} +#endif + +#endif diff --git a/include/linux/input/synaptics_dsx_v2.h b/include/linux/input/synaptics_dsx_v2.h new file mode 100644 index 000000000000..9df212c3cdfe --- /dev/null +++ b/include/linux/input/synaptics_dsx_v2.h @@ -0,0 +1,108 @@ +/* + * Synaptics DSX touchscreen driver + * + * Copyright (C) 2012 Synaptics Incorporated + * + * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> + * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> + * Copyright (c) 2015-2016, 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 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 _SYNAPTICS_DSX_H_ +#define _SYNAPTICS_DSX_H_ + +#define PLATFORM_DRIVER_NAME "synaptics_dsx" +#define I2C_DRIVER_NAME "synaptics_dsx_i2c" +#define SPI_DRIVER_NAME "synaptics_dsx_spi" + +/* + * struct synaptics_dsx_cap_button_map - 0d button map + * @nbuttons: number of 0d buttons + * @map: pointer to array of button types + */ +struct synaptics_dsx_cap_button_map { + unsigned char nbuttons; + unsigned char *map; +}; + +/* + * struct synaptics_virtual_key_map - 2d button map + * @nkeys: number of virtual keys + * @map: pointer to array of virtual keys + */ +struct synaptics_rmi4_virtual_key_map { + unsigned char nkeys; + unsigned int *map; +}; + +/* + * struct synaptics_dsx_board_data - dsx board data + * @x_flip: x flip flag + * @y_flip: y flip flag + * @irq_gpio: attention interrupt gpio + * @power_gpio: power switch gpio + * @power_on_state: power switch active state + * @reset_gpio: reset gpio + * @reset_on_state: reset active state + * @irq_flags: irq flags + * @panel_x: x-axis resolution of display panel + * @panel_y: y-axis resolution of display panel + * @power_delay_ms: delay time to wait after power-on + * @reset_delay_ms: delay time to wait after reset + * @reset_active_ms: reset active time + * @byte_delay_us: delay time between two bytes of SPI data + * @block_delay_us: delay time between two SPI transfers + * @regulator_name: pointer to name of regulator + * @gpio_config: pointer to gpio configuration function + * @cap_button_map: pointer to 0d button map + */ +struct synaptics_dsx_board_data { + bool x_flip; + bool y_flip; + bool swap_axes; + int irq_gpio; + u32 irq_flags; + int power_gpio; + int power_on_state; + int reset_gpio; + u32 reset_flags; + int reset_on_state; + unsigned int panel_x; + unsigned int panel_y; + unsigned int power_delay_ms; + unsigned int reset_delay_ms; + unsigned int reset_active_ms; + unsigned int byte_delay_us; + unsigned int block_delay_us; + unsigned char *regulator_name; + unsigned int package_id; + int (*gpio_config)(int gpio, bool configure, int dir, int state); + struct synaptics_dsx_cap_button_map *cap_button_map; + struct synaptics_rmi4_virtual_key_map *virtual_key_map; + u32 panel_minx; + u32 panel_miny; + u32 panel_maxx; + u32 panel_maxy; + u32 disp_minx; + u32 disp_miny; + u32 disp_maxx; + u32 disp_maxy; + u32 config_id; + bool disable_gpios; + bool detect_device; + bool bypass_packrat_id_check; + bool resume_in_workqueue; + const char *fw_name; +}; + +#endif diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 9ddd6a0ce3a2..aa4933365485 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -424,6 +424,12 @@ enum }; #define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ)) +/* Softirq's where the handling might be long: */ +#define LONG_SOFTIRQ_MASK ((1 << NET_TX_SOFTIRQ) | \ + (1 << NET_RX_SOFTIRQ) | \ + (1 << BLOCK_SOFTIRQ) | \ + (1 << BLOCK_IOPOLL_SOFTIRQ) | \ + (1 << TASKLET_SOFTIRQ)) /* map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq. @@ -459,6 +465,7 @@ extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); DECLARE_PER_CPU(struct task_struct *, ksoftirqd); +DECLARE_PER_CPU(__u32, active_softirqs); static inline struct task_struct *this_cpu_ksoftirqd(void) { diff --git a/include/linux/io-pgtable-fast.h b/include/linux/io-pgtable-fast.h new file mode 100644 index 000000000000..6a56f0039f15 --- /dev/null +++ b/include/linux/io-pgtable-fast.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2016-2017, 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 __LINUX_IO_PGTABLE_FAST_H +#define __LINUX_IO_PGTABLE_FAST_H + +#include <linux/notifier.h> + +typedef u64 av8l_fast_iopte; + +#define iopte_pmd_offset(pmds, base, iova) (pmds + ((iova - base) >> 12)) + +int av8l_fast_map_public(av8l_fast_iopte *ptep, phys_addr_t paddr, size_t size, + int prot); +void av8l_fast_unmap_public(av8l_fast_iopte *ptep, size_t size); + +/* 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(av8l_fast_iopte *puds, u64 base, + u64 start, 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(av8l_fast_iopte *puds, + u64 base, + u64 start, + 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 */ diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f28dff313b07..2767fcdec5a1 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -23,13 +23,14 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/types.h> -#include <linux/scatterlist.h> #include <trace/events/iommu.h> #define IOMMU_READ (1 << 0) #define IOMMU_WRITE (1 << 1) #define IOMMU_CACHE (1 << 2) /* DMA cache coherency */ #define IOMMU_NOEXEC (1 << 3) +#define IOMMU_PRIV (1 << 4) +#define IOMMU_DEVICE (1 << 5) /* Indicates access to device memory */ struct iommu_ops; struct iommu_group; @@ -39,8 +40,12 @@ struct iommu_domain; struct notifier_block; /* iommu fault flags */ -#define IOMMU_FAULT_READ 0x0 -#define IOMMU_FAULT_WRITE 0x1 +#define IOMMU_FAULT_READ (1 << 0) +#define IOMMU_FAULT_WRITE (1 << 1) +#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) typedef int (*iommu_fault_handler_t)(struct iommu_domain *, struct device *, unsigned long, int, void *); @@ -51,6 +56,10 @@ struct iommu_domain_geometry { bool force_aperture; /* DMA only allowed in mappable range? */ }; +struct iommu_pgtbl_info { + void *pmds; +}; + /* Domain feature flags */ #define __IOMMU_DOMAIN_PAGING (1U << 0) /* Support for iommu_map/unmap */ #define __IOMMU_DOMAIN_DMA_API (1U << 1) /* Domain for use in DMA-API @@ -112,9 +121,28 @@ enum iommu_attr { DOMAIN_ATTR_FSL_PAMU_ENABLE, DOMAIN_ATTR_FSL_PAMUV1, DOMAIN_ATTR_NESTING, /* two stages of translation */ + DOMAIN_ATTR_PT_BASE_ADDR, + DOMAIN_ATTR_SECURE_VMID, + DOMAIN_ATTR_ATOMIC, + DOMAIN_ATTR_CONTEXT_BANK, + DOMAIN_ATTR_TTBR0, + DOMAIN_ATTR_CONTEXTIDR, + DOMAIN_ATTR_PROCID, + DOMAIN_ATTR_DYNAMIC, + DOMAIN_ATTR_NON_FATAL_FAULTS, + DOMAIN_ATTR_S1_BYPASS, + DOMAIN_ATTR_FAST, + DOMAIN_ATTR_PGTBL_INFO, + DOMAIN_ATTR_EARLY_MAP, + DOMAIN_ATTR_PAGE_TABLE_IS_COHERENT, + DOMAIN_ATTR_PAGE_TABLE_FORCE_COHERENT, + DOMAIN_ATTR_ENABLE_TTBR1, + DOMAIN_ATTR_CB_STALL_DISABLE, DOMAIN_ATTR_MAX, }; +extern struct dentry *iommu_debugfs_top; + /** * struct iommu_dm_region - descriptor for a direct mapped memory region * @list: Linked list pointers @@ -142,12 +170,21 @@ struct iommu_dm_region { * @map_sg: map a scatter-gather list of physically contiguous memory chunks * to an iommu domain * @iova_to_phys: translate iova to physical address + * @iova_to_phys_hard: translate iova to physical address using IOMMU hardware * @add_device: add device to iommu grouping * @remove_device: remove device from iommu grouping * @domain_get_attr: Query domain attributes * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping * @pgsize_bitmap: bitmap of supported page sizes + * @get_pgsize_bitmap: gets a bitmap of supported page sizes for a domain + * This takes precedence over @pgsize_bitmap. + * @trigger_fault: trigger a fault on the device attached to an iommu domain + * @reg_read: read an IOMMU register + * @reg_write: write an IOMMU register + * @tlbi_domain: Invalidate all TLBs covering an iommu domain + * @enable_config_clocks: Enable all config clocks for this domain's IOMMU + * @disable_config_clocks: Disable all config clocks for this domain's IOMMU * @priv: per-instance data private to the iommu driver */ struct iommu_ops { @@ -166,6 +203,8 @@ struct iommu_ops { size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); + phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain, + dma_addr_t iova); int (*add_device)(struct device *dev); void (*remove_device)(struct device *dev); struct iommu_group *(*device_group)(struct device *dev); @@ -186,11 +225,25 @@ struct iommu_ops { int (*domain_set_windows)(struct iommu_domain *domain, u32 w_count); /* Get the numer of window per domain */ u32 (*domain_get_windows)(struct iommu_domain *domain); + int (*dma_supported)(struct iommu_domain *domain, struct device *dev, + u64 mask); + void (*trigger_fault)(struct iommu_domain *domain, unsigned long flags); + unsigned long (*reg_read)(struct iommu_domain *domain, + unsigned long offset); + void (*reg_write)(struct iommu_domain *domain, unsigned long val, + unsigned long offset); + void (*tlbi_domain)(struct iommu_domain *domain); + int (*enable_config_clocks)(struct iommu_domain *domain); + void (*disable_config_clocks)(struct iommu_domain *domain); + uint64_t (*iova_to_pte)(struct iommu_domain *domain, + dma_addr_t iova); #ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev, struct of_phandle_args *args); #endif + unsigned long (*get_pgsize_bitmap)(struct iommu_domain *domain); + bool (*is_iova_coherent)(struct iommu_domain *domain, dma_addr_t iova); unsigned long pgsize_bitmap; void *priv; }; @@ -212,17 +265,31 @@ extern int iommu_attach_device(struct iommu_domain *domain, struct device *dev); extern void iommu_detach_device(struct iommu_domain *domain, struct device *dev); +extern size_t iommu_pgsize(unsigned long pgsize_bitmap, + unsigned long addr_merge, size_t size); extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot); extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size); +extern int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova, + unsigned int len); extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg,unsigned int nents, int prot); extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova); +extern phys_addr_t iommu_iova_to_phys_hard(struct iommu_domain *domain, + dma_addr_t iova); +extern bool iommu_is_iova_coherent(struct iommu_domain *domain, + dma_addr_t iova); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); +extern void iommu_trigger_fault(struct iommu_domain *domain, + unsigned long flags); +extern unsigned long iommu_reg_read(struct iommu_domain *domain, + unsigned long offset); +extern void iommu_reg_write(struct iommu_domain *domain, unsigned long offset, + unsigned long val); extern void iommu_get_dm_regions(struct device *dev, struct list_head *list); extern void iommu_put_dm_regions(struct device *dev, struct list_head *list); @@ -269,6 +336,9 @@ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t offset, u64 size, int prot); extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr); + +extern uint64_t iommu_iova_to_pte(struct iommu_domain *domain, + dma_addr_t iova); /** * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework * @domain: the iommu domain where the fault has happened @@ -292,6 +362,11 @@ extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr) * Specifically, -ENOSYS is returned if a fault handler isn't installed * (though fault handlers can also return -ENOSYS, in case they want to * elicit the default behavior of the IOMMU drivers). + + * Client fault handler returns -EBUSY to signal to the IOMMU driver + * that the client will take responsibility for any further fault + * handling, including clearing fault status registers or retrying + * the faulting transaction. */ static inline int report_iommu_fault(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags) @@ -314,14 +389,41 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot) { - return domain->ops->map_sg(domain, iova, sg, nents, prot); + size_t ret; + + trace_map_sg_start(iova, nents); + ret = domain->ops->map_sg(domain, iova, sg, nents, prot); + trace_map_sg_end(iova, nents); + return ret; } +extern int iommu_dma_supported(struct iommu_domain *domain, struct device *dev, + u64 mask); + /* PCI device grouping function */ extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +static inline void iommu_tlbiall(struct iommu_domain *domain) +{ + if (domain->ops->tlbi_domain) + domain->ops->tlbi_domain(domain); +} + +static inline int iommu_enable_config_clocks(struct iommu_domain *domain) +{ + if (domain->ops->enable_config_clocks) + return domain->ops->enable_config_clocks(domain); + return 0; +} + +static inline void iommu_disable_config_clocks(struct iommu_domain *domain) +{ + if (domain->ops->disable_config_clocks) + domain->ops->disable_config_clocks(domain); +} + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; @@ -379,6 +481,12 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova, return -ENODEV; } +static inline int iommu_unmap_range(struct iommu_domain *domain, + unsigned int iova, unsigned int len) +{ + return -ENODEV; +} + static inline size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot) @@ -403,11 +511,39 @@ static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_ad return 0; } +static inline phys_addr_t iommu_iova_to_phys_hard(struct iommu_domain *domain, + dma_addr_t iova) +{ + return 0; +} + +static inline bool iommu_is_iova_coherent(struct iommu_domain *domain, + dma_addr_t iova) +{ + return 0; +} + static inline void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token) { } +static inline void iommu_trigger_fault(struct iommu_domain *domain, + unsigned long flags) +{ +} + +static inline unsigned long iommu_reg_read(struct iommu_domain *domain, + unsigned long offset) +{ + return 0; +} + +static inline void iommu_reg_write(struct iommu_domain *domain, + unsigned long val, unsigned long offset) +{ +} + static inline void iommu_get_dm_regions(struct device *dev, struct list_head *list) { @@ -532,6 +668,25 @@ static inline void iommu_device_unlink(struct device *dev, struct device *link) { } +static inline int iommu_dma_supported(struct iommu_domain *domain, + struct device *dev, u64 mask) +{ + return -EINVAL; +} + +static inline void iommu_tlbiall(struct iommu_domain *domain) +{ +} + +static inline int iommu_enable_config_clocks(struct iommu_domain *domain) +{ + return 0; +} + +static inline void iommu_disable_config_clocks(struct iommu_domain *domain) +{ +} + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */ diff --git a/include/linux/ion.h b/include/linux/ion.h new file mode 100644 index 000000000000..242fef6ba990 --- /dev/null +++ b/include/linux/ion.h @@ -0,0 +1,6 @@ +#ifndef __LINUX_ION_H__ +#define __LINUX_ION_H__ + +#include "../../drivers/staging/android/ion/ion.h" + +#endif /* __LINUX_ION_H__ */ diff --git a/include/linux/ipa.h b/include/linux/ipa.h new file mode 100644 index 000000000000..2586395886a3 --- /dev/null +++ b/include/linux/ipa.h @@ -0,0 +1,2321 @@ +/* Copyright (c) 2012-2018, 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 _IPA_H_ +#define _IPA_H_ + +#include <linux/msm_ipa.h> +#include <linux/skbuff.h> +#include <linux/types.h> +#include <linux/msm-sps.h> +#include <linux/if_ether.h> +#include "linux/msm_gsi.h" + +#define IPA_APPS_MAX_BW_IN_MBPS 700 +/** + * enum ipa_transport_type + * transport type: either GSI or SPS + */ +enum ipa_transport_type { + IPA_TRANSPORT_TYPE_SPS, + IPA_TRANSPORT_TYPE_GSI +}; + +/** + * enum ipa_nat_en_type - NAT setting type in IPA end-point + */ +enum ipa_nat_en_type { + IPA_BYPASS_NAT, + IPA_SRC_NAT, + IPA_DST_NAT, +}; + +/** + * enum ipa_ipv6ct_en_type - IPv6CT setting type in IPA end-point + */ +enum ipa_ipv6ct_en_type { + IPA_BYPASS_IPV6CT, + IPA_ENABLE_IPV6CT, +}; + +/** + * enum ipa_mode_type - mode setting type in IPA end-point + * @BASIC: basic mode + * @ENABLE_FRAMING_HDLC: not currently supported + * @ENABLE_DEFRAMING_HDLC: not currently supported + * @DMA: all data arriving IPA will not go through IPA logic blocks, this + * allows IPA to work as DMA for specific pipes. + */ +enum ipa_mode_type { + IPA_BASIC, + IPA_ENABLE_FRAMING_HDLC, + IPA_ENABLE_DEFRAMING_HDLC, + IPA_DMA, +}; + +/** + * enum ipa_aggr_en_type - aggregation setting type in IPA + * end-point + */ +enum ipa_aggr_en_type { + IPA_BYPASS_AGGR, + IPA_ENABLE_AGGR, + IPA_ENABLE_DEAGGR, +}; + +/** + * enum ipa_aggr_type - type of aggregation in IPA end-point + */ +enum ipa_aggr_type { + IPA_MBIM_16 = 0, + IPA_HDLC = 1, + IPA_TLP = 2, + IPA_RNDIS = 3, + IPA_GENERIC = 4, + IPA_QCMAP = 6, +}; + +/** + * enum ipa_aggr_mode - global aggregation mode + */ +enum ipa_aggr_mode { + IPA_MBIM_AGGR, + IPA_QCNCM_AGGR, +}; + +/** + * enum ipa_dp_evt_type - type of event client callback is + * invoked for on data path + * @IPA_RECEIVE: data is struct sk_buff + * @IPA_WRITE_DONE: data is struct sk_buff + */ +enum ipa_dp_evt_type { + IPA_RECEIVE, + IPA_WRITE_DONE, + IPA_CLIENT_START_POLL, + IPA_CLIENT_COMP_NAPI, +}; + +/** + * enum hdr_total_len_or_pad_type - type of value held by TOTAL_LEN_OR_PAD + * field in header configuration register. + * @IPA_HDR_PAD: field is used as padding length + * @IPA_HDR_TOTAL_LEN: field is used as total length + */ +enum hdr_total_len_or_pad_type { + IPA_HDR_PAD = 0, + IPA_HDR_TOTAL_LEN = 1, +}; + +/** + * struct ipa_ep_cfg_nat - NAT configuration in IPA end-point + * @nat_en: This defines the default NAT mode for the pipe: in case of + * filter miss - the default NAT mode defines the NATing operation + * on the packet. Valid for Input Pipes only (IPA consumer) + */ +struct ipa_ep_cfg_nat { + enum ipa_nat_en_type nat_en; +}; + +/** + * struct ipa_ep_cfg_conn_track - IPv6 Connection tracking configuration in + * IPA end-point + * @conn_track_en: Defines speculative conn_track action, means if specific + * pipe needs to have UL/DL IPv6 Connection Tracking or Bypass + * IPv6 Connection Tracking. 0: Bypass IPv6 Connection Tracking + * 1: IPv6 UL/DL Connection Tracking. + * Valid for Input Pipes only (IPA consumer) + */ +struct ipa_ep_cfg_conn_track { + enum ipa_ipv6ct_en_type conn_track_en; +}; + +/** + * struct ipa_ep_cfg_hdr - header configuration in IPA end-point + * + * @hdr_len:Header length in bytes to be added/removed. Assuming + * header len is constant per endpoint. Valid for + * both Input and Output Pipes + * @hdr_ofst_metadata_valid: 0: Metadata_Ofst value is invalid, i.e., no + * metadata within header. + * 1: Metadata_Ofst value is valid, i.e., metadata + * within header is in offset Metadata_Ofst Valid + * for Input Pipes only (IPA Consumer) (for output + * pipes, metadata already set within the header) + * @hdr_ofst_metadata: Offset within header in which metadata resides + * Size of metadata - 4bytes + * Example - Stream ID/SSID/mux ID. + * Valid for Input Pipes only (IPA Consumer) (for output + * pipes, metadata already set within the header) + * @hdr_additional_const_len: Defines the constant length that should be added + * to the payload length in order for IPA to update + * correctly the length field within the header + * (valid only in case Hdr_Ofst_Pkt_Size_Valid=1) + * Valid for Output Pipes (IPA Producer) + * @hdr_ofst_pkt_size_valid: 0: Hdr_Ofst_Pkt_Size value is invalid, i.e., no + * length field within the inserted header + * 1: Hdr_Ofst_Pkt_Size value is valid, i.e., a + * packet length field resides within the header + * Valid for Output Pipes (IPA Producer) + * @hdr_ofst_pkt_size: Offset within header in which packet size reside. Upon + * Header Insertion, IPA will update this field within the + * header with the packet length . Assumption is that + * header length field size is constant and is 2Bytes + * Valid for Output Pipes (IPA Producer) + * @hdr_a5_mux: Determines whether A5 Mux header should be added to the packet. + * This bit is valid only when Hdr_En=01(Header Insertion) + * SW should set this bit for IPA-to-A5 pipes. + * 0: Do not insert A5 Mux Header + * 1: Insert A5 Mux Header + * Valid for Output Pipes (IPA Producer) + * @hdr_remove_additional: bool switch, remove more of the header + * based on the aggregation configuration (register + * HDR_LEN_INC_DEAGG_HDR) + * @hdr_metadata_reg_valid: bool switch, metadata from + * register INIT_HDR_METADATA_n is valid. + * (relevant only for IPA Consumer pipes) + */ +struct ipa_ep_cfg_hdr { + u32 hdr_len; + u32 hdr_ofst_metadata_valid; + u32 hdr_ofst_metadata; + u32 hdr_additional_const_len; + u32 hdr_ofst_pkt_size_valid; + u32 hdr_ofst_pkt_size; + u32 hdr_a5_mux; + u32 hdr_remove_additional; + u32 hdr_metadata_reg_valid; +}; + +/** + * struct ipa_ep_cfg_hdr_ext - extended header configuration in IPA end-point + * @hdr_pad_to_alignment: Pad packet to specified alignment + * (2^pad to alignment value), i.e. value of 3 means pad to 2^3 = 8 bytes + * alignment. Alignment is to 0,2 up to 32 bytes (IPAv2 does not support 64 + * byte alignment). Valid for Output Pipes only (IPA Producer). + * @hdr_total_len_or_pad_offset: Offset to length field containing either + * total length or pad length, per hdr_total_len_or_pad config + * @hdr_payload_len_inc_padding: 0-IPA_ENDP_INIT_HDR_n's + * HDR_OFST_PKT_SIZE does + * not includes padding bytes size, payload_len = packet length, + * 1-IPA_ENDP_INIT_HDR_n's HDR_OFST_PKT_SIZE includes + * padding bytes size, payload_len = packet length + padding + * @hdr_total_len_or_pad: field is used as PAD length ot as Total length + * (header + packet + padding) + * @hdr_total_len_or_pad_valid: 0-Ignore TOTAL_LEN_OR_PAD field, 1-Process + * TOTAL_LEN_OR_PAD field + * @hdr_little_endian: 0-Big Endian, 1-Little Endian + */ +struct ipa_ep_cfg_hdr_ext { + u32 hdr_pad_to_alignment; + u32 hdr_total_len_or_pad_offset; + bool hdr_payload_len_inc_padding; + enum hdr_total_len_or_pad_type hdr_total_len_or_pad; + bool hdr_total_len_or_pad_valid; + bool hdr_little_endian; +}; + +/** + * struct ipa_ep_cfg_mode - mode configuration in IPA end-point + * @mode: Valid for Input Pipes only (IPA Consumer) + * @dst: This parameter specifies the output pipe to which the packets + * will be routed to. + * This parameter is valid for Mode=DMA and not valid for + * Mode=Basic + * Valid for Input Pipes only (IPA Consumer) + */ +struct ipa_ep_cfg_mode { + enum ipa_mode_type mode; + enum ipa_client_type dst; +}; + +/** + * struct ipa_ep_cfg_aggr - aggregation configuration in IPA end-point + * + * @aggr_en: Valid for both Input and Output Pipes + * @aggr: aggregation type (Valid for both Input and Output Pipes) + * @aggr_byte_limit: Limit of aggregated packet size in KB (<=32KB) When set + * to 0, there is no size limitation on the aggregation. + * When both, Aggr_Byte_Limit and Aggr_Time_Limit are set + * to 0, there is no aggregation, every packet is sent + * independently according to the aggregation structure + * Valid for Output Pipes only (IPA Producer ) + * @aggr_time_limit: Timer to close aggregated packet (<=32ms) When set to 0, + * there is no time limitation on the aggregation. When + * both, Aggr_Byte_Limit and Aggr_Time_Limit are set to 0, + * there is no aggregation, every packet is sent + * independently according to the aggregation structure + * Valid for Output Pipes only (IPA Producer) + * @aggr_pkt_limit: Defines if EOF close aggregation or not. if set to false + * HW closes aggregation (sends EOT) only based on its + * aggregation config (byte/time limit, etc). if set to + * true EOF closes aggregation in addition to HW based + * aggregation closure. Valid for Output Pipes only (IPA + * Producer). EOF affects only Pipes configured for + * generic aggregation. + * @aggr_hard_byte_limit_en: If set to 1, byte-limit aggregation for this + * pipe will apply a hard-limit behavior which will not + * allow frames to be closed with more than byte-limit + * bytes. If set to 0, previous byte-limit behavior + * will apply - frames close once a packet causes the + * accumulated byte-count to cross the byte-limit + * threshold (closed frame will contain that packet). + * @aggr_sw_eof_active: 0: EOF does not close aggregation. HW closes aggregation + * (sends EOT) only based on its aggregation config + * (byte/time limit, etc). + * 1: EOF closes aggregation in addition to HW based + * aggregation closure. Valid for Output Pipes only (IPA + * Producer). EOF affects only Pipes configured for generic + * aggregation. + */ +struct ipa_ep_cfg_aggr { + enum ipa_aggr_en_type aggr_en; + enum ipa_aggr_type aggr; + u32 aggr_byte_limit; + u32 aggr_time_limit; + u32 aggr_pkt_limit; + u32 aggr_hard_byte_limit_en; + bool aggr_sw_eof_active; +}; + +/** + * struct ipa_ep_cfg_route - route configuration in IPA end-point + * @rt_tbl_hdl: Defines the default routing table index to be used in case there + * is no filter rule matching, valid for Input Pipes only (IPA + * Consumer). Clients should set this to 0 which will cause default + * v4 and v6 routes setup internally by IPA driver to be used for + * this end-point + */ +struct ipa_ep_cfg_route { + u32 rt_tbl_hdl; +}; + +/** + * struct ipa_ep_cfg_holb - head of line blocking configuration in IPA end-point + * @en: enable(1 => ok to drop pkt)/disable(0 => never drop pkt) + * @tmr_val: duration in units of 128 IPA clk clock cyles [0,511], 1 clk=1.28us + * IPAv2.5 support 32 bit HOLB timeout value, previous versions + * supports 16 bit + */ +struct ipa_ep_cfg_holb { + u16 en; + u32 tmr_val; +}; + +/** + * struct ipa_ep_cfg_deaggr - deaggregation configuration in IPA end-point + * @deaggr_hdr_len: Deaggregation Header length in bytes. Valid only for Input + * Pipes, which are configured for 'Generic' deaggregation. + * @packet_offset_valid: - 0: PACKET_OFFSET is not used, 1: PACKET_OFFSET is + * used. + * @packet_offset_location: Location of packet offset field, which specifies + * the offset to the packet from the start of the packet offset field. + * @max_packet_len: DEAGGR Max Packet Length in Bytes. A Packet with higher + * size wil be treated as an error. 0 - Packet Length is not Bound, + * IPA should not check for a Max Packet Length. + */ +struct ipa_ep_cfg_deaggr { + u32 deaggr_hdr_len; + bool packet_offset_valid; + u32 packet_offset_location; + u32 max_packet_len; +}; + +/** + * enum ipa_cs_offload - checksum offload setting + */ +enum ipa_cs_offload { + IPA_DISABLE_CS_OFFLOAD, + IPA_ENABLE_CS_OFFLOAD_UL, + IPA_ENABLE_CS_OFFLOAD_DL, + IPA_CS_RSVD +}; + +/** + * struct ipa_ep_cfg_cfg - IPA ENDP_INIT Configuration register + * @frag_offload_en: - 0 - IP packet fragment handling is disabled. IP packet + * fragments should be sent to SW. SW is responsible for + * configuring filter rules, and IP packet filter exception should be + * used to send all fragments to SW. 1 - IP packet fragment + * handling is enabled. IPA checks for fragments and uses frag + * rules table for processing fragments. Valid only for Input Pipes + * (IPA Consumer) + * @cs_offload_en: Checksum offload enable: 00: Disable checksum offload, 01: + * Enable checksum calculation offload (UL) - For output pipe + * (IPA producer) specifies that checksum trailer is to be added. + * For input pipe (IPA consumer) specifies presence of checksum + * header and IPA checksum calculation accordingly. 10: Enable + * checksum calculation offload (DL) - For output pipe (IPA + * producer) specifies that checksum trailer is to be added. For + * input pipe (IPA consumer) specifies IPA checksum calculation. + * 11: Reserved + * @cs_metadata_hdr_offset: Offset in Words (4 bytes) within header in which + * checksum meta info header (4 bytes) starts (UL). Values are 0-15, which + * mean 0 - 60 byte checksum header offset. Valid for input + * pipes only (IPA consumer) + * @gen_qmb_master_sel: Select bit for ENDP GEN-QMB master. This is used to + * separate DDR & PCIe transactions in-order to limit them as + * a group (using MAX_WRITES/READS limiation). Valid for input and + * output pipes (IPA consumer+producer) + */ +struct ipa_ep_cfg_cfg { + bool frag_offload_en; + enum ipa_cs_offload cs_offload_en; + u8 cs_metadata_hdr_offset; + u8 gen_qmb_master_sel; +}; + +/** + * struct ipa_ep_cfg_metadata_mask - Endpoint initialization hdr metadata mask + * @metadata_mask: Mask specifying which metadata bits to write to + * IPA_ENDP_INIT_HDR_n.s HDR_OFST_METADATA. Only + * masked metadata bits (set to 1) will be written. Valid for Output + * Pipes only (IPA Producer) + */ +struct ipa_ep_cfg_metadata_mask { + u32 metadata_mask; +}; + +/** + * struct ipa_ep_cfg_metadata - Meta Data configuration in IPA end-point + * @md: This defines the meta data from tx data descriptor + * @qmap_id: qmap id + */ +struct ipa_ep_cfg_metadata { + u32 qmap_id; +}; + +/** + * struct ipa_ep_cfg_seq - HPS/DPS sequencer type configuration in IPA end-point + * @set_dynamic: 0 - HPS/DPS seq type is configured statically, + * 1 - HPS/DPS seq type is set to seq_type + * @seq_type: HPS/DPS sequencer type configuration + */ +struct ipa_ep_cfg_seq { + bool set_dynamic; + int seq_type; +}; + +/** + * struct ipa_ep_cfg - configuration of IPA end-point + * @nat: NAT parameters + * @conn_track: IPv6CT parameters + * @hdr: Header parameters + * @hdr_ext: Extended header parameters + * @mode: Mode parameters + * @aggr: Aggregation parameters + * @deaggr: Deaggregation params + * @route: Routing parameters + * @cfg: Configuration register data + * @metadata_mask: Hdr metadata mask + * @meta: Meta Data + * @seq: HPS/DPS sequencers configuration + */ +struct ipa_ep_cfg { + struct ipa_ep_cfg_nat nat; + struct ipa_ep_cfg_conn_track conn_track; + struct ipa_ep_cfg_hdr hdr; + struct ipa_ep_cfg_hdr_ext hdr_ext; + struct ipa_ep_cfg_mode mode; + struct ipa_ep_cfg_aggr aggr; + struct ipa_ep_cfg_deaggr deaggr; + struct ipa_ep_cfg_route route; + struct ipa_ep_cfg_cfg cfg; + struct ipa_ep_cfg_metadata_mask metadata_mask; + struct ipa_ep_cfg_metadata meta; + struct ipa_ep_cfg_seq seq; +}; + +/** + * struct ipa_ep_cfg_ctrl - Control configuration in IPA end-point + * @ipa_ep_suspend: 0 - ENDP is enabled, 1 - ENDP is suspended (disabled). + * Valid for PROD Endpoints + * @ipa_ep_delay: 0 - ENDP is free-running, 1 - ENDP is delayed. + * SW controls the data flow of an endpoint usind this bit. + * Valid for CONS Endpoints + */ +struct ipa_ep_cfg_ctrl { + bool ipa_ep_suspend; + bool ipa_ep_delay; +}; + +/** + * x should be in bytes + */ +#define IPA_NUM_OF_FIFO_DESC(x) (x/sizeof(struct sps_iovec)) +typedef void (*ipa_notify_cb)(void *priv, enum ipa_dp_evt_type evt, + unsigned long data); + +/** + * enum ipa_wdi_meter_evt_type - type of event client callback is + * for AP+STA mode metering + * @IPA_GET_WDI_SAP_STATS: get IPA_stats betwen SAP and STA - + * use ipa_get_wdi_sap_stats structure + * @IPA_SET_WIFI_QUOTA: set quota limit on STA - + * use ipa_set_wifi_quota structure + */ +enum ipa_wdi_meter_evt_type { + IPA_GET_WDI_SAP_STATS, + IPA_SET_WIFI_QUOTA, +}; + +struct ipa_get_wdi_sap_stats { + /* indicate to reset stats after query */ + uint8_t reset_stats; + /* indicate valid stats from wlan-fw */ + uint8_t stats_valid; + /* Tx: SAP->STA */ + uint64_t ipv4_tx_packets; + uint64_t ipv4_tx_bytes; + /* Rx: STA->SAP */ + uint64_t ipv4_rx_packets; + uint64_t ipv4_rx_bytes; + uint64_t ipv6_tx_packets; + uint64_t ipv6_tx_bytes; + uint64_t ipv6_rx_packets; + uint64_t ipv6_rx_bytes; +}; + +/** + * struct ipa_set_wifi_quota - structure used for + * IPA_SET_WIFI_QUOTA. + * + * @quota_bytes: Quota (in bytes) for the STA interface. + * @set_quota: Indicate whether to set the quota (use 1) or + * unset the quota. + * + */ +struct ipa_set_wifi_quota { + uint64_t quota_bytes; + uint8_t set_quota; + /* indicate valid quota set from wlan-fw */ + uint8_t set_valid; +}; + +typedef void (*ipa_wdi_meter_notifier_cb)(enum ipa_wdi_meter_evt_type evt, + void *data); + +/** + * struct ipa_connect_params - low-level client connect input parameters. Either + * client allocates the data and desc FIFO and specifies that in data+desc OR + * specifies sizes and pipe_mem pref and IPA does the allocation. + * + * @ipa_ep_cfg: IPA EP configuration + * @client: type of "client" + * @client_bam_hdl: client SPS handle + * @client_ep_idx: client PER EP index + * @priv: callback cookie + * @notify: callback + * priv - callback cookie evt - type of event data - data relevant + * to event. May not be valid. See event_type enum for valid + * cases. + * @desc_fifo_sz: size of desc FIFO + * @data_fifo_sz: size of data FIFO + * @pipe_mem_preferred: if true, try to alloc the FIFOs in pipe mem, fallback + * to sys mem if pipe mem alloc fails + * @desc: desc FIFO meta-data when client has allocated it + * @data: data FIFO meta-data when client has allocated it + * @skip_ep_cfg: boolean field that determines if EP should be configured + * by IPA driver + * @keep_ipa_awake: when true, IPA will not be clock gated + */ +struct ipa_connect_params { + struct ipa_ep_cfg ipa_ep_cfg; + enum ipa_client_type client; + unsigned long client_bam_hdl; + u32 client_ep_idx; + void *priv; + ipa_notify_cb notify; + u32 desc_fifo_sz; + u32 data_fifo_sz; + bool pipe_mem_preferred; + struct sps_mem_buffer desc; + struct sps_mem_buffer data; + bool skip_ep_cfg; + bool keep_ipa_awake; +}; + +/** + * struct ipa_sps_params - SPS related output parameters resulting from + * low/high level client connect + * @ipa_bam_hdl: IPA SPS handle + * @ipa_ep_idx: IPA PER EP index + * @desc: desc FIFO meta-data + * @data: data FIFO meta-data + */ +struct ipa_sps_params { + unsigned long ipa_bam_hdl; + u32 ipa_ep_idx; + struct sps_mem_buffer desc; + struct sps_mem_buffer data; +}; + +/** + * struct ipa_tx_intf - interface tx properties + * @num_props: number of tx properties + * @prop: the tx properties array + */ +struct ipa_tx_intf { + u32 num_props; + struct ipa_ioc_tx_intf_prop *prop; +}; + +/** + * struct ipa_rx_intf - interface rx properties + * @num_props: number of rx properties + * @prop: the rx properties array + */ +struct ipa_rx_intf { + u32 num_props; + struct ipa_ioc_rx_intf_prop *prop; +}; + +/** + * struct ipa_ext_intf - interface ext properties + * @excp_pipe_valid: is next field valid? + * @excp_pipe: exception packets should be routed to this pipe + * @num_props: number of ext properties + * @prop: the ext properties array + */ +struct ipa_ext_intf { + bool excp_pipe_valid; + enum ipa_client_type excp_pipe; + u32 num_props; + struct ipa_ioc_ext_intf_prop *prop; +}; + +/** + * struct ipa_sys_connect_params - information needed to setup an IPA end-point + * in system-BAM mode + * @ipa_ep_cfg: IPA EP configuration + * @client: the type of client who "owns" the EP + * @desc_fifo_sz: size of desc FIFO. This number is used to allocate the desc + * fifo for BAM. For GSI, this size is used by IPA driver as a + * baseline to calculate the GSI ring size in the following way: + * For PROD pipes, GSI ring is 4 * desc_fifo_sz. + For PROD pipes, GSI ring is 2 * desc_fifo_sz. + * @priv: callback cookie + * @notify: callback + * priv - callback cookie + * evt - type of event + * data - data relevant to event. May not be valid. See event_type + * enum for valid cases. + * @skip_ep_cfg: boolean field that determines if EP should be configured + * by IPA driver + * @keep_ipa_awake: when true, IPA will not be clock gated + * @napi_enabled: when true, IPA call client callback to start polling + */ +struct ipa_sys_connect_params { + struct ipa_ep_cfg ipa_ep_cfg; + enum ipa_client_type client; + u32 desc_fifo_sz; + void *priv; + ipa_notify_cb notify; + bool skip_ep_cfg; + bool keep_ipa_awake; + bool napi_enabled; + bool recycle_enabled; +}; + +/** + * struct ipa_tx_meta - meta-data for the TX packet + * @dma_address: dma mapped address of TX packet + * @dma_address_valid: is above field valid? + */ +struct ipa_tx_meta { + u8 pkt_init_dst_ep; + bool pkt_init_dst_ep_valid; + bool pkt_init_dst_ep_remote; + dma_addr_t dma_address; + bool dma_address_valid; +}; + +/** + * typedef ipa_msg_free_fn - callback function + * @param buff - [in] the message payload to free + * @param len - [in] size of message payload + * @param type - [in] the message type + * + * Message callback registered by kernel client with IPA driver to + * free message payload after IPA driver processing is complete + * + * No return value + */ +typedef void (*ipa_msg_free_fn)(void *buff, u32 len, u32 type); + +/** + * typedef ipa_msg_pull_fn - callback function + * @param buff - [in] where to copy message payload + * @param len - [in] size of buffer to copy payload into + * @param type - [in] the message type + * + * Message callback registered by kernel client with IPA driver for + * IPA driver to pull messages from the kernel client upon demand from + * user-space + * + * Returns how many bytes were copied into the buffer. + */ +typedef int (*ipa_msg_pull_fn)(void *buff, u32 len, u32 type); + +/** + * enum ipa_voltage_level - IPA Voltage levels + */ +enum ipa_voltage_level { + IPA_VOLTAGE_UNSPECIFIED, + IPA_VOLTAGE_SVS = IPA_VOLTAGE_UNSPECIFIED, + IPA_VOLTAGE_NOMINAL, + IPA_VOLTAGE_TURBO, + IPA_VOLTAGE_MAX, +}; + +/** + * enum ipa_rm_event - IPA RM events + * + * Indicate the resource state change + */ +enum ipa_rm_event { + IPA_RM_RESOURCE_GRANTED, + IPA_RM_RESOURCE_RELEASED +}; + +typedef void (*ipa_rm_notify_cb)(void *user_data, + enum ipa_rm_event event, + unsigned long data); +/** + * struct ipa_rm_register_params - information needed to + * register IPA RM client with IPA RM + * + * @user_data: IPA RM client provided information + * to be passed to notify_cb callback below + * @notify_cb: callback which is called by resource + * to notify the IPA RM client about its state + * change IPA RM client is expected to perform non + * blocking operations only in notify_cb and + * release notification context as soon as + * possible. + */ +struct ipa_rm_register_params { + void *user_data; + ipa_rm_notify_cb notify_cb; +}; + +/** + * struct ipa_rm_create_params - information needed to initialize + * the resource + * @name: resource name + * @floor_voltage: floor voltage needed for client to operate in maximum + * bandwidth. + * @reg_params: register parameters, contains are ignored + * for consumer resource NULL should be provided + * for consumer resource + * @request_resource: function which should be called to request resource, + * NULL should be provided for producer resource + * @release_resource: function which should be called to release resource, + * NULL should be provided for producer resource + * + * IPA RM client is expected to perform non blocking operations only + * in request_resource and release_resource functions and + * release notification context as soon as possible. + */ +struct ipa_rm_create_params { + enum ipa_rm_resource_name name; + enum ipa_voltage_level floor_voltage; + struct ipa_rm_register_params reg_params; + int (*request_resource)(void); + int (*release_resource)(void); +}; + +/** + * struct ipa_rm_perf_profile - information regarding IPA RM client performance + * profile + * + * @max_bandwidth_mbps: maximum bandwidth need of the client in Mbps + */ +struct ipa_rm_perf_profile { + u32 max_supported_bandwidth_mbps; +}; + +#define A2_MUX_HDR_NAME_V4_PREF "dmux_hdr_v4_" +#define A2_MUX_HDR_NAME_V6_PREF "dmux_hdr_v6_" + +/** + * enum teth_tethering_mode - Tethering mode (Rmnet / MBIM) + */ +enum teth_tethering_mode { + TETH_TETHERING_MODE_RMNET, + TETH_TETHERING_MODE_MBIM, + TETH_TETHERING_MODE_MAX, +}; + +/** + * teth_bridge_init_params - Parameters used for in/out USB API + * @usb_notify_cb: Callback function which should be used by the caller. + * Output parameter. + * @private_data: Data for the callback function. Should be used by the + * caller. Output parameter. + * @skip_ep_cfg: boolean field that determines if Apps-processor + * should or should not confiugre this end-point. + */ +struct teth_bridge_init_params { + ipa_notify_cb usb_notify_cb; + void *private_data; + enum ipa_client_type client; + bool skip_ep_cfg; +}; + +/** + * struct teth_bridge_connect_params - Parameters used in teth_bridge_connect() + * @ipa_usb_pipe_hdl: IPA to USB pipe handle, returned from ipa_connect() + * @usb_ipa_pipe_hdl: USB to IPA pipe handle, returned from ipa_connect() + * @tethering_mode: Rmnet or MBIM + * @ipa_client_type: IPA "client" name (IPA_CLIENT_USB#_PROD) + */ +struct teth_bridge_connect_params { + u32 ipa_usb_pipe_hdl; + u32 usb_ipa_pipe_hdl; + enum teth_tethering_mode tethering_mode; + enum ipa_client_type client_type; +}; + +/** + * struct ipa_tx_data_desc - information needed + * to send data packet to HW link: link to data descriptors + * priv: client specific private data + * @pyld_buffer: pointer to the data buffer that holds frame + * @pyld_len: length of the data packet + */ +struct ipa_tx_data_desc { + struct list_head link; + void *priv; + void *pyld_buffer; + u16 pyld_len; +}; + +/** + * struct ipa_rx_data - information needed + * to send to wlan driver on receiving data from ipa hw + * @skb: skb + * @dma_addr: DMA address of this Rx packet + */ +struct ipa_rx_data { + struct sk_buff *skb; + dma_addr_t dma_addr; +}; + +/** + * enum ipa_irq_type - IPA Interrupt Type + * Used to register handlers for IPA interrupts + * + * Below enum is a logical mapping and not the actual interrupt bit in HW + */ +enum ipa_irq_type { + IPA_BAD_SNOC_ACCESS_IRQ, + IPA_EOT_COAL_IRQ, + IPA_UC_IRQ_0, + IPA_UC_IRQ_1, + IPA_UC_IRQ_2, + IPA_UC_IRQ_3, + IPA_UC_IN_Q_NOT_EMPTY_IRQ, + IPA_UC_RX_CMD_Q_NOT_FULL_IRQ, + IPA_UC_TX_CMD_Q_NOT_FULL_IRQ, + IPA_UC_TO_PROC_ACK_Q_NOT_FULL_IRQ, + IPA_PROC_TO_UC_ACK_Q_NOT_EMPTY_IRQ, + IPA_RX_ERR_IRQ, + IPA_DEAGGR_ERR_IRQ, + IPA_TX_ERR_IRQ, + IPA_STEP_MODE_IRQ, + IPA_PROC_ERR_IRQ, + IPA_TX_SUSPEND_IRQ, + IPA_TX_HOLB_DROP_IRQ, + IPA_BAM_IDLE_IRQ, + IPA_BAM_GSI_IDLE_IRQ = IPA_BAM_IDLE_IRQ, + IPA_IRQ_MAX +}; + +/** + * struct ipa_tx_suspend_irq_data - interrupt data for IPA_TX_SUSPEND_IRQ + * @endpoints: bitmask of endpoints which case IPA_TX_SUSPEND_IRQ interrupt + * @dma_addr: DMA address of this Rx packet + */ +struct ipa_tx_suspend_irq_data { + u32 endpoints; +}; + + +/** + * typedef ipa_irq_handler_t - irq handler/callback type + * @param ipa_irq_type - [in] interrupt type + * @param private_data - [in, out] the client private data + * @param interrupt_data - [out] interrupt information data + * + * callback registered by ipa_add_interrupt_handler function to + * handle a specific interrupt type + * + * No return value + */ +typedef void (*ipa_irq_handler_t)(enum ipa_irq_type interrupt, + void *private_data, + void *interrupt_data); + +/** + * struct IpaHwBamStats_t - Strucuture holding the BAM statistics + * + * @bamFifoFull : Number of times Bam Fifo got full - For In Ch: Good, + * For Out Ch: Bad + * @bamFifoEmpty : Number of times Bam Fifo got empty - For In Ch: Bad, + * For Out Ch: Good + * @bamFifoUsageHigh : Number of times Bam fifo usage went above 75% - + * For In Ch: Good, For Out Ch: Bad + * @bamFifoUsageLow : Number of times Bam fifo usage went below 25% - + * For In Ch: Bad, For Out Ch: Good +*/ +struct IpaHwBamStats_t { + u32 bamFifoFull; + u32 bamFifoEmpty; + u32 bamFifoUsageHigh; + u32 bamFifoUsageLow; + u32 bamUtilCount; +} __packed; + +/** + * struct IpaHwRingStats_t - Strucuture holding the Ring statistics + * + * @ringFull : Number of times Transfer Ring got full - For In Ch: Good, + * For Out Ch: Bad + * @ringEmpty : Number of times Transfer Ring got empty - For In Ch: Bad, + * For Out Ch: Good + * @ringUsageHigh : Number of times Transfer Ring usage went above 75% - + * For In Ch: Good, For Out Ch: Bad + * @ringUsageLow : Number of times Transfer Ring usage went below 25% - + * For In Ch: Bad, For Out Ch: Good +*/ +struct IpaHwRingStats_t { + u32 ringFull; + u32 ringEmpty; + u32 ringUsageHigh; + u32 ringUsageLow; + u32 RingUtilCount; +} __packed; + +/** + * struct IpaHwStatsWDIRxInfoData_t - Structure holding the WDI Rx channel + * structures + * + * @max_outstanding_pkts : Number of outstanding packets in Rx Ring + * @num_pkts_processed : Number of packets processed - cumulative + * @rx_ring_rp_value : Read pointer last advertized to the WLAN FW + * @rx_ind_ring_stats : Ring info + * @bam_stats : BAM info + * @num_bam_int_handled : Number of Bam Interrupts handled by FW + * @num_db : Number of times the doorbell was rung + * @num_unexpected_db : Number of unexpected doorbells + * @num_pkts_in_dis_uninit_state : number of completions we + * received in disabled or uninitialized state + * @num_ic_inj_vdev_change : Number of times the Imm Cmd is + * injected due to vdev_id change + * @num_ic_inj_fw_desc_change : Number of times the Imm Cmd is + * injected due to fw_desc change + * @num_qmb_int_handled : Number of QMB interrupts handled +*/ +struct IpaHwStatsWDIRxInfoData_t { + u32 max_outstanding_pkts; + u32 num_pkts_processed; + u32 rx_ring_rp_value; + struct IpaHwRingStats_t rx_ind_ring_stats; + struct IpaHwBamStats_t bam_stats; + u32 num_bam_int_handled; + u32 num_db; + u32 num_unexpected_db; + u32 num_pkts_in_dis_uninit_state; + u32 num_ic_inj_vdev_change; + u32 num_ic_inj_fw_desc_change; + u32 num_qmb_int_handled; + u32 reserved1; + u32 reserved2; +} __packed; + +/** + * struct IpaHwStatsWDITxInfoData_t - Structure holding the WDI Tx channel + * structures + * + * @num_pkts_processed : Number of packets processed - cumulative + * @copy_engine_doorbell_value : latest value of doorbell written to copy engine + * @num_db_fired : Number of DB from uC FW to Copy engine + * @tx_comp_ring_stats : ring info + * @bam_stats : BAM info + * @num_db : Number of times the doorbell was rung + * @num_unexpected_db : Number of unexpected doorbells + * @num_bam_int_handled : Number of Bam Interrupts handled by FW + * @num_bam_int_in_non_running_state : Number of Bam interrupts while not in + * Running state + * @num_qmb_int_handled : Number of QMB interrupts handled +*/ +struct IpaHwStatsWDITxInfoData_t { + u32 num_pkts_processed; + u32 copy_engine_doorbell_value; + u32 num_db_fired; + struct IpaHwRingStats_t tx_comp_ring_stats; + struct IpaHwBamStats_t bam_stats; + u32 num_db; + u32 num_unexpected_db; + u32 num_bam_int_handled; + u32 num_bam_int_in_non_runnning_state; + u32 num_qmb_int_handled; + u32 num_bam_int_handled_while_wait_for_bam; +} __packed; + +/** + * struct IpaHwStatsWDIInfoData_t - Structure holding the WDI channel structures + * + * @rx_ch_stats : RX stats + * @tx_ch_stats : TX stats +*/ +struct IpaHwStatsWDIInfoData_t { + struct IpaHwStatsWDIRxInfoData_t rx_ch_stats; + struct IpaHwStatsWDITxInfoData_t tx_ch_stats; +} __packed; + + +/** + * struct ipa_wdi_ul_params - WDI_RX configuration + * @rdy_ring_base_pa: physical address of the base of the Rx ring (containing + * Rx buffers) + * @rdy_ring_size: size of the Rx ring in bytes + * @rdy_ring_rp_pa: physical address of the location through which IPA uc is + * reading (WDI-1.0) + * @rdy_comp_ring_base_pa: physical address of the base of the Rx completion + * ring (WDI-2.0) + * @rdy_comp_ring_wp_pa: physical address of the location through which IPA + * uc is writing (WDI-2.0) + * @rdy_comp_ring_size: size of the Rx_completion ring in bytes + * expected to communicate about the Read pointer into the Rx Ring + */ +struct ipa_wdi_ul_params { + phys_addr_t rdy_ring_base_pa; + u32 rdy_ring_size; + phys_addr_t rdy_ring_rp_pa; + phys_addr_t rdy_comp_ring_base_pa; + phys_addr_t rdy_comp_ring_wp_pa; + u32 rdy_comp_ring_size; + u32 *rdy_ring_rp_va; + u32 *rdy_comp_ring_wp_va; +}; + +/** + * struct ipa_wdi_ul_params_smmu - WDI_RX configuration (with WLAN SMMU) + * @rdy_ring: SG table describing the Rx ring (containing Rx buffers) + * @rdy_ring_size: size of the Rx ring in bytes + * @rdy_ring_rp_pa: physical address of the location through which IPA uc is + * expected to communicate about the Read pointer into the Rx Ring + */ +struct ipa_wdi_ul_params_smmu { + struct sg_table rdy_ring; + u32 rdy_ring_size; + phys_addr_t rdy_ring_rp_pa; + struct sg_table rdy_comp_ring; + phys_addr_t rdy_comp_ring_wp_pa; + u32 rdy_comp_ring_size; + u32 *rdy_ring_rp_va; + u32 *rdy_comp_ring_wp_va; +}; + +/** + * struct ipa_wdi_dl_params - WDI_TX configuration + * @comp_ring_base_pa: physical address of the base of the Tx completion ring + * @comp_ring_size: size of the Tx completion ring in bytes + * @ce_ring_base_pa: physical address of the base of the Copy Engine Source + * Ring + * @ce_door_bell_pa: physical address of the doorbell that the IPA uC has to + * write into to trigger the copy engine + * @ce_ring_size: Copy Engine Ring size in bytes + * @num_tx_buffers: Number of pkt buffers allocated + */ +struct ipa_wdi_dl_params { + phys_addr_t comp_ring_base_pa; + u32 comp_ring_size; + phys_addr_t ce_ring_base_pa; + phys_addr_t ce_door_bell_pa; + u32 ce_ring_size; + u32 num_tx_buffers; +}; + +/** + * struct ipa_wdi_dl_params_smmu - WDI_TX configuration (with WLAN SMMU) + * @comp_ring: SG table describing the Tx completion ring + * @comp_ring_size: size of the Tx completion ring in bytes + * @ce_ring: SG table describing the Copy Engine Source Ring + * @ce_door_bell_pa: physical address of the doorbell that the IPA uC has to + * write into to trigger the copy engine + * @ce_ring_size: Copy Engine Ring size in bytes + * @num_tx_buffers: Number of pkt buffers allocated + */ +struct ipa_wdi_dl_params_smmu { + struct sg_table comp_ring; + u32 comp_ring_size; + struct sg_table ce_ring; + phys_addr_t ce_door_bell_pa; + u32 ce_ring_size; + u32 num_tx_buffers; +}; + +/** + * struct ipa_wdi_in_params - information provided by WDI client + * @sys: IPA EP configuration info + * @ul: WDI_RX configuration info + * @dl: WDI_TX configuration info + * @ul_smmu: WDI_RX configuration info when WLAN uses SMMU + * @dl_smmu: WDI_TX configuration info when WLAN uses SMMU + * @smmu_enabled: true if WLAN uses SMMU + * @ipa_wdi_meter_notifier_cb: Get WDI stats and quato info + */ +struct ipa_wdi_in_params { + struct ipa_sys_connect_params sys; + union { + struct ipa_wdi_ul_params ul; + struct ipa_wdi_dl_params dl; + struct ipa_wdi_ul_params_smmu ul_smmu; + struct ipa_wdi_dl_params_smmu dl_smmu; + } u; + bool smmu_enabled; +#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN + ipa_wdi_meter_notifier_cb wdi_notify; +#endif +}; + +enum ipa_upstream_type { + IPA_UPSTEAM_MODEM = 1, + IPA_UPSTEAM_WLAN, + IPA_UPSTEAM_MAX +}; + +/** + * struct ipa_wdi_out_params - information provided to WDI client + * @uc_door_bell_pa: physical address of IPA uc doorbell + * @clnt_hdl: opaque handle assigned to client + */ +struct ipa_wdi_out_params { + phys_addr_t uc_door_bell_pa; + u32 clnt_hdl; +}; + +/** + * struct ipa_wdi_db_params - information provided to retrieve + * physical address of uC doorbell + * @client: type of "client" (IPA_CLIENT_WLAN#_PROD/CONS) + * @uc_door_bell_pa: physical address of IPA uc doorbell + */ +struct ipa_wdi_db_params { + enum ipa_client_type client; + phys_addr_t uc_door_bell_pa; +}; + +/** + * struct ipa_wdi_uc_ready_params - uC ready CB parameters + * @is_uC_ready: uC loaded or not + * @priv : callback cookie + * @notify: callback + */ +typedef void (*ipa_uc_ready_cb)(void *priv); +struct ipa_wdi_uc_ready_params { + bool is_uC_ready; + void *priv; + ipa_uc_ready_cb notify; +}; + +/** + * struct ipa_wdi_buffer_info - address info of a WLAN allocated buffer + * @pa: physical address of the buffer + * @iova: IOVA of the buffer as embedded inside the WDI descriptors + * @size: size in bytes of the buffer + * @result: result of map or unmap operations (out param) + * + * IPA driver will create/release IOMMU mapping in IPA SMMU from iova->pa + */ +struct ipa_wdi_buffer_info { + phys_addr_t pa; + unsigned long iova; + size_t size; + int result; +}; + +/** + * struct ipa_gsi_ep_config - IPA GSI endpoint configurations + * + * @ipa_ep_num: IPA EP pipe number + * @ipa_gsi_chan_num: GSI channel number + * @ipa_if_tlv: number of IPA_IF TLV + * @ipa_if_aos: number of IPA_IF AOS + * @ee: Execution environment + */ +struct ipa_gsi_ep_config { + int ipa_ep_num; + int ipa_gsi_chan_num; + int ipa_if_tlv; + int ipa_if_aos; + int ee; +}; + +/** + * union ipa_bam_sw_peer_desc - IPA sps sw peer desc + * + * @sw_dsc_ofst: software desc offset + * @sw_ofst_in_desc: offset in desc + * @p_dsc_fifo_peer_ofst: peer desc offset + * @p_bytes_consumed: bytes consumed + */ +union ipa_bam_sw_peer_desc { + struct sw_ofsts_reg { + u32 sw_dsc_ofst:16; + u32 sw_ofst_in_desc:15; + } sw_desc; + + struct evnt_reg { + u32 p_dsc_fifo_peer_ofst:16; + u32 p_bytes_consumed:15; + } peer_desc; + + u32 read_reg; +}; + +#if defined CONFIG_IPA || defined CONFIG_IPA3 + +/* + * Connect / Disconnect + */ +int ipa_connect(const struct ipa_connect_params *in, struct ipa_sps_params *sps, + u32 *clnt_hdl); +int ipa_disconnect(u32 clnt_hdl); + +/* + * Resume / Suspend + */ +int ipa_reset_endpoint(u32 clnt_hdl); + +/* + * Remove ep delay + */ +int ipa_clear_endpoint_delay(u32 clnt_hdl); + +/* + * Disable ep + */ +int ipa_disable_endpoint(u32 clnt_hdl); + +/* + * Configuration + */ +int ipa_cfg_ep(u32 clnt_hdl, const struct ipa_ep_cfg *ipa_ep_cfg); + +int ipa_cfg_ep_nat(u32 clnt_hdl, const struct ipa_ep_cfg_nat *ipa_ep_cfg); + +int ipa_cfg_ep_hdr(u32 clnt_hdl, const struct ipa_ep_cfg_hdr *ipa_ep_cfg); + +int ipa_cfg_ep_hdr_ext(u32 clnt_hdl, + const struct ipa_ep_cfg_hdr_ext *ipa_ep_cfg); + +int ipa_cfg_ep_mode(u32 clnt_hdl, const struct ipa_ep_cfg_mode *ipa_ep_cfg); + +int ipa_cfg_ep_aggr(u32 clnt_hdl, const struct ipa_ep_cfg_aggr *ipa_ep_cfg); + +int ipa_cfg_ep_deaggr(u32 clnt_hdl, + const struct ipa_ep_cfg_deaggr *ipa_ep_cfg); + +int ipa_cfg_ep_route(u32 clnt_hdl, const struct ipa_ep_cfg_route *ipa_ep_cfg); + +int ipa_cfg_ep_holb(u32 clnt_hdl, const struct ipa_ep_cfg_holb *ipa_ep_cfg); + +int ipa_cfg_ep_cfg(u32 clnt_hdl, const struct ipa_ep_cfg_cfg *ipa_ep_cfg); + +int ipa_cfg_ep_metadata_mask(u32 clnt_hdl, const struct ipa_ep_cfg_metadata_mask + *ipa_ep_cfg); + +int ipa_cfg_ep_holb_by_client(enum ipa_client_type client, + const struct ipa_ep_cfg_holb *ipa_ep_cfg); + +int ipa_cfg_ep_ctrl(u32 clnt_hdl, const struct ipa_ep_cfg_ctrl *ep_ctrl); + +/* + * Header removal / addition + */ +int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs); + +int ipa_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool user_only); + +int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls); + +int ipa_commit_hdr(void); + +int ipa_reset_hdr(bool user_only); + +int ipa_get_hdr(struct ipa_ioc_get_hdr *lookup); + +int ipa_put_hdr(u32 hdr_hdl); + +int ipa_copy_hdr(struct ipa_ioc_copy_hdr *copy); + +/* + * Header Processing Context + */ +int ipa_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, + bool user_only); + +int ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls); + +/* + * Routing + */ +int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules); + +int ipa_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, bool user_only); + +int ipa_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls); + +int ipa_commit_rt(enum ipa_ip_type ip); + +int ipa_reset_rt(enum ipa_ip_type ip, bool user_only); + +int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup); + +int ipa_put_rt_tbl(u32 rt_tbl_hdl); + +int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in); + +int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules); + +/* + * Filtering + */ +int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules); + +int ipa_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only); + +int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls); + +int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules); + +int ipa_commit_flt(enum ipa_ip_type ip); + +int ipa_reset_flt(enum ipa_ip_type ip, bool user_only); + +/* + * NAT + */ +int allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem); + +int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init); + +int ipa_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma); + +int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del); + +/* + * Messaging + */ +int ipa_send_msg(struct ipa_msg_meta *meta, void *buff, + ipa_msg_free_fn callback); +int ipa_register_pull_msg(struct ipa_msg_meta *meta, ipa_msg_pull_fn callback); +int ipa_deregister_pull_msg(struct ipa_msg_meta *meta); + +/* + * Interface + */ +int ipa_register_intf(const char *name, const struct ipa_tx_intf *tx, + const struct ipa_rx_intf *rx); +int ipa_register_intf_ext(const char *name, const struct ipa_tx_intf *tx, + const struct ipa_rx_intf *rx, + const struct ipa_ext_intf *ext); +int ipa_deregister_intf(const char *name); + +/* + * Aggregation + */ +int ipa_set_aggr_mode(enum ipa_aggr_mode mode); + +int ipa_set_qcncm_ndp_sig(char sig[3]); + +int ipa_set_single_ndp_per_mbim(bool enable); + +/* + * Data path + */ +int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, + struct ipa_tx_meta *metadata); + +/* + * To transfer multiple data packets + * While passing the data descriptor list, the anchor node + * should be of type struct ipa_tx_data_desc not list_head +*/ +int ipa_tx_dp_mul(enum ipa_client_type dst, + struct ipa_tx_data_desc *data_desc); + +void ipa_free_skb(struct ipa_rx_data *); +int ipa_rx_poll(u32 clnt_hdl, int budget); +void ipa_recycle_wan_skb(struct sk_buff *skb); + +/* + * System pipes + */ +int ipa_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl); + +int ipa_teardown_sys_pipe(u32 clnt_hdl); + +int ipa_connect_wdi_pipe(struct ipa_wdi_in_params *in, + struct ipa_wdi_out_params *out); +int ipa_disconnect_wdi_pipe(u32 clnt_hdl); +int ipa_enable_wdi_pipe(u32 clnt_hdl); +int ipa_disable_wdi_pipe(u32 clnt_hdl); +int ipa_resume_wdi_pipe(u32 clnt_hdl); +int ipa_suspend_wdi_pipe(u32 clnt_hdl); +int ipa_get_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats); +u16 ipa_get_smem_restr_bytes(void); +int ipa_broadcast_wdi_quota_reach_ind(uint32_t fid, + uint64_t num_bytes); + +/* + * To retrieve doorbell physical address of + * wlan pipes + */ +int ipa_uc_wdi_get_dbpa(struct ipa_wdi_db_params *out); + +/* + * To register uC ready callback if uC not ready + * and also check uC readiness + * if uC not ready only, register callback + */ +int ipa_uc_reg_rdyCB(struct ipa_wdi_uc_ready_params *param); +/* + * To de-register uC ready callback + */ +int ipa_uc_dereg_rdyCB(void); + +int ipa_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info); +int ipa_release_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info); + +/* + * Resource manager + */ +int ipa_rm_create_resource(struct ipa_rm_create_params *create_params); + +int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name); + +int ipa_rm_register(enum ipa_rm_resource_name resource_name, + struct ipa_rm_register_params *reg_params); + +int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, + struct ipa_rm_register_params *reg_params); + +int ipa_rm_set_perf_profile(enum ipa_rm_resource_name resource_name, + struct ipa_rm_perf_profile *profile); + +int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name); + +int ipa_rm_add_dependency_sync(enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name); + +int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name); + +int ipa_rm_request_resource(enum ipa_rm_resource_name resource_name); + +int ipa_rm_release_resource(enum ipa_rm_resource_name resource_name); + +int ipa_rm_notify_completion(enum ipa_rm_event event, + enum ipa_rm_resource_name resource_name); + +int ipa_rm_inactivity_timer_init(enum ipa_rm_resource_name resource_name, + unsigned long msecs); + +int ipa_rm_inactivity_timer_destroy(enum ipa_rm_resource_name resource_name); + +int ipa_rm_inactivity_timer_request_resource( + enum ipa_rm_resource_name resource_name); + +int ipa_rm_inactivity_timer_release_resource( + enum ipa_rm_resource_name resource_name); + +/* + * Tethering bridge (Rmnet / MBIM) + */ +int teth_bridge_init(struct teth_bridge_init_params *params); + +int teth_bridge_disconnect(enum ipa_client_type client); + +int teth_bridge_connect(struct teth_bridge_connect_params *connect_params); + +/* + * Tethering client info + */ +void ipa_set_client(int index, enum ipacm_client_enum client, bool uplink); + +enum ipacm_client_enum ipa_get_client(int pipe_idx); + +bool ipa_get_client_uplink(int pipe_idx); + +/* + * IPADMA + */ +int ipa_dma_init(void); + +int ipa_dma_enable(void); + +int ipa_dma_disable(void); + +int ipa_dma_sync_memcpy(u64 dest, u64 src, int len); + +int ipa_dma_async_memcpy(u64 dest, u64 src, int len, + void (*user_cb)(void *user1), void *user_param); + +int ipa_dma_uc_memcpy(phys_addr_t dest, phys_addr_t src, int len); + +void ipa_dma_destroy(void); + +/* + * mux id + */ +int ipa_write_qmap_id(struct ipa_ioc_write_qmapid *param_in); + +/* + * interrupts + */ +int ipa_add_interrupt_handler(enum ipa_irq_type interrupt, + ipa_irq_handler_t handler, + bool deferred_flag, + void *private_data); + +int ipa_remove_interrupt_handler(enum ipa_irq_type interrupt); + +int ipa_restore_suspend_handler(void); + +/* + * Miscellaneous + */ +void ipa_bam_reg_dump(void); + +int ipa_get_ep_mapping(enum ipa_client_type client); + +bool ipa_is_ready(void); + +void ipa_proxy_clk_vote(void); +void ipa_proxy_clk_unvote(void); + +enum ipa_hw_type ipa_get_hw_type(void); + +bool ipa_is_client_handle_valid(u32 clnt_hdl); + +enum ipa_client_type ipa_get_client_mapping(int pipe_idx); + +enum ipa_rm_resource_name ipa_get_rm_resource_from_ep(int pipe_idx); + +bool ipa_get_modem_cfg_emb_pipe_flt(void); + +enum ipa_transport_type ipa_get_transport_type(void); + +struct device *ipa_get_dma_dev(void); +struct iommu_domain *ipa_get_smmu_domain(void); + +int ipa_disable_apps_wan_cons_deaggr(uint32_t agg_size, uint32_t agg_count); + +struct ipa_gsi_ep_config *ipa_get_gsi_ep_info(int ipa_ep_idx); + +int ipa_stop_gsi_channel(u32 clnt_hdl); + +typedef void (*ipa_ready_cb)(void *user_data); + +/** +* ipa_register_ipa_ready_cb() - register a callback to be invoked +* when IPA core driver initialization is complete. +* +* @ipa_ready_cb: CB to be triggered. +* @user_data: Data to be sent to the originator of the CB. +* +* Note: This function is expected to be utilized when ipa_is_ready +* function returns false. +* An IPA client may also use this function directly rather than +* calling ipa_is_ready beforehand, as if this API returns -EEXIST, +* this means IPA initialization is complete (and no callback will +* be triggered). +* When the callback is triggered, the client MUST perform his +* operations in a different context. +* +* The function will return 0 on success, -ENOMEM on memory issues and +* -EEXIST if IPA initialization is complete already. +*/ +int ipa_register_ipa_ready_cb(void (*ipa_ready_cb)(void *user_data), + void *user_data); + +#else /* (CONFIG_IPA || CONFIG_IPA3) */ + +/* + * Connect / Disconnect + */ +static inline int ipa_connect(const struct ipa_connect_params *in, + struct ipa_sps_params *sps, u32 *clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_disconnect(u32 clnt_hdl) +{ + return -EPERM; +} + +/* + * Resume / Suspend + */ +static inline int ipa_reset_endpoint(u32 clnt_hdl) +{ + return -EPERM; +} + +/* + * Remove ep delay + */ +static inline int ipa_clear_endpoint_delay(u32 clnt_hdl) +{ + return -EPERM; +} + +/* + * Disable ep + */ +static inline int ipa_disable_endpoint(u32 clnt_hdl) +{ + return -EPERM; +} + +/* + * Configuration + */ +static inline int ipa_cfg_ep(u32 clnt_hdl, + const struct ipa_ep_cfg *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_nat(u32 clnt_hdl, + const struct ipa_ep_cfg_nat *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_hdr(u32 clnt_hdl, + const struct ipa_ep_cfg_hdr *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_hdr_ext(u32 clnt_hdl, + const struct ipa_ep_cfg_hdr_ext *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_mode(u32 clnt_hdl, + const struct ipa_ep_cfg_mode *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_aggr(u32 clnt_hdl, + const struct ipa_ep_cfg_aggr *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_deaggr(u32 clnt_hdl, + const struct ipa_ep_cfg_deaggr *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_route(u32 clnt_hdl, + const struct ipa_ep_cfg_route *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_holb(u32 clnt_hdl, + const struct ipa_ep_cfg_holb *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_cfg(u32 clnt_hdl, + const struct ipa_ep_cfg_cfg *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_metadata_mask(u32 clnt_hdl, + const struct ipa_ep_cfg_metadata_mask *ipa_ep_cfg) +{ + return -EPERM; +} + +static inline int ipa_cfg_ep_ctrl(u32 clnt_hdl, + const struct ipa_ep_cfg_ctrl *ep_ctrl) +{ + return -EPERM; +} + +/* + * Header removal / addition + */ +static inline int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs) +{ + return -EPERM; +} + +static inline int ipa_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, + bool user_only) +{ + return -EPERM; +} + +static inline int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls) +{ + return -EPERM; +} + +static inline int ipa_commit_hdr(void) +{ + return -EPERM; +} + +static inline int ipa_reset_hdr(bool user_only) +{ + return -EPERM; +} + +static inline int ipa_get_hdr(struct ipa_ioc_get_hdr *lookup) +{ + return -EPERM; +} + +static inline int ipa_put_hdr(u32 hdr_hdl) +{ + return -EPERM; +} + +static inline int ipa_copy_hdr(struct ipa_ioc_copy_hdr *copy) +{ + return -EPERM; +} + +/* + * Header Processing Context + */ +static inline int ipa_add_hdr_proc_ctx( + struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, + bool user_only) +{ + return -EPERM; +} + +static inline int ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +{ + return -EPERM; +} +/* + * Routing + */ +static inline int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules) +{ + return -EPERM; +} + +static inline int ipa_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, + bool user_only) +{ + return -EPERM; +} + +static inline int ipa_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls) +{ + return -EPERM; +} + +static inline int ipa_commit_rt(enum ipa_ip_type ip) +{ + return -EPERM; +} + +static inline int ipa_reset_rt(enum ipa_ip_type ip, bool user_only) +{ + return -EPERM; +} + +static inline int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup) +{ + return -EPERM; +} + +static inline int ipa_put_rt_tbl(u32 rt_tbl_hdl) +{ + return -EPERM; +} + +static inline int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in) +{ + return -EPERM; +} + +static inline int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules) +{ + return -EPERM; +} + +/* + * Filtering + */ +static inline int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) +{ + return -EPERM; +} + +static inline int ipa_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, + bool user_only) +{ + return -EPERM; +} + +static inline int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls) +{ + return -EPERM; +} + +static inline int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules) +{ + return -EPERM; +} + +static inline int ipa_commit_flt(enum ipa_ip_type ip) +{ + return -EPERM; +} + +static inline int ipa_reset_flt(enum ipa_ip_type ip, bool user_only) +{ + return -EPERM; +} + +/* + * NAT + */ +static inline int allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem) +{ + return -EPERM; +} + + +static inline int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) +{ + return -EPERM; +} + + +static inline int ipa_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma) +{ + return -EPERM; +} + + +static inline int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) +{ + return -EPERM; +} + +/* + * Messaging + */ +static inline int ipa_send_msg(struct ipa_msg_meta *meta, void *buff, + ipa_msg_free_fn callback) +{ + return -EPERM; +} + +static inline int ipa_register_pull_msg(struct ipa_msg_meta *meta, + ipa_msg_pull_fn callback) +{ + return -EPERM; +} + +static inline int ipa_deregister_pull_msg(struct ipa_msg_meta *meta) +{ + return -EPERM; +} + +/* + * Interface + */ +static inline int ipa_register_intf(const char *name, + const struct ipa_tx_intf *tx, + const struct ipa_rx_intf *rx) +{ + return -EPERM; +} + +static inline int ipa_register_intf_ext(const char *name, + const struct ipa_tx_intf *tx, + const struct ipa_rx_intf *rx, + const struct ipa_ext_intf *ext) +{ + return -EPERM; +} + +static inline int ipa_deregister_intf(const char *name) +{ + return -EPERM; +} + +/* + * Aggregation + */ +static inline int ipa_set_aggr_mode(enum ipa_aggr_mode mode) +{ + return -EPERM; +} + +static inline int ipa_set_qcncm_ndp_sig(char sig[3]) +{ + return -EPERM; +} + +static inline int ipa_set_single_ndp_per_mbim(bool enable) +{ + return -EPERM; +} + +/* + * Data path + */ +static inline int ipa_tx_dp(enum ipa_client_type dst, struct sk_buff *skb, + struct ipa_tx_meta *metadata) +{ + return -EPERM; +} + +/* + * To transfer multiple data packets + */ +static inline int ipa_tx_dp_mul( + enum ipa_client_type dst, + struct ipa_tx_data_desc *data_desc) +{ + return -EPERM; +} + +static inline void ipa_free_skb(struct ipa_rx_data *rx_in) +{ + return; +} + +static inline int ipa_rx_poll(u32 clnt_hdl, int budget) +{ + return -EPERM; +} + +static inline void ipa_recycle_wan_skb(struct sk_buff *skb) +{ +} + +/* + * System pipes + */ +static inline u16 ipa_get_smem_restr_bytes(void) +{ + return -EPERM; +} + +static inline int ipa_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, + u32 *clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_teardown_sys_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_connect_wdi_pipe(struct ipa_wdi_in_params *in, + struct ipa_wdi_out_params *out) +{ + return -EPERM; +} + +static inline int ipa_disconnect_wdi_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_enable_wdi_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_disable_wdi_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_resume_wdi_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_suspend_wdi_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_broadcast_wdi_quota_reach_ind(uint32_t fid, + uint64_t num_bytes) +{ + return -EPERM; +} + +static inline int ipa_uc_wdi_get_dbpa( + struct ipa_wdi_db_params *out) +{ + return -EPERM; +} + +static inline int ipa_uc_reg_rdyCB( + struct ipa_wdi_uc_ready_params *param) +{ + return -EPERM; +} + +static inline int ipa_uc_dereg_rdyCB(void) +{ + return -EPERM; +} + + +/* + * Resource manager + */ +static inline int ipa_rm_create_resource( + struct ipa_rm_create_params *create_params) +{ + return -EPERM; +} + +static inline int ipa_rm_delete_resource( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_register(enum ipa_rm_resource_name resource_name, + struct ipa_rm_register_params *reg_params) +{ + return -EPERM; +} + +static inline int ipa_rm_set_perf_profile( + enum ipa_rm_resource_name resource_name, + struct ipa_rm_perf_profile *profile) +{ + return -EPERM; +} + +static inline int ipa_rm_deregister(enum ipa_rm_resource_name resource_name, + struct ipa_rm_register_params *reg_params) +{ + return -EPERM; +} + +static inline int ipa_rm_add_dependency( + enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name) +{ + return -EPERM; +} + +static inline int ipa_rm_add_dependency_sync( + enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name) +{ + return -EPERM; +} + +static inline int ipa_rm_delete_dependency( + enum ipa_rm_resource_name resource_name, + enum ipa_rm_resource_name depends_on_name) +{ + return -EPERM; +} + +static inline int ipa_rm_request_resource( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_release_resource( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_notify_completion(enum ipa_rm_event event, + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_inactivity_timer_init( + enum ipa_rm_resource_name resource_name, + unsigned long msecs) +{ + return -EPERM; +} + +static inline int ipa_rm_inactivity_timer_destroy( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_inactivity_timer_request_resource( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +static inline int ipa_rm_inactivity_timer_release_resource( + enum ipa_rm_resource_name resource_name) +{ + return -EPERM; +} + +/* + * Tethering bridge (Rmnet / MBIM) + */ +static inline int teth_bridge_init(struct teth_bridge_init_params *params) +{ + return -EPERM; +} + +static inline int teth_bridge_disconnect(enum ipa_client_type client) +{ + return -EPERM; +} + +static inline int teth_bridge_connect(struct teth_bridge_connect_params + *connect_params) +{ + return -EPERM; +} + +/* + * Tethering client info + */ +static inline void ipa_set_client(int index, enum ipacm_client_enum client, + bool uplink) +{ + return; +} + +static inline enum ipacm_client_enum ipa_get_client(int pipe_idx) +{ + return -EPERM; +} + +static inline bool ipa_get_client_uplink(int pipe_idx) +{ + return -EPERM; +} + +/* + * IPADMA + */ +static inline int ipa_dma_init(void) +{ + return -EPERM; +} + +static inline int ipa_dma_enable(void) +{ + return -EPERM; +} + +static inline int ipa_dma_disable(void) +{ + return -EPERM; +} + +static inline int ipa_dma_sync_memcpy(phys_addr_t dest, phys_addr_t src + , int len) +{ + return -EPERM; +} + +static inline int ipa_dma_async_memcpy(phys_addr_t dest, phys_addr_t src + , int len, void (*user_cb)(void *user1), + void *user_param) +{ + return -EPERM; +} + +static inline int ipa_dma_uc_memcpy(phys_addr_t dest, phys_addr_t src, int len) +{ + return -EPERM; +} + +static inline void ipa_dma_destroy(void) +{ + return; +} + +/* + * mux id + */ +static inline int ipa_write_qmap_id(struct ipa_ioc_write_qmapid *param_in) +{ + return -EPERM; +} + +/* + * interrupts + */ +static inline int ipa_add_interrupt_handler(enum ipa_irq_type interrupt, + ipa_irq_handler_t handler, + bool deferred_flag, + void *private_data) +{ + return -EPERM; +} + +static inline int ipa_remove_interrupt_handler(enum ipa_irq_type interrupt) +{ + return -EPERM; +} + +static inline int ipa_restore_suspend_handler(void) +{ + return -EPERM; +} + +/* + * Miscellaneous + */ +static inline void ipa_bam_reg_dump(void) +{ + return; +} + +static inline int ipa_get_wdi_stats(struct IpaHwStatsWDIInfoData_t *stats) +{ + return -EPERM; +} + +static inline int ipa_get_ep_mapping(enum ipa_client_type client) +{ + return -EPERM; +} + +static inline bool ipa_is_ready(void) +{ + return false; +} + +static inline void ipa_proxy_clk_vote(void) +{ +} + +static inline void ipa_proxy_clk_unvote(void) +{ +} + +static inline enum ipa_hw_type ipa_get_hw_type(void) +{ + return IPA_HW_None; +} + +static inline bool ipa_is_client_handle_valid(u32 clnt_hdl) +{ + return -EINVAL; +} + +static inline enum ipa_client_type ipa_get_client_mapping(int pipe_idx) +{ + return -EINVAL; +} + +static inline enum ipa_rm_resource_name ipa_get_rm_resource_from_ep( + int pipe_idx) +{ + return -EFAULT; +} + +static inline bool ipa_get_modem_cfg_emb_pipe_flt(void) +{ + return -EINVAL; +} + +static inline enum ipa_transport_type ipa_get_transport_type(void) +{ + return -EFAULT; +} + +static inline struct device *ipa_get_dma_dev(void) +{ + return NULL; +} + +static inline struct iommu_domain *ipa_get_smmu_domain(void) +{ + return NULL; +} + +static inline int ipa_create_wdi_mapping(u32 num_buffers, + struct ipa_wdi_buffer_info *info) +{ + return -EINVAL; +} + +static inline int ipa_release_wdi_mapping(u32 num_buffers, + struct ipa_wdi_buffer_info *info) +{ + return -EINVAL; +} + +static inline int ipa_disable_apps_wan_cons_deaggr(void) +{ + return -EINVAL; +} + +static inline struct ipa_gsi_ep_config *ipa_get_gsi_ep_info(int ipa_ep_idx) +{ + return NULL; +} + +static inline int ipa_stop_gsi_channel(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_register_ipa_ready_cb( + void (*ipa_ready_cb)(void *user_data), + void *user_data) +{ + return -EPERM; +} + +#endif /* (CONFIG_IPA || CONFIG_IPA3) */ + +#endif /* _IPA_H_ */ diff --git a/include/linux/ipa_mhi.h b/include/linux/ipa_mhi.h new file mode 100644 index 000000000000..4d3b9747a876 --- /dev/null +++ b/include/linux/ipa_mhi.h @@ -0,0 +1,161 @@ +/* Copyright (c) 2016, 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 IPA_MHI_H_ +#define IPA_MHI_H_ + +#include <linux/ipa.h> +#include <linux/types.h> + +/** + * enum ipa_mhi_event_type - event type for mhi callback + * + * @IPA_MHI_EVENT_READY: IPA MHI is ready and IPA uC is loaded. After getting + * this event MHI client is expected to call to ipa_mhi_start() API + * @IPA_MHI_EVENT_DATA_AVAILABLE: downlink data available on MHI channel + */ +enum ipa_mhi_event_type { + IPA_MHI_EVENT_READY, + IPA_MHI_EVENT_DATA_AVAILABLE, + IPA_MHI_EVENT_MAX, +}; + +typedef void (*mhi_client_cb)(void *priv, enum ipa_mhi_event_type event, + unsigned long data); + +/** + * struct ipa_mhi_msi_info - parameters for MSI (Message Signaled Interrupts) + * @addr_low: MSI lower base physical address + * @addr_hi: MSI higher base physical address + * @data: Data Pattern to use when generating the MSI + * @mask: Mask indicating number of messages assigned by the host to device + * + * msi value is written according to this formula: + * ((data & ~mask) | (mmio.msiVec & mask)) + */ +struct ipa_mhi_msi_info { + u32 addr_low; + u32 addr_hi; + u32 data; + u32 mask; +}; + +/** + * struct ipa_mhi_init_params - parameters for IPA MHI initialization API + * + * @msi: MSI (Message Signaled Interrupts) parameters + * @mmio_addr: MHI MMIO physical address + * @first_ch_idx: First channel ID for hardware accelerated channels. + * @first_er_idx: First event ring ID for hardware accelerated channels. + * @assert_bit40: should assert bit 40 in order to access host space. + * if PCIe iATU is configured then not need to assert bit40 + * @notify: client callback + * @priv: client private data to be provided in client callback + * @test_mode: flag to indicate if IPA MHI is in unit test mode + */ +struct ipa_mhi_init_params { + struct ipa_mhi_msi_info msi; + u32 mmio_addr; + u32 first_ch_idx; + u32 first_er_idx; + bool assert_bit40; + mhi_client_cb notify; + void *priv; + bool test_mode; +}; + +/** + * struct ipa_mhi_start_params - parameters for IPA MHI start API + * + * @host_ctrl_addr: Base address of MHI control data structures + * @host_data_addr: Base address of MHI data buffers + * @channel_context_addr: channel context array address in host address space + * @event_context_addr: event context array address in host address space + */ +struct ipa_mhi_start_params { + u32 host_ctrl_addr; + u32 host_data_addr; + u64 channel_context_array_addr; + u64 event_context_array_addr; +}; + +/** + * struct ipa_mhi_connect_params - parameters for IPA MHI channel connect API + * + * @sys: IPA EP configuration info + * @channel_id: MHI channel id + */ +struct ipa_mhi_connect_params { + struct ipa_sys_connect_params sys; + u8 channel_id; +}; + +/* bit #40 in address should be asserted for MHI transfers over pcie */ +#define IPA_MHI_HOST_ADDR(addr) ((addr) | BIT_ULL(40)) + +#if defined CONFIG_IPA || defined CONFIG_IPA3 + +int ipa_mhi_init(struct ipa_mhi_init_params *params); + +int ipa_mhi_start(struct ipa_mhi_start_params *params); + +int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl); + +int ipa_mhi_disconnect_pipe(u32 clnt_hdl); + +int ipa_mhi_suspend(bool force); + +int ipa_mhi_resume(void); + +void ipa_mhi_destroy(void); + +#else /* (CONFIG_IPA || CONFIG_IPA3) */ + +static inline int ipa_mhi_init(struct ipa_mhi_init_params *params) +{ + return -EPERM; +} + +static inline int ipa_mhi_start(struct ipa_mhi_start_params *params) +{ + return -EPERM; +} + +static inline int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, + u32 *clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_mhi_disconnect_pipe(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_mhi_suspend(bool force) +{ + return -EPERM; +} + +static inline int ipa_mhi_resume(void) +{ + return -EPERM; +} + +static inline void ipa_mhi_destroy(void) +{ + +} + +#endif /* (CONFIG_IPA || CONFIG_IPA3) */ + +#endif /* IPA_MHI_H_ */ diff --git a/include/linux/ipa_odu_bridge.h b/include/linux/ipa_odu_bridge.h new file mode 100644 index 000000000000..5d30a9784998 --- /dev/null +++ b/include/linux/ipa_odu_bridge.h @@ -0,0 +1,84 @@ +/* Copyright (c) 2012-2016, 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 _IPA_ODO_BRIDGE_H_ +#define _IPA_ODO_BRIDGE_H_ + +#include <linux/ipa.h> + +/** + * struct odu_bridge_params - parameters for odu bridge initialization API + * + * @netdev_name: network interface name + * @priv: private data that will be supplied to client's callback + * @tx_dp_notify: callback for handling SKB. the following event are supported: + * IPA_WRITE_DONE: will be called after client called to odu_bridge_tx_dp() + * Client is expected to free the skb. + * IPA_RECEIVE: will be called for delivering skb to APPS. + * Client is expected to deliver the skb to network stack. + * @send_dl_skb: callback for sending skb on downlink direction to adapter. + * Client is expected to free the skb. + * @device_ethaddr: device Ethernet address in network order. + * @ipa_desc_size: IPA Sys Pipe Desc Size + */ +struct odu_bridge_params { + const char *netdev_name; + void *priv; + ipa_notify_cb tx_dp_notify; + int (*send_dl_skb)(void *priv, struct sk_buff *skb); + u8 device_ethaddr[ETH_ALEN]; + u32 ipa_desc_size; +}; + +#if defined CONFIG_IPA || defined CONFIG_IPA3 + +int odu_bridge_init(struct odu_bridge_params *params); + +int odu_bridge_connect(void); + +int odu_bridge_disconnect(void); + +int odu_bridge_tx_dp(struct sk_buff *skb, struct ipa_tx_meta *metadata); + +int odu_bridge_cleanup(void); + +#else + +static inline int odu_bridge_init(struct odu_bridge_params *params) +{ + return -EPERM; +} + +static inline int odu_bridge_disconnect(void) +{ + return -EPERM; +} + +static inline int odu_bridge_connect(void) +{ + return -EPERM; +} + +static inline int odu_bridge_tx_dp(struct sk_buff *skb, + struct ipa_tx_meta *metadata) +{ + return -EPERM; +} + +static inline int odu_bridge_cleanup(void) +{ + return -EPERM; +} + +#endif /* CONFIG_IPA || defined CONFIG_IPA3 */ + +#endif /* _IPA_ODO_BRIDGE_H */ diff --git a/include/linux/ipa_uc_offload.h b/include/linux/ipa_uc_offload.h new file mode 100644 index 000000000000..85d0ce92e6f6 --- /dev/null +++ b/include/linux/ipa_uc_offload.h @@ -0,0 +1,295 @@ +/* Copyright (c) 2016-2017, 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 _IPA_UC_OFFLOAD_H_ +#define _IPA_UC_OFFLOAD_H_ + +#include <linux/ipa.h> + +/** + * enum ipa_uc_offload_proto + * Protocol type: either WDI or Neutrino + * + * @IPA_UC_WDI: wdi Protocol + * @IPA_UC_NTN: Neutrino Protocol + */ +enum ipa_uc_offload_proto { + IPA_UC_INVALID = 0, + IPA_UC_WDI = 1, + IPA_UC_NTN = 2, + IPA_UC_MAX_PROT_SIZE +}; + +/** + * struct ipa_hdr_info - Header to install on IPA HW + * + * @hdr: header to install on IPA HW + * @hdr_len: length of header + * @dst_mac_addr_offset: destination mac address offset + * @hdr_type: layer two header type + */ +struct ipa_hdr_info { + u8 *hdr; + u8 hdr_len; + u8 dst_mac_addr_offset; + enum ipa_hdr_l2_type hdr_type; +}; + +/** + * struct ipa_uc_offload_intf_params - parameters for uC offload + * interface registration + * + * @netdev_name: network interface name + * @notify: callback for exception/embedded packets + * @priv: callback cookie + * @hdr_info: header information + * @meta_data: meta data if any + * @meta_data_mask: meta data mask + * @proto: uC offload protocol type + * @alt_dst_pipe: alternate routing output pipe + */ +struct ipa_uc_offload_intf_params { + const char *netdev_name; + ipa_notify_cb notify; + void *priv; + struct ipa_hdr_info hdr_info[IPA_IP_MAX]; + u8 is_meta_data_valid; + u32 meta_data; + u32 meta_data_mask; + enum ipa_uc_offload_proto proto; + enum ipa_client_type alt_dst_pipe; +}; + +/** + * struct ipa_ntn_setup_info - NTN TX/Rx configuration + * @client: type of "client" (IPA_CLIENT_ODU#_PROD/CONS) + * @ring_base_pa: physical address of the base of the Tx/Rx ring + * @ntn_ring_size: size of the Tx/Rx ring (in terms of elements) + * @buff_pool_base_pa: physical address of the base of the Tx/Rx + * buffer pool + * @num_buffers: Rx/Tx buffer pool size (in terms of elements) + * @data_buff_size: size of the each data buffer allocated in DDR + * @ntn_reg_base_ptr_pa: physical address of the Tx/Rx NTN Ring's + * tail pointer + */ +struct ipa_ntn_setup_info { + enum ipa_client_type client; + phys_addr_t ring_base_pa; + u32 ntn_ring_size; + + phys_addr_t buff_pool_base_pa; + u32 num_buffers; + u32 data_buff_size; + + phys_addr_t ntn_reg_base_ptr_pa; +}; + +/** + * struct ipa_uc_offload_out_params - out parameters for uC offload + * + * @clnt_hndl: Handle that client need to pass during + * further operations + */ +struct ipa_uc_offload_out_params { + u32 clnt_hndl; +}; + +/** + * struct ipa_ntn_conn_in_params - NTN TX/Rx connect parameters + * @ul: parameters to connect UL pipe(from Neutrino to IPA) + * @dl: parameters to connect DL pipe(from IPA to Neutrino) + */ +struct ipa_ntn_conn_in_params { + struct ipa_ntn_setup_info ul; + struct ipa_ntn_setup_info dl; +}; + +/** + * struct ipa_ntn_conn_out_params - information provided + * to uC offload client + * @ul_uc_db_pa: physical address of IPA uc doorbell for UL + * @dl_uc_db_pa: physical address of IPA uc doorbell for DL + * @clnt_hdl: opaque handle assigned to offload client + */ +struct ipa_ntn_conn_out_params { + phys_addr_t ul_uc_db_pa; + phys_addr_t dl_uc_db_pa; +}; + +/** + * struct ipa_uc_offload_conn_in_params - information provided by + * uC offload client + * @clnt_hndl: Handle that return as part of reg interface + * @proto: Protocol to use for offload data path + * @ntn: uC RX/Tx configuration info + */ +struct ipa_uc_offload_conn_in_params { + u32 clnt_hndl; + union { + struct ipa_ntn_conn_in_params ntn; + } u; +}; + +/** + * struct ipa_uc_offload_conn_out_params - information provided + * to uC offload client + * @ul_uc_db_pa: physical address of IPA uc doorbell for UL + * @dl_uc_db_pa: physical address of IPA uc doorbell for DL + * @clnt_hdl: opaque handle assigned to offload client + */ +struct ipa_uc_offload_conn_out_params { + union { + struct ipa_ntn_conn_out_params ntn; + } u; +}; + +/** + * struct ipa_perf_profile - To set BandWidth profile + * + * @client: type of "client" (IPA_CLIENT_ODU#_PROD/CONS) + * @max_supported_bw_mbps: maximum bandwidth needed (in Mbps) + */ +struct ipa_perf_profile { + enum ipa_client_type client; + u32 max_supported_bw_mbps; +}; + +/** + * struct ipa_uc_ready_params - uC ready CB parameters + * @is_uC_ready: uC loaded or not + * @priv : callback cookie + * @notify: callback + * @proto: uC offload protocol type + */ +struct ipa_uc_ready_params { + bool is_uC_ready; + void *priv; + ipa_uc_ready_cb notify; + enum ipa_uc_offload_proto proto; +}; + +#if defined CONFIG_IPA || defined CONFIG_IPA3 + +/** + * ipa_uc_offload_reg_intf - Client should call this function to + * init uC offload data path + * + * @init: [in] initialization parameters + * + * Note: Should not be called from atomic context and only + * after checking IPA readiness using ipa_register_ipa_ready_cb() + * + * @Return 0 on success, negative on failure + */ +int ipa_uc_offload_reg_intf( + struct ipa_uc_offload_intf_params *in, + struct ipa_uc_offload_out_params *out); + +/** + * ipa_uc_offload_cleanup - Client Driver should call this + * function before unload and after disconnect + * + * @Return 0 on success, negative on failure + */ +int ipa_uc_offload_cleanup(u32 clnt_hdl); + +/** + * ipa_uc_offload_conn_pipes - Client should call this + * function to connect uC pipe for offload data path + * + * @in: [in] input parameters from client + * @out: [out] output params to client + * + * Note: Should not be called from atomic context and only + * after checking IPA readiness using ipa_register_ipa_ready_cb() + * + * @Return 0 on success, negative on failure + */ +int ipa_uc_offload_conn_pipes(struct ipa_uc_offload_conn_in_params *in, + struct ipa_uc_offload_conn_out_params *out); + +/** + * ipa_uc_offload_disconn_pipes() - Client should call this + * function to disconnect uC pipe to disable offload data path + * @clnt_hdl: [in] opaque client handle assigned by IPA to client + * + * Note: Should not be called from atomic context + * + * Returns: 0 on success, negative on failure + */ +int ipa_uc_offload_disconn_pipes(u32 clnt_hdl); + +/** + * ipa_set_perf_profile() - Client should call this function to + * set IPA clock Band Width based on data rates + * @profile: [in] BandWidth profile to use + * + * Returns: 0 on success, negative on failure + */ +int ipa_set_perf_profile(struct ipa_perf_profile *profile); + + +/* + * To register uC ready callback if uC not ready + * and also check uC readiness + * if uC not ready only, register callback + */ +int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *param); + +/* + * To de-register uC ready callback + */ +void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto); + +#else /* (CONFIG_IPA || CONFIG_IPA3) */ + +static inline int ipa_uc_offload_reg_intf( + struct ipa_uc_offload_intf_params *in, + struct ipa_uc_offload_out_params *out) +{ + return -EPERM; +} + +static inline int ipa_uC_offload_cleanup(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_uc_offload_conn_pipes( + struct ipa_uc_offload_conn_in_params *in, + struct ipa_uc_offload_conn_out_params *out) +{ + return -EPERM; +} + +static inline int ipa_uc_offload_disconn_pipes(u32 clnt_hdl) +{ + return -EPERM; +} + +static inline int ipa_set_perf_profile(struct ipa_perf_profile *profile) +{ + return -EPERM; +} + +static inline int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *param) +{ + return -EPERM; +} + +static void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto) +{ +} + +#endif /* CONFIG_IPA3 */ + +#endif /* _IPA_UC_OFFLOAD_H_ */ diff --git a/include/linux/ipa_usb.h b/include/linux/ipa_usb.h new file mode 100644 index 000000000000..de1163348c05 --- /dev/null +++ b/include/linux/ipa_usb.h @@ -0,0 +1,333 @@ +/* Copyright (c) 2012-2016, 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 _IPA_USB_H_ +#define _IPA_USB_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_MAX_TETH_PROT_SIZE +}; + +/** + * 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_HIGH_SPEED_512B = 512, + IPA_USB_SUPER_SPEED_1024B = 1024 +}; + +/** + * 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: high speed or full speed + * @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 + * + * @client: type of "client" + * @ipa_ep_cfg: IPA EP configuration + * @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_ring_base_addr: physical base address of transfer ring. Address must be + * aligned to xfer_ring_len rounded to power of two + * @xfer_scratch: parameters for xDCI channel scratch + * @xfer_ring_base_addr_iova: IO virtual address mapped to xfer_ring_base_addr + * @data_buff_base_len: length of data buffer allocated by USB driver + * @data_buff_base_addr: physical base address for the data buffer (where TRBs + * points) + * @data_buff_base_addr_iova: IO virtual address mapped to data_buff_base_addr + * + */ +struct ipa_usb_xdci_chan_params { + /* IPA EP params */ + enum ipa_client_type client; + struct ipa_ep_cfg ipa_ep_cfg; + 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 gsi_chan_dir dir; + u16 xfer_ring_len; + u64 xfer_ring_base_addr; + struct ipa_usb_xdci_chan_scratch xfer_scratch; + u64 xfer_ring_base_addr_iova; + u32 data_buff_base_len; + u64 data_buff_base_addr; + u64 data_buff_base_addr_iova; +}; + +/** + * 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; +}; + +#ifdef CONFIG_IPA3 + +/** + * ipa_usb_init_teth_prot - Peripheral should call this function to initialize + * RNDIS/ECM/teth_bridge/DPL, prior to calling ipa_usb_xdci_connect() + * + * @usb_teth_type: tethering protocol type + * @teth_params: pointer to tethering protocol parameters. + * Should be struct ipa_usb_teth_params for RNDIS/ECM, + * or NULL for teth_bridge + * @ipa_usb_notify_cb: will be called to notify USB driver on certain events + * @user_data: cookie used for ipa_usb_notify_cb + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_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); + +/** + * ipa_usb_xdci_connect - Peripheral should call this function to start IN & + * OUT xDCI channels, and connect RNDIS/ECM/MBIM/RMNET. + * For DPL, only starts IN channel. + * + * @ul_chan_params: parameters for allocating UL xDCI channel. containing + * required info on event and transfer rings, and IPA EP + * configuration + * @ul_out_params: [out] opaque client handle assigned by IPA to client & DB + * registers physical address for UL channel + * @dl_chan_params: parameters for allocating DL xDCI channel. containing + * required info on event and transfer rings, and IPA EP + * configuration + * @dl_out_params: [out] opaque client handle assigned by IPA to client & DB + * registers physical address for DL channel + * @connect_params: handles and scratch params of the required channels, + * tethering protocol and the tethering protocol parameters. + * + * Note: Should not be called from atomic context + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_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); + +/** + * ipa_usb_xdci_disconnect - Peripheral should call this function to stop + * IN & OUT xDCI channels + * For DPL, only stops IN channel. + * + * @ul_clnt_hdl: client handle received from ipa_usb_xdci_connect() + * for OUT channel + * @dl_clnt_hdl: client handle received from ipa_usb_xdci_connect() + * for IN channel + * @teth_prot: tethering protocol + * + * Note: Should not be called from atomic context + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot); + +/** + * ipa_usb_deinit_teth_prot - Peripheral should call this function to deinit + * RNDIS/ECM/MBIM/RMNET + * + * @teth_prot: tethering protocol + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot); + +/** + * ipa_usb_xdci_suspend - Peripheral should call this function to suspend + * IN & OUT or DPL xDCI channels + * + * @ul_clnt_hdl: client handle previously obtained from + * ipa_usb_xdci_connect() for OUT channel + * @dl_clnt_hdl: client handle previously obtained from + * ipa_usb_xdci_connect() for IN channel + * @teth_prot: tethering protocol + * @with_remote_wakeup: Does host support remote wakeup? + * + * Note: Should not be called from atomic context + * Note: for DPL, the ul will be ignored as irrelevant + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot, + bool with_remote_wakeup); + +/** + * ipa_usb_xdci_resume - Peripheral should call this function to resume + * IN & OUT or DPL xDCI channels + * + * @ul_clnt_hdl: client handle received from ipa_usb_xdci_connect() + * for OUT channel + * @dl_clnt_hdl: client handle received from ipa_usb_xdci_connect() + * for IN channel + * @teth_prot: tethering protocol + * + * Note: Should not be called from atomic context + * Note: for DPL, the ul will be ignored as irrelevant + * + * @Return 0 on success, negative on failure + */ +int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot); + +#else /* CONFIG_IPA3 */ + +static inline int ipa_usb_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) +{ + return -EPERM; +} + +static inline int ipa_usb_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) +{ + return -EPERM; +} + +static inline int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot) +{ + return -EPERM; +} + +static inline int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) +{ + return -EPERM; +} + +static inline int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot, + bool with_remote_wakeup) +{ + return -EPERM; +} + +static inline int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl, + enum ipa_usb_teth_prot teth_prot) +{ + return -EPERM; +} + + +#endif /* CONFIG_IPA3 */ + +#endif /* _IPA_USB_H_ */ diff --git a/include/linux/ipc_logging.h b/include/linux/ipc_logging.h new file mode 100644 index 000000000000..f6bf9b1a0505 --- /dev/null +++ b/include/linux/ipc_logging.h @@ -0,0 +1,291 @@ +/* Copyright (c) 2012-2015, 2018, 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 _IPC_LOGGING_H +#define _IPC_LOGGING_H + +#include <linux/types.h> +#include <linux/errno.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 defined(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 + * @user_version : Version number of user-defined message formats + * + * returns context id on success, NULL on failure + */ +void *ipc_log_context_create(int max_num_pages, const char *modname, + uint16_t user_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_int32_write: Writes a 32-bit integer value + * + * @ectxt: Context initialized by calling msg_encode_start() + * @n: Integer to write + */ +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); + +/* + * msg_encode_end: Complete the message encode process + * + * @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_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 + */ +void tsv_byte_array_read(struct encode_context *ectxt, + struct decode_context *dctxt, const char *format); + +/* + * add_deserialization_func: Register a deserialization function to + * 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); + +#else + +static inline void *ipc_log_context_create(int max_num_pages, + const char *modname, uint16_t user_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 diff --git a/include/linux/ipc_router.h b/include/linux/ipc_router.h new file mode 100644 index 000000000000..94f779f6a666 --- /dev/null +++ b/include/linux/ipc_router.h @@ -0,0 +1,357 @@ +/* Copyright (c) 2012-2015,2017 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 _IPC_ROUTER_H +#define _IPC_ROUTER_H + +#include <linux/types.h> +#include <linux/socket.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/pm.h> +#include <linux/msm_ipc.h> +#include <linux/device.h> +#include <linux/kref.h> + +/* Maximum Wakeup Source Name Size */ +#define MAX_WS_NAME_SZ 32 + +#define IPC_RTR_ERR(buf, ...) \ + pr_err("IPC_RTR: " buf, __VA_ARGS__) + +/** + * enum msm_ipc_router_event - Events that will be generated by IPC Router + */ +enum msm_ipc_router_event { + IPC_ROUTER_CTRL_CMD_DATA = 1, + IPC_ROUTER_CTRL_CMD_HELLO, + IPC_ROUTER_CTRL_CMD_BYE, + IPC_ROUTER_CTRL_CMD_NEW_SERVER, + IPC_ROUTER_CTRL_CMD_REMOVE_SERVER, + IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT, + IPC_ROUTER_CTRL_CMD_RESUME_TX, +}; + +/** + * rr_control_msg - Control message structure + * @cmd: Command identifier for HELLO message in Version 1. + * @hello: Message structure for HELLO message in Version 2. + * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. + * @cli: Message structure for REMOVE_CLIENT event. + */ +union rr_control_msg { + uint32_t cmd; + struct { + uint32_t cmd; + uint32_t checksum; + uint32_t versions; + uint32_t capability; + uint32_t reserved; + } hello; + struct { + uint32_t cmd; + uint32_t service; + uint32_t instance; + uint32_t node_id; + uint32_t port_id; + } srv; + struct { + uint32_t cmd; + uint32_t node_id; + uint32_t port_id; + } cli; +}; + +struct comm_mode_info { + int mode; + void *xprt_info; +}; + +enum ipc_rtr_af_event_type { + IPCRTR_AF_INIT = 1, + IPCRTR_AF_DEINIT, +}; + +/** + * msm_ipc_port - Definition of IPC Router port + * @list: List(local/control ports) in which this port is present. + * @ref: Reference count for this port. + * @this_port: Contains port's node_id and port_id information. + * @port_name: Contains service & instance info if the port hosts a service. + * @type: Type of the port - Client, Service, Control or Security Config. + * @flags: Flags to identify the port state. + * @port_lock_lhc3: Lock to protect access to the port information. + * @mode_info: Communication mode of the port owner. + * @port_rx_q: Receive queue where incoming messages are queued. + * @port_rx_q_lock_lhc3: Lock to protect access to the port's rx_q. + * @rx_ws_name: Name of the receive wakeup source. + * @port_rx_ws: Wakeup source to prevent suspend until the rx_q is empty. + * @port_rx_wait_q: Wait queue to wait for the incoming messages. + * @restart_state: Flag to hold the restart state information. + * @restart_lock: Lock to protect access to the restart_state. + * @restart_wait: Wait Queue to wait for any restart events. + * @endpoint: Contains the information related to user-space interface. + * @notify: Function to notify the incoming events on the port. + * @check_send_permissions: Function to check access control from this port. + * @num_tx: Number of packets transmitted. + * @num_rx: Number of packets received. + * @num_tx_bytes: Number of bytes transmitted. + * @num_rx_bytes: Number of bytes received. + * @priv: Private information registered by the port owner. + */ +struct msm_ipc_port { + struct list_head list; + struct kref ref; + + struct msm_ipc_port_addr this_port; + struct msm_ipc_port_name port_name; + uint32_t type; + unsigned flags; + struct mutex port_lock_lhc3; + struct comm_mode_info mode_info; + + struct msm_ipc_port_addr dest_addr; + int conn_status; + + struct list_head port_rx_q; + struct mutex port_rx_q_lock_lhc3; + char rx_ws_name[MAX_WS_NAME_SZ]; + struct wakeup_source *port_rx_ws; + wait_queue_head_t port_rx_wait_q; + wait_queue_head_t port_tx_wait_q; + + int restart_state; + spinlock_t restart_lock; + wait_queue_head_t restart_wait; + + void *rport_info; + void *endpoint; + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv); + int (*check_send_permissions)(void *data); + + uint32_t num_tx; + uint32_t num_rx; + unsigned long num_tx_bytes; + unsigned long num_rx_bytes; + uint32_t last_served_svc_id; + void *priv; +}; + +#ifdef CONFIG_IPC_ROUTER +/** + * msm_ipc_router_create_port() - Create a IPC Router port/endpoint + * @notify: Callback function to notify any event on the port. + * @event: Event ID to be handled. + * @oob_data: Any out-of-band data associated with the event. + * @oob_data_len: Size of the out-of-band data, if valid. + * @priv: Private data registered during the port creation. + * @priv: Private info to be passed while the notification is generated. + * + * @return: Pointer to the port on success, NULL on error. + */ +struct msm_ipc_port *msm_ipc_router_create_port( + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv), + void *priv); + +/** + * msm_ipc_router_bind_control_port() - Bind a port as a control port + * @port_ptr: Port which needs to be marked as a control port. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_lookup_server_name() - Resolve server address + * @srv_name: Name<service:instance> of the server to be resolved. + * @srv_info: Buffer to hold the resolved address. + * @num_entries_in_array: Number of server info the buffer can hold. + * @lookup_mask: Mask to specify the range of instances to be resolved. + * + * @return: Number of server addresses resolved on success, < 0 on error. + */ +int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, + struct msm_ipc_server_info *srv_info, + int num_entries_in_array, + uint32_t lookup_mask); + +/** + * msm_ipc_router_send_msg() - Send a message/packet + * @src: Sender's address/port. + * @dest: Destination address. + * @data: Pointer to the data to be sent. + * @data_len: Length of the data to be sent. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_send_msg(struct msm_ipc_port *src, + struct msm_ipc_addr *dest, + void *data, unsigned int data_len); + +/** + * msm_ipc_router_get_curr_pkt_size() - Get the packet size of the first + * packet in the rx queue + * @port_ptr: Port which owns the rx queue. + * + * @return: Returns the size of the first packet, if available. + * 0 if no packets available, < 0 on error. + */ +int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_read_msg() - Read a message/packet + * @port_ptr: Receiver's port/address. + * @data: Pointer containing the address of the received data. + * @src: Address of the sender/source. + * @len: Length of the data being read. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, + struct msm_ipc_addr *src, + unsigned char **data, + unsigned int *len); + +/** + * msm_ipc_router_close_port() - Close the port + * @port_ptr: Pointer to the port to be closed. + * + * @return: 0 on success, < 0 on error. + */ +int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr); + +/** + * msm_ipc_router_register_server() - Register a service on a port + * @server_port: IPC Router port with which a service is registered. + * @name: Service name <service_id:instance_id> that gets registered. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_register_server(struct msm_ipc_port *server_port, + struct msm_ipc_addr *name); + +/** + * msm_ipc_router_unregister_server() - Unregister a service from a port + * @server_port: Port with with a service is already registered. + * + * @return: 0 on success, standard Linux error codes on error. + */ +int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port); + +/** + * register_ipcrtr_af_init_notifier() - Register for ipc router socket + * address family initialization callback + * @nb: Notifier block which will be notified once address family is + * initialized. + * + * Return: 0 on success, standard error code otherwise. + */ +int register_ipcrtr_af_init_notifier(struct notifier_block *nb); + +/** + * unregister_ipcrtr_af_init_notifier() - Unregister for ipc router socket + * address family initialization callback + * @nb: Notifier block which will be notified once address family is + * initialized. + * + * Return: 0 on success, standard error code otherwise. + */ +int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb); + +/** + * msm_ipc_router_set_ws_allowed() - To Enable/disable the wakeup source allowed + * flag + * @flag: Flag to set/clear the wakeup soruce allowed + * + */ +void msm_ipc_router_set_ws_allowed(bool flag); + +#else + +struct msm_ipc_port *msm_ipc_router_create_port( + void (*notify)(unsigned event, void *oob_data, + size_t oob_data_len, void *priv), + void *priv) +{ + return NULL; +} + +static inline int msm_ipc_router_bind_control_port( + struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, + struct msm_ipc_server_info *srv_info, + int num_entries_in_array, + uint32_t lookup_mask) +{ + return -ENODEV; +} + +int msm_ipc_router_send_msg(struct msm_ipc_port *src, + struct msm_ipc_addr *dest, + void *data, unsigned int data_len) +{ + return -ENODEV; +} + +int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, + struct msm_ipc_addr *src, + unsigned char **data, + unsigned int *len) +{ + return -ENODEV; +} + +int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr) +{ + return -ENODEV; +} + +static inline int msm_ipc_router_register_server( + struct msm_ipc_port *server_port, + struct msm_ipc_addr *name) +{ + return -ENODEV; +} + +static inline int msm_ipc_router_unregister_server( + struct msm_ipc_port *server_port) +{ + return -ENODEV; +} + +int register_ipcrtr_af_init_notifier(struct notifier_block *nb) +{ + return -ENODEV; +} + +int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb) +{ + return -ENODEV; +} + +void msm_ipc_router_set_ws_allowed(bool flag) { } + +#endif + +#endif diff --git a/include/linux/ipc_router_xprt.h b/include/linux/ipc_router_xprt.h new file mode 100644 index 000000000000..ac6c1e4db8a4 --- /dev/null +++ b/include/linux/ipc_router_xprt.h @@ -0,0 +1,178 @@ +/* Copyright (c) 2011-2015,2017 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 _IPC_ROUTER_XPRT_H +#define _IPC_ROUTER_XPRT_H + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/platform_device.h> +#include <linux/msm_ipc.h> +#include <linux/ipc_router.h> +#include <linux/kref.h> + +#define IPC_ROUTER_XPRT_EVENT_DATA 1 +#define IPC_ROUTER_XPRT_EVENT_OPEN 2 +#define IPC_ROUTER_XPRT_EVENT_CLOSE 3 + +#define FRAG_PKT_WRITE_ENABLE 0x1 + +/** + * rr_header_v1 - IPC Router header version 1 + * @version: Version information. + * @type: IPC Router Message Type. + * @src_node_id: Source Node ID of the message. + * @src_port_id: Source Port ID of the message. + * @control_flag: Flag to indicate flow control. + * @size: Size of the IPC Router payload. + * @dst_node_id: Destination Node ID of the message. + * @dst_port_id: Destination Port ID of the message. + */ +struct rr_header_v1 { + uint32_t version; + uint32_t type; + uint32_t src_node_id; + uint32_t src_port_id; + uint32_t control_flag; + uint32_t size; + uint32_t dst_node_id; + uint32_t dst_port_id; +}; + +/** + * rr_header_v2 - IPC Router header version 2 + * @version: Version information. + * @type: IPC Router Message Type. + * @control_flag: Flags to indicate flow control, optional header etc. + * @opt_len: Combined size of the all optional headers in units of words. + * @size: Size of the IPC Router payload. + * @src_node_id: Source Node ID of the message. + * @src_port_id: Source Port ID of the message. + * @dst_node_id: Destination Node ID of the message. + * @dst_port_id: Destination Port ID of the message. + */ +struct rr_header_v2 { + uint8_t version; + uint8_t type; + uint8_t control_flag; + uint8_t opt_len; + uint32_t size; + uint16_t src_node_id; + uint16_t src_port_id; + uint16_t dst_node_id; + uint16_t dst_port_id; +} __attribute__((__packed__)); + +union rr_header { + struct rr_header_v1 hdr_v1; + struct rr_header_v2 hdr_v2; +}; + +/** + * rr_opt_hdr - Optional header for IPC Router header version 2 + * @len: Total length of the optional header. + * @data: Pointer to the actual optional header. + */ +struct rr_opt_hdr { + size_t len; + unsigned char *data; +}; + +#define IPC_ROUTER_HDR_SIZE sizeof(union rr_header) +#define IPCR_WORD_SIZE 4 + +/** + * rr_packet - Router to Router packet structure + * @list: Pointer to prev & next packets in a port's rx list. + * @hdr: Header information extracted from or prepended to a packet. + * @opt_hdr: Optinal header information. + * @pkt_fragment_q: Queue of SKBs containing payload. + * @length: Length of data in the chain of SKBs + * @ref: Reference count for the packet. + * @ws_need: Flag to check wakeup soruce need + */ +struct rr_packet { + struct list_head list; + struct rr_header_v1 hdr; + struct rr_opt_hdr opt_hdr; + struct sk_buff_head *pkt_fragment_q; + uint32_t length; + struct kref ref; + bool ws_need; +}; + +/** + * msm_ipc_router_xprt - Structure to hold XPRT specific information + * @name: Name of the XPRT. + * @link_id: Network cluster ID to which the XPRT belongs to. + * @priv: XPRT's private data. + * @get_version: Method to get header version supported by the XPRT. + * @set_version: Method to set header version in XPRT. + * @get_option: Method to get XPRT specific options. + * @read_avail: Method to get data size available to be read from the XPRT. + * @read: Method to read data from the XPRT. + * @write_avail: Method to get write space available in the XPRT. + * @write: Method to write data to the XPRT. + * @close: Method to close the XPRT. + * @sft_close_done: Method to indicate to the XPRT that handling of reset + * event is complete. + * @get_ws_info: Method to get the wakeup soruce inforamtion of the XPRT + */ +struct msm_ipc_router_xprt { + char *name; + uint32_t link_id; + void *priv; + + int (*get_version)(struct msm_ipc_router_xprt *xprt); + int (*get_option)(struct msm_ipc_router_xprt *xprt); + void (*set_version)(struct msm_ipc_router_xprt *xprt, + unsigned version); + int (*read_avail)(struct msm_ipc_router_xprt *xprt); + int (*read)(void *data, uint32_t len, + struct msm_ipc_router_xprt *xprt); + int (*write_avail)(struct msm_ipc_router_xprt *xprt); + int (*write)(void *data, uint32_t len, + struct msm_ipc_router_xprt *xprt); + int (*close)(struct msm_ipc_router_xprt *xprt); + void (*sft_close_done)(struct msm_ipc_router_xprt *xprt); + bool (*get_ws_info)(struct msm_ipc_router_xprt *xprt); +}; + +void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt, + unsigned event, + void *data); + +/** + * create_pkt() - Create a Router packet + * @data: SKB queue to be contained inside the packet. + * + * @return: pointer to packet on success, NULL on failure. + */ +struct rr_packet *create_pkt(struct sk_buff_head *data); +struct rr_packet *clone_pkt(struct rr_packet *pkt); +void release_pkt(struct rr_packet *pkt); + +/** + * ipc_router_peek_pkt_size() - Peek into the packet header to get potential packet size + * @data: Starting address of the packet which points to router header. + * + * @returns: potential packet size on success, < 0 on error. + * + * This function is used by the underlying transport abstraction layer to + * peek into the potential packet size of an incoming packet. This information + * is used to perform link layer fragmentation and re-assembly + */ +int ipc_router_peek_pkt_size(char *data); + +#endif diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e4e22ed3fc0c..454fa09de1c7 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -53,16 +53,19 @@ struct ipv6_devconf { __s32 mc_forwarding; #endif __s32 disable_ipv6; + __s32 drop_unicast_in_l2_multicast; __s32 accept_dad; __s32 force_tllao; __s32 ndisc_notify; __s32 suppress_frag_ndisc; __s32 accept_ra_mtu; + __s32 drop_unsolicited_na; struct ipv6_stable_secret { bool initialized; struct in6_addr secret; } stable_secret; __s32 use_oif_addrs_only; + __s32 accept_ra_prefix_route; void *sysctl; }; diff --git a/include/linux/irq.h b/include/linux/irq.h index f7cade00c525..8da001eb82aa 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -73,6 +73,7 @@ enum irqchip_irq_state; * it from the spurious interrupt detection * mechanism and from core side polling. * IRQ_DISABLE_UNLAZY - Disable lazy irq disable + * IRQ_AFFINITY_MANAGED - Affinity is auto-managed by the kernel */ enum { IRQ_TYPE_NONE = 0x00000000, @@ -99,13 +100,14 @@ enum { IRQ_PER_CPU_DEVID = (1 << 17), IRQ_IS_POLLED = (1 << 18), IRQ_DISABLE_UNLAZY = (1 << 19), + IRQ_AFFINITY_MANAGED = (1 << 21), }; #define IRQF_MODIFY_MASK \ (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ - IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY) + IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_AFFINITY_MANAGED) #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) @@ -191,6 +193,7 @@ struct irq_data { * IRQD_IRQ_INPROGRESS - In progress state of the interrupt * IRQD_WAKEUP_ARMED - Wakeup mode armed * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU + * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel */ enum { IRQD_TRIGGER_MASK = 0xf, @@ -206,6 +209,7 @@ enum { IRQD_IRQ_INPROGRESS = (1 << 18), IRQD_WAKEUP_ARMED = (1 << 19), IRQD_FORWARDED_TO_VCPU = (1 << 20), + IRQD_AFFINITY_MANAGED = (1 << 21), }; #define __irqd_to_state(d) ((d)->common->state_use_accessors) @@ -299,6 +303,11 @@ static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d) __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU; } +static inline bool irqd_affinity_is_managed(struct irq_data *d) +{ + return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED; +} + static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) { return d->hwirq; @@ -464,15 +473,15 @@ static inline int irq_set_parent(int irq, int parent_irq) * Built-in IRQ handlers for various IRQ types, * callable via desc->handle_irq() */ -extern void handle_level_irq(struct irq_desc *desc); -extern void handle_fasteoi_irq(struct irq_desc *desc); -extern void handle_edge_irq(struct irq_desc *desc); -extern void handle_edge_eoi_irq(struct irq_desc *desc); -extern void handle_simple_irq(struct irq_desc *desc); -extern void handle_percpu_irq(struct irq_desc *desc); -extern void handle_percpu_devid_irq(struct irq_desc *desc); -extern void handle_bad_irq(struct irq_desc *desc); -extern void handle_nested_irq(unsigned int irq); +extern bool handle_level_irq(struct irq_desc *desc); +extern bool handle_fasteoi_irq(struct irq_desc *desc); +extern bool handle_edge_irq(struct irq_desc *desc); +extern bool handle_edge_eoi_irq(struct irq_desc *desc); +extern bool handle_simple_irq(struct irq_desc *desc); +extern bool handle_percpu_irq(struct irq_desc *desc); +extern bool handle_percpu_devid_irq(struct irq_desc *desc); +extern bool handle_bad_irq(struct irq_desc *desc); +extern bool handle_nested_irq(unsigned int irq); extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index bae69e5d693c..77c08b4c72c1 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -100,6 +100,11 @@ struct device_node; +extern struct irq_chip gic_arch_extn; + +void gic_set_irqchip_flags(unsigned long flags); +void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, + u32 offset, struct device_node *); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); int gic_cpu_if_down(unsigned int gic_nr); diff --git a/include/linux/irqchip/msm-gpio-irq.h b/include/linux/irqchip/msm-gpio-irq.h new file mode 100644 index 000000000000..f57279424038 --- /dev/null +++ b/include/linux/irqchip/msm-gpio-irq.h @@ -0,0 +1,51 @@ +/* Copyright (c) 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 MSM_GPIO_IRQ_H +#define MSM_GPIO_IRQ_H + +#include <linux/irq.h> + +#if (defined(CONFIG_GPIO_MSM_V1) || defined(CONFIG_GPIO_MSM_V2) \ + || defined(CONFIG_GPIO_MSM_V3) && !defined(CONFIG_USE_PINCTRL_IRQ)) +int __init msm_gpio_of_init(struct device_node *node, + struct device_node *parent); +extern struct irq_chip msm_gpio_irq_extn; +static inline int __init msm_tlmm_of_irq_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#elif defined(CONFIG_PINCTRL_MSM_TLMM) +int __init msm_tlmm_of_irq_init(struct device_node *node, + struct device_node *parent); +extern struct irq_chip mpm_tlmm_irq_extn; +static inline int __init msm_gpio_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#else +extern struct irq_chip mpm_pinctrl_extn; +static inline int __init msm_tlmm_of_irq_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} + +static inline int __init msm_gpio_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/irqchip/msm-mpm-irq.h b/include/linux/irqchip/msm-mpm-irq.h new file mode 100644 index 000000000000..118153ee8c8b --- /dev/null +++ b/include/linux/irqchip/msm-mpm-irq.h @@ -0,0 +1,167 @@ +/* Copyright (c) 2010-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 __MSM_MPM_IRQ_H +#define __MSM_MPM_IRQ_H + +#include <linux/types.h> +#include <linux/list.h> + +#define MSM_MPM_NR_MPM_IRQS 64 + +#if defined(CONFIG_MSM_MPM_OF) +/** + * msm_mpm_enable_pin() - Enable/Disable a MPM pin for idle wakeups. + * + * @pin: MPM pin to set + * @enable: enable/disable the pin + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure MPM pins for wakeup from idle low + * power modes. The API provides a direct access to the configuring MPM pins + * that are not connected to a IRQ/GPIO + */ +int msm_mpm_enable_pin(unsigned int pin, unsigned int enable); + +/** + * msm_mpm_set_pin_wake() - Enable/Disable a MPM pin during suspend + * + * @pin: MPM pin to set + * @enable: enable/disable the pin as wakeup + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure MPM pins for wakeup from suspend + * low power modes. The API provides a direct access to the configuring MPM pins + * that are not connected to a IRQ/GPIO + */ +int msm_mpm_set_pin_wake(unsigned int pin, unsigned int on); +/** + * msm_mpm_set_pin_type() - Set the flowtype of a MPM pin. + * + * @pin: MPM pin to configure + * @flow_type: flowtype of the MPM pin. + * + * returns 0 on success or errorno + * + * Drivers can call the function to configure the flowtype of the MPM pins + * The API provides a direct access to the configuring MPM pins that are not + * connected to a IRQ/GPIO + */ +int msm_mpm_set_pin_type(unsigned int pin, unsigned int flow_type); +/** + * msm_mpm_irqs_detectable() - Check if active irqs can be monitored by MPM + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * returns true if all active interrupts can be monitored by the MPM + * + * Low power management code calls into this API to check if all active + * interrupts can be monitored by MPM and choose a level such that all active + * interrupts can wake the system up from low power mode. + */ +bool msm_mpm_irqs_detectable(bool from_idle); +/** + * msm_mpm_gpio_detectable() - Check if active gpio irqs can be monitored by + * MPM + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * returns true if all active GPIO interrupts can be monitored by the MPM + * + * Low power management code calls into this API to check if all active + * GPIO interrupts can be monitored by MPM and choose a level such that all + * active interrupts can wake the system up from low power mode. + */ +bool msm_mpm_gpio_irqs_detectable(bool from_idle); +/** + * msm_mpm_enter_sleep() -Called from PM code before entering low power mode + * + * @sclk_count: wakeup time in sclk counts for programmed RPM wakeup + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * @cpumask: the next cpu to wakeup. + * + * Low power management code calls into this API to configure the MPM to + * monitor the active irqs before going to sleep. + */ +void msm_mpm_enter_sleep(uint64_t sclk_count, bool from_idle, + const struct cpumask *cpumask); +/** + * msm_mpm_exit_sleep() -Called from PM code after resuming from low power mode + * + * @from_idle: indicates if the sytem is entering low power mode as a part of + * suspend/idle task. + * + * Low power management code calls into this API to query the MPM for the + * wakeup source and retriggering the appropriate interrupt. + */ +void msm_mpm_exit_sleep(bool from_idle); +/** + * of_mpm_init() - Device tree initialization function + * + * The initialization function is called after * GPIO/GIC device initialization + * routines are called and before any device irqs are requested. MPM driver + * keeps track of all enabled/wakeup interrupts in the system to be able to + * configure MPM when entering a system wide low power mode. The MPM is a + * alway-on low power hardware block that monitors 64 wakeup interrupts when the + * system is in a low power mode. The initialization function constructs the MPM + * mapping between the IRQs and the MPM pin based on data in the device tree. + */ +void of_mpm_init(void); +#else +static inline int msm_mpm_enable_irq(unsigned int irq, unsigned int enable) +{ return -ENODEV; } +static inline int msm_mpm_set_irq_wake(unsigned int irq, unsigned int on) +{ return -ENODEV; } +static inline int msm_mpm_set_irq_type(unsigned int irq, unsigned int flow_type) +{ return -ENODEV; } +static inline int msm_mpm_enable_pin(unsigned int pin, unsigned int enable) +{ return -ENODEV; } +static inline int msm_mpm_set_pin_wake(unsigned int pin, unsigned int on) +{ return -ENODEV; } +static inline int msm_mpm_set_pin_type(unsigned int pin, + unsigned int flow_type) +{ return -ENODEV; } +static inline bool msm_mpm_irqs_detectable(bool from_idle) +{ return false; } +static inline bool msm_mpm_gpio_irqs_detectable(bool from_idle) +{ return false; } +static inline void msm_mpm_enter_sleep(uint64_t sclk_count, bool from_idle, + const struct cpumask *cpumask) {} +static inline void msm_mpm_exit_sleep(bool from_idle) {} +static inline void of_mpm_init(void) {} +#endif +#ifdef CONFIG_MSM_MPM_OF +/** msm_mpm_suspend_prepare() - Called at prepare_late() op during suspend + * + * + * When called the MPM driver checks if the wakeup interrupts can be monitored + * by MPM hardware and program them accordingly. If wake up interrupts cannot + * be monitored then it disallows system low power modes. + */ +void msm_mpm_suspend_prepare(void); +/** msm_mpm_suspend_wake - Called during wake() op in suspend. + * + * When called MPM drivers sets the vote for system low power modes depending + * on the active interrupts. + */ +void msm_mpm_suspend_wake(void); +#else +static inline void msm_mpm_suspend_prepare(void) {} +static inline void msm_mpm_suspend_wake(void) {} +#endif +#endif /* __MSM_MPM_IRQ_H */ diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index a587a33363c7..50b55bdfe0bd 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -135,9 +135,9 @@ static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc) * Architectures call this to let the generic IRQ layer * handle an interrupt. */ -static inline void generic_handle_irq_desc(struct irq_desc *desc) +static inline bool generic_handle_irq_desc(struct irq_desc *desc) { - desc->handle_irq(desc); + return desc->handle_irq(desc); } int generic_handle_irq(unsigned int irq); diff --git a/include/linux/irqhandler.h b/include/linux/irqhandler.h index 661bed0ed1f3..b31ab4b59c16 100644 --- a/include/linux/irqhandler.h +++ b/include/linux/irqhandler.h @@ -8,7 +8,7 @@ struct irq_desc; struct irq_data; -typedef void (*irq_flow_handler_t)(struct irq_desc *desc); +typedef bool (*irq_flow_handler_t)(struct irq_desc *desc); typedef void (*irq_preflow_handler_t)(struct irq_data *data); #endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 05b63a1e9f84..3098b65177a3 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -605,6 +605,9 @@ do { \ * let gcc optimize the rest. */ +#ifdef CONFIG_DISABLE_TRACE_PRINTK +#define trace_printk pr_debug +#else #define trace_printk(fmt, ...) \ do { \ char _______STR[] = __stringify((__VA_ARGS__)); \ @@ -627,6 +630,7 @@ do { \ else \ __trace_printk(_THIS_IP_, fmt, ##args); \ } while (0) +#endif extern __printf(2, 3) int __trace_bprintk(unsigned long ip, const char *fmt, ...); diff --git a/include/linux/kobject.h b/include/linux/kobject.h index d9d4485ebad2..fe8f6408ec5b 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -29,7 +29,7 @@ #include <linux/workqueue.h> #define UEVENT_HELPER_PATH_LEN 256 -#define UEVENT_NUM_ENVP 32 /* number of env pointers */ +#define UEVENT_NUM_ENVP 64 /* number of env pointers */ #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ #ifdef CONFIG_UEVENT_HELPER diff --git a/include/linux/kref.h b/include/linux/kref.h index e2df6d397ff0..edbc8f653c10 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h @@ -19,6 +19,7 @@ #include <linux/atomic.h> #include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/spinlock.h> struct kref { atomic_t refcount; @@ -103,6 +104,38 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) return kref_sub(kref, 1, release); } +/** + * kref_put_spinlock_irqsave - decrement refcount for object. + * @kref: object. + * @release: pointer to the function that will clean up the object when the + * last reference to the object is released. + * This pointer is required, and it is not acceptable to pass kfree + * in as this function. + * @lock: lock to take in release case + * + * Behaves identical to kref_put with one exception. If the reference count + * drops to zero, the lock will be taken atomically wrt dropping the reference + * count. The release function has to call spin_unlock() without _irqrestore. + */ +static inline int kref_put_spinlock_irqsave(struct kref *kref, + void (*release)(struct kref *kref), + spinlock_t *lock) +{ + unsigned long flags; + + WARN_ON(release == NULL); + if (atomic_add_unless(&kref->refcount, -1, 1)) + return 0; + spin_lock_irqsave(lock, flags); + if (atomic_dec_and_test(&kref->refcount)) { + release(kref); + local_irq_restore(flags); + return 1; + } + spin_unlock_irqrestore(lock, flags); + return 0; +} + static inline int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *lock) diff --git a/include/linux/ksm.h b/include/linux/ksm.h index 7ae216a39c9e..481c8c4627ca 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h @@ -43,8 +43,7 @@ static inline struct stable_node *page_stable_node(struct page *page) static inline void set_page_stable_node(struct page *page, struct stable_node *stable_node) { - page->mapping = (void *)stable_node + - (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); + page->mapping = (void *)((unsigned long)stable_node | PAGE_MAPPING_KSM); } /* diff --git a/include/linux/leds-qpnp-flash-v2.h b/include/linux/leds-qpnp-flash-v2.h new file mode 100644 index 000000000000..1ae77e2e277b --- /dev/null +++ b/include/linux/leds-qpnp-flash-v2.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2016, 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. 1 + */ + +#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 diff --git a/include/linux/leds-qpnp-flash.h b/include/linux/leds-qpnp-flash.h new file mode 100644 index 000000000000..e3b9cf148cbd --- /dev/null +++ b/include/linux/leds-qpnp-flash.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2016-2018, 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 __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_CURRENT BIT(2) + +#define FLASH_LED_PREPARE_OPTIONS_MASK GENMASK(3, 0) + +#if (defined CONFIG_LEDS_QPNP_FLASH || defined CONFIG_LEDS_QPNP_FLASH_V2) +extern 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 +#endif diff --git a/include/linux/leds-qpnp-wled.h b/include/linux/leds-qpnp-wled.h new file mode 100644 index 000000000000..6880bc41394c --- /dev/null +++ b/include/linux/leds-qpnp-wled.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2014, 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 __LEDS_QPNP_WLED_H + +#ifdef CONFIG_LEDS_QPNP_WLED +int qpnp_ibb_enable(bool state); +#else +int qpnp_ibb_enable(bool state) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/leds.h b/include/linux/leds.h index fa359c79c825..197b61500ab7 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -35,6 +35,7 @@ struct led_classdev { const char *name; enum led_brightness brightness; enum led_brightness max_brightness; + enum led_brightness usr_brightness_req; int flags; /* Lower 16 bits reflect status */ @@ -48,6 +49,7 @@ struct led_classdev { #define SET_BRIGHTNESS_ASYNC (1 << 21) #define SET_BRIGHTNESS_SYNC (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) +#define LED_KEEP_TRIGGER (1 << 24) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ diff --git a/include/linux/list.h b/include/linux/list.h index 993395a2e55c..d5750f2f1c36 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -28,27 +28,42 @@ static inline void INIT_LIST_HEAD(struct list_head *list) list->prev = list; } +#ifdef CONFIG_DEBUG_LIST +extern bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next); +extern bool __list_del_entry_valid(struct list_head *entry); +#else +static inline bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + return true; +} +static inline bool __list_del_entry_valid(struct list_head *entry) +{ + return true; +} +#endif + /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { + if (!__list_add_valid(new, prev, next)) + return; + next->prev = new; new->next = next; new->prev = prev; prev->next = new; } -#else -extern void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next); -#endif /** * list_add - add a new entry @@ -96,22 +111,20 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_del_entry(struct list_head *entry) { + if (!__list_del_entry_valid(entry)) + return; + __list_del(entry->prev, entry->next); } static inline void list_del(struct list_head *entry) { - __list_del(entry->prev, entry->next); + __list_del_entry(entry); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } -#else -extern void __list_del_entry(struct list_head *entry); -extern void list_del(struct list_head *entry); -#endif /** * list_replace - replace old entry by new one diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index ec3a6bab29de..cf4832db2b29 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1384,6 +1384,8 @@ union security_list_options { size_t *len); int (*inode_create)(struct inode *dir, struct dentry *dentry, umode_t mode); + int (*inode_post_create)(struct inode *dir, struct dentry *dentry, + umode_t mode); int (*inode_link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); int (*inode_unlink)(struct inode *dir, struct dentry *dentry); @@ -1440,6 +1442,7 @@ union security_list_options { struct fown_struct *fown, int sig); int (*file_receive)(struct file *file); int (*file_open)(struct file *file, const struct cred *cred); + int (*file_close)(struct file *file); int (*task_create)(unsigned long clone_flags); void (*task_free)(struct task_struct *task); @@ -1666,6 +1669,7 @@ struct security_hook_heads { struct list_head inode_free_security; struct list_head inode_init_security; struct list_head inode_create; + struct list_head inode_post_create; struct list_head inode_link; struct list_head inode_unlink; struct list_head inode_symlink; @@ -1702,6 +1706,7 @@ struct security_hook_heads { struct list_head file_send_sigiotask; struct list_head file_receive; struct list_head file_open; + struct list_head file_close; struct list_head task_create; struct list_head task_free; struct list_head cred_alloc_blank; diff --git a/include/linux/mdio.h b/include/linux/mdio.h index b42963bc81dd..a0d6dadd787e 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -11,6 +11,53 @@ #include <uapi/linux/mdio.h> +struct mdio_device { + struct device dev; + + const struct dev_pm_ops *pm_ops; + struct mii_bus *bus; + + int (*bus_match)(struct device *dev, struct device_driver *drv); + void (*device_free)(struct mdio_device *mdiodev); + void (*device_remove)(struct mdio_device *mdiodev); + + /* Bus address of the MDIO device (0-31) */ + int addr; + int flags; +}; +#define to_mdio_device(d) container_of(d, struct mdio_device, dev) + +/* struct mdio_driver_common: Common to all MDIO drivers */ +struct mdio_driver_common { + struct device_driver driver; + int flags; +}; +#define MDIO_DEVICE_FLAG_PHY 1 +#define to_mdio_common_driver(d) \ + container_of(d, struct mdio_driver_common, driver) + +/* struct mdio_driver: Generic MDIO driver */ +struct mdio_driver { + struct mdio_driver_common mdiodrv; + + /* + * Called during discovery. Used to set + * up device-specific structures, if any + */ + int (*probe)(struct mdio_device *mdiodev); + + /* Clears up any memory if needed */ + void (*remove)(struct mdio_device *mdiodev); +}; +#define to_mdio_driver(d) \ + container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv) + +void mdio_device_free(struct mdio_device *mdiodev); +struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr); +int mdio_device_register(struct mdio_device *mdiodev); +void mdio_device_remove(struct mdio_device *mdiodev); +int mdio_driver_register(struct mdio_driver *drv); +void mdio_driver_unregister(struct mdio_driver *drv); static inline bool mdio_phy_id_is_c45(int phy_id) { diff --git a/include/linux/mdss_io_util.h b/include/linux/mdss_io_util.h new file mode 100644 index 000000000000..3cca007e618c --- /dev/null +++ b/include/linux/mdss_io_util.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2012, 2016-2017, 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 __MDSS_IO_UTIL_H__ +#define __MDSS_IO_UTIL_H__ + +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/i2c.h> +#include <linux/types.h> + +#ifdef DEBUG +#define DEV_DBG(fmt, args...) pr_err(fmt, ##args) +#else +#define DEV_DBG(fmt, args...) pr_debug(fmt, ##args) +#endif +#define DEV_INFO(fmt, args...) pr_info(fmt, ##args) +#define DEV_WARN(fmt, args...) pr_warn(fmt, ##args) +#define DEV_ERR(fmt, args...) pr_err(fmt, ##args) + +struct dss_io_data { + u32 len; + void __iomem *base; +}; + +void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug); +u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug); +void dss_reg_dump(void __iomem *base, u32 len, const char *prefix, u32 debug); + +#define DSS_REG_W_ND(io, offset, val) dss_reg_w(io, offset, val, false) +#define DSS_REG_W(io, offset, val) dss_reg_w(io, offset, val, true) +#define DSS_REG_R_ND(io, offset) dss_reg_r(io, offset, false) +#define DSS_REG_R(io, offset) dss_reg_r(io, offset, true) + +enum dss_vreg_type { + DSS_REG_LDO, + DSS_REG_VS, +}; + +struct dss_vreg { + struct regulator *vreg; /* vreg handle */ + char vreg_name[32]; + int min_voltage; + int max_voltage; + int enable_load; + int disable_load; + int pre_on_sleep; + int post_on_sleep; + int pre_off_sleep; + int post_off_sleep; + bool lp_disable_allowed; + bool disabled; +}; + +struct dss_gpio { + unsigned gpio; + unsigned value; + char gpio_name[32]; +}; + +enum dss_clk_type { + DSS_CLK_AHB, /* no set rate. rate controlled through rpm */ + DSS_CLK_PCLK, + DSS_CLK_OTHER, +}; + +struct dss_clk { + struct clk *clk; /* clk handle */ + char clk_name[32]; + enum dss_clk_type type; + unsigned long rate; + unsigned long max_rate; +}; + +struct dss_module_power { + unsigned num_vreg; + struct dss_vreg *vreg_config; + unsigned num_gpio; + struct dss_gpio *gpio_config; + unsigned num_clk; + struct dss_clk *clk_config; +}; + +int msm_dss_ioremap_byname(struct platform_device *pdev, + struct dss_io_data *io_data, const char *name); +void msm_dss_iounmap(struct dss_io_data *io_data); + +int msm_dss_enable_gpio(struct dss_gpio *in_gpio, int num_gpio, int enable); +int msm_dss_gpio_enable(struct dss_gpio *in_gpio, int num_gpio, int enable); + +int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg, + int num_vreg, int config); +int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable); + +int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk); +void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk); +int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk); +int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable); + +int mdss_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr, + uint8_t reg_offset, uint8_t *read_buf); +int mdss_i2c_byte_write(struct i2c_client *client, uint8_t slave_addr, + uint8_t reg_offset, uint8_t *value); + +#endif /* __MDSS_IO_UTIL_H__ */ diff --git a/include/linux/mdss_smmu_ext.h b/include/linux/mdss_smmu_ext.h new file mode 100644 index 000000000000..12ad4305f145 --- /dev/null +++ b/include/linux/mdss_smmu_ext.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2017, 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 MDSS_SMMU_EXT_H +#define MDSS_SMMU_EXT_H + +/** + * struct msm_smmu:interface exposed to the clients which use smmu driver. + * @dev: smmu device for attach/dettach + * @domain: domain for the context bank. + * @is_secure: bool variable to check for secure domain. + * @iommu_ctrl: iommu ctrl function for enable/disable attach. + * @secure_session_ctrl: ctrl function for enable/disable session. + * @wait_for_transition:function to wait till secure transtion is complete. + * @reg_lock /reg_unlock: Lock to access shared registers. + */ +struct mdss_smmu_intf { + struct device *dev; + int domain; + bool is_secure; + int (*iommu_ctrl)(int); + int (*secure_session_ctrl)(int); + int (*wait_for_transition)(int state, int request); + void (*reg_lock)(void); + void (*reg_unlock)(void); + bool (*handoff_pending)(void); +}; + +typedef void (*msm_smmu_handler_t) (struct mdss_smmu_intf *smmu); + +/** + * mdss_smmu_request_mappings: function to request smmu mappings. + * Client driver can request smmu dev via this API. + * dev will be returned in the same call context + * if probe is not finished then dev will be + * returned once it is completed. + * @callback: callback function that is called to return smmu + * dev + */ + +int mdss_smmu_request_mappings(msm_smmu_handler_t callback); + +#endif /* MDSS_SMMU_EXT_H */ diff --git a/include/linux/memblock.h b/include/linux/memblock.h index f88a536f8069..d3f41bfe05f1 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -84,7 +84,10 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); +int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); ulong choose_memblock_flags(void); +unsigned long memblock_region_resize_late_begin(void); +void memblock_region_resize_late_end(unsigned long); /* Low level functions */ int memblock_add_range(struct memblock_type *type, @@ -328,6 +331,7 @@ void memblock_enforce_memory_limit(phys_addr_t memory_limit); int memblock_is_memory(phys_addr_t addr); int memblock_is_map_memory(phys_addr_t addr); int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); +bool memblock_overlaps_memory(phys_addr_t base, phys_addr_t size); int memblock_is_reserved(phys_addr_t addr); bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); @@ -399,6 +403,11 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \ region++) +#define for_each_memblock_rev(memblock_type, region) \ + for (region = memblock.memblock_type.regions + \ + memblock.memblock_type.cnt - 1; \ + region >= memblock.memblock_type.regions; \ + region--) #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK #define __init_memblock __meminit diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 538488bd1d3d..ba23995e51b4 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -89,7 +89,7 @@ extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, unsigned long *valid_start, unsigned long *valid_end); extern void __offline_isolated_pages(unsigned long, unsigned long); -typedef void (*online_page_callback_t)(struct page *page); +typedef int (*online_page_callback_t)(struct page *page); extern int set_online_page_callback(online_page_callback_t callback); extern int restore_online_page_callback(online_page_callback_t callback); diff --git a/include/linux/mfd/msm-cdc-pinctrl.h b/include/linux/mfd/msm-cdc-pinctrl.h new file mode 100644 index 000000000000..951b8d4d1ed9 --- /dev/null +++ b/include/linux/mfd/msm-cdc-pinctrl.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2016, 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 __MFD_CDC_PINCTRL_H_ +#define __MFD_CDC_PINCTRL_H_ + +#include <linux/types.h> +#include <linux/of.h> + +#ifdef CONFIG_MSM_CDC_PINCTRL +extern int msm_cdc_pinctrl_select_sleep_state(struct device_node *); +extern int msm_cdc_pinctrl_select_active_state(struct device_node *); +extern bool msm_cdc_pinctrl_get_state(struct device_node *); +extern int msm_cdc_get_gpio_state(struct device_node *); + +#else +int msm_cdc_pinctrl_select_sleep_state(struct device_node *np) +{ + return 0; +} +int msm_cdc_pinctrl_select_active_state(struct device_node *np) +{ + return 0; +} +int msm_cdc_get_gpio_state(struct device_node *np) +{ + return 0; +} +# +#endif + +#endif diff --git a/include/linux/mfd/msm-cdc-supply.h b/include/linux/mfd/msm-cdc-supply.h new file mode 100644 index 000000000000..b40f44b1f12f --- /dev/null +++ b/include/linux/mfd/msm-cdc-supply.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2016, 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 __CODEC_POWER_SUPPLY_H__ +#define __CODEC_POWER_SUPPLY_H__ + +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/regulator/consumer.h> + +struct cdc_regulator { + const char *name; + int min_uV; + int max_uV; + int optimum_uA; + bool ondemand; + struct regulator *regulator; +}; + +extern int msm_cdc_get_power_supplies(struct device *dev, + struct cdc_regulator **cdc_vreg, + int *total_num_supplies); +extern int msm_cdc_disable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_release_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_enable_static_supplies(struct device *dev, + struct regulator_bulk_data *supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +extern int msm_cdc_init_supplies(struct device *dev, + struct regulator_bulk_data **supplies, + struct cdc_regulator *cdc_vreg, + int num_supplies); +#endif diff --git a/include/linux/mfd/wcd9335/registers.h b/include/linux/mfd/wcd9335/registers.h new file mode 100755 index 000000000000..c50430d4278f --- /dev/null +++ b/include/linux/mfd/wcd9335/registers.h @@ -0,0 +1,1348 @@ +/* + * Copyright (c) 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 _WCD9335_REGISTERS_H +#define _WCD9335_REGISTERS_H + +#define WCD9335_PAGE_SIZE 256 +#define WCD9335_NUM_PAGES 256 + +extern const u8 *wcd9335_reg[WCD9335_NUM_PAGES]; + +enum { + PAGE_0 = 0, + PAGE_1, + PAGE_2, + PAGE_6 = 6, + PAGE_10 = 0xA, + PAGE_11, + PAGE_12, + PAGE_13, + PAGE_0X80, +}; + +/* Page-0 Registers */ +#define WCD9335_PAGE0_PAGE_REGISTER 0x0000 +#define WCD9335_CODEC_RPM_CLK_BYPASS 0x0001 +#define WCD9335_CODEC_RPM_CLK_GATE 0x0002 +#define WCD9335_CODEC_RPM_CLK_MCLK_CFG 0x0003 +#define WCD9335_CODEC_RPM_RST_CTL 0x0009 +#define WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL 0x0011 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_1 0x0012 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_2 0x0013 +#define WCD9335_CODEC_RPM_PWR_CPE_DEEPSLP_3 0x0014 +#define WCD9335_CODEC_RPM_PWR_CPE_IRAM_SHUTDOWN 0x0015 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM1_SHUTDOWN 0x0016 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_1 0x0017 +#define WCD9335_CODEC_RPM_PWR_CPE_DRAM0_SHUTDOWN_2 0x0018 +#define WCD9335_CODEC_RPM_INT_MASK 0x001d +#define WCD9335_CODEC_RPM_INT_STATUS 0x001e +#define WCD9335_CODEC_RPM_INT_CLEAR 0x001f +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0 0x0021 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE1 0x0022 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2 0x0023 +#define WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE3 0x0024 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_CTL 0x0025 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_TEST0 0x0026 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_TEST1 0x0027 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0 0x0029 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 0x002a +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 0x002b +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT3 0x002c +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT4 0x002d +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT5 0x002e +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT6 0x002f +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT7 0x0030 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT8 0x0031 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT9 0x0032 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10 0x0033 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11 0x0034 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT12 0x0035 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT13 0x0036 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT14 0x0037 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT15 0x0038 +#define WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS 0x0039 +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO 0x003a +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 0x003b +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 0x003c +#define WCD9335_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 0x003d +#define WCD9335_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL 0x003e +#define WCD9335_CHIP_TIER_CTRL_I2C_ACTIVE 0x003f +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CTL 0x0041 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_STATUS 0x0042 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_MSB 0x0043 +#define WCD9335_CHIP_TIER_CTRL_PROC1_MON_CNT_LSB 0x0044 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CTL 0x0045 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_STATUS 0x0046 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_MSB 0x0047 +#define WCD9335_CHIP_TIER_CTRL_PROC2_MON_CNT_LSB 0x0048 +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CTL 0x0049 +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_STATUS 0x004a +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_MSB 0x004b +#define WCD9335_CHIP_TIER_CTRL_PROC3_MON_CNT_LSB 0x004c +#define WCD9335_DATA_HUB_DATA_HUB_RX_I2S_CTL 0x0051 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_CTL 0x0052 +#define WCD9335_DATA_HUB_DATA_HUB_I2S_CLK 0x0053 +#define WCD9335_DATA_HUB_DATA_HUB_RX0_INP_CFG 0x0054 +#define WCD9335_DATA_HUB_DATA_HUB_RX1_INP_CFG 0x0055 +#define WCD9335_DATA_HUB_DATA_HUB_RX2_INP_CFG 0x0056 +#define WCD9335_DATA_HUB_DATA_HUB_RX3_INP_CFG 0x0057 +#define WCD9335_DATA_HUB_DATA_HUB_RX4_INP_CFG 0x0058 +#define WCD9335_DATA_HUB_DATA_HUB_RX5_INP_CFG 0x0059 +#define WCD9335_DATA_HUB_DATA_HUB_RX6_INP_CFG 0x005a +#define WCD9335_DATA_HUB_DATA_HUB_RX7_INP_CFG 0x005b +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX0_INP_CFG 0x0061 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX1_INP_CFG 0x0062 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX2_INP_CFG 0x0063 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX3_INP_CFG 0x0064 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX4_INP_CFG 0x0065 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX5_INP_CFG 0x0066 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX6_INP_CFG 0x0067 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX7_INP_CFG 0x0068 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX8_INP_CFG 0x0069 +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX9_INP_CFG 0x006a +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX10_INP_CFG 0x006b +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX11_INP_CFG 0x006c +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX13_INP_CFG 0x006e +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX14_INP_CFG 0x006f +#define WCD9335_DATA_HUB_DATA_HUB_SB_TX15_INP_CFG 0x0070 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_L_CFG 0x0071 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD0_R_CFG 0x0072 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_L_CFG 0x0073 +#define WCD9335_DATA_HUB_DATA_HUB_TX_I2S_SD1_R_CFG 0x0074 +#define WCD9335_DATA_HUB_NATIVE_FIFO_SYNC 0x0075 +#define WCD9335_DATA_HUB_NATIVE_FIFO_STATUS 0x007D +#define WCD9335_INTR_CFG 0x0081 +#define WCD9335_INTR_CLR_COMMIT 0x0082 +#define WCD9335_INTR_PIN1_MASK0 0x0089 +#define WCD9335_INTR_PIN1_MASK1 0x008a +#define WCD9335_INTR_PIN1_MASK2 0x008b +#define WCD9335_INTR_PIN1_MASK3 0x008c +#define WCD9335_INTR_PIN1_STATUS0 0x0091 +#define WCD9335_INTR_PIN1_STATUS1 0x0092 +#define WCD9335_INTR_PIN1_STATUS2 0x0093 +#define WCD9335_INTR_PIN1_STATUS3 0x0094 +#define WCD9335_INTR_PIN1_CLEAR0 0x0099 +#define WCD9335_INTR_PIN1_CLEAR1 0x009a +#define WCD9335_INTR_PIN1_CLEAR2 0x009b +#define WCD9335_INTR_PIN1_CLEAR3 0x009c +#define WCD9335_INTR_PIN2_MASK0 0x00a1 +#define WCD9335_INTR_PIN2_MASK1 0x00a2 +#define WCD9335_INTR_PIN2_MASK2 0x00a3 +#define WCD9335_INTR_PIN2_MASK3 0x00a4 +#define WCD9335_INTR_PIN2_STATUS0 0x00a9 +#define WCD9335_INTR_PIN2_STATUS1 0x00aa +#define WCD9335_INTR_PIN2_STATUS2 0x00ab +#define WCD9335_INTR_PIN2_STATUS3 0x00ac +#define WCD9335_INTR_PIN2_CLEAR0 0x00b1 +#define WCD9335_INTR_PIN2_CLEAR1 0x00b2 +#define WCD9335_INTR_PIN2_CLEAR2 0x00b3 +#define WCD9335_INTR_PIN2_CLEAR3 0x00b4 +#define WCD9335_INTR_LEVEL0 0x00e1 +#define WCD9335_INTR_LEVEL1 0x00e2 +#define WCD9335_INTR_LEVEL2 0x00e3 +#define WCD9335_INTR_LEVEL3 0x00e4 +#define WCD9335_INTR_BYPASS0 0x00e9 +#define WCD9335_INTR_BYPASS1 0x00ea +#define WCD9335_INTR_BYPASS2 0x00eb +#define WCD9335_INTR_BYPASS3 0x00ec +#define WCD9335_INTR_SET0 0x00f1 +#define WCD9335_INTR_SET1 0x00f2 +#define WCD9335_INTR_SET2 0x00f3 +#define WCD9335_INTR_SET3 0x00f4 + +/* Page-1 Registers */ +#define WCD9335_PAGE1_PAGE_REGISTER 0x0100 +#define WCD9335_CPE_FLL_USER_CTL_0 0x0101 +#define WCD9335_CPE_FLL_USER_CTL_1 0x0102 +#define WCD9335_CPE_FLL_USER_CTL_2 0x0103 +#define WCD9335_CPE_FLL_USER_CTL_3 0x0104 +#define WCD9335_CPE_FLL_USER_CTL_4 0x0105 +#define WCD9335_CPE_FLL_USER_CTL_5 0x0106 +#define WCD9335_CPE_FLL_USER_CTL_6 0x0107 +#define WCD9335_CPE_FLL_USER_CTL_7 0x0108 +#define WCD9335_CPE_FLL_USER_CTL_8 0x0109 +#define WCD9335_CPE_FLL_USER_CTL_9 0x010a +#define WCD9335_CPE_FLL_L_VAL_CTL_0 0x010b +#define WCD9335_CPE_FLL_L_VAL_CTL_1 0x010c +#define WCD9335_CPE_FLL_DSM_FRAC_CTL_0 0x010d +#define WCD9335_CPE_FLL_DSM_FRAC_CTL_1 0x010e +#define WCD9335_CPE_FLL_CONFIG_CTL_0 0x010f +#define WCD9335_CPE_FLL_CONFIG_CTL_1 0x0110 +#define WCD9335_CPE_FLL_CONFIG_CTL_2 0x0111 +#define WCD9335_CPE_FLL_CONFIG_CTL_3 0x0112 +#define WCD9335_CPE_FLL_CONFIG_CTL_4 0x0113 +#define WCD9335_CPE_FLL_TEST_CTL_0 0x0114 +#define WCD9335_CPE_FLL_TEST_CTL_1 0x0115 +#define WCD9335_CPE_FLL_TEST_CTL_2 0x0116 +#define WCD9335_CPE_FLL_TEST_CTL_3 0x0117 +#define WCD9335_CPE_FLL_TEST_CTL_4 0x0118 +#define WCD9335_CPE_FLL_TEST_CTL_5 0x0119 +#define WCD9335_CPE_FLL_TEST_CTL_6 0x011a +#define WCD9335_CPE_FLL_TEST_CTL_7 0x011b +#define WCD9335_CPE_FLL_FREQ_CTL_0 0x011c +#define WCD9335_CPE_FLL_FREQ_CTL_1 0x011d +#define WCD9335_CPE_FLL_FREQ_CTL_2 0x011e +#define WCD9335_CPE_FLL_FREQ_CTL_3 0x011f +#define WCD9335_CPE_FLL_SSC_CTL_0 0x0120 +#define WCD9335_CPE_FLL_SSC_CTL_1 0x0121 +#define WCD9335_CPE_FLL_SSC_CTL_2 0x0122 +#define WCD9335_CPE_FLL_SSC_CTL_3 0x0123 +#define WCD9335_CPE_FLL_FLL_MODE 0x0124 +#define WCD9335_CPE_FLL_STATUS_0 0x0125 +#define WCD9335_CPE_FLL_STATUS_1 0x0126 +#define WCD9335_CPE_FLL_STATUS_2 0x0127 +#define WCD9335_CPE_FLL_STATUS_3 0x0128 +#define WCD9335_I2S_FLL_USER_CTL_0 0x0141 +#define WCD9335_I2S_FLL_USER_CTL_1 0x0142 +#define WCD9335_I2S_FLL_USER_CTL_2 0x0143 +#define WCD9335_I2S_FLL_USER_CTL_3 0x0144 +#define WCD9335_I2S_FLL_USER_CTL_4 0x0145 +#define WCD9335_I2S_FLL_USER_CTL_5 0x0146 +#define WCD9335_I2S_FLL_USER_CTL_6 0x0147 +#define WCD9335_I2S_FLL_USER_CTL_7 0x0148 +#define WCD9335_I2S_FLL_USER_CTL_8 0x0149 +#define WCD9335_I2S_FLL_USER_CTL_9 0x014a +#define WCD9335_I2S_FLL_L_VAL_CTL_0 0x014b +#define WCD9335_I2S_FLL_L_VAL_CTL_1 0x014c +#define WCD9335_I2S_FLL_DSM_FRAC_CTL_0 0x014d +#define WCD9335_I2S_FLL_DSM_FRAC_CTL_1 0x014e +#define WCD9335_I2S_FLL_CONFIG_CTL_0 0x014f +#define WCD9335_I2S_FLL_CONFIG_CTL_1 0x0150 +#define WCD9335_I2S_FLL_CONFIG_CTL_2 0x0151 +#define WCD9335_I2S_FLL_CONFIG_CTL_3 0x0152 +#define WCD9335_I2S_FLL_CONFIG_CTL_4 0x0153 +#define WCD9335_I2S_FLL_TEST_CTL_0 0x0154 +#define WCD9335_I2S_FLL_TEST_CTL_1 0x0155 +#define WCD9335_I2S_FLL_TEST_CTL_2 0x0156 +#define WCD9335_I2S_FLL_TEST_CTL_3 0x0157 +#define WCD9335_I2S_FLL_TEST_CTL_4 0x0158 +#define WCD9335_I2S_FLL_TEST_CTL_5 0x0159 +#define WCD9335_I2S_FLL_TEST_CTL_6 0x015a +#define WCD9335_I2S_FLL_TEST_CTL_7 0x015b +#define WCD9335_I2S_FLL_FREQ_CTL_0 0x015c +#define WCD9335_I2S_FLL_FREQ_CTL_1 0x015d +#define WCD9335_I2S_FLL_FREQ_CTL_2 0x015e +#define WCD9335_I2S_FLL_FREQ_CTL_3 0x015f +#define WCD9335_I2S_FLL_SSC_CTL_0 0x0160 +#define WCD9335_I2S_FLL_SSC_CTL_1 0x0161 +#define WCD9335_I2S_FLL_SSC_CTL_2 0x0162 +#define WCD9335_I2S_FLL_SSC_CTL_3 0x0163 +#define WCD9335_I2S_FLL_FLL_MODE 0x0164 +#define WCD9335_I2S_FLL_STATUS_0 0x0165 +#define WCD9335_I2S_FLL_STATUS_1 0x0166 +#define WCD9335_I2S_FLL_STATUS_2 0x0167 +#define WCD9335_I2S_FLL_STATUS_3 0x0168 +#define WCD9335_SB_FLL_USER_CTL_0 0x0181 +#define WCD9335_SB_FLL_USER_CTL_1 0x0182 +#define WCD9335_SB_FLL_USER_CTL_2 0x0183 +#define WCD9335_SB_FLL_USER_CTL_3 0x0184 +#define WCD9335_SB_FLL_USER_CTL_4 0x0185 +#define WCD9335_SB_FLL_USER_CTL_5 0x0186 +#define WCD9335_SB_FLL_USER_CTL_6 0x0187 +#define WCD9335_SB_FLL_USER_CTL_7 0x0188 +#define WCD9335_SB_FLL_USER_CTL_8 0x0189 +#define WCD9335_SB_FLL_USER_CTL_9 0x018a +#define WCD9335_SB_FLL_L_VAL_CTL_0 0x018b +#define WCD9335_SB_FLL_L_VAL_CTL_1 0x018c +#define WCD9335_SB_FLL_DSM_FRAC_CTL_0 0x018d +#define WCD9335_SB_FLL_DSM_FRAC_CTL_1 0x018e +#define WCD9335_SB_FLL_CONFIG_CTL_0 0x018f +#define WCD9335_SB_FLL_CONFIG_CTL_1 0x0190 +#define WCD9335_SB_FLL_CONFIG_CTL_2 0x0191 +#define WCD9335_SB_FLL_CONFIG_CTL_3 0x0192 +#define WCD9335_SB_FLL_CONFIG_CTL_4 0x0193 +#define WCD9335_SB_FLL_TEST_CTL_0 0x0194 +#define WCD9335_SB_FLL_TEST_CTL_1 0x0195 +#define WCD9335_SB_FLL_TEST_CTL_2 0x0196 +#define WCD9335_SB_FLL_TEST_CTL_3 0x0197 +#define WCD9335_SB_FLL_TEST_CTL_4 0x0198 +#define WCD9335_SB_FLL_TEST_CTL_5 0x0199 +#define WCD9335_SB_FLL_TEST_CTL_6 0x019a +#define WCD9335_SB_FLL_TEST_CTL_7 0x019b +#define WCD9335_SB_FLL_FREQ_CTL_0 0x019c +#define WCD9335_SB_FLL_FREQ_CTL_1 0x019d +#define WCD9335_SB_FLL_FREQ_CTL_2 0x019e +#define WCD9335_SB_FLL_FREQ_CTL_3 0x019f +#define WCD9335_SB_FLL_SSC_CTL_0 0x01a0 +#define WCD9335_SB_FLL_SSC_CTL_1 0x01a1 +#define WCD9335_SB_FLL_SSC_CTL_2 0x01a2 +#define WCD9335_SB_FLL_SSC_CTL_3 0x01a3 +#define WCD9335_SB_FLL_FLL_MODE 0x01a4 +#define WCD9335_SB_FLL_STATUS_0 0x01a5 +#define WCD9335_SB_FLL_STATUS_1 0x01a6 +#define WCD9335_SB_FLL_STATUS_2 0x01a7 +#define WCD9335_SB_FLL_STATUS_3 0x01a8 + +/* Page-2 Registers */ +#define WCD9335_PAGE2_PAGE_REGISTER 0x0200 +#define WCD9335_CPE_SS_MEM_PTR_0 0x0201 +#define WCD9335_CPE_SS_MEM_PTR_1 0x0202 +#define WCD9335_CPE_SS_MEM_PTR_2 0x0203 +#define WCD9335_CPE_SS_MEM_CTRL 0x0205 +#define WCD9335_CPE_SS_MEM_BANK_0 0x0206 +#define WCD9335_CPE_SS_MEM_BANK_1 0x0207 +#define WCD9335_CPE_SS_MEM_BANK_2 0x0208 +#define WCD9335_CPE_SS_MEM_BANK_3 0x0209 +#define WCD9335_CPE_SS_MEM_BANK_4 0x020a +#define WCD9335_CPE_SS_MEM_BANK_5 0x020b +#define WCD9335_CPE_SS_MEM_BANK_6 0x020c +#define WCD9335_CPE_SS_MEM_BANK_7 0x020d +#define WCD9335_CPE_SS_MEM_BANK_8 0x020e +#define WCD9335_CPE_SS_MEM_BANK_9 0x020f +#define WCD9335_CPE_SS_MEM_BANK_10 0x0210 +#define WCD9335_CPE_SS_MEM_BANK_11 0x0211 +#define WCD9335_CPE_SS_MEM_BANK_12 0x0212 +#define WCD9335_CPE_SS_MEM_BANK_13 0x0213 +#define WCD9335_CPE_SS_MEM_BANK_14 0x0214 +#define WCD9335_CPE_SS_MEM_BANK_15 0x0215 +#define WCD9335_CPE_SS_INBOX1_TRG 0x0216 +#define WCD9335_CPE_SS_INBOX2_TRG 0x0217 +#define WCD9335_CPE_SS_INBOX1_0 0x0218 +#define WCD9335_CPE_SS_INBOX1_1 0x0219 +#define WCD9335_CPE_SS_INBOX1_2 0x021a +#define WCD9335_CPE_SS_INBOX1_3 0x021b +#define WCD9335_CPE_SS_INBOX1_4 0x021c +#define WCD9335_CPE_SS_INBOX1_5 0x021d +#define WCD9335_CPE_SS_INBOX1_6 0x021e +#define WCD9335_CPE_SS_INBOX1_7 0x021f +#define WCD9335_CPE_SS_INBOX1_8 0x0220 +#define WCD9335_CPE_SS_INBOX1_9 0x0221 +#define WCD9335_CPE_SS_INBOX1_10 0x0222 +#define WCD9335_CPE_SS_INBOX1_11 0x0223 +#define WCD9335_CPE_SS_INBOX1_12 0x0224 +#define WCD9335_CPE_SS_INBOX1_13 0x0225 +#define WCD9335_CPE_SS_INBOX1_14 0x0226 +#define WCD9335_CPE_SS_INBOX1_15 0x0227 +#define WCD9335_CPE_SS_OUTBOX1_0 0x0228 +#define WCD9335_CPE_SS_OUTBOX1_1 0x0229 +#define WCD9335_CPE_SS_OUTBOX1_2 0x022a +#define WCD9335_CPE_SS_OUTBOX1_3 0x022b +#define WCD9335_CPE_SS_OUTBOX1_4 0x022c +#define WCD9335_CPE_SS_OUTBOX1_5 0x022d +#define WCD9335_CPE_SS_OUTBOX1_6 0x022e +#define WCD9335_CPE_SS_OUTBOX1_7 0x022f +#define WCD9335_CPE_SS_OUTBOX1_8 0x0230 +#define WCD9335_CPE_SS_OUTBOX1_9 0x0231 +#define WCD9335_CPE_SS_OUTBOX1_10 0x0232 +#define WCD9335_CPE_SS_OUTBOX1_11 0x0233 +#define WCD9335_CPE_SS_OUTBOX1_12 0x0234 +#define WCD9335_CPE_SS_OUTBOX1_13 0x0235 +#define WCD9335_CPE_SS_OUTBOX1_14 0x0236 +#define WCD9335_CPE_SS_OUTBOX1_15 0x0237 +#define WCD9335_CPE_SS_INBOX2_0 0x0238 +#define WCD9335_CPE_SS_INBOX2_1 0x0239 +#define WCD9335_CPE_SS_INBOX2_2 0x023a +#define WCD9335_CPE_SS_INBOX2_3 0x023b +#define WCD9335_CPE_SS_INBOX2_4 0x023c +#define WCD9335_CPE_SS_INBOX2_5 0x023d +#define WCD9335_CPE_SS_INBOX2_6 0x023e +#define WCD9335_CPE_SS_INBOX2_7 0x023f +#define WCD9335_CPE_SS_INBOX2_8 0x0240 +#define WCD9335_CPE_SS_INBOX2_9 0x0241 +#define WCD9335_CPE_SS_INBOX2_10 0x0242 +#define WCD9335_CPE_SS_INBOX2_11 0x0243 +#define WCD9335_CPE_SS_INBOX2_12 0x0244 +#define WCD9335_CPE_SS_INBOX2_13 0x0245 +#define WCD9335_CPE_SS_INBOX2_14 0x0246 +#define WCD9335_CPE_SS_INBOX2_15 0x0247 +#define WCD9335_CPE_SS_OUTBOX2_0 0x0248 +#define WCD9335_CPE_SS_OUTBOX2_1 0x0249 +#define WCD9335_CPE_SS_OUTBOX2_2 0x024a +#define WCD9335_CPE_SS_OUTBOX2_3 0x024b +#define WCD9335_CPE_SS_OUTBOX2_4 0x024c +#define WCD9335_CPE_SS_OUTBOX2_5 0x024d +#define WCD9335_CPE_SS_OUTBOX2_6 0x024e +#define WCD9335_CPE_SS_OUTBOX2_7 0x024f +#define WCD9335_CPE_SS_OUTBOX2_8 0x0250 +#define WCD9335_CPE_SS_OUTBOX2_9 0x0251 +#define WCD9335_CPE_SS_OUTBOX2_10 0x0252 +#define WCD9335_CPE_SS_OUTBOX2_11 0x0253 +#define WCD9335_CPE_SS_OUTBOX2_12 0x0254 +#define WCD9335_CPE_SS_OUTBOX2_13 0x0255 +#define WCD9335_CPE_SS_OUTBOX2_14 0x0256 +#define WCD9335_CPE_SS_OUTBOX2_15 0x0257 +#define WCD9335_CPE_SS_OUTBOX1_ACK 0x0258 +#define WCD9335_CPE_SS_OUTBOX2_ACK 0x0259 +#define WCD9335_CPE_SS_EC_BUF_INT_PERIOD 0x025a +#define WCD9335_CPE_SS_US_BUF_INT_PERIOD 0x025b +#define WCD9335_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD 0x025c +#define WCD9335_CPE_SS_CFG 0x025d +#define WCD9335_CPE_SS_US_EC_MUX_CFG 0x025e +#define WCD9335_CPE_SS_MAD_CTL 0x025f +#define WCD9335_CPE_SS_CPAR_CTL 0x0260 +#define WCD9335_CPE_SS_TX_PP_BUF_INT_PERIOD 0x0261 +#define WCD9335_CPE_SS_TX_PP_CFG 0x0262 +#define WCD9335_CPE_SS_DMIC0_CTL 0x0263 +#define WCD9335_CPE_SS_DMIC1_CTL 0x0264 +#define WCD9335_CPE_SS_DMIC2_CTL 0x0265 +#define WCD9335_CPE_SS_DMIC_CFG 0x0266 +#define WCD9335_CPE_SS_SVA_CFG 0x0267 +#define WCD9335_CPE_SS_CPAR_CFG 0x0271 +#define WCD9335_CPE_SS_WDOG_CFG 0x0272 +#define WCD9335_CPE_SS_BACKUP_INT 0x0273 +#define WCD9335_CPE_SS_STATUS 0x0274 +#define WCD9335_CPE_SS_CPE_OCD_CFG 0x0275 +#define WCD9335_CPE_SS_SS_ERROR_INT_MASK 0x0276 +#define WCD9335_CPE_SS_SS_ERROR_INT_STATUS 0x0277 +#define WCD9335_CPE_SS_SS_ERROR_INT_CLEAR 0x0278 +#define WCD9335_SOC_MAD_MAIN_CTL_1 0x0281 +#define WCD9335_SOC_MAD_MAIN_CTL_2 0x0282 +#define WCD9335_SOC_MAD_AUDIO_CTL_1 0x0283 +#define WCD9335_SOC_MAD_AUDIO_CTL_2 0x0284 +#define WCD9335_SOC_MAD_AUDIO_CTL_3 0x0285 +#define WCD9335_SOC_MAD_AUDIO_CTL_4 0x0286 +#define WCD9335_SOC_MAD_AUDIO_CTL_5 0x0287 +#define WCD9335_SOC_MAD_AUDIO_CTL_6 0x0288 +#define WCD9335_SOC_MAD_AUDIO_CTL_7 0x0289 +#define WCD9335_SOC_MAD_AUDIO_CTL_8 0x028a +#define WCD9335_SOC_MAD_AUDIO_IIR_CTL_PTR 0x028b +#define WCD9335_SOC_MAD_AUDIO_IIR_CTL_VAL 0x028c +#define WCD9335_SOC_MAD_ULTR_CTL_1 0x028d +#define WCD9335_SOC_MAD_ULTR_CTL_2 0x028e +#define WCD9335_SOC_MAD_ULTR_CTL_3 0x028f +#define WCD9335_SOC_MAD_ULTR_CTL_4 0x0290 +#define WCD9335_SOC_MAD_ULTR_CTL_5 0x0291 +#define WCD9335_SOC_MAD_ULTR_CTL_6 0x0292 +#define WCD9335_SOC_MAD_ULTR_CTL_7 0x0293 +#define WCD9335_SOC_MAD_BEACON_CTL_1 0x0294 +#define WCD9335_SOC_MAD_BEACON_CTL_2 0x0295 +#define WCD9335_SOC_MAD_BEACON_CTL_3 0x0296 +#define WCD9335_SOC_MAD_BEACON_CTL_4 0x0297 +#define WCD9335_SOC_MAD_BEACON_CTL_5 0x0298 +#define WCD9335_SOC_MAD_BEACON_CTL_6 0x0299 +#define WCD9335_SOC_MAD_BEACON_CTL_7 0x029a +#define WCD9335_SOC_MAD_BEACON_CTL_8 0x029b +#define WCD9335_SOC_MAD_BEACON_IIR_CTL_PTR 0x029c +#define WCD9335_SOC_MAD_BEACON_IIR_CTL_VAL 0x029d +#define WCD9335_SOC_MAD_INP_SEL 0x029e + +/* Page-6 Registers */ +#define WCD9335_PAGE6_PAGE_REGISTER 0x0600 +#define WCD9335_ANA_BIAS 0x0601 +#define WCD9335_ANA_CLK_TOP 0x0602 +#define WCD9335_ANA_RCO 0x0603 +#define WCD9335_ANA_BUCK_VOUT_A 0x0604 +#define WCD9335_ANA_BUCK_VOUT_D 0x0605 +#define WCD9335_ANA_BUCK_CTL 0x0606 +#define WCD9335_ANA_BUCK_STATUS 0x0607 +#define WCD9335_ANA_RX_SUPPLIES 0x0608 +#define WCD9335_ANA_HPH 0x0609 +#define WCD9335_ANA_EAR 0x060a +#define WCD9335_ANA_LO_1_2 0x060b +#define WCD9335_ANA_LO_3_4 0x060c +#define WCD9335_ANA_MAD_SETUP 0x060d +#define WCD9335_ANA_AMIC1 0x060e +#define WCD9335_ANA_AMIC2 0x060f +#define WCD9335_ANA_AMIC3 0x0610 +#define WCD9335_ANA_AMIC4 0x0611 +#define WCD9335_ANA_AMIC5 0x0612 +#define WCD9335_ANA_AMIC6 0x0613 +#define WCD9335_ANA_MBHC_MECH 0x0614 +#define WCD9335_ANA_MBHC_ELECT 0x0615 +#define WCD9335_ANA_MBHC_ZDET 0x0616 +#define WCD9335_ANA_MBHC_RESULT_1 0x0617 +#define WCD9335_ANA_MBHC_RESULT_2 0x0618 +#define WCD9335_ANA_MBHC_RESULT_3 0x0619 +#define WCD9335_ANA_MBHC_BTN0 0x061a +#define WCD9335_ANA_MBHC_BTN1 0x061b +#define WCD9335_ANA_MBHC_BTN2 0x061c +#define WCD9335_ANA_MBHC_BTN3 0x061d +#define WCD9335_ANA_MBHC_BTN4 0x061e +#define WCD9335_ANA_MBHC_BTN5 0x061f +#define WCD9335_ANA_MBHC_BTN6 0x0620 +#define WCD9335_ANA_MBHC_BTN7 0x0621 +#define WCD9335_ANA_MICB1 0x0622 +#define WCD9335_ANA_MICB2 0x0623 +#define WCD9335_ANA_MICB2_RAMP 0x0624 +#define WCD9335_ANA_MICB3 0x0625 +#define WCD9335_ANA_MICB4 0x0626 +#define WCD9335_ANA_VBADC 0x0627 +#define WCD9335_BIAS_CTL 0x0628 +#define WCD9335_BIAS_VBG_FINE_ADJ 0x0629 +#define WCD9335_CLOCK_TEST_CTL 0x062d +#define WCD9335_RCO_CTRL_1 0x062e +#define WCD9335_RCO_CTRL_2 0x062f +#define WCD9335_RCO_CAL 0x0630 +#define WCD9335_RCO_CAL_1 0x0631 +#define WCD9335_RCO_CAL_2 0x0632 +#define WCD9335_RCO_TEST_CTRL 0x0633 +#define WCD9335_RCO_CAL_OUT_1 0x0634 +#define WCD9335_RCO_CAL_OUT_2 0x0635 +#define WCD9335_RCO_CAL_OUT_3 0x0636 +#define WCD9335_RCO_CAL_OUT_4 0x0637 +#define WCD9335_RCO_CAL_OUT_5 0x0638 +#define WCD9335_SIDO_SIDO_MODE_1 0x063a +#define WCD9335_SIDO_SIDO_MODE_2 0x063b +#define WCD9335_SIDO_SIDO_MODE_3 0x063c +#define WCD9335_SIDO_SIDO_MODE_4 0x063d +#define WCD9335_SIDO_SIDO_VCL_1 0x063e +#define WCD9335_SIDO_SIDO_VCL_2 0x063f +#define WCD9335_SIDO_SIDO_VCL_3 0x0640 +#define WCD9335_SIDO_SIDO_CCL_1 0x0641 +#define WCD9335_SIDO_SIDO_CCL_2 0x0642 +#define WCD9335_SIDO_SIDO_CCL_3 0x0643 +#define WCD9335_SIDO_SIDO_CCL_4 0x0644 +#define WCD9335_SIDO_SIDO_CCL_5 0x0645 +#define WCD9335_SIDO_SIDO_CCL_6 0x0646 +#define WCD9335_SIDO_SIDO_CCL_7 0x0647 +#define WCD9335_SIDO_SIDO_CCL_8 0x0648 +#define WCD9335_SIDO_SIDO_CCL_9 0x0649 +#define WCD9335_SIDO_SIDO_CCL_10 0x064a +#define WCD9335_SIDO_SIDO_FILTER_1 0x064b +#define WCD9335_SIDO_SIDO_FILTER_2 0x064c +#define WCD9335_SIDO_SIDO_DRIVER_1 0x064d +#define WCD9335_SIDO_SIDO_DRIVER_2 0x064e +#define WCD9335_SIDO_SIDO_DRIVER_3 0x064f +#define WCD9335_SIDO_SIDO_CAL_CODE_EXT_1 0x0650 +#define WCD9335_SIDO_SIDO_CAL_CODE_EXT_2 0x0651 +#define WCD9335_SIDO_SIDO_CAL_CODE_OUT_1 0x0652 +#define WCD9335_SIDO_SIDO_CAL_CODE_OUT_2 0x0653 +#define WCD9335_SIDO_SIDO_TEST_1 0x0654 +#define WCD9335_SIDO_SIDO_TEST_2 0x0655 +#define WCD9335_MBHC_CTL_1 0x0656 +#define WCD9335_MBHC_CTL_2 0x0657 +#define WCD9335_MBHC_PLUG_DETECT_CTL 0x0658 +#define WCD9335_MBHC_ZDET_ANA_CTL 0x0659 +#define WCD9335_MBHC_ZDET_RAMP_CTL 0x065a +#define WCD9335_MBHC_FSM_DEBUG 0x065b /* v1.x */ +#define WCD9335_MBHC_FSM_STATUS 0x065b /* v2.0 */ +#define WCD9335_MBHC_TEST_CTL 0x065c +#define WCD9335_VBADC_SUBBLOCK_EN 0x065d +#define WCD9335_VBADC_IBIAS_FE 0x065e +#define WCD9335_VBADC_BIAS_ADC 0x065f +#define WCD9335_VBADC_FE_CTRL 0x0660 +#define WCD9335_VBADC_ADC_REF 0x0661 +#define WCD9335_VBADC_ADC_IO 0x0662 +#define WCD9335_VBADC_ADC_SAR 0x0663 +#define WCD9335_VBADC_DEBUG 0x0664 +#define WCD9335_VBADC_ADC_DOUTMSB 0x0665 +#define WCD9335_VBADC_ADC_DOUTLSB 0x0666 +#define WCD9335_LDOH_MODE 0x0667 +#define WCD9335_LDOH_BIAS 0x0668 +#define WCD9335_LDOH_STB_LOADS 0x0669 +#define WCD9335_LDOH_SLOWRAMP 0x066a +#define WCD9335_MICB1_TEST_CTL_1 0x066b +#define WCD9335_MICB1_TEST_CTL_2 0x066c +#define WCD9335_MICB1_TEST_CTL_3 0x066d +#define WCD9335_MICB2_TEST_CTL_1 0x066e +#define WCD9335_MICB2_TEST_CTL_2 0x066f +#define WCD9335_MICB2_TEST_CTL_3 0x0670 +#define WCD9335_MICB3_TEST_CTL_1 0x0671 +#define WCD9335_MICB3_TEST_CTL_2 0x0672 +#define WCD9335_MICB3_TEST_CTL_3 0x0673 +#define WCD9335_MICB4_TEST_CTL_1 0x0674 +#define WCD9335_MICB4_TEST_CTL_2 0x0675 +#define WCD9335_MICB4_TEST_CTL_3 0x0676 +#define WCD9335_TX_COM_ADC_VCM 0x0677 +#define WCD9335_TX_COM_BIAS_ATEST 0x0678 +#define WCD9335_TX_COM_ADC_INT1_IB 0x0679 +#define WCD9335_TX_COM_ADC_INT2_IB 0x067a +#define WCD9335_TX_COM_TXFE_DIV_CTL 0x067b +#define WCD9335_TX_COM_TXFE_DIV_START 0x067c +#define WCD9335_TX_COM_TXFE_DIV_STOP_9P6M 0x067d +#define WCD9335_TX_COM_TXFE_DIV_STOP_12P288M 0x067e +#define WCD9335_TX_1_2_TEST_EN 0x067f +#define WCD9335_TX_1_2_ADC_IB 0x0680 +#define WCD9335_TX_1_2_ATEST_REFCTL 0x0681 +#define WCD9335_TX_1_2_TEST_CTL 0x0682 +#define WCD9335_TX_1_2_TEST_BLK_EN 0x0683 +#define WCD9335_TX_1_2_TXFE_CLKDIV 0x0684 +#define WCD9335_TX_1_2_SAR1_ERR 0x0685 +#define WCD9335_TX_1_2_SAR2_ERR 0x0686 +#define WCD9335_TX_3_4_TEST_EN 0x0687 +#define WCD9335_TX_3_4_ADC_IB 0x0688 +#define WCD9335_TX_3_4_ATEST_REFCTL 0x0689 +#define WCD9335_TX_3_4_TEST_CTL 0x068a +#define WCD9335_TX_3_4_TEST_BLK_EN 0x068b +#define WCD9335_TX_3_4_TXFE_CLKDIV 0x068c +#define WCD9335_TX_3_4_SAR1_ERR 0x068d +#define WCD9335_TX_3_4_SAR2_ERR 0x068e +#define WCD9335_TX_5_6_TEST_EN 0x068f +#define WCD9335_TX_5_6_ADC_IB 0x0690 +#define WCD9335_TX_5_6_ATEST_REFCTL 0x0691 +#define WCD9335_TX_5_6_TEST_CTL 0x0692 +#define WCD9335_TX_5_6_TEST_BLK_EN 0x0693 +#define WCD9335_TX_5_6_TXFE_CLKDIV 0x0694 +#define WCD9335_TX_5_6_SAR1_ERR 0x0695 +#define WCD9335_TX_5_6_SAR2_ERR 0x0696 +#define WCD9335_CLASSH_MODE_1 0x0697 +#define WCD9335_CLASSH_MODE_2 0x0698 +#define WCD9335_CLASSH_MODE_3 0x0699 +#define WCD9335_CLASSH_CTRL_VCL_1 0x069a +#define WCD9335_CLASSH_CTRL_VCL_2 0x069b +#define WCD9335_CLASSH_CTRL_CCL_1 0x069c +#define WCD9335_CLASSH_CTRL_CCL_2 0x069d +#define WCD9335_CLASSH_CTRL_CCL_3 0x069e +#define WCD9335_CLASSH_CTRL_CCL_4 0x069f +#define WCD9335_CLASSH_CTRL_CCL_5 0x06a0 +#define WCD9335_CLASSH_BUCK_TMUX_A_D 0x06a1 +#define WCD9335_CLASSH_BUCK_SW_DRV_CNTL 0x06a2 +#define WCD9335_CLASSH_SPARE 0x06a3 +#define WCD9335_FLYBACK_EN 0x06a4 +#define WCD9335_FLYBACK_VNEG_CTRL_1 0x06a5 +#define WCD9335_FLYBACK_VNEG_CTRL_2 0x06a6 +#define WCD9335_FLYBACK_VNEG_CTRL_3 0x06a7 +#define WCD9335_FLYBACK_VNEG_CTRL_4 0x06a8 +#define WCD9335_FLYBACK_VNEG_CTRL_5 0x06a9 +#define WCD9335_FLYBACK_VNEG_CTRL_6 0x06aa +#define WCD9335_FLYBACK_VNEG_CTRL_7 0x06ab +#define WCD9335_FLYBACK_VNEG_CTRL_8 0x06ac +#define WCD9335_FLYBACK_VNEG_CTRL_9 0x06ad +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_1 0x06ae +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_2 0x06af +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_3 0x06b0 +#define WCD9335_FLYBACK_VNEG_DAC_CTRL_4 0x06b1 /* v1.x */ +#define WCD9335_FLYBACK_CTRL_1 0x06b1 /* v2.0 */ +#define WCD9335_FLYBACK_TEST_CTL 0x06b2 +#define WCD9335_RX_AUX_SW_CTL 0x06b3 +#define WCD9335_RX_PA_AUX_IN_CONN 0x06b4 +#define WCD9335_RX_TIMER_DIV 0x06b5 +#define WCD9335_RX_OCP_CTL 0x06b6 +#define WCD9335_RX_OCP_COUNT 0x06b7 +#define WCD9335_RX_BIAS_EAR_DAC 0x06b8 +#define WCD9335_RX_BIAS_EAR_AMP 0x06b9 +#define WCD9335_RX_BIAS_HPH_LDO 0x06ba +#define WCD9335_RX_BIAS_HPH_PA 0x06bb +#define WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2 0x06bc +#define WCD9335_RX_BIAS_HPH_RDAC_LDO 0x06bd +#define WCD9335_RX_BIAS_HPH_CNP1 0x06be +#define WCD9335_RX_BIAS_HPH_LOWPOWER 0x06bf +#define WCD9335_RX_BIAS_DIFFLO_PA 0x06c0 +#define WCD9335_RX_BIAS_DIFFLO_REF 0x06c1 +#define WCD9335_RX_BIAS_DIFFLO_LDO 0x06c2 +#define WCD9335_RX_BIAS_SELO_DAC_PA 0x06c3 +#define WCD9335_RX_BIAS_BUCK_RST 0x06c4 +#define WCD9335_RX_BIAS_BUCK_VREF_ERRAMP 0x06c5 +#define WCD9335_RX_BIAS_FLYB_ERRAMP 0x06c6 +#define WCD9335_RX_BIAS_FLYB_BUFF 0x06c7 +#define WCD9335_RX_BIAS_FLYB_MID_RST 0x06c8 +#define WCD9335_HPH_L_STATUS 0x06c9 +#define WCD9335_HPH_R_STATUS 0x06ca +#define WCD9335_HPH_CNP_EN 0x06cb +#define WCD9335_HPH_CNP_WG_CTL 0x06cc +#define WCD9335_HPH_CNP_WG_TIME 0x06cd +#define WCD9335_HPH_OCP_CTL 0x06ce +#define WCD9335_HPH_AUTO_CHOP 0x06cf +#define WCD9335_HPH_CHOP_CTL 0x06d0 +#define WCD9335_HPH_PA_CTL1 0x06d1 +#define WCD9335_HPH_PA_CTL2 0x06d2 +#define WCD9335_HPH_L_EN 0x06d3 +#define WCD9335_HPH_L_TEST 0x06d4 +#define WCD9335_HPH_L_ATEST 0x06d5 +#define WCD9335_HPH_R_EN 0x06d6 +#define WCD9335_HPH_R_TEST 0x06d7 +#define WCD9335_HPH_R_ATEST 0x06d8 +#define WCD9335_HPH_RDAC_CLK_CTL1 0x06d9 +#define WCD9335_HPH_RDAC_CLK_CTL2 0x06da +#define WCD9335_HPH_RDAC_LDO_CTL 0x06db +#define WCD9335_HPH_RDAC_CHOP_CLK_LP_CTL 0x06dc +#define WCD9335_HPH_REFBUFF_UHQA_CTL 0x06dd +#define WCD9335_HPH_REFBUFF_LP_CTL 0x06de +#define WCD9335_HPH_L_DAC_CTL 0x06df +#define WCD9335_HPH_R_DAC_CTL 0x06e0 +#define WCD9335_EAR_EN_REG 0x06e1 +#define WCD9335_EAR_CMBUFF 0x06e2 +#define WCD9335_EAR_ICTL 0x06e3 +#define WCD9335_EAR_EN_DBG_CTL 0x06e4 +#define WCD9335_EAR_CNP 0x06e5 +#define WCD9335_EAR_DAC_CTL_ATEST 0x06e6 +#define WCD9335_EAR_STATUS_REG 0x06e7 +#define WCD9335_EAR_OUT_SHORT 0x06e8 +#define WCD9335_DIFF_LO_MISC 0x06e9 +#define WCD9335_DIFF_LO_LO2_COMPANDER 0x06ea +#define WCD9335_DIFF_LO_LO1_COMPANDER 0x06eb +#define WCD9335_DIFF_LO_COMMON 0x06ec +#define WCD9335_DIFF_LO_BYPASS_EN 0x06ed +#define WCD9335_DIFF_LO_CNP 0x06ee +#define WCD9335_DIFF_LO_CORE_OUT_PROG 0x06ef +#define WCD9335_DIFF_LO_LDO_OUT_PROG 0x06f0 +#define WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ 0x06f1 +#define WCD9335_DIFF_LO_COM_PA_FREQ 0x06f2 +#define WCD9335_DIFF_LO_RESERVED_REG 0x06f3 +#define WCD9335_DIFF_LO_LO1_STATUS_1 0x06f4 +#define WCD9335_DIFF_LO_LO1_STATUS_2 0x06f5 +#define WCD9335_SE_LO_COM1 0x06f6 +#define WCD9335_SE_LO_COM2 0x06f7 +#define WCD9335_SE_LO_LO3_GAIN 0x06f8 +#define WCD9335_SE_LO_LO3_CTRL 0x06f9 +#define WCD9335_SE_LO_LO4_GAIN 0x06fa +#define WCD9335_SE_LO_LO4_CTRL 0x06fb +#define WCD9335_SE_LO_LO3_STATUS 0x06fe +#define WCD9335_SE_LO_LO4_STATUS 0x06ff + +/* Page-10 Registers */ +#define WCD9335_PAGE10_PAGE_REGISTER 0x0a00 +#define WCD9335_CDC_ANC0_CLK_RESET_CTL 0x0a01 +#define WCD9335_CDC_ANC0_MODE_1_CTL 0x0a02 +#define WCD9335_CDC_ANC0_MODE_2_CTL 0x0a03 +#define WCD9335_CDC_ANC0_FF_SHIFT 0x0a04 +#define WCD9335_CDC_ANC0_FB_SHIFT 0x0a05 +#define WCD9335_CDC_ANC0_LPF_FF_A_CTL 0x0a06 +#define WCD9335_CDC_ANC0_LPF_FF_B_CTL 0x0a07 +#define WCD9335_CDC_ANC0_LPF_FB_CTL 0x0a08 +#define WCD9335_CDC_ANC0_SMLPF_CTL 0x0a09 +#define WCD9335_CDC_ANC0_DCFLT_SHIFT_CTL 0x0a0a +#define WCD9335_CDC_ANC0_IIR_ADAPT_CTL 0x0a0b +#define WCD9335_CDC_ANC0_IIR_COEFF_1_CTL 0x0a0c +#define WCD9335_CDC_ANC0_IIR_COEFF_2_CTL 0x0a0d +#define WCD9335_CDC_ANC0_FF_A_GAIN_CTL 0x0a0e +#define WCD9335_CDC_ANC0_FF_B_GAIN_CTL 0x0a0f +#define WCD9335_CDC_ANC0_FB_GAIN_CTL 0x0a10 +#define WCD9335_CDC_ANC1_CLK_RESET_CTL 0x0a19 +#define WCD9335_CDC_ANC1_MODE_1_CTL 0x0a1a +#define WCD9335_CDC_ANC1_MODE_2_CTL 0x0a1b +#define WCD9335_CDC_ANC1_FF_SHIFT 0x0a1c +#define WCD9335_CDC_ANC1_FB_SHIFT 0x0a1d +#define WCD9335_CDC_ANC1_LPF_FF_A_CTL 0x0a1e +#define WCD9335_CDC_ANC1_LPF_FF_B_CTL 0x0a1f +#define WCD9335_CDC_ANC1_LPF_FB_CTL 0x0a20 +#define WCD9335_CDC_ANC1_SMLPF_CTL 0x0a21 +#define WCD9335_CDC_ANC1_DCFLT_SHIFT_CTL 0x0a22 +#define WCD9335_CDC_ANC1_IIR_ADAPT_CTL 0x0a23 +#define WCD9335_CDC_ANC1_IIR_COEFF_1_CTL 0x0a24 +#define WCD9335_CDC_ANC1_IIR_COEFF_2_CTL 0x0a25 +#define WCD9335_CDC_ANC1_FF_A_GAIN_CTL 0x0a26 +#define WCD9335_CDC_ANC1_FF_B_GAIN_CTL 0x0a27 +#define WCD9335_CDC_ANC1_FB_GAIN_CTL 0x0a28 +#define WCD9335_CDC_TX0_TX_PATH_CTL 0x0a31 +#define WCD9335_CDC_TX0_TX_PATH_CFG0 0x0a32 +#define WCD9335_CDC_TX0_TX_PATH_CFG1 0x0a33 +#define WCD9335_CDC_TX0_TX_VOL_CTL 0x0a34 +#define WCD9335_CDC_TX0_TX_PATH_192_CTL 0x0a35 +#define WCD9335_CDC_TX0_TX_PATH_192_CFG 0x0a36 +#define WCD9335_CDC_TX0_TX_PATH_SEC0 0x0a37 +#define WCD9335_CDC_TX0_TX_PATH_SEC1 0x0a38 +#define WCD9335_CDC_TX0_TX_PATH_SEC2 0x0a39 +#define WCD9335_CDC_TX0_TX_PATH_SEC3 0x0a3a +#define WCD9335_CDC_TX0_TX_PATH_SEC4 0x0a3b +#define WCD9335_CDC_TX0_TX_PATH_SEC5 0x0a3c +#define WCD9335_CDC_TX0_TX_PATH_SEC6 0x0a3d +#define WCD9335_CDC_TX0_TX_PATH_SEC7 0x0a3e +#define WCD9335_CDC_TX1_TX_PATH_CTL 0x0a41 +#define WCD9335_CDC_TX1_TX_PATH_CFG0 0x0a42 +#define WCD9335_CDC_TX1_TX_PATH_CFG1 0x0a43 +#define WCD9335_CDC_TX1_TX_VOL_CTL 0x0a44 +#define WCD9335_CDC_TX1_TX_PATH_192_CTL 0x0a45 +#define WCD9335_CDC_TX1_TX_PATH_192_CFG 0x0a46 +#define WCD9335_CDC_TX1_TX_PATH_SEC0 0x0a47 +#define WCD9335_CDC_TX1_TX_PATH_SEC1 0x0a48 +#define WCD9335_CDC_TX1_TX_PATH_SEC2 0x0a49 +#define WCD9335_CDC_TX1_TX_PATH_SEC3 0x0a4a +#define WCD9335_CDC_TX1_TX_PATH_SEC4 0x0a4b +#define WCD9335_CDC_TX1_TX_PATH_SEC5 0x0a4c +#define WCD9335_CDC_TX1_TX_PATH_SEC6 0x0a4d +#define WCD9335_CDC_TX2_TX_PATH_CTL 0x0a51 +#define WCD9335_CDC_TX2_TX_PATH_CFG0 0x0a52 +#define WCD9335_CDC_TX2_TX_PATH_CFG1 0x0a53 +#define WCD9335_CDC_TX2_TX_VOL_CTL 0x0a54 +#define WCD9335_CDC_TX2_TX_PATH_192_CTL 0x0a55 +#define WCD9335_CDC_TX2_TX_PATH_192_CFG 0x0a56 +#define WCD9335_CDC_TX2_TX_PATH_SEC0 0x0a57 +#define WCD9335_CDC_TX2_TX_PATH_SEC1 0x0a58 +#define WCD9335_CDC_TX2_TX_PATH_SEC2 0x0a59 +#define WCD9335_CDC_TX2_TX_PATH_SEC3 0x0a5a +#define WCD9335_CDC_TX2_TX_PATH_SEC4 0x0a5b +#define WCD9335_CDC_TX2_TX_PATH_SEC5 0x0a5c +#define WCD9335_CDC_TX2_TX_PATH_SEC6 0x0a5d +#define WCD9335_CDC_TX3_TX_PATH_CTL 0x0a61 +#define WCD9335_CDC_TX3_TX_PATH_CFG0 0x0a62 +#define WCD9335_CDC_TX3_TX_PATH_CFG1 0x0a63 +#define WCD9335_CDC_TX3_TX_VOL_CTL 0x0a64 +#define WCD9335_CDC_TX3_TX_PATH_192_CTL 0x0a65 +#define WCD9335_CDC_TX3_TX_PATH_192_CFG 0x0a66 +#define WCD9335_CDC_TX3_TX_PATH_SEC0 0x0a67 +#define WCD9335_CDC_TX3_TX_PATH_SEC1 0x0a68 +#define WCD9335_CDC_TX3_TX_PATH_SEC2 0x0a69 +#define WCD9335_CDC_TX3_TX_PATH_SEC3 0x0a6a +#define WCD9335_CDC_TX3_TX_PATH_SEC4 0x0a6b +#define WCD9335_CDC_TX3_TX_PATH_SEC5 0x0a6c +#define WCD9335_CDC_TX3_TX_PATH_SEC6 0x0a6d +#define WCD9335_CDC_TX4_TX_PATH_CTL 0x0a71 +#define WCD9335_CDC_TX4_TX_PATH_CFG0 0x0a72 +#define WCD9335_CDC_TX4_TX_PATH_CFG1 0x0a73 +#define WCD9335_CDC_TX4_TX_VOL_CTL 0x0a74 +#define WCD9335_CDC_TX4_TX_PATH_192_CTL 0x0a75 +#define WCD9335_CDC_TX4_TX_PATH_192_CFG 0x0a76 +#define WCD9335_CDC_TX4_TX_PATH_SEC0 0x0a77 +#define WCD9335_CDC_TX4_TX_PATH_SEC1 0x0a78 +#define WCD9335_CDC_TX4_TX_PATH_SEC2 0x0a79 +#define WCD9335_CDC_TX4_TX_PATH_SEC3 0x0a7a +#define WCD9335_CDC_TX4_TX_PATH_SEC4 0x0a7b +#define WCD9335_CDC_TX4_TX_PATH_SEC5 0x0a7c +#define WCD9335_CDC_TX4_TX_PATH_SEC6 0x0a7d +#define WCD9335_CDC_TX5_TX_PATH_CTL 0x0a81 +#define WCD9335_CDC_TX5_TX_PATH_CFG0 0x0a82 +#define WCD9335_CDC_TX5_TX_PATH_CFG1 0x0a83 +#define WCD9335_CDC_TX5_TX_VOL_CTL 0x0a84 +#define WCD9335_CDC_TX5_TX_PATH_192_CTL 0x0a85 +#define WCD9335_CDC_TX5_TX_PATH_192_CFG 0x0a86 +#define WCD9335_CDC_TX5_TX_PATH_SEC0 0x0a87 +#define WCD9335_CDC_TX5_TX_PATH_SEC1 0x0a88 +#define WCD9335_CDC_TX5_TX_PATH_SEC2 0x0a89 +#define WCD9335_CDC_TX5_TX_PATH_SEC3 0x0a8a +#define WCD9335_CDC_TX5_TX_PATH_SEC4 0x0a8b +#define WCD9335_CDC_TX5_TX_PATH_SEC5 0x0a8c +#define WCD9335_CDC_TX5_TX_PATH_SEC6 0x0a8d +#define WCD9335_CDC_TX6_TX_PATH_CTL 0x0a91 +#define WCD9335_CDC_TX6_TX_PATH_CFG0 0x0a92 +#define WCD9335_CDC_TX6_TX_PATH_CFG1 0x0a93 +#define WCD9335_CDC_TX6_TX_VOL_CTL 0x0a94 +#define WCD9335_CDC_TX6_TX_PATH_192_CTL 0x0a95 +#define WCD9335_CDC_TX6_TX_PATH_192_CFG 0x0a96 +#define WCD9335_CDC_TX6_TX_PATH_SEC0 0x0a97 +#define WCD9335_CDC_TX6_TX_PATH_SEC1 0x0a98 +#define WCD9335_CDC_TX6_TX_PATH_SEC2 0x0a99 +#define WCD9335_CDC_TX6_TX_PATH_SEC3 0x0a9a +#define WCD9335_CDC_TX6_TX_PATH_SEC4 0x0a9b +#define WCD9335_CDC_TX6_TX_PATH_SEC5 0x0a9c +#define WCD9335_CDC_TX6_TX_PATH_SEC6 0x0a9d +#define WCD9335_CDC_TX7_TX_PATH_CTL 0x0aa1 +#define WCD9335_CDC_TX7_TX_PATH_CFG0 0x0aa2 +#define WCD9335_CDC_TX7_TX_PATH_CFG1 0x0aa3 +#define WCD9335_CDC_TX7_TX_VOL_CTL 0x0aa4 +#define WCD9335_CDC_TX7_TX_PATH_192_CTL 0x0aa5 +#define WCD9335_CDC_TX7_TX_PATH_192_CFG 0x0aa6 +#define WCD9335_CDC_TX7_TX_PATH_SEC0 0x0aa7 +#define WCD9335_CDC_TX7_TX_PATH_SEC1 0x0aa8 +#define WCD9335_CDC_TX7_TX_PATH_SEC2 0x0aa9 +#define WCD9335_CDC_TX7_TX_PATH_SEC3 0x0aaa +#define WCD9335_CDC_TX7_TX_PATH_SEC4 0x0aab +#define WCD9335_CDC_TX7_TX_PATH_SEC5 0x0aac +#define WCD9335_CDC_TX7_TX_PATH_SEC6 0x0aad +#define WCD9335_CDC_TX8_TX_PATH_CTL 0x0ab1 +#define WCD9335_CDC_TX8_TX_PATH_CFG0 0x0ab2 +#define WCD9335_CDC_TX8_TX_PATH_CFG1 0x0ab3 +#define WCD9335_CDC_TX8_TX_VOL_CTL 0x0ab4 +#define WCD9335_CDC_TX8_TX_PATH_192_CTL 0x0ab5 +#define WCD9335_CDC_TX8_TX_PATH_192_CFG 0x0ab6 +#define WCD9335_CDC_TX8_TX_PATH_SEC0 0x0ab7 +#define WCD9335_CDC_TX8_TX_PATH_SEC1 0x0ab8 +#define WCD9335_CDC_TX8_TX_PATH_SEC2 0x0ab9 +#define WCD9335_CDC_TX8_TX_PATH_SEC3 0x0aba +#define WCD9335_CDC_TX8_TX_PATH_SEC4 0x0abb +#define WCD9335_CDC_TX8_TX_PATH_SEC5 0x0abc +#define WCD9335_CDC_TX8_TX_PATH_SEC6 0x0abd +#define WCD9335_CDC_TX9_SPKR_PROT_PATH_CTL 0x0ac2 +#define WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0 0x0ac3 +#define WCD9335_CDC_TX10_SPKR_PROT_PATH_CTL 0x0ac6 +#define WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0 0x0ac7 +#define WCD9335_CDC_TX11_SPKR_PROT_PATH_CTL 0x0aca +#define WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0 0x0acb +#define WCD9335_CDC_TX12_SPKR_PROT_PATH_CTL 0x0ace +#define WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0 0x0acf + +/* Page-11 Registers */ +#define WCD9335_PAGE11_PAGE_REGISTER 0x0b00 +#define WCD9335_CDC_COMPANDER1_CTL0 0x0b01 +#define WCD9335_CDC_COMPANDER1_CTL1 0x0b02 +#define WCD9335_CDC_COMPANDER1_CTL2 0x0b03 +#define WCD9335_CDC_COMPANDER1_CTL3 0x0b04 +#define WCD9335_CDC_COMPANDER1_CTL4 0x0b05 +#define WCD9335_CDC_COMPANDER1_CTL5 0x0b06 +#define WCD9335_CDC_COMPANDER1_CTL6 0x0b07 +#define WCD9335_CDC_COMPANDER1_CTL7 0x0b08 +#define WCD9335_CDC_COMPANDER2_CTL0 0x0b09 +#define WCD9335_CDC_COMPANDER2_CTL1 0x0b0a +#define WCD9335_CDC_COMPANDER2_CTL2 0x0b0b +#define WCD9335_CDC_COMPANDER2_CTL3 0x0b0c +#define WCD9335_CDC_COMPANDER2_CTL4 0x0b0d +#define WCD9335_CDC_COMPANDER2_CTL5 0x0b0e +#define WCD9335_CDC_COMPANDER2_CTL6 0x0b0f +#define WCD9335_CDC_COMPANDER2_CTL7 0x0b10 +#define WCD9335_CDC_COMPANDER3_CTL0 0x0b11 +#define WCD9335_CDC_COMPANDER3_CTL1 0x0b12 +#define WCD9335_CDC_COMPANDER3_CTL2 0x0b13 +#define WCD9335_CDC_COMPANDER3_CTL3 0x0b14 +#define WCD9335_CDC_COMPANDER3_CTL4 0x0b15 +#define WCD9335_CDC_COMPANDER3_CTL5 0x0b16 +#define WCD9335_CDC_COMPANDER3_CTL6 0x0b17 +#define WCD9335_CDC_COMPANDER3_CTL7 0x0b18 +#define WCD9335_CDC_COMPANDER4_CTL0 0x0b19 +#define WCD9335_CDC_COMPANDER4_CTL1 0x0b1a +#define WCD9335_CDC_COMPANDER4_CTL2 0x0b1b +#define WCD9335_CDC_COMPANDER4_CTL3 0x0b1c +#define WCD9335_CDC_COMPANDER4_CTL4 0x0b1d +#define WCD9335_CDC_COMPANDER4_CTL5 0x0b1e +#define WCD9335_CDC_COMPANDER4_CTL6 0x0b1f +#define WCD9335_CDC_COMPANDER4_CTL7 0x0b20 +#define WCD9335_CDC_COMPANDER5_CTL0 0x0b21 +#define WCD9335_CDC_COMPANDER5_CTL1 0x0b22 +#define WCD9335_CDC_COMPANDER5_CTL2 0x0b23 +#define WCD9335_CDC_COMPANDER5_CTL3 0x0b24 +#define WCD9335_CDC_COMPANDER5_CTL4 0x0b25 +#define WCD9335_CDC_COMPANDER5_CTL5 0x0b26 +#define WCD9335_CDC_COMPANDER5_CTL6 0x0b27 +#define WCD9335_CDC_COMPANDER5_CTL7 0x0b28 +#define WCD9335_CDC_COMPANDER6_CTL0 0x0b29 +#define WCD9335_CDC_COMPANDER6_CTL1 0x0b2a +#define WCD9335_CDC_COMPANDER6_CTL2 0x0b2b +#define WCD9335_CDC_COMPANDER6_CTL3 0x0b2c +#define WCD9335_CDC_COMPANDER6_CTL4 0x0b2d +#define WCD9335_CDC_COMPANDER6_CTL5 0x0b2e +#define WCD9335_CDC_COMPANDER6_CTL6 0x0b2f +#define WCD9335_CDC_COMPANDER6_CTL7 0x0b30 +#define WCD9335_CDC_COMPANDER7_CTL0 0x0b31 +#define WCD9335_CDC_COMPANDER7_CTL1 0x0b32 +#define WCD9335_CDC_COMPANDER7_CTL2 0x0b33 +#define WCD9335_CDC_COMPANDER7_CTL3 0x0b34 +#define WCD9335_CDC_COMPANDER7_CTL4 0x0b35 +#define WCD9335_CDC_COMPANDER7_CTL5 0x0b36 +#define WCD9335_CDC_COMPANDER7_CTL6 0x0b37 +#define WCD9335_CDC_COMPANDER7_CTL7 0x0b38 +#define WCD9335_CDC_COMPANDER8_CTL0 0x0b39 +#define WCD9335_CDC_COMPANDER8_CTL1 0x0b3a +#define WCD9335_CDC_COMPANDER8_CTL2 0x0b3b +#define WCD9335_CDC_COMPANDER8_CTL3 0x0b3c +#define WCD9335_CDC_COMPANDER8_CTL4 0x0b3d +#define WCD9335_CDC_COMPANDER8_CTL5 0x0b3e +#define WCD9335_CDC_COMPANDER8_CTL6 0x0b3f +#define WCD9335_CDC_COMPANDER8_CTL7 0x0b40 +#define WCD9335_CDC_RX0_RX_PATH_CTL 0x0b41 +#define WCD9335_CDC_RX0_RX_PATH_CFG0 0x0b42 +#define WCD9335_CDC_RX0_RX_PATH_CFG1 0x0b43 +#define WCD9335_CDC_RX0_RX_PATH_CFG2 0x0b44 +#define WCD9335_CDC_RX0_RX_VOL_CTL 0x0b45 +#define WCD9335_CDC_RX0_RX_PATH_MIX_CTL 0x0b46 +#define WCD9335_CDC_RX0_RX_PATH_MIX_CFG 0x0b47 +#define WCD9335_CDC_RX0_RX_VOL_MIX_CTL 0x0b48 +#define WCD9335_CDC_RX0_RX_PATH_SEC0 0x0b49 +#define WCD9335_CDC_RX0_RX_PATH_SEC1 0x0b4a +#define WCD9335_CDC_RX0_RX_PATH_SEC2 0x0b4b +#define WCD9335_CDC_RX0_RX_PATH_SEC3 0x0b4c +#define WCD9335_CDC_RX0_RX_PATH_SEC5 0x0b4e +#define WCD9335_CDC_RX0_RX_PATH_SEC6 0x0b4f +#define WCD9335_CDC_RX0_RX_PATH_SEC7 0x0b50 +#define WCD9335_CDC_RX0_RX_PATH_MIX_SEC0 0x0b51 +#define WCD9335_CDC_RX0_RX_PATH_MIX_SEC1 0x0b52 +#define WCD9335_CDC_RX1_RX_PATH_CTL 0x0b55 +#define WCD9335_CDC_RX1_RX_PATH_CFG0 0x0b56 +#define WCD9335_CDC_RX1_RX_PATH_CFG1 0x0b57 +#define WCD9335_CDC_RX1_RX_PATH_CFG2 0x0b58 +#define WCD9335_CDC_RX1_RX_VOL_CTL 0x0b59 +#define WCD9335_CDC_RX1_RX_PATH_MIX_CTL 0x0b5a +#define WCD9335_CDC_RX1_RX_PATH_MIX_CFG 0x0b5b +#define WCD9335_CDC_RX1_RX_VOL_MIX_CTL 0x0b5c +#define WCD9335_CDC_RX1_RX_PATH_SEC0 0x0b5d +#define WCD9335_CDC_RX1_RX_PATH_SEC1 0x0b5e +#define WCD9335_CDC_RX1_RX_PATH_SEC2 0x0b5f +#define WCD9335_CDC_RX1_RX_PATH_SEC3 0x0b60 +#define WCD9335_CDC_RX1_RX_PATH_SEC4 0x0b61 +#define WCD9335_CDC_RX1_RX_PATH_SEC5 0x0b62 +#define WCD9335_CDC_RX1_RX_PATH_SEC6 0x0b63 +#define WCD9335_CDC_RX1_RX_PATH_SEC7 0x0b64 +#define WCD9335_CDC_RX1_RX_PATH_MIX_SEC0 0x0b65 +#define WCD9335_CDC_RX1_RX_PATH_MIX_SEC1 0x0b66 +#define WCD9335_CDC_RX2_RX_PATH_CTL 0x0b69 +#define WCD9335_CDC_RX2_RX_PATH_CFG0 0x0b6a +#define WCD9335_CDC_RX2_RX_PATH_CFG1 0x0b6b +#define WCD9335_CDC_RX2_RX_PATH_CFG2 0x0b6c +#define WCD9335_CDC_RX2_RX_VOL_CTL 0x0b6d +#define WCD9335_CDC_RX2_RX_PATH_MIX_CTL 0x0b6e +#define WCD9335_CDC_RX2_RX_PATH_MIX_CFG 0x0b6f +#define WCD9335_CDC_RX2_RX_VOL_MIX_CTL 0x0b70 +#define WCD9335_CDC_RX2_RX_PATH_SEC0 0x0b71 +#define WCD9335_CDC_RX2_RX_PATH_SEC1 0x0b72 +#define WCD9335_CDC_RX2_RX_PATH_SEC2 0x0b73 +#define WCD9335_CDC_RX2_RX_PATH_SEC3 0x0b74 +#define WCD9335_CDC_RX2_RX_PATH_SEC4 0x0b75 +#define WCD9335_CDC_RX2_RX_PATH_SEC5 0x0b76 +#define WCD9335_CDC_RX2_RX_PATH_SEC6 0x0b77 +#define WCD9335_CDC_RX2_RX_PATH_SEC7 0x0b78 +#define WCD9335_CDC_RX2_RX_PATH_MIX_SEC0 0x0b79 +#define WCD9335_CDC_RX2_RX_PATH_MIX_SEC1 0x0b7a +#define WCD9335_CDC_RX3_RX_PATH_CTL 0x0b7d +#define WCD9335_CDC_RX3_RX_PATH_CFG0 0x0b7e +#define WCD9335_CDC_RX3_RX_PATH_CFG1 0x0b7f +#define WCD9335_CDC_RX3_RX_PATH_CFG2 0x0b80 +#define WCD9335_CDC_RX3_RX_VOL_CTL 0x0b81 +#define WCD9335_CDC_RX3_RX_PATH_MIX_CTL 0x0b82 +#define WCD9335_CDC_RX3_RX_PATH_MIX_CFG 0x0b83 +#define WCD9335_CDC_RX3_RX_VOL_MIX_CTL 0x0b84 +#define WCD9335_CDC_RX3_RX_PATH_SEC0 0x0b85 +#define WCD9335_CDC_RX3_RX_PATH_SEC1 0x0b86 +#define WCD9335_CDC_RX3_RX_PATH_SEC2 0x0b87 +#define WCD9335_CDC_RX3_RX_PATH_SEC3 0x0b88 +#define WCD9335_CDC_RX3_RX_PATH_SEC5 0x0b8a +#define WCD9335_CDC_RX3_RX_PATH_SEC6 0x0b8b +#define WCD9335_CDC_RX3_RX_PATH_SEC7 0x0b8c +#define WCD9335_CDC_RX3_RX_PATH_MIX_SEC0 0x0b8d +#define WCD9335_CDC_RX3_RX_PATH_MIX_SEC1 0x0b8e +#define WCD9335_CDC_RX4_RX_PATH_CTL 0x0b91 +#define WCD9335_CDC_RX4_RX_PATH_CFG0 0x0b92 +#define WCD9335_CDC_RX4_RX_PATH_CFG1 0x0b93 +#define WCD9335_CDC_RX4_RX_PATH_CFG2 0x0b94 +#define WCD9335_CDC_RX4_RX_VOL_CTL 0x0b95 +#define WCD9335_CDC_RX4_RX_PATH_MIX_CTL 0x0b96 +#define WCD9335_CDC_RX4_RX_PATH_MIX_CFG 0x0b97 +#define WCD9335_CDC_RX4_RX_VOL_MIX_CTL 0x0b98 +#define WCD9335_CDC_RX4_RX_PATH_SEC0 0x0b99 +#define WCD9335_CDC_RX4_RX_PATH_SEC1 0x0b9a +#define WCD9335_CDC_RX4_RX_PATH_SEC2 0x0b9b +#define WCD9335_CDC_RX4_RX_PATH_SEC3 0x0b9c +#define WCD9335_CDC_RX4_RX_PATH_SEC5 0x0b9e +#define WCD9335_CDC_RX4_RX_PATH_SEC6 0x0b9f +#define WCD9335_CDC_RX4_RX_PATH_SEC7 0x0ba0 +#define WCD9335_CDC_RX4_RX_PATH_MIX_SEC0 0x0ba1 +#define WCD9335_CDC_RX4_RX_PATH_MIX_SEC1 0x0ba2 +#define WCD9335_CDC_RX5_RX_PATH_CTL 0x0ba5 +#define WCD9335_CDC_RX5_RX_PATH_CFG0 0x0ba6 +#define WCD9335_CDC_RX5_RX_PATH_CFG1 0x0ba7 +#define WCD9335_CDC_RX5_RX_PATH_CFG2 0x0ba8 +#define WCD9335_CDC_RX5_RX_VOL_CTL 0x0ba9 +#define WCD9335_CDC_RX5_RX_PATH_MIX_CTL 0x0baa +#define WCD9335_CDC_RX5_RX_PATH_MIX_CFG 0x0bab +#define WCD9335_CDC_RX5_RX_VOL_MIX_CTL 0x0bac +#define WCD9335_CDC_RX5_RX_PATH_SEC0 0x0bad +#define WCD9335_CDC_RX5_RX_PATH_SEC1 0x0bae +#define WCD9335_CDC_RX5_RX_PATH_SEC2 0x0baf +#define WCD9335_CDC_RX5_RX_PATH_SEC3 0x0bb0 +#define WCD9335_CDC_RX5_RX_PATH_SEC5 0x0bb2 +#define WCD9335_CDC_RX5_RX_PATH_SEC6 0x0bb3 +#define WCD9335_CDC_RX5_RX_PATH_SEC7 0x0bb4 +#define WCD9335_CDC_RX5_RX_PATH_MIX_SEC0 0x0bb5 +#define WCD9335_CDC_RX5_RX_PATH_MIX_SEC1 0x0bb6 +#define WCD9335_CDC_RX6_RX_PATH_CTL 0x0bb9 +#define WCD9335_CDC_RX6_RX_PATH_CFG0 0x0bba +#define WCD9335_CDC_RX6_RX_PATH_CFG1 0x0bbb +#define WCD9335_CDC_RX6_RX_PATH_CFG2 0x0bbc +#define WCD9335_CDC_RX6_RX_VOL_CTL 0x0bbd +#define WCD9335_CDC_RX6_RX_PATH_MIX_CTL 0x0bbe +#define WCD9335_CDC_RX6_RX_PATH_MIX_CFG 0x0bbf +#define WCD9335_CDC_RX6_RX_VOL_MIX_CTL 0x0bc0 +#define WCD9335_CDC_RX6_RX_PATH_SEC0 0x0bc1 +#define WCD9335_CDC_RX6_RX_PATH_SEC1 0x0bc2 +#define WCD9335_CDC_RX6_RX_PATH_SEC2 0x0bc3 +#define WCD9335_CDC_RX6_RX_PATH_SEC3 0x0bc4 +#define WCD9335_CDC_RX6_RX_PATH_SEC5 0x0bc6 +#define WCD9335_CDC_RX6_RX_PATH_SEC6 0x0bc7 +#define WCD9335_CDC_RX6_RX_PATH_SEC7 0x0bc8 +#define WCD9335_CDC_RX6_RX_PATH_MIX_SEC0 0x0bc9 +#define WCD9335_CDC_RX6_RX_PATH_MIX_SEC1 0x0bca +#define WCD9335_CDC_RX7_RX_PATH_CTL 0x0bcd +#define WCD9335_CDC_RX7_RX_PATH_CFG0 0x0bce +#define WCD9335_CDC_RX7_RX_PATH_CFG1 0x0bcf +#define WCD9335_CDC_RX7_RX_PATH_CFG2 0x0bd0 +#define WCD9335_CDC_RX7_RX_VOL_CTL 0x0bd1 +#define WCD9335_CDC_RX7_RX_PATH_MIX_CTL 0x0bd2 +#define WCD9335_CDC_RX7_RX_PATH_MIX_CFG 0x0bd3 +#define WCD9335_CDC_RX7_RX_VOL_MIX_CTL 0x0bd4 +#define WCD9335_CDC_RX7_RX_PATH_SEC0 0x0bd5 +#define WCD9335_CDC_RX7_RX_PATH_SEC1 0x0bd6 +#define WCD9335_CDC_RX7_RX_PATH_SEC2 0x0bd7 +#define WCD9335_CDC_RX7_RX_PATH_SEC3 0x0bd8 +#define WCD9335_CDC_RX7_RX_PATH_SEC5 0x0bda +#define WCD9335_CDC_RX7_RX_PATH_SEC6 0x0bdb +#define WCD9335_CDC_RX7_RX_PATH_SEC7 0x0bdc +#define WCD9335_CDC_RX7_RX_PATH_MIX_SEC0 0x0bdd +#define WCD9335_CDC_RX7_RX_PATH_MIX_SEC1 0x0bde +#define WCD9335_CDC_RX8_RX_PATH_CTL 0x0be1 +#define WCD9335_CDC_RX8_RX_PATH_CFG0 0x0be2 +#define WCD9335_CDC_RX8_RX_PATH_CFG1 0x0be3 +#define WCD9335_CDC_RX8_RX_PATH_CFG2 0x0be4 +#define WCD9335_CDC_RX8_RX_VOL_CTL 0x0be5 +#define WCD9335_CDC_RX8_RX_PATH_MIX_CTL 0x0be6 +#define WCD9335_CDC_RX8_RX_PATH_MIX_CFG 0x0be7 +#define WCD9335_CDC_RX8_RX_VOL_MIX_CTL 0x0be8 +#define WCD9335_CDC_RX8_RX_PATH_SEC0 0x0be9 +#define WCD9335_CDC_RX8_RX_PATH_SEC1 0x0bea +#define WCD9335_CDC_RX8_RX_PATH_SEC2 0x0beb +#define WCD9335_CDC_RX8_RX_PATH_SEC3 0x0bec +#define WCD9335_CDC_RX8_RX_PATH_SEC5 0x0bee +#define WCD9335_CDC_RX8_RX_PATH_SEC6 0x0bef +#define WCD9335_CDC_RX8_RX_PATH_SEC7 0x0bf0 +#define WCD9335_CDC_RX8_RX_PATH_MIX_SEC0 0x0bf1 +#define WCD9335_CDC_RX8_RX_PATH_MIX_SEC1 0x0bf2 + +/* Page-12 Registers */ +#define WCD9335_PAGE12_PAGE_REGISTER 0x0c00 +#define WCD9335_CDC_CLSH_CRC 0x0c01 +#define WCD9335_CDC_CLSH_DLY_CTRL 0x0c02 +#define WCD9335_CDC_CLSH_DECAY_CTRL 0x0c03 +#define WCD9335_CDC_CLSH_HPH_V_PA 0x0c04 +#define WCD9335_CDC_CLSH_EAR_V_PA 0x0c05 +#define WCD9335_CDC_CLSH_HPH_V_HD 0x0c06 +#define WCD9335_CDC_CLSH_EAR_V_HD 0x0c07 +#define WCD9335_CDC_CLSH_K1_MSB 0x0c08 +#define WCD9335_CDC_CLSH_K1_LSB 0x0c09 +#define WCD9335_CDC_CLSH_K2_MSB 0x0c0a +#define WCD9335_CDC_CLSH_K2_LSB 0x0c0b +#define WCD9335_CDC_CLSH_IDLE_CTRL 0x0c0c +#define WCD9335_CDC_CLSH_IDLE_HPH 0x0c0d +#define WCD9335_CDC_CLSH_IDLE_EAR 0x0c0e +#define WCD9335_CDC_CLSH_TEST0 0x0c0f +#define WCD9335_CDC_CLSH_TEST1 0x0c10 +#define WCD9335_CDC_CLSH_OVR_VREF 0x0c11 +#define WCD9335_CDC_BOOST0_BOOST_PATH_CTL 0x0c19 +#define WCD9335_CDC_BOOST0_BOOST_CTL 0x0c1a +#define WCD9335_CDC_BOOST0_BOOST_CFG1 0x0c1b +#define WCD9335_CDC_BOOST0_BOOST_CFG2 0x0c1c +#define WCD9335_CDC_BOOST1_BOOST_PATH_CTL 0x0c21 +#define WCD9335_CDC_BOOST1_BOOST_CTL 0x0c22 +#define WCD9335_CDC_BOOST1_BOOST_CFG1 0x0c23 +#define WCD9335_CDC_BOOST1_BOOST_CFG2 0x0c24 +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_0 0x0c29 +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_1 0x0c2a +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_2 0x0c2b +#define WCD9335_SWR_AHB_BRIDGE_WR_DATA_3 0x0c2c +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_0 0x0c2d +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_1 0x0c2e +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_2 0x0c2f +#define WCD9335_SWR_AHB_BRIDGE_WR_ADDR_3 0x0c30 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_0 0x0c31 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_1 0x0c32 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_2 0x0c33 +#define WCD9335_SWR_AHB_BRIDGE_RD_ADDR_3 0x0c34 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_0 0x0c35 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_1 0x0c36 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_2 0x0c37 +#define WCD9335_SWR_AHB_BRIDGE_RD_DATA_3 0x0c38 +#define WCD9335_SWR_AHB_BRIDGE_ACCESS_CFG 0x0c39 +#define WCD9335_SWR_AHB_BRIDGE_ACCESS_STATUS 0x0c3a +#define WCD9335_CDC_VBAT_VBAT_PATH_CTL 0x0c3d +#define WCD9335_CDC_VBAT_VBAT_CFG 0x0c3e +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL1 0x0c3f +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL2 0x0c40 +#define WCD9335_CDC_VBAT_VBAT_ADC_CAL3 0x0c41 +#define WCD9335_CDC_VBAT_VBAT_PK_EST1 0x0c42 +#define WCD9335_CDC_VBAT_VBAT_PK_EST2 0x0c43 +#define WCD9335_CDC_VBAT_VBAT_PK_EST3 0x0c44 +#define WCD9335_CDC_VBAT_VBAT_RF_PROC1 0x0c45 +#define WCD9335_CDC_VBAT_VBAT_RF_PROC2 0x0c46 +#define WCD9335_CDC_VBAT_VBAT_TAC1 0x0c47 +#define WCD9335_CDC_VBAT_VBAT_TAC2 0x0c48 +#define WCD9335_CDC_VBAT_VBAT_TAC3 0x0c49 +#define WCD9335_CDC_VBAT_VBAT_TAC4 0x0c4a +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD1 0x0c4b +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD2 0x0c4c +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD3 0x0c4d +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD4 0x0c4e +#define WCD9335_CDC_VBAT_VBAT_DEBUG1 0x0c4f +#define WCD9335_CDC_VBAT_VBAT_GAIN_UPD_MON 0x0c50 +#define WCD9335_CDC_VBAT_VBAT_GAIN_MON_VAL 0x0c51 +#define WCD9335_SPLINE_SRC0_CLK_RST_CTL_0 0x0c55 +#define WCD9335_SPLINE_SRC0_STATUS 0x0c56 +#define WCD9335_SPLINE_SRC1_CLK_RST_CTL_0 0x0c6d +#define WCD9335_SPLINE_SRC1_STATUS 0x0c6e +#define WCD9335_SPLINE_SRC2_CLK_RST_CTL_0 0x0c85 +#define WCD9335_SPLINE_SRC2_STATUS 0x0c86 +#define WCD9335_SPLINE_SRC3_CLK_RST_CTL_0 0x0c9d +#define WCD9335_SPLINE_SRC3_STATUS 0x0c9e +#define WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL 0x0cb5 +#define WCD9335_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 0x0cb6 +#define WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL 0x0cb9 +#define WCD9335_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1 0x0cba + +/* Page-13 Registers */ +#define WCD9335_PAGE13_PAGE_REGISTER 0x0d00 +#define WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0 0x0d01 +#define WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1 0x0d02 +#define WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0 0x0d03 +#define WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1 0x0d04 +#define WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0 0x0d05 +#define WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1 0x0d06 +#define WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0 0x0d07 +#define WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1 0x0d08 +#define WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0 0x0d09 +#define WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1 0x0d0a +#define WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0 0x0d0b +#define WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1 0x0d0c +#define WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0 0x0d0d +#define WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1 0x0d0e +#define WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0 0x0d0f +#define WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1 0x0d10 +#define WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0 0x0d11 +#define WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1 0x0d12 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG0 0x0d13 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG1 0x0d14 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG2 0x0d15 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG3 0x0d16 +#define WCD9335_CDC_RX_INP_MUX_RX_MIX_CFG4 0x0d17 +#define WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 0x0d18 +#define WCD9335_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 0x0d19 +#define WCD9335_CDC_RX_INP_MUX_ANC_CFG0 0x0d1a +#define WCD9335_CDC_RX_INP_MUX_SPLINE_SRC_CFG0 0x0d1b +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 0x0d1d +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 0x0d1e +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0 0x0d1f +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1 0x0d20 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0 0x0d21 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1 0x0d22 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0 0x0d23 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1 0x0d24 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 0x0d25 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0 0x0d26 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0 0x0d27 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0 0x0d28 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0 0x0d29 +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX10_CFG0 0x0d2b +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX11_CFG0 0x0d2c +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX12_CFG0 0x0d2d +#define WCD9335_CDC_TX_INP_MUX_ADC_MUX13_CFG0 0x0d2e +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 0x0d31 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 0x0d32 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 0x0d33 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 0x0d34 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0 0x0d35 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1 0x0d36 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2 0x0d37 +#define WCD9335_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3 0x0d38 +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0 0x0d3a +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1 0x0d3b +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2 0x0d3c +#define WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3 0x0d3d +#define WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 +#define WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 +#define WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL 0x0d43 +#define WCD9335_CDC_PROX_DETECT_PROX_CTL 0x0d49 +#define WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD0 0x0d4a +#define WCD9335_CDC_PROX_DETECT_PROX_POLL_PERIOD1 0x0d4b +#define WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB 0x0d4c +#define WCD9335_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB 0x0d4d +#define WCD9335_CDC_PROX_DETECT_PROX_STATUS 0x0d4e +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_CTRL 0x0d4f +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB 0x0d50 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB 0x0d51 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD 0x0d52 +#define WCD9335_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD 0x0d53 +#define WCD9335_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT 0x0d54 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_PATH_CTL 0x0d55 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL 0x0d56 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL 0x0d57 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL 0x0d58 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL 0x0d59 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL 0x0d5a +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL 0x0d5b +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL 0x0d5c +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL 0x0d5d +#define WCD9335_CDC_SIDETONE_IIR0_IIR_CTL 0x0d5e +#define WCD9335_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL 0x0d5f +#define WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL 0x0d60 +#define WCD9335_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL 0x0d61 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_PATH_CTL 0x0d65 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL 0x0d66 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL 0x0d67 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL 0x0d68 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL 0x0d69 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL 0x0d6a +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL 0x0d6b +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL 0x0d6c +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL 0x0d6d +#define WCD9335_CDC_SIDETONE_IIR1_IIR_CTL 0x0d6e +#define WCD9335_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL 0x0d6f +#define WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL 0x0d70 +#define WCD9335_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL 0x0d71 +#define WCD9335_CDC_TOP_TOP_CFG0 0x0d81 +#define WCD9335_CDC_TOP_TOP_CFG1 0x0d82 +#define WCD9335_CDC_TOP_TOP_CFG2 0x0d83 +#define WCD9335_CDC_TOP_TOP_CFG3 0x0d84 +#define WCD9335_CDC_TOP_TOP_CFG4 0x0d85 +#define WCD9335_CDC_TOP_TOP_CFG5 0x0d86 +#define WCD9335_CDC_TOP_TOP_CFG6 0x0d87 +#define WCD9335_CDC_TOP_TOP_CFG7 0x0d88 +#define WCD9335_CDC_TOP_HPHL_COMP_WR_LSB 0x0d89 +#define WCD9335_CDC_TOP_HPHL_COMP_WR_MSB 0x0d8a +#define WCD9335_CDC_TOP_HPHL_COMP_LUT 0x0d8b +#define WCD9335_CDC_TOP_HPHL_COMP_RD_LSB 0x0d8c +#define WCD9335_CDC_TOP_HPHL_COMP_RD_MSB 0x0d8d +#define WCD9335_CDC_TOP_HPHR_COMP_WR_LSB 0x0d8e +#define WCD9335_CDC_TOP_HPHR_COMP_WR_MSB 0x0d8f +#define WCD9335_CDC_TOP_HPHR_COMP_LUT 0x0d90 +#define WCD9335_CDC_TOP_HPHR_COMP_RD_LSB 0x0d91 +#define WCD9335_CDC_TOP_HPHR_COMP_RD_MSB 0x0d92 +#define WCD9335_CDC_TOP_DIFFL_COMP_WR_LSB 0x0d93 +#define WCD9335_CDC_TOP_DIFFL_COMP_WR_MSB 0x0d94 +#define WCD9335_CDC_TOP_DIFFL_COMP_LUT 0x0d95 +#define WCD9335_CDC_TOP_DIFFL_COMP_RD_LSB 0x0d96 +#define WCD9335_CDC_TOP_DIFFL_COMP_RD_MSB 0x0d97 +#define WCD9335_CDC_TOP_DIFFR_COMP_WR_LSB 0x0d98 +#define WCD9335_CDC_TOP_DIFFR_COMP_WR_MSB 0x0d99 +#define WCD9335_CDC_TOP_DIFFR_COMP_LUT 0x0d9a +#define WCD9335_CDC_TOP_DIFFR_COMP_RD_LSB 0x0d9b +#define WCD9335_CDC_TOP_DIFFR_COMP_RD_MSB 0x0d9c + +/* Page-0x80 Registers */ +#define WCD9335_PAGE80_PAGE_REGISTER 0x8000 +#define WCD9335_TLMM_BIST_MODE_PINCFG 0x8001 +#define WCD9335_TLMM_RF_PA_ON_PINCFG 0x8002 +#define WCD9335_TLMM_INTR1_PINCFG 0x8003 +#define WCD9335_TLMM_INTR2_PINCFG 0x8004 +#define WCD9335_TLMM_SWR_DATA_PINCFG 0x8005 +#define WCD9335_TLMM_SWR_CLK_PINCFG 0x8006 +#define WCD9335_TLMM_SLIMBUS_DATA2_PINCFG 0x8007 +#define WCD9335_TLMM_I2C_CLK_PINCFG 0x8008 +#define WCD9335_TLMM_I2C_DATA_PINCFG 0x8009 +#define WCD9335_TLMM_I2S_RX_SD0_PINCFG 0x800a +#define WCD9335_TLMM_I2S_RX_SD1_PINCFG 0x800b +#define WCD9335_TLMM_I2S_RX_SCK_PINCFG 0x800c +#define WCD9335_TLMM_I2S_RX_WS_PINCFG 0x800d +#define WCD9335_TLMM_I2S_TX_SD0_PINCFG 0x800e +#define WCD9335_TLMM_I2S_TX_SD1_PINCFG 0x800f +#define WCD9335_TLMM_I2S_TX_SCK_PINCFG 0x8010 +#define WCD9335_TLMM_I2S_TX_WS_PINCFG 0x8011 +#define WCD9335_TLMM_DMIC1_CLK_PINCFG 0x8012 +#define WCD9335_TLMM_DMIC1_DATA_PINCFG 0x8013 +#define WCD9335_TLMM_DMIC2_CLK_PINCFG 0x8014 +#define WCD9335_TLMM_DMIC2_DATA_PINCFG 0x8015 +#define WCD9335_TLMM_DMIC3_CLK_PINCFG 0x8016 +#define WCD9335_TLMM_DMIC3_DATA_PINCFG 0x8017 +#define WCD9335_TLMM_JTDI_PINCFG 0x8018 +#define WCD9335_TLMM_JTDO_PINCFG 0x8019 +#define WCD9335_TLMM_JTMS_PINCFG 0x801a +#define WCD9335_TLMM_JTCK_PINCFG 0x801b +#define WCD9335_TLMM_JTRST_PINCFG 0x801c +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_0 0x8031 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_1 0x8032 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_2 0x8033 +#define WCD9335_TEST_DEBUG_PIN_CTL_OE_3 0x8034 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_0 0x8035 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_1 0x8036 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_2 0x8037 +#define WCD9335_TEST_DEBUG_PIN_CTL_DATA_3 0x8038 +#define WCD9335_TEST_DEBUG_PAD_DRVCTL 0x8039 +#define WCD9335_TEST_DEBUG_PIN_STATUS 0x803a +#define WCD9335_TEST_DEBUG_NPL_DLY_TEST_1 0x803b +#define WCD9335_TEST_DEBUG_NPL_DLY_TEST_2 0x803c +#define WCD9335_TEST_DEBUG_MEM_CTRL 0x803d +#define WCD9335_TEST_DEBUG_DEBUG_BUS_SEL 0x8041 +#define WCD9335_TEST_DEBUG_DEBUG_JTAG 0x8042 +#define WCD9335_TEST_DEBUG_DEBUG_EN_1 0x8043 +#define WCD9335_TEST_DEBUG_DEBUG_EN_2 0x8044 +#define WCD9335_TEST_DEBUG_DEBUG_EN_3 0x8045 +#define WCD9335_MAX_REGISTER 0x80FF + +/* SLIMBUS Slave Registers */ +#define TASHA_SLIM_PGD_PORT_INT_EN0 (0x30) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define TASHA_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define TASHA_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define TASHA_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define TASHA_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define TASHA_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define TASHA_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define TASHA_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +/* Macros for Packing Register Writes into a U32 */ +#define TASHA_PACKED_REG_SIZE sizeof(u32) + +#define TASHA_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\ + ((mask & 0xff) << 8)|((reg & 0xffff) << 16)) +#define TASHA_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) +#endif diff --git a/include/linux/mfd/wcd934x/registers.h b/include/linux/mfd/wcd934x/registers.h new file mode 100644 index 000000000000..a824875096e4 --- /dev/null +++ b/include/linux/mfd/wcd934x/registers.h @@ -0,0 +1,1848 @@ +/* + * Copyright (c) 2016, 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 _WCD934X_REGISTERS_H +#define _WCD934X_REGISTERS_H + +#define WCD934X_PAGE_SIZE 256 +#define WCD934X_NUM_PAGES 256 + +extern const u8 * const wcd934x_reg[WCD934X_NUM_PAGES]; + +enum { + WCD934X_PAGE_0 = 0, + WCD934X_PAGE_1, + WCD934X_PAGE_2, + WCD934X_PAGE_4 = 4, + WCD934X_PAGE_5, + WCD934X_PAGE_6, + WCD934X_PAGE_7, + WCD934X_PAGE_10 = 0xA, + WCD934X_PAGE_11, + WCD934X_PAGE_12, + WCD934X_PAGE_13, + WCD934X_PAGE_14, + WCD934X_PAGE_15, + WCD934X_PAGE_0x50, + WCD934X_PAGE_0X80, +}; + +enum { + WCD934X_WRITE = 0, + WCD934X_READ, + WCD934X_READ_WRITE, +}; + +/* Page-0 Registers */ +#define WCD934X_PAGE0_PAGE_REGISTER 0x0000 +#define WCD934X_CODEC_RPM_CLK_BYPASS 0x0001 +#define WCD934X_CODEC_RPM_CLK_GATE 0x0002 +#define WCD934X_CODEC_RPM_CLK_MCLK_CFG 0x0003 +#define WCD934X_CODEC_RPM_CLK_MCLK2_CFG 0x0004 +#define WCD934X_CODEC_RPM_I2S_DSD_CLK_SEL 0x0005 +#define WCD934X_CODEC_RPM_RST_CTL 0x0009 +#define WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL 0x0011 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0 0x0021 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE1 0x0022 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2 0x0023 +#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE3 0x0024 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_CTL 0x0025 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_TEST0 0x0026 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_TEST1 0x0027 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT0 0x0029 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 0x002a +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 0x002b +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT3 0x002c +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT4 0x002d +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT5 0x002e +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT6 0x002f +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT7 0x0030 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT8 0x0031 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT9 0x0032 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT10 0x0033 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT11 0x0034 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT12 0x0035 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT13 0x0036 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14 0x0037 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15 0x0038 +#define WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS 0x0039 +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO 0x003a +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 0x003b +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 0x003c +#define WCD934X_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 0x003d +#define WCD934X_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL 0x003e +#define WCD934X_CHIP_TIER_CTRL_SLNQ_WAIT_STATE_CTL 0x003f +#define WCD934X_CHIP_TIER_CTRL_I2C_ACTIVE 0x0040 +#define WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN 0x0041 +#define WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE 0x0042 +#define WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA 0x0043 +#define WCD934X_DATA_HUB_RX0_CFG 0x0051 +#define WCD934X_DATA_HUB_RX1_CFG 0x0052 +#define WCD934X_DATA_HUB_RX2_CFG 0x0053 +#define WCD934X_DATA_HUB_RX3_CFG 0x0054 +#define WCD934X_DATA_HUB_RX4_CFG 0x0055 +#define WCD934X_DATA_HUB_RX5_CFG 0x0056 +#define WCD934X_DATA_HUB_RX6_CFG 0x0057 +#define WCD934X_DATA_HUB_RX7_CFG 0x0058 +#define WCD934X_DATA_HUB_SB_TX0_INP_CFG 0x0061 +#define WCD934X_DATA_HUB_SB_TX1_INP_CFG 0x0062 +#define WCD934X_DATA_HUB_SB_TX2_INP_CFG 0x0063 +#define WCD934X_DATA_HUB_SB_TX3_INP_CFG 0x0064 +#define WCD934X_DATA_HUB_SB_TX4_INP_CFG 0x0065 +#define WCD934X_DATA_HUB_SB_TX5_INP_CFG 0x0066 +#define WCD934X_DATA_HUB_SB_TX6_INP_CFG 0x0067 +#define WCD934X_DATA_HUB_SB_TX7_INP_CFG 0x0068 +#define WCD934X_DATA_HUB_SB_TX8_INP_CFG 0x0069 +#define WCD934X_DATA_HUB_SB_TX9_INP_CFG 0x006a +#define WCD934X_DATA_HUB_SB_TX10_INP_CFG 0x006b +#define WCD934X_DATA_HUB_SB_TX11_INP_CFG 0x006c +#define WCD934X_DATA_HUB_SB_TX13_INP_CFG 0x006e +#define WCD934X_DATA_HUB_SB_TX14_INP_CFG 0x006f +#define WCD934X_DATA_HUB_SB_TX15_INP_CFG 0x0070 +#define WCD934X_DATA_HUB_I2S_TX0_CFG 0x0071 +#define WCD934X_DATA_HUB_I2S_TX1_0_CFG 0x0073 +#define WCD934X_DATA_HUB_I2S_TX1_1_CFG 0x0074 +#define WCD934X_DATA_HUB_I2S_0_CTL 0x0081 +#define WCD934X_DATA_HUB_I2S_1_CTL 0x0082 +#define WCD934X_DATA_HUB_I2S_2_CTL 0x0083 +#define WCD934X_DATA_HUB_I2S_3_CTL 0x0084 +#define WCD934X_DATA_HUB_I2S_CLKSRC_CTL 0x0085 +#define WCD934X_DATA_HUB_I2S_COMMON_CTL 0x0086 +#define WCD934X_DATA_HUB_I2S_0_TDM_CTL 0x0087 +#define WCD934X_DATA_HUB_I2S_STATUS 0x0088 +#define WCD934X_DMA_RDMA_CTL_0 0x0091 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_0 0x0092 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_0 0x0093 +#define WCD934X_DMA_RDMA_CTL_1 0x0094 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_1 0x0095 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_1 0x0096 +#define WCD934X_DMA_RDMA_CTL_2 0x0097 +#define WCD934X_DMA_CH_2_3_CFG_RDMA_2 0x0098 +#define WCD934X_DMA_CH_0_1_CFG_RDMA_2 0x0099 +#define WCD934X_DMA_RDMA_CTL_3 0x009A +#define WCD934X_DMA_CH_2_3_CFG_RDMA_3 0x009B +#define WCD934X_DMA_CH_0_1_CFG_RDMA_3 0x009C +#define WCD934X_DMA_RDMA_CTL_4 0x009D +#define WCD934X_DMA_CH_2_3_CFG_RDMA_4 0x009E +#define WCD934X_DMA_CH_0_1_CFG_RDMA_4 0x009F +#define WCD934X_DMA_RDMA4_PRT_CFG 0x00b1 +#define WCD934X_DMA_RDMA_SBTX0_7_CFG 0x00b9 +#define WCD934X_DMA_RDMA_SBTX8_11_CFG 0x00ba +#define WCD934X_DMA_WDMA_CTL_0 0x00c1 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_0 0x00c2 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_0 0x00c3 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_0 0x00c4 +#define WCD934X_DMA_WDMA_CTL_1 0x00C6 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_1 0x00C7 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_1 0x00C8 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_1 0x00C9 +#define WCD934X_DMA_WDMA_CTL_2 0x00CB +#define WCD934X_DMA_CH_4_5_CFG_WDMA_2 0x00CC +#define WCD934X_DMA_CH_2_3_CFG_WDMA_2 0x00CD +#define WCD934X_DMA_CH_0_1_CFG_WDMA_2 0x00CE +#define WCD934X_DMA_WDMA_CTL_3 0x00D0 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_3 0x00D1 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_3 0x00D2 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_3 0x00D3 +#define WCD934X_DMA_WDMA_CTL_4 0x00D5 +#define WCD934X_DMA_CH_4_5_CFG_WDMA_4 0x00D6 +#define WCD934X_DMA_CH_2_3_CFG_WDMA_4 0x00D7 +#define WCD934X_DMA_CH_0_1_CFG_WDMA_4 0x00D8 +#define WCD934X_DMA_WDMA0_PRT_CFG 0x00E1 +#define WCD934X_DMA_WDMA3_PRT_CFG 0x00E2 +#define WCD934X_DMA_WDMA4_PRT0_3_CFG 0x00E3 +#define WCD934X_DMA_WDMA4_PRT4_7_CFG 0x00E4 +#define WCD934X_PAGE1_PAGE_REGISTER 0x0100 +#define WCD934X_CPE_FLL_USER_CTL_0 0x0101 +#define WCD934X_CPE_FLL_USER_CTL_1 0x0102 +#define WCD934X_CPE_FLL_USER_CTL_2 0x0103 +#define WCD934X_CPE_FLL_USER_CTL_3 0x0104 +#define WCD934X_CPE_FLL_USER_CTL_4 0x0105 +#define WCD934X_CPE_FLL_USER_CTL_5 0x0106 +#define WCD934X_CPE_FLL_USER_CTL_6 0x0107 +#define WCD934X_CPE_FLL_USER_CTL_7 0x0108 +#define WCD934X_CPE_FLL_USER_CTL_8 0x0109 +#define WCD934X_CPE_FLL_USER_CTL_9 0x010a +#define WCD934X_CPE_FLL_L_VAL_CTL_0 0x010b +#define WCD934X_CPE_FLL_L_VAL_CTL_1 0x010c +#define WCD934X_CPE_FLL_DSM_FRAC_CTL_0 0x010d +#define WCD934X_CPE_FLL_DSM_FRAC_CTL_1 0x010e +#define WCD934X_CPE_FLL_CONFIG_CTL_0 0x010f +#define WCD934X_CPE_FLL_CONFIG_CTL_1 0x0110 +#define WCD934X_CPE_FLL_CONFIG_CTL_2 0x0111 +#define WCD934X_CPE_FLL_CONFIG_CTL_3 0x0112 +#define WCD934X_CPE_FLL_CONFIG_CTL_4 0x0113 +#define WCD934X_CPE_FLL_TEST_CTL_0 0x0114 +#define WCD934X_CPE_FLL_TEST_CTL_1 0x0115 +#define WCD934X_CPE_FLL_TEST_CTL_2 0x0116 +#define WCD934X_CPE_FLL_TEST_CTL_3 0x0117 +#define WCD934X_CPE_FLL_TEST_CTL_4 0x0118 +#define WCD934X_CPE_FLL_TEST_CTL_5 0x0119 +#define WCD934X_CPE_FLL_TEST_CTL_6 0x011a +#define WCD934X_CPE_FLL_TEST_CTL_7 0x011b +#define WCD934X_CPE_FLL_FREQ_CTL_0 0x011c +#define WCD934X_CPE_FLL_FREQ_CTL_1 0x011d +#define WCD934X_CPE_FLL_FREQ_CTL_2 0x011e +#define WCD934X_CPE_FLL_FREQ_CTL_3 0x011f +#define WCD934X_CPE_FLL_SSC_CTL_0 0x0120 +#define WCD934X_CPE_FLL_SSC_CTL_1 0x0121 +#define WCD934X_CPE_FLL_SSC_CTL_2 0x0122 +#define WCD934X_CPE_FLL_SSC_CTL_3 0x0123 +#define WCD934X_CPE_FLL_FLL_MODE 0x0124 +#define WCD934X_CPE_FLL_STATUS_0 0x0125 +#define WCD934X_CPE_FLL_STATUS_1 0x0126 +#define WCD934X_CPE_FLL_STATUS_2 0x0127 +#define WCD934X_CPE_FLL_STATUS_3 0x0128 +#define WCD934X_I2S_FLL_USER_CTL_0 0x0141 +#define WCD934X_I2S_FLL_USER_CTL_1 0x0142 +#define WCD934X_I2S_FLL_USER_CTL_2 0x0143 +#define WCD934X_I2S_FLL_USER_CTL_3 0x0144 +#define WCD934X_I2S_FLL_USER_CTL_4 0x0145 +#define WCD934X_I2S_FLL_USER_CTL_5 0x0146 +#define WCD934X_I2S_FLL_USER_CTL_6 0x0147 +#define WCD934X_I2S_FLL_USER_CTL_7 0x0148 +#define WCD934X_I2S_FLL_USER_CTL_8 0x0149 +#define WCD934X_I2S_FLL_USER_CTL_9 0x014a +#define WCD934X_I2S_FLL_L_VAL_CTL_0 0x014b +#define WCD934X_I2S_FLL_L_VAL_CTL_1 0x014c +#define WCD934X_I2S_FLL_DSM_FRAC_CTL_0 0x014d +#define WCD934X_I2S_FLL_DSM_FRAC_CTL_1 0x014e +#define WCD934X_I2S_FLL_CONFIG_CTL_0 0x014f +#define WCD934X_I2S_FLL_CONFIG_CTL_1 0x0150 +#define WCD934X_I2S_FLL_CONFIG_CTL_2 0x0151 +#define WCD934X_I2S_FLL_CONFIG_CTL_3 0x0152 +#define WCD934X_I2S_FLL_CONFIG_CTL_4 0x0153 +#define WCD934X_I2S_FLL_TEST_CTL_0 0x0154 +#define WCD934X_I2S_FLL_TEST_CTL_1 0x0155 +#define WCD934X_I2S_FLL_TEST_CTL_2 0x0156 +#define WCD934X_I2S_FLL_TEST_CTL_3 0x0157 +#define WCD934X_I2S_FLL_TEST_CTL_4 0x0158 +#define WCD934X_I2S_FLL_TEST_CTL_5 0x0159 +#define WCD934X_I2S_FLL_TEST_CTL_6 0x015a +#define WCD934X_I2S_FLL_TEST_CTL_7 0x015b +#define WCD934X_I2S_FLL_FREQ_CTL_0 0x015c +#define WCD934X_I2S_FLL_FREQ_CTL_1 0x015d +#define WCD934X_I2S_FLL_FREQ_CTL_2 0x015e +#define WCD934X_I2S_FLL_FREQ_CTL_3 0x015f +#define WCD934X_I2S_FLL_SSC_CTL_0 0x0160 +#define WCD934X_I2S_FLL_SSC_CTL_1 0x0161 +#define WCD934X_I2S_FLL_SSC_CTL_2 0x0162 +#define WCD934X_I2S_FLL_SSC_CTL_3 0x0163 +#define WCD934X_I2S_FLL_FLL_MODE 0x0164 +#define WCD934X_I2S_FLL_STATUS_0 0x0165 +#define WCD934X_I2S_FLL_STATUS_1 0x0166 +#define WCD934X_I2S_FLL_STATUS_2 0x0167 +#define WCD934X_I2S_FLL_STATUS_3 0x0168 +#define WCD934X_SB_FLL_USER_CTL_0 0x0181 +#define WCD934X_SB_FLL_USER_CTL_1 0x0182 +#define WCD934X_SB_FLL_USER_CTL_2 0x0183 +#define WCD934X_SB_FLL_USER_CTL_3 0x0184 +#define WCD934X_SB_FLL_USER_CTL_4 0x0185 +#define WCD934X_SB_FLL_USER_CTL_5 0x0186 +#define WCD934X_SB_FLL_USER_CTL_6 0x0187 +#define WCD934X_SB_FLL_USER_CTL_7 0x0188 +#define WCD934X_SB_FLL_USER_CTL_8 0x0189 +#define WCD934X_SB_FLL_USER_CTL_9 0x018a +#define WCD934X_SB_FLL_L_VAL_CTL_0 0x018b +#define WCD934X_SB_FLL_L_VAL_CTL_1 0x018c +#define WCD934X_SB_FLL_DSM_FRAC_CTL_0 0x018d +#define WCD934X_SB_FLL_DSM_FRAC_CTL_1 0x018e +#define WCD934X_SB_FLL_CONFIG_CTL_0 0x018f +#define WCD934X_SB_FLL_CONFIG_CTL_1 0x0190 +#define WCD934X_SB_FLL_CONFIG_CTL_2 0x0191 +#define WCD934X_SB_FLL_CONFIG_CTL_3 0x0192 +#define WCD934X_SB_FLL_CONFIG_CTL_4 0x0193 +#define WCD934X_SB_FLL_TEST_CTL_0 0x0194 +#define WCD934X_SB_FLL_TEST_CTL_1 0x0195 +#define WCD934X_SB_FLL_TEST_CTL_2 0x0196 +#define WCD934X_SB_FLL_TEST_CTL_3 0x0197 +#define WCD934X_SB_FLL_TEST_CTL_4 0x0198 +#define WCD934X_SB_FLL_TEST_CTL_5 0x0199 +#define WCD934X_SB_FLL_TEST_CTL_6 0x019a +#define WCD934X_SB_FLL_TEST_CTL_7 0x019b +#define WCD934X_SB_FLL_FREQ_CTL_0 0x019c +#define WCD934X_SB_FLL_FREQ_CTL_1 0x019d +#define WCD934X_SB_FLL_FREQ_CTL_2 0x019e +#define WCD934X_SB_FLL_FREQ_CTL_3 0x019f +#define WCD934X_SB_FLL_SSC_CTL_0 0x01a0 +#define WCD934X_SB_FLL_SSC_CTL_1 0x01a1 +#define WCD934X_SB_FLL_SSC_CTL_2 0x01a2 +#define WCD934X_SB_FLL_SSC_CTL_3 0x01a3 +#define WCD934X_SB_FLL_FLL_MODE 0x01a4 +#define WCD934X_SB_FLL_STATUS_0 0x01a5 +#define WCD934X_SB_FLL_STATUS_1 0x01a6 +#define WCD934X_SB_FLL_STATUS_2 0x01a7 +#define WCD934X_SB_FLL_STATUS_3 0x01a8 +#define WCD934X_PAGE2_PAGE_REGISTER 0x0200 +#define WCD934X_CPE_SS_CPE_CTL 0x0201 +#define WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_0 0x0202 +#define WCD934X_CPE_SS_PWR_SYS_PSTATE_CTL_1 0x0203 +#define WCD934X_CPE_SS_PWR_CPEFLL_CTL 0x0204 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0 0x0205 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1 0x0206 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_OVERRIDE 0x0207 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0 0x0208 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1 0x0209 +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2 0x020a +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3 0x020b +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4 0x020c +#define WCD934X_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_5 0x020d +#define WCD934X_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN 0x020e +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL 0x020f +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL 0x0210 +#define WCD934X_CPE_SS_SOC_SW_COLLAPSE_OVERRIDE_CTL1 0x0211 +#define WCD934X_CPE_SS_US_BUF_INT_PERIOD 0x0212 +#define WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD 0x0213 +#define WCD934X_CPE_SS_SVA_CFG 0x0214 +#define WCD934X_CPE_SS_US_CFG 0x0215 +#define WCD934X_CPE_SS_MAD_CTL 0x0216 +#define WCD934X_CPE_SS_CPAR_CTL 0x0217 +#define WCD934X_CPE_SS_DMIC0_CTL 0x0218 +#define WCD934X_CPE_SS_DMIC1_CTL 0x0219 +#define WCD934X_CPE_SS_DMIC2_CTL 0x021a +#define WCD934X_CPE_SS_DMIC_CFG 0x021b +#define WCD934X_CPE_SS_CPAR_CFG 0x021c +#define WCD934X_CPE_SS_WDOG_CFG 0x021d +#define WCD934X_CPE_SS_BACKUP_INT 0x021e +#define WCD934X_CPE_SS_STATUS 0x021f +#define WCD934X_CPE_SS_CPE_OCD_CFG 0x0220 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A 0x0221 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_0B 0x0222 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_1A 0x0223 +#define WCD934X_CPE_SS_SS_ERROR_INT_MASK_1B 0x0224 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0A 0x0225 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_0B 0x0226 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1A 0x0227 +#define WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B 0x0228 +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0A 0x0229 +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_0B 0x022a +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1A 0x022b +#define WCD934X_CPE_SS_SS_ERROR_INT_CLEAR_1B 0x022c +#define WCD934X_SOC_MAD_MAIN_CTL_1 0x0281 +#define WCD934X_SOC_MAD_MAIN_CTL_2 0x0282 +#define WCD934X_SOC_MAD_AUDIO_CTL_1 0x0283 +#define WCD934X_SOC_MAD_AUDIO_CTL_2 0x0284 +#define WCD934X_SOC_MAD_AUDIO_CTL_3 0x0285 +#define WCD934X_SOC_MAD_AUDIO_CTL_4 0x0286 +#define WCD934X_SOC_MAD_AUDIO_CTL_5 0x0287 +#define WCD934X_SOC_MAD_AUDIO_CTL_6 0x0288 +#define WCD934X_SOC_MAD_AUDIO_CTL_7 0x0289 +#define WCD934X_SOC_MAD_AUDIO_CTL_8 0x028a +#define WCD934X_SOC_MAD_AUDIO_IIR_CTL_PTR 0x028b +#define WCD934X_SOC_MAD_AUDIO_IIR_CTL_VAL 0x028c +#define WCD934X_SOC_MAD_ULTR_CTL_1 0x028d +#define WCD934X_SOC_MAD_ULTR_CTL_2 0x028e +#define WCD934X_SOC_MAD_ULTR_CTL_3 0x028f +#define WCD934X_SOC_MAD_ULTR_CTL_4 0x0290 +#define WCD934X_SOC_MAD_ULTR_CTL_5 0x0291 +#define WCD934X_SOC_MAD_ULTR_CTL_6 0x0292 +#define WCD934X_SOC_MAD_ULTR_CTL_7 0x0293 +#define WCD934X_SOC_MAD_BEACON_CTL_1 0x0294 +#define WCD934X_SOC_MAD_BEACON_CTL_2 0x0295 +#define WCD934X_SOC_MAD_BEACON_CTL_3 0x0296 +#define WCD934X_SOC_MAD_BEACON_CTL_4 0x0297 +#define WCD934X_SOC_MAD_BEACON_CTL_5 0x0298 +#define WCD934X_SOC_MAD_BEACON_CTL_6 0x0299 +#define WCD934X_SOC_MAD_BEACON_CTL_7 0x029a +#define WCD934X_SOC_MAD_BEACON_CTL_8 0x029b +#define WCD934X_SOC_MAD_BEACON_IIR_CTL_PTR 0x029c +#define WCD934X_SOC_MAD_BEACON_IIR_CTL_VAL 0x029d +#define WCD934X_SOC_MAD_INP_SEL 0x029e +#define WCD934X_PAGE4_PAGE_REGISTER 0x0400 +#define WCD934X_INTR_CFG 0x0401 +#define WCD934X_INTR_CLR_COMMIT 0x0402 +#define WCD934X_INTR_PIN1_MASK0 0x0409 +#define WCD934X_INTR_PIN1_MASK1 0x040a +#define WCD934X_INTR_PIN1_MASK2 0x040b +#define WCD934X_INTR_PIN1_MASK3 0x040c +#define WCD934X_INTR_PIN1_STATUS0 0x0411 +#define WCD934X_INTR_PIN1_STATUS1 0x0412 +#define WCD934X_INTR_PIN1_STATUS2 0x0413 +#define WCD934X_INTR_PIN1_STATUS3 0x0414 +#define WCD934X_INTR_PIN1_CLEAR0 0x0419 +#define WCD934X_INTR_PIN1_CLEAR1 0x041a +#define WCD934X_INTR_PIN1_CLEAR2 0x041b +#define WCD934X_INTR_PIN1_CLEAR3 0x041c +#define WCD934X_INTR_PIN2_MASK3 0x0424 +#define WCD934X_INTR_PIN2_STATUS3 0x042c +#define WCD934X_INTR_PIN2_CLEAR3 0x0434 +#define WCD934X_INTR_CPESS_SUMRY_MASK2 0x043b +#define WCD934X_INTR_CPESS_SUMRY_MASK3 0x043c +#define WCD934X_INTR_CPESS_SUMRY_STATUS2 0x0443 +#define WCD934X_INTR_CPESS_SUMRY_STATUS3 0x0444 +#define WCD934X_INTR_CPESS_SUMRY_CLEAR2 0x044b +#define WCD934X_INTR_CPESS_SUMRY_CLEAR3 0x044c +#define WCD934X_INTR_LEVEL0 0x0461 +#define WCD934X_INTR_LEVEL1 0x0462 +#define WCD934X_INTR_LEVEL2 0x0463 +#define WCD934X_INTR_LEVEL3 0x0464 +#define WCD934X_INTR_BYPASS0 0x0469 +#define WCD934X_INTR_BYPASS1 0x046a +#define WCD934X_INTR_BYPASS2 0x046b +#define WCD934X_INTR_BYPASS3 0x046c +#define WCD934X_INTR_SET0 0x0471 +#define WCD934X_INTR_SET1 0x0472 +#define WCD934X_INTR_SET2 0x0473 +#define WCD934X_INTR_SET3 0x0474 +#define WCD934X_INTR_CODEC_MISC_MASK 0x04b1 +#define WCD934X_INTR_CODEC_MISC_STATUS 0x04b2 +#define WCD934X_INTR_CODEC_MISC_CLEAR 0x04b3 +#define WCD934X_PAGE5_PAGE_REGISTER 0x0500 +#define WCD934X_SLNQ_DIG_DEVICE 0x0501 +#define WCD934X_SLNQ_DIG_REVISION 0x0502 +#define WCD934X_SLNQ_DIG_H_COMMAND 0x0511 +#define WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_MSB 0x0512 +#define WCD934X_SLNQ_DIG_NUMBER_OF_BYTE_LSB 0x0513 +#define WCD934X_SLNQ_DIG_MASTER_ADDRESS_MSB 0x0514 +#define WCD934X_SLNQ_DIG_MASTER_ADDRESS_LSB 0x0515 +#define WCD934X_SLNQ_DIG_SLAVE_ADDRESS_MSB 0x0516 +#define WCD934X_SLNQ_DIG_SLAVE_ADDRESS_LSB 0x0517 +#define WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_MSB 0x0518 +#define WCD934X_SLNQ_DIG_TIMER0_INTERRUPT_LSB 0x0519 +#define WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_MSB 0x051a +#define WCD934X_SLNQ_DIG_TIMER1_INTERRUPT_LSB 0x051b +#define WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_MSB 0x051c +#define WCD934X_SLNQ_DIG_TIMER2_INTERRUPT_LSB 0x051d +#define WCD934X_SLNQ_DIG_COMM_CTL 0x0520 +#define WCD934X_SLNQ_DIG_FRAME_CTRL 0x0542 +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH1_2 0x055c +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH3_4 0x055d +#define WCD934X_SLNQ_DIG_PDM_2ND_DATA_CH5 0x055e +#define WCD934X_SLNQ_DIG_SW_EVENT_RD 0x0561 +#define WCD934X_SLNQ_DIG_SW_EVENT_CTRL 0x0562 +#define WCD934X_SLNQ_DIG_PDM_SELECT_1 0x0563 +#define WCD934X_SLNQ_DIG_PDM_SELECT_2 0x0564 +#define WCD934X_SLNQ_DIG_PDM_SELECT_3 0x0565 +#define WCD934X_SLNQ_DIG_PDM_SAMPLING_FREQ 0x0566 +#define WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_CTL 0x0569 +#define WCD934X_SLNQ_DIG_PDM_DC_CONVERSION_SEL 0x056a +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_MSB 0x056b +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHA_LSB 0x056c +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_MSB 0x056d +#define WCD934X_SLNQ_DIG_PDM_DC_CONV_CHB_LSB 0x056e +#define WCD934X_SLNQ_DIG_RAM_CNTRL 0x0571 +#define WCD934X_SLNQ_DIG_SRAM_BANK 0x0572 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_0 0x0573 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1 0x0574 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2 0x0575 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3 0x0576 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_4 0x0577 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_5 0x0578 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_6 0x0579 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_7 0x057a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_8 0x057b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_9 0x057c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_A 0x057d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_B 0x057e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_C 0x057f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_D 0x0580 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_E 0x0581 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_F 0x0582 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_10 0x0583 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_11 0x0584 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_12 0x0585 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_13 0x0586 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_14 0x0587 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_15 0x0588 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_16 0x0589 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_17 0x058a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_18 0x058b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_19 0x058c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1A 0x058d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1B 0x058e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1C 0x058f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1D 0x0590 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1E 0x0591 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_1F 0x0592 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_20 0x0593 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_21 0x0594 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_22 0x0595 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_23 0x0596 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_24 0x0597 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_25 0x0598 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_26 0x0599 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_27 0x059a +#define WCD934X_SLNQ_DIG_SRAM_BYTE_28 0x059b +#define WCD934X_SLNQ_DIG_SRAM_BYTE_29 0x059c +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2A 0x059d +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2B 0x059e +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2C 0x059f +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2D 0x05a0 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2E 0x05a1 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_2F 0x05a2 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_30 0x05a3 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_31 0x05a4 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_32 0x05a5 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_33 0x05a6 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_34 0x05a7 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_35 0x05a8 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_36 0x05a9 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_37 0x05aa +#define WCD934X_SLNQ_DIG_SRAM_BYTE_38 0x05ab +#define WCD934X_SLNQ_DIG_SRAM_BYTE_39 0x05ac +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3A 0x05ad +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3B 0x05ae +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3C 0x05af +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3D 0x05b0 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3E 0x05b1 +#define WCD934X_SLNQ_DIG_SRAM_BYTE_3F 0x05b2 +#define WCD934X_SLNQ_DIG_TOP_CTRL1 0x05b3 +#define WCD934X_SLNQ_DIG_TOP_CTRL2 0x05b4 +#define WCD934X_SLNQ_DIG_PDM_CTRL 0x05b5 +#define WCD934X_SLNQ_DIG_PDM_MUTE_CTRL 0x05b6 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_CTRL 0x05b7 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_STATUS 0x05b8 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_FS 0x05b9 +#define WCD934X_SLNQ_DIG_DEC_BYPASS_IN_SEL 0x05ba +#define WCD934X_SLNQ_DIG_GPOUT_ENABLE 0x05bb +#define WCD934X_SLNQ_DIG_GPOUT_VAL 0x05bc +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_MASK 0x05be +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_STATUS 0x05bf +#define WCD934X_SLNQ_DIG_ANA_INTERRUPT_CLR 0x05c0 +#define WCD934X_SLNQ_DIG_IP_TESTING 0x05c1 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNTRL 0x05e3 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT 0x05e9 +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT_MSB 0x05eb +#define WCD934X_SLNQ_DIG_INTERRUPT_CNT_LSB 0x05ec +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK0 0x05f1 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK1 0x05f2 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK2 0x05f3 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK3 0x05f4 +#define WCD934X_SLNQ_DIG_INTERRUPT_MASK4 0x05f5 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS0 0x05f6 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS1 0x05f7 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS2 0x05f8 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS3 0x05f9 +#define WCD934X_SLNQ_DIG_INTERRUPT_STATUS4 0x05fa +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR0 0x05fb +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR1 0x05fc +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR2 0x05fd +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR3 0x05fe +#define WCD934X_SLNQ_DIG_INTERRUPT_CLR4 0x05ff +#define WCD934X_ANA_PAGE_REGISTER 0x0600 +#define WCD934X_ANA_BIAS 0x0601 +#define WCD934X_ANA_RCO 0x0603 +#define WCD934X_ANA_PAGE6_SPARE2 0x0604 +#define WCD934X_ANA_PAGE6_SPARE3 0x0605 +#define WCD934X_ANA_BUCK_CTL 0x0606 +#define WCD934X_ANA_BUCK_STATUS 0x0607 +#define WCD934X_ANA_RX_SUPPLIES 0x0608 +#define WCD934X_ANA_HPH 0x0609 +#define WCD934X_ANA_EAR 0x060a +#define WCD934X_ANA_LO_1_2 0x060b +#define WCD934X_ANA_MAD_SETUP 0x060d +#define WCD934X_ANA_AMIC1 0x060e +#define WCD934X_ANA_AMIC2 0x060f +#define WCD934X_ANA_AMIC3 0x0610 +#define WCD934X_ANA_AMIC4 0x0611 +#define WCD934X_ANA_MBHC_MECH 0x0614 +#define WCD934X_ANA_MBHC_ELECT 0x0615 +#define WCD934X_ANA_MBHC_ZDET 0x0616 +#define WCD934X_ANA_MBHC_RESULT_1 0x0617 +#define WCD934X_ANA_MBHC_RESULT_2 0x0618 +#define WCD934X_ANA_MBHC_RESULT_3 0x0619 +#define WCD934X_ANA_MBHC_BTN0 0x061a +#define WCD934X_ANA_MBHC_BTN1 0x061b +#define WCD934X_ANA_MBHC_BTN2 0x061c +#define WCD934X_ANA_MBHC_BTN3 0x061d +#define WCD934X_ANA_MBHC_BTN4 0x061e +#define WCD934X_ANA_MBHC_BTN5 0x061f +#define WCD934X_ANA_MBHC_BTN6 0x0620 +#define WCD934X_ANA_MBHC_BTN7 0x0621 +#define WCD934X_ANA_MICB1 0x0622 +#define WCD934X_ANA_MICB2 0x0623 +#define WCD934X_ANA_MICB2_RAMP 0x0624 +#define WCD934X_ANA_MICB3 0x0625 +#define WCD934X_ANA_MICB4 0x0626 +#define WCD934X_ANA_VBADC 0x0627 +#define WCD934X_BIAS_CTL 0x0628 +#define WCD934X_BIAS_VBG_FINE_ADJ 0x0629 +#define WCD934X_RCO_CTRL_1 0x062e +#define WCD934X_RCO_CTRL_2 0x062f +#define WCD934X_RCO_CAL 0x0630 +#define WCD934X_RCO_CAL_1 0x0631 +#define WCD934X_RCO_CAL_2 0x0632 +#define WCD934X_RCO_TEST_CTRL 0x0633 +#define WCD934X_RCO_CAL_OUT_1 0x0634 +#define WCD934X_RCO_CAL_OUT_2 0x0635 +#define WCD934X_RCO_CAL_OUT_3 0x0636 +#define WCD934X_RCO_CAL_OUT_4 0x0637 +#define WCD934X_RCO_CAL_OUT_5 0x0638 +#define WCD934X_SIDO_MODE_1 0x063a +#define WCD934X_SIDO_MODE_2 0x063b +#define WCD934X_SIDO_MODE_3 0x063c +#define WCD934X_SIDO_MODE_4 0x063d +#define WCD934X_SIDO_VCL_1 0x063e +#define WCD934X_SIDO_VCL_2 0x063f +#define WCD934X_SIDO_VCL_3 0x0640 +#define WCD934X_SIDO_CCL_1 0x0641 +#define WCD934X_SIDO_CCL_2 0x0642 +#define WCD934X_SIDO_CCL_3 0x0643 +#define WCD934X_SIDO_CCL_4 0x0644 +#define WCD934X_SIDO_CCL_5 0x0645 +#define WCD934X_SIDO_CCL_6 0x0646 +#define WCD934X_SIDO_CCL_7 0x0647 +#define WCD934X_SIDO_CCL_8 0x0648 +#define WCD934X_SIDO_CCL_9 0x0649 +#define WCD934X_SIDO_CCL_10 0x064a +#define WCD934X_SIDO_FILTER_1 0x064b +#define WCD934X_SIDO_FILTER_2 0x064c +#define WCD934X_SIDO_DRIVER_1 0x064d +#define WCD934X_SIDO_DRIVER_2 0x064e +#define WCD934X_SIDO_DRIVER_3 0x064f +#define WCD934X_SIDO_CAL_CODE_EXT_1 0x0650 +#define WCD934X_SIDO_CAL_CODE_EXT_2 0x0651 +#define WCD934X_SIDO_CAL_CODE_OUT_1 0x0652 +#define WCD934X_SIDO_CAL_CODE_OUT_2 0x0653 +#define WCD934X_SIDO_TEST_1 0x0654 +#define WCD934X_SIDO_TEST_2 0x0655 +#define WCD934X_MBHC_CTL_CLK 0x0656 +#define WCD934X_MBHC_CTL_ANA 0x0657 +#define WCD934X_MBHC_CTL_SPARE_1 0x0658 +#define WCD934X_MBHC_CTL_SPARE_2 0x0659 +#define WCD934X_MBHC_CTL_BCS 0x065a +#define WCD934X_MBHC_STATUS_SPARE_1 0x065b +#define WCD934X_MBHC_TEST_CTL 0x065c +#define WCD934X_VBADC_SUBBLOCK_EN 0x065d +#define WCD934X_VBADC_IBIAS_FE 0x065e +#define WCD934X_VBADC_BIAS_ADC 0x065f +#define WCD934X_VBADC_FE_CTRL 0x0660 +#define WCD934X_VBADC_ADC_REF 0x0661 +#define WCD934X_VBADC_ADC_IO 0x0662 +#define WCD934X_VBADC_ADC_SAR 0x0663 +#define WCD934X_VBADC_DEBUG 0x0664 +#define WCD934X_LDOH_MODE 0x0667 +#define WCD934X_LDOH_BIAS 0x0668 +#define WCD934X_LDOH_STB_LOADS 0x0669 +#define WCD934X_LDOH_SLOWRAMP 0x066a +#define WCD934X_MICB1_TEST_CTL_1 0x066b +#define WCD934X_MICB1_TEST_CTL_2 0x066c +#define WCD934X_MICB1_TEST_CTL_3 0x066d +#define WCD934X_MICB2_TEST_CTL_1 0x066e +#define WCD934X_MICB2_TEST_CTL_2 0x066f +#define WCD934X_MICB2_TEST_CTL_3 0x0670 +#define WCD934X_MICB3_TEST_CTL_1 0x0671 +#define WCD934X_MICB3_TEST_CTL_2 0x0672 +#define WCD934X_MICB3_TEST_CTL_3 0x0673 +#define WCD934X_MICB4_TEST_CTL_1 0x0674 +#define WCD934X_MICB4_TEST_CTL_2 0x0675 +#define WCD934X_MICB4_TEST_CTL_3 0x0676 +#define WCD934X_TX_COM_ADC_VCM 0x0677 +#define WCD934X_TX_COM_BIAS_ATEST 0x0678 +#define WCD934X_TX_COM_ADC_INT1_IB 0x0679 +#define WCD934X_TX_COM_ADC_INT2_IB 0x067a +#define WCD934X_TX_COM_TXFE_DIV_CTL 0x067b +#define WCD934X_TX_COM_TXFE_DIV_START 0x067c +#define WCD934X_TX_COM_TXFE_DIV_STOP_9P6M 0x067d +#define WCD934X_TX_COM_TXFE_DIV_STOP_12P288M 0x067e +#define WCD934X_TX_1_2_TEST_EN 0x067f +#define WCD934X_TX_1_2_ADC_IB 0x0680 +#define WCD934X_TX_1_2_ATEST_REFCTL 0x0681 +#define WCD934X_TX_1_2_TEST_CTL 0x0682 +#define WCD934X_TX_1_2_TEST_BLK_EN 0x0683 +#define WCD934X_TX_1_2_TXFE_CLKDIV 0x0684 +#define WCD934X_TX_1_2_SAR1_ERR 0x0685 +#define WCD934X_TX_1_2_SAR2_ERR 0x0686 +#define WCD934X_TX_3_4_TEST_EN 0x0687 +#define WCD934X_TX_3_4_ADC_IB 0x0688 +#define WCD934X_TX_3_4_ATEST_REFCTL 0x0689 +#define WCD934X_TX_3_4_TEST_CTL 0x068a +#define WCD934X_TX_3_4_TEST_BLK_EN 0x068b +#define WCD934X_TX_3_4_TXFE_CLKDIV 0x068c +#define WCD934X_TX_3_4_SAR1_ERR 0x068d +#define WCD934X_TX_3_4_SAR2_ERR 0x068e +#define WCD934X_CLASSH_MODE_1 0x0697 +#define WCD934X_CLASSH_MODE_2 0x0698 +#define WCD934X_CLASSH_MODE_3 0x0699 +#define WCD934X_CLASSH_CTRL_VCL_1 0x069a +#define WCD934X_CLASSH_CTRL_VCL_2 0x069b +#define WCD934X_CLASSH_CTRL_CCL_1 0x069c +#define WCD934X_CLASSH_CTRL_CCL_2 0x069d +#define WCD934X_CLASSH_CTRL_CCL_3 0x069e +#define WCD934X_CLASSH_CTRL_CCL_4 0x069f +#define WCD934X_CLASSH_CTRL_CCL_5 0x06a0 +#define WCD934X_CLASSH_BUCK_TMUX_A_D 0x06a1 +#define WCD934X_CLASSH_BUCK_SW_DRV_CNTL 0x06a2 +#define WCD934X_CLASSH_SPARE 0x06a3 +#define WCD934X_FLYBACK_EN 0x06a4 +#define WCD934X_FLYBACK_VNEG_CTRL_1 0x06a5 +#define WCD934X_FLYBACK_VNEG_CTRL_2 0x06a6 +#define WCD934X_FLYBACK_VNEG_CTRL_3 0x06a7 +#define WCD934X_FLYBACK_VNEG_CTRL_4 0x06a8 +#define WCD934X_FLYBACK_VNEG_CTRL_5 0x06a9 +#define WCD934X_FLYBACK_VNEG_CTRL_6 0x06aa +#define WCD934X_FLYBACK_VNEG_CTRL_7 0x06ab +#define WCD934X_FLYBACK_VNEG_CTRL_8 0x06ac +#define WCD934X_FLYBACK_VNEG_CTRL_9 0x06ad +#define WCD934X_FLYBACK_VNEGDAC_CTRL_1 0x06ae +#define WCD934X_FLYBACK_VNEGDAC_CTRL_2 0x06af +#define WCD934X_FLYBACK_VNEGDAC_CTRL_3 0x06b0 +#define WCD934X_FLYBACK_CTRL_1 0x06b1 +#define WCD934X_FLYBACK_TEST_CTL 0x06b2 +#define WCD934X_RX_AUX_SW_CTL 0x06b3 +#define WCD934X_RX_PA_AUX_IN_CONN 0x06b4 +#define WCD934X_RX_TIMER_DIV 0x06b5 +#define WCD934X_RX_OCP_CTL 0x06b6 +#define WCD934X_RX_OCP_COUNT 0x06b7 +#define WCD934X_RX_BIAS_EAR_DAC 0x06b8 +#define WCD934X_RX_BIAS_EAR_AMP 0x06b9 +#define WCD934X_RX_BIAS_HPH_LDO 0x06ba +#define WCD934X_RX_BIAS_HPH_PA 0x06bb +#define WCD934X_RX_BIAS_HPH_RDACBUFF_CNP2 0x06bc +#define WCD934X_RX_BIAS_HPH_RDAC_LDO 0x06bd +#define WCD934X_RX_BIAS_HPH_CNP1 0x06be +#define WCD934X_RX_BIAS_HPH_LOWPOWER 0x06bf +#define WCD934X_RX_BIAS_DIFFLO_PA 0x06c0 +#define WCD934X_RX_BIAS_DIFFLO_REF 0x06c1 +#define WCD934X_RX_BIAS_DIFFLO_LDO 0x06c2 +#define WCD934X_RX_BIAS_SELO_DAC_PA 0x06c3 +#define WCD934X_RX_BIAS_BUCK_RST 0x06c4 +#define WCD934X_RX_BIAS_BUCK_VREF_ERRAMP 0x06c5 +#define WCD934X_RX_BIAS_FLYB_ERRAMP 0x06c6 +#define WCD934X_RX_BIAS_FLYB_BUFF 0x06c7 +#define WCD934X_RX_BIAS_FLYB_MID_RST 0x06c8 +#define WCD934X_HPH_L_STATUS 0x06c9 +#define WCD934X_HPH_R_STATUS 0x06ca +#define WCD934X_HPH_CNP_EN 0x06cb +#define WCD934X_HPH_CNP_WG_CTL 0x06cc +#define WCD934X_HPH_CNP_WG_TIME 0x06cd +#define WCD934X_HPH_OCP_CTL 0x06ce +#define WCD934X_HPH_AUTO_CHOP 0x06cf +#define WCD934X_HPH_CHOP_CTL 0x06d0 +#define WCD934X_HPH_PA_CTL1 0x06d1 +#define WCD934X_HPH_PA_CTL2 0x06d2 +#define WCD934X_HPH_L_EN 0x06d3 +#define WCD934X_HPH_L_TEST 0x06d4 +#define WCD934X_HPH_L_ATEST 0x06d5 +#define WCD934X_HPH_R_EN 0x06d6 +#define WCD934X_HPH_R_TEST 0x06d7 +#define WCD934X_HPH_R_ATEST 0x06d8 +#define WCD934X_HPH_RDAC_CLK_CTL1 0x06d9 +#define WCD934X_HPH_RDAC_CLK_CTL2 0x06da +#define WCD934X_HPH_RDAC_LDO_CTL 0x06db +#define WCD934X_HPH_RDAC_CHOP_CLK_LP_CTL 0x06dc +#define WCD934X_HPH_REFBUFF_UHQA_CTL 0x06dd +#define WCD934X_HPH_REFBUFF_LP_CTL 0x06de +#define WCD934X_HPH_L_DAC_CTL 0x06df +#define WCD934X_HPH_R_DAC_CTL 0x06e0 +#define WCD934X_EAR_EN_REG 0x06e1 +#define WCD934X_EAR_CMBUFF 0x06e2 +#define WCD934X_EAR_ICTL 0x06e3 +#define WCD934X_EAR_EN_DBG_CTL 0x06e4 +#define WCD934X_EAR_CNP 0x06e5 +#define WCD934X_EAR_DAC_CTL_ATEST 0x06e6 +#define WCD934X_EAR_STATUS_REG 0x06e7 +#define WCD934X_EAR_EAR_MISC 0x06e8 +#define WCD934X_DIFF_LO_MISC 0x06e9 +#define WCD934X_DIFF_LO_LO2_COMPANDER 0x06ea +#define WCD934X_DIFF_LO_LO1_COMPANDER 0x06eb +#define WCD934X_DIFF_LO_COMMON 0x06ec +#define WCD934X_DIFF_LO_BYPASS_EN 0x06ed +#define WCD934X_DIFF_LO_CNP 0x06ee +#define WCD934X_DIFF_LO_CORE_OUT_PROG 0x06ef +#define WCD934X_DIFF_LO_LDO_OUT_PROG 0x06f0 +#define WCD934X_DIFF_LO_COM_SWCAP_REFBUF_FREQ 0x06f1 +#define WCD934X_DIFF_LO_COM_PA_FREQ 0x06f2 +#define WCD934X_DIFF_LO_RESERVED_REG 0x06f3 +#define WCD934X_DIFF_LO_LO1_STATUS_1 0x06f4 +#define WCD934X_DIFF_LO_LO1_STATUS_2 0x06f5 +#define WCD934X_ANA_NEW_PAGE_REGISTER 0x0700 +#define WCD934X_HPH_NEW_ANA_HPH2 0x0701 +#define WCD934X_HPH_NEW_ANA_HPH3 0x0702 +#define WCD934X_SLNQ_ANA_EN 0x0703 +#define WCD934X_SLNQ_ANA_STATUS 0x0704 +#define WCD934X_SLNQ_ANA_LDO_CONFIG 0x0705 +#define WCD934X_SLNQ_ANA_LDO_OCP_CONFIG 0x0706 +#define WCD934X_SLNQ_ANA_TX_LDO_CONFIG 0x0707 +#define WCD934X_SLNQ_ANA_TX_DRV_CONFIG 0x0708 +#define WCD934X_SLNQ_ANA_RX_CONFIG_1 0x0709 +#define WCD934X_SLNQ_ANA_RX_CONFIG_2 0x070a +#define WCD934X_SLNQ_ANA_PLL_ENABLES 0x070b +#define WCD934X_SLNQ_ANA_PLL_PRESET 0x070c +#define WCD934X_SLNQ_ANA_PLL_STATUS 0x070d +#define WCD934X_CLK_SYS_PLL_ENABLES 0x070e +#define WCD934X_CLK_SYS_PLL_PRESET 0x070f +#define WCD934X_CLK_SYS_PLL_STATUS 0x0710 +#define WCD934X_CLK_SYS_MCLK_PRG 0x0711 +#define WCD934X_CLK_SYS_MCLK2_PRG1 0x0712 +#define WCD934X_CLK_SYS_MCLK2_PRG2 0x0713 +#define WCD934X_CLK_SYS_XO_PRG 0x0714 +#define WCD934X_CLK_SYS_XO_CAP_XTP 0x0715 +#define WCD934X_CLK_SYS_XO_CAP_XTM 0x0716 +#define WCD934X_BOOST_BST_EN_DLY 0x0718 +#define WCD934X_BOOST_CTRL_ILIM 0x0719 +#define WCD934X_BOOST_VOUT_SETTING 0x071a +#define WCD934X_SIDO_NEW_VOUT_A_STARTUP 0x071b +#define WCD934X_SIDO_NEW_VOUT_D_STARTUP 0x071c +#define WCD934X_SIDO_NEW_VOUT_D_FREQ1 0x071d +#define WCD934X_SIDO_NEW_VOUT_D_FREQ2 0x071e +#define WCD934X_MBHC_NEW_ELECT_REM_CLAMP_CTL 0x071f +#define WCD934X_MBHC_NEW_CTL_1 0x0720 +#define WCD934X_MBHC_NEW_CTL_2 0x0721 +#define WCD934X_MBHC_NEW_PLUG_DETECT_CTL 0x0722 +#define WCD934X_MBHC_NEW_ZDET_ANA_CTL 0x0723 +#define WCD934X_MBHC_NEW_ZDET_RAMP_CTL 0x0724 +#define WCD934X_MBHC_NEW_FSM_STATUS 0x0725 +#define WCD934X_MBHC_NEW_ADC_RESULT 0x0726 +#define WCD934X_TX_NEW_AMIC_4_5_SEL 0x0727 +#define WCD934X_VBADC_NEW_ADC_MODE 0x072f +#define WCD934X_VBADC_NEW_ADC_DOUTMSB 0x0730 +#define WCD934X_VBADC_NEW_ADC_DOUTLSB 0x0731 +#define WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL 0x0732 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL 0x0733 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L 0x0733 +#define WCD934X_HPH_NEW_INT_RDAC_VREF_CTL 0x0734 +#define WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL 0x0735 +#define WCD934X_HPH_NEW_INT_RDAC_MISC1 0x0736 +#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R 0x0736 +#define WCD934X_HPH_NEW_INT_PA_MISC1 0x0737 +#define WCD934X_HPH_NEW_INT_PA_MISC2 0x0738 +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC 0x0739 +#define WCD934X_HPH_NEW_INT_HPH_TIMER1 0x073a +#define WCD934X_HPH_NEW_INT_HPH_TIMER2 0x073b +#define WCD934X_HPH_NEW_INT_HPH_TIMER3 0x073c +#define WCD934X_HPH_NEW_INT_HPH_TIMER4 0x073d +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC2 0x073e +#define WCD934X_HPH_NEW_INT_PA_RDAC_MISC3 0x073f +#define WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI 0x0745 +#define WCD934X_RX_NEW_INT_HPH_RDAC_BIAS_ULP 0x0746 +#define WCD934X_RX_NEW_INT_HPH_RDAC_LDO_LP 0x0747 +#define WCD934X_SLNQ_INT_ANA_INT_LDO_TEST 0x074b +#define WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_1 0x074c +#define WCD934X_SLNQ_INT_ANA_INT_LDO_DEBUG_2 0x074d +#define WCD934X_SLNQ_INT_ANA_INT_TX_LDO_TEST 0x074e +#define WCD934X_SLNQ_INT_ANA_INT_TX_DRV_TEST 0x074f +#define WCD934X_SLNQ_INT_ANA_INT_RX_TEST 0x0750 +#define WCD934X_SLNQ_INT_ANA_INT_RX_TEST_STATUS 0x0751 +#define WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_1 0x0752 +#define WCD934X_SLNQ_INT_ANA_INT_RX_DEBUG_2 0x0753 +#define WCD934X_SLNQ_INT_ANA_INT_CLK_CTRL 0x0754 +#define WCD934X_SLNQ_INT_ANA_INT_RESERVED_1 0x0755 +#define WCD934X_SLNQ_INT_ANA_INT_RESERVED_2 0x0756 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG0 0x0757 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_POST_DIV_REG1 0x0758 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG0 0x0759 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_REF_DIV_REG1 0x075a +#define WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG0 0x075b +#define WCD934X_SLNQ_INT_ANA_INT_PLL_FILTER_REG1 0x075c +#define WCD934X_SLNQ_INT_ANA_INT_PLL_L_VAL 0x075d +#define WCD934X_SLNQ_INT_ANA_INT_PLL_M_VAL 0x075e +#define WCD934X_SLNQ_INT_ANA_INT_PLL_N_VAL 0x075f +#define WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG0 0x0760 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_PFD_CP_DSM_PROG 0x0761 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_VCO_PROG 0x0762 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_TEST_REG1 0x0763 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_LDO_LOCK_CFG 0x0764 +#define WCD934X_SLNQ_INT_ANA_INT_PLL_DIG_LOCK_DET_CFG 0x0765 +#define WCD934X_CLK_SYS_INT_POST_DIV_REG0 0x076c +#define WCD934X_CLK_SYS_INT_POST_DIV_REG1 0x076d +#define WCD934X_CLK_SYS_INT_REF_DIV_REG0 0x076e +#define WCD934X_CLK_SYS_INT_REF_DIV_REG1 0x076f +#define WCD934X_CLK_SYS_INT_FILTER_REG0 0x0770 +#define WCD934X_CLK_SYS_INT_FILTER_REG1 0x0771 +#define WCD934X_CLK_SYS_INT_PLL_L_VAL 0x0772 +#define WCD934X_CLK_SYS_INT_PLL_M_VAL 0x0773 +#define WCD934X_CLK_SYS_INT_PLL_N_VAL 0x0774 +#define WCD934X_CLK_SYS_INT_TEST_REG0 0x0775 +#define WCD934X_CLK_SYS_INT_PFD_CP_DSM_PROG 0x0776 +#define WCD934X_CLK_SYS_INT_VCO_PROG 0x0777 +#define WCD934X_CLK_SYS_INT_TEST_REG1 0x0778 +#define WCD934X_CLK_SYS_INT_LDO_LOCK_CFG 0x0779 +#define WCD934X_CLK_SYS_INT_DIG_LOCK_DET_CFG 0x077a +#define WCD934X_CLK_SYS_INT_CLK_TEST1 0x077b +#define WCD934X_CLK_SYS_INT_CLK_TEST2 0x077c +#define WCD934X_CLK_SYS_INT_CLK_TEST3 0x077d +#define WCD934X_CLK_SYS_INT_XO_TEST1 0x077e +#define WCD934X_CLK_SYS_INT_XO_TEST2 0x077f +#define WCD934X_BOOST_INT_VCOMP_HYST 0x0787 +#define WCD934X_BOOST_INT_VLOOP_FILTER 0x0788 +#define WCD934X_BOOST_INT_CTRL_IDELTA 0x0789 +#define WCD934X_BOOST_INT_CTRL_ILIM_STARTUP 0x078a +#define WCD934X_BOOST_INT_CTRL_MIN_ONTIME 0x078b +#define WCD934X_BOOST_INT_CTRL_MAX_ONTIME 0x078c +#define WCD934X_BOOST_INT_CTRL_TIMING 0x078d +#define WCD934X_BOOST_INT_TMUX_A_D 0x078e +#define WCD934X_BOOST_INT_SW_DRV_CNTL 0x078f +#define WCD934X_BOOST_INT_SPARE1 0x0790 +#define WCD934X_BOOST_INT_SPARE2 0x0791 +#define WCD934X_SIDO_NEW_INT_RAMP_STATUS 0x0796 +#define WCD934X_SIDO_NEW_INT_SPARE_1 0x0797 +#define WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A 0x0798 +#define WCD934X_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D 0x0799 +#define WCD934X_SIDO_NEW_INT_RAMP_INC_WAIT 0x079a +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL 0x079b +#define WCD934X_SIDO_NEW_INT_RAMP_IBLEED_CTL 0x079c +#define WCD934X_SIDO_NEW_INT_DEBUG_CPROVR_TEST 0x079d +#define WCD934X_SIDO_NEW_INT_RAMP_CTL_A 0x079e +#define WCD934X_SIDO_NEW_INT_RAMP_CTL_D 0x079f +#define WCD934X_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD 0x07a0 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1 0x07a1 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2 0x07a2 +#define WCD934X_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3 0x07a3 +#define WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1 0x07a4 +#define WCD934X_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2 0x07a5 +#define WCD934X_MBHC_NEW_INT_SLNQ_HPF 0x07af +#define WCD934X_MBHC_NEW_INT_SLNQ_REF 0x07b0 +#define WCD934X_MBHC_NEW_INT_SLNQ_COMP 0x07b1 +#define WCD934X_MBHC_NEW_INT_SPARE_2 0x07b2 +#define WCD934X_PAGE10_PAGE_REGISTER 0x0a00 +#define WCD934X_CDC_ANC0_CLK_RESET_CTL 0x0a01 +#define WCD934X_CDC_ANC0_MODE_1_CTL 0x0a02 +#define WCD934X_CDC_ANC0_MODE_2_CTL 0x0a03 +#define WCD934X_CDC_ANC0_FF_SHIFT 0x0a04 +#define WCD934X_CDC_ANC0_FB_SHIFT 0x0a05 +#define WCD934X_CDC_ANC0_LPF_FF_A_CTL 0x0a06 +#define WCD934X_CDC_ANC0_LPF_FF_B_CTL 0x0a07 +#define WCD934X_CDC_ANC0_LPF_FB_CTL 0x0a08 +#define WCD934X_CDC_ANC0_SMLPF_CTL 0x0a09 +#define WCD934X_CDC_ANC0_DCFLT_SHIFT_CTL 0x0a0a +#define WCD934X_CDC_ANC0_IIR_ADAPT_CTL 0x0a0b +#define WCD934X_CDC_ANC0_IIR_COEFF_1_CTL 0x0a0c +#define WCD934X_CDC_ANC0_IIR_COEFF_2_CTL 0x0a0d +#define WCD934X_CDC_ANC0_FF_A_GAIN_CTL 0x0a0e +#define WCD934X_CDC_ANC0_FF_B_GAIN_CTL 0x0a0f +#define WCD934X_CDC_ANC0_FB_GAIN_CTL 0x0a10 +#define WCD934X_CDC_ANC0_RC_COMMON_CTL 0x0a11 +#define WCD934X_CDC_ANC0_FIFO_COMMON_CTL 0x0a13 +#define WCD934X_CDC_ANC0_RC0_STATUS_FMIN_CNTR 0x0a14 +#define WCD934X_CDC_ANC0_RC1_STATUS_FMIN_CNTR 0x0a15 +#define WCD934X_CDC_ANC0_RC0_STATUS_FMAX_CNTR 0x0a16 +#define WCD934X_CDC_ANC0_RC1_STATUS_FMAX_CNTR 0x0a17 +#define WCD934X_CDC_ANC0_STATUS_FIFO 0x0a18 +#define WCD934X_CDC_ANC1_CLK_RESET_CTL 0x0a19 +#define WCD934X_CDC_ANC1_MODE_1_CTL 0x0a1a +#define WCD934X_CDC_ANC1_MODE_2_CTL 0x0a1b +#define WCD934X_CDC_ANC1_FF_SHIFT 0x0a1c +#define WCD934X_CDC_ANC1_FB_SHIFT 0x0a1d +#define WCD934X_CDC_ANC1_LPF_FF_A_CTL 0x0a1e +#define WCD934X_CDC_ANC1_LPF_FF_B_CTL 0x0a1f +#define WCD934X_CDC_ANC1_LPF_FB_CTL 0x0a20 +#define WCD934X_CDC_ANC1_SMLPF_CTL 0x0a21 +#define WCD934X_CDC_ANC1_DCFLT_SHIFT_CTL 0x0a22 +#define WCD934X_CDC_ANC1_IIR_ADAPT_CTL 0x0a23 +#define WCD934X_CDC_ANC1_IIR_COEFF_1_CTL 0x0a24 +#define WCD934X_CDC_ANC1_IIR_COEFF_2_CTL 0x0a25 +#define WCD934X_CDC_ANC1_FF_A_GAIN_CTL 0x0a26 +#define WCD934X_CDC_ANC1_FF_B_GAIN_CTL 0x0a27 +#define WCD934X_CDC_ANC1_FB_GAIN_CTL 0x0a28 +#define WCD934X_CDC_ANC1_RC_COMMON_CTL 0x0a29 +#define WCD934X_CDC_ANC1_FIFO_COMMON_CTL 0x0a2b +#define WCD934X_CDC_ANC1_RC0_STATUS_FMIN_CNTR 0x0a2c +#define WCD934X_CDC_ANC1_RC1_STATUS_FMIN_CNTR 0x0a2d +#define WCD934X_CDC_ANC1_RC0_STATUS_FMAX_CNTR 0x0a2e +#define WCD934X_CDC_ANC1_RC1_STATUS_FMAX_CNTR 0x0a2f +#define WCD934X_CDC_ANC1_STATUS_FIFO 0x0a30 +#define WCD934X_CDC_TX0_TX_PATH_CTL 0x0a31 +#define WCD934X_CDC_TX0_TX_PATH_CFG0 0x0a32 +#define WCD934X_CDC_TX0_TX_PATH_CFG1 0x0a33 +#define WCD934X_CDC_TX0_TX_VOL_CTL 0x0a34 +#define WCD934X_CDC_TX0_TX_PATH_192_CTL 0x0a35 +#define WCD934X_CDC_TX0_TX_PATH_192_CFG 0x0a36 +#define WCD934X_CDC_TX0_TX_PATH_SEC0 0x0a37 +#define WCD934X_CDC_TX0_TX_PATH_SEC1 0x0a38 +#define WCD934X_CDC_TX0_TX_PATH_SEC2 0x0a39 +#define WCD934X_CDC_TX0_TX_PATH_SEC3 0x0a3a +#define WCD934X_CDC_TX0_TX_PATH_SEC4 0x0a3b +#define WCD934X_CDC_TX0_TX_PATH_SEC5 0x0a3c +#define WCD934X_CDC_TX0_TX_PATH_SEC6 0x0a3d +#define WCD934X_CDC_TX0_TX_PATH_SEC7 0x0a3e +#define WCD934X_CDC_TX1_TX_PATH_CTL 0x0a41 +#define WCD934X_CDC_TX1_TX_PATH_CFG0 0x0a42 +#define WCD934X_CDC_TX1_TX_PATH_CFG1 0x0a43 +#define WCD934X_CDC_TX1_TX_VOL_CTL 0x0a44 +#define WCD934X_CDC_TX1_TX_PATH_192_CTL 0x0a45 +#define WCD934X_CDC_TX1_TX_PATH_192_CFG 0x0a46 +#define WCD934X_CDC_TX1_TX_PATH_SEC0 0x0a47 +#define WCD934X_CDC_TX1_TX_PATH_SEC1 0x0a48 +#define WCD934X_CDC_TX1_TX_PATH_SEC2 0x0a49 +#define WCD934X_CDC_TX1_TX_PATH_SEC3 0x0a4a +#define WCD934X_CDC_TX1_TX_PATH_SEC4 0x0a4b +#define WCD934X_CDC_TX1_TX_PATH_SEC5 0x0a4c +#define WCD934X_CDC_TX1_TX_PATH_SEC6 0x0a4d +#define WCD934X_CDC_TX2_TX_PATH_CTL 0x0a51 +#define WCD934X_CDC_TX2_TX_PATH_CFG0 0x0a52 +#define WCD934X_CDC_TX2_TX_PATH_CFG1 0x0a53 +#define WCD934X_CDC_TX2_TX_VOL_CTL 0x0a54 +#define WCD934X_CDC_TX2_TX_PATH_192_CTL 0x0a55 +#define WCD934X_CDC_TX2_TX_PATH_192_CFG 0x0a56 +#define WCD934X_CDC_TX2_TX_PATH_SEC0 0x0a57 +#define WCD934X_CDC_TX2_TX_PATH_SEC1 0x0a58 +#define WCD934X_CDC_TX2_TX_PATH_SEC2 0x0a59 +#define WCD934X_CDC_TX2_TX_PATH_SEC3 0x0a5a +#define WCD934X_CDC_TX2_TX_PATH_SEC4 0x0a5b +#define WCD934X_CDC_TX2_TX_PATH_SEC5 0x0a5c +#define WCD934X_CDC_TX2_TX_PATH_SEC6 0x0a5d +#define WCD934X_CDC_TX3_TX_PATH_CTL 0x0a61 +#define WCD934X_CDC_TX3_TX_PATH_CFG0 0x0a62 +#define WCD934X_CDC_TX3_TX_PATH_CFG1 0x0a63 +#define WCD934X_CDC_TX3_TX_VOL_CTL 0x0a64 +#define WCD934X_CDC_TX3_TX_PATH_192_CTL 0x0a65 +#define WCD934X_CDC_TX3_TX_PATH_192_CFG 0x0a66 +#define WCD934X_CDC_TX3_TX_PATH_SEC0 0x0a67 +#define WCD934X_CDC_TX3_TX_PATH_SEC1 0x0a68 +#define WCD934X_CDC_TX3_TX_PATH_SEC2 0x0a69 +#define WCD934X_CDC_TX3_TX_PATH_SEC3 0x0a6a +#define WCD934X_CDC_TX3_TX_PATH_SEC4 0x0a6b +#define WCD934X_CDC_TX3_TX_PATH_SEC5 0x0a6c +#define WCD934X_CDC_TX3_TX_PATH_SEC6 0x0a6d +#define WCD934X_CDC_TX4_TX_PATH_CTL 0x0a71 +#define WCD934X_CDC_TX4_TX_PATH_CFG0 0x0a72 +#define WCD934X_CDC_TX4_TX_PATH_CFG1 0x0a73 +#define WCD934X_CDC_TX4_TX_VOL_CTL 0x0a74 +#define WCD934X_CDC_TX4_TX_PATH_192_CTL 0x0a75 +#define WCD934X_CDC_TX4_TX_PATH_192_CFG 0x0a76 +#define WCD934X_CDC_TX4_TX_PATH_SEC0 0x0a77 +#define WCD934X_CDC_TX4_TX_PATH_SEC1 0x0a78 +#define WCD934X_CDC_TX4_TX_PATH_SEC2 0x0a79 +#define WCD934X_CDC_TX4_TX_PATH_SEC3 0x0a7a +#define WCD934X_CDC_TX4_TX_PATH_SEC4 0x0a7b +#define WCD934X_CDC_TX4_TX_PATH_SEC5 0x0a7c +#define WCD934X_CDC_TX4_TX_PATH_SEC6 0x0a7d +#define WCD934X_CDC_TX5_TX_PATH_CTL 0x0a81 +#define WCD934X_CDC_TX5_TX_PATH_CFG0 0x0a82 +#define WCD934X_CDC_TX5_TX_PATH_CFG1 0x0a83 +#define WCD934X_CDC_TX5_TX_VOL_CTL 0x0a84 +#define WCD934X_CDC_TX5_TX_PATH_192_CTL 0x0a85 +#define WCD934X_CDC_TX5_TX_PATH_192_CFG 0x0a86 +#define WCD934X_CDC_TX5_TX_PATH_SEC0 0x0a87 +#define WCD934X_CDC_TX5_TX_PATH_SEC1 0x0a88 +#define WCD934X_CDC_TX5_TX_PATH_SEC2 0x0a89 +#define WCD934X_CDC_TX5_TX_PATH_SEC3 0x0a8a +#define WCD934X_CDC_TX5_TX_PATH_SEC4 0x0a8b +#define WCD934X_CDC_TX5_TX_PATH_SEC5 0x0a8c +#define WCD934X_CDC_TX5_TX_PATH_SEC6 0x0a8d +#define WCD934X_CDC_TX6_TX_PATH_CTL 0x0a91 +#define WCD934X_CDC_TX6_TX_PATH_CFG0 0x0a92 +#define WCD934X_CDC_TX6_TX_PATH_CFG1 0x0a93 +#define WCD934X_CDC_TX6_TX_VOL_CTL 0x0a94 +#define WCD934X_CDC_TX6_TX_PATH_192_CTL 0x0a95 +#define WCD934X_CDC_TX6_TX_PATH_192_CFG 0x0a96 +#define WCD934X_CDC_TX6_TX_PATH_SEC0 0x0a97 +#define WCD934X_CDC_TX6_TX_PATH_SEC1 0x0a98 +#define WCD934X_CDC_TX6_TX_PATH_SEC2 0x0a99 +#define WCD934X_CDC_TX6_TX_PATH_SEC3 0x0a9a +#define WCD934X_CDC_TX6_TX_PATH_SEC4 0x0a9b +#define WCD934X_CDC_TX6_TX_PATH_SEC5 0x0a9c +#define WCD934X_CDC_TX6_TX_PATH_SEC6 0x0a9d +#define WCD934X_CDC_TX7_TX_PATH_CTL 0x0aa1 +#define WCD934X_CDC_TX7_TX_PATH_CFG0 0x0aa2 +#define WCD934X_CDC_TX7_TX_PATH_CFG1 0x0aa3 +#define WCD934X_CDC_TX7_TX_VOL_CTL 0x0aa4 +#define WCD934X_CDC_TX7_TX_PATH_192_CTL 0x0aa5 +#define WCD934X_CDC_TX7_TX_PATH_192_CFG 0x0aa6 +#define WCD934X_CDC_TX7_TX_PATH_SEC0 0x0aa7 +#define WCD934X_CDC_TX7_TX_PATH_SEC1 0x0aa8 +#define WCD934X_CDC_TX7_TX_PATH_SEC2 0x0aa9 +#define WCD934X_CDC_TX7_TX_PATH_SEC3 0x0aaa +#define WCD934X_CDC_TX7_TX_PATH_SEC4 0x0aab +#define WCD934X_CDC_TX7_TX_PATH_SEC5 0x0aac +#define WCD934X_CDC_TX7_TX_PATH_SEC6 0x0aad +#define WCD934X_CDC_TX8_TX_PATH_CTL 0x0ab1 +#define WCD934X_CDC_TX8_TX_PATH_CFG0 0x0ab2 +#define WCD934X_CDC_TX8_TX_PATH_CFG1 0x0ab3 +#define WCD934X_CDC_TX8_TX_VOL_CTL 0x0ab4 +#define WCD934X_CDC_TX8_TX_PATH_192_CTL 0x0ab5 +#define WCD934X_CDC_TX8_TX_PATH_192_CFG 0x0ab6 +#define WCD934X_CDC_TX8_TX_PATH_SEC0 0x0ab7 +#define WCD934X_CDC_TX8_TX_PATH_SEC1 0x0ab8 +#define WCD934X_CDC_TX8_TX_PATH_SEC2 0x0ab9 +#define WCD934X_CDC_TX8_TX_PATH_SEC3 0x0aba +#define WCD934X_CDC_TX8_TX_PATH_SEC4 0x0abb +#define WCD934X_CDC_TX8_TX_PATH_SEC5 0x0abc +#define WCD934X_CDC_TX8_TX_PATH_SEC6 0x0abd +#define WCD934X_CDC_TX9_SPKR_PROT_PATH_CTL 0x0ac2 +#define WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0 0x0ac3 +#define WCD934X_CDC_TX10_SPKR_PROT_PATH_CTL 0x0ac6 +#define WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0 0x0ac7 +#define WCD934X_CDC_TX11_SPKR_PROT_PATH_CTL 0x0aca +#define WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0 0x0acb +#define WCD934X_CDC_TX12_SPKR_PROT_PATH_CTL 0x0ace +#define WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0 0x0acf +#define WCD934X_PAGE11_PAGE_REGISTER 0x0b00 +#define WCD934X_CDC_COMPANDER1_CTL0 0x0b01 +#define WCD934X_CDC_COMPANDER1_CTL1 0x0b02 +#define WCD934X_CDC_COMPANDER1_CTL2 0x0b03 +#define WCD934X_CDC_COMPANDER1_CTL3 0x0b04 +#define WCD934X_CDC_COMPANDER1_CTL4 0x0b05 +#define WCD934X_CDC_COMPANDER1_CTL5 0x0b06 +#define WCD934X_CDC_COMPANDER1_CTL6 0x0b07 +#define WCD934X_CDC_COMPANDER1_CTL7 0x0b08 +#define WCD934X_CDC_COMPANDER2_CTL0 0x0b09 +#define WCD934X_CDC_COMPANDER2_CTL1 0x0b0a +#define WCD934X_CDC_COMPANDER2_CTL2 0x0b0b +#define WCD934X_CDC_COMPANDER2_CTL3 0x0b0c +#define WCD934X_CDC_COMPANDER2_CTL4 0x0b0d +#define WCD934X_CDC_COMPANDER2_CTL5 0x0b0e +#define WCD934X_CDC_COMPANDER2_CTL6 0x0b0f +#define WCD934X_CDC_COMPANDER2_CTL7 0x0b10 +#define WCD934X_CDC_COMPANDER3_CTL0 0x0b11 +#define WCD934X_CDC_COMPANDER3_CTL1 0x0b12 +#define WCD934X_CDC_COMPANDER3_CTL2 0x0b13 +#define WCD934X_CDC_COMPANDER3_CTL3 0x0b14 +#define WCD934X_CDC_COMPANDER3_CTL4 0x0b15 +#define WCD934X_CDC_COMPANDER3_CTL5 0x0b16 +#define WCD934X_CDC_COMPANDER3_CTL6 0x0b17 +#define WCD934X_CDC_COMPANDER3_CTL7 0x0b18 +#define WCD934X_CDC_COMPANDER4_CTL0 0x0b19 +#define WCD934X_CDC_COMPANDER4_CTL1 0x0b1a +#define WCD934X_CDC_COMPANDER4_CTL2 0x0b1b +#define WCD934X_CDC_COMPANDER4_CTL3 0x0b1c +#define WCD934X_CDC_COMPANDER4_CTL4 0x0b1d +#define WCD934X_CDC_COMPANDER4_CTL5 0x0b1e +#define WCD934X_CDC_COMPANDER4_CTL6 0x0b1f +#define WCD934X_CDC_COMPANDER4_CTL7 0x0b20 +#define WCD934X_CDC_COMPANDER7_CTL0 0x0b31 +#define WCD934X_CDC_COMPANDER7_CTL1 0x0b32 +#define WCD934X_CDC_COMPANDER7_CTL2 0x0b33 +#define WCD934X_CDC_COMPANDER7_CTL3 0x0b34 +#define WCD934X_CDC_COMPANDER7_CTL4 0x0b35 +#define WCD934X_CDC_COMPANDER7_CTL5 0x0b36 +#define WCD934X_CDC_COMPANDER7_CTL6 0x0b37 +#define WCD934X_CDC_COMPANDER7_CTL7 0x0b38 +#define WCD934X_CDC_COMPANDER8_CTL0 0x0b39 +#define WCD934X_CDC_COMPANDER8_CTL1 0x0b3a +#define WCD934X_CDC_COMPANDER8_CTL2 0x0b3b +#define WCD934X_CDC_COMPANDER8_CTL3 0x0b3c +#define WCD934X_CDC_COMPANDER8_CTL4 0x0b3d +#define WCD934X_CDC_COMPANDER8_CTL5 0x0b3e +#define WCD934X_CDC_COMPANDER8_CTL6 0x0b3f +#define WCD934X_CDC_COMPANDER8_CTL7 0x0b40 +#define WCD934X_CDC_RX0_RX_PATH_CTL 0x0b41 +#define WCD934X_CDC_RX0_RX_PATH_CFG0 0x0b42 +#define WCD934X_CDC_RX0_RX_PATH_CFG1 0x0b43 +#define WCD934X_CDC_RX0_RX_PATH_CFG2 0x0b44 +#define WCD934X_CDC_RX0_RX_VOL_CTL 0x0b45 +#define WCD934X_CDC_RX0_RX_PATH_MIX_CTL 0x0b46 +#define WCD934X_CDC_RX0_RX_PATH_MIX_CFG 0x0b47 +#define WCD934X_CDC_RX0_RX_VOL_MIX_CTL 0x0b48 +#define WCD934X_CDC_RX0_RX_PATH_SEC0 0x0b49 +#define WCD934X_CDC_RX0_RX_PATH_SEC1 0x0b4a +#define WCD934X_CDC_RX0_RX_PATH_SEC2 0x0b4b +#define WCD934X_CDC_RX0_RX_PATH_SEC3 0x0b4c +#define WCD934X_CDC_RX0_RX_PATH_SEC5 0x0b4e +#define WCD934X_CDC_RX0_RX_PATH_SEC6 0x0b4f +#define WCD934X_CDC_RX0_RX_PATH_SEC7 0x0b50 +#define WCD934X_CDC_RX0_RX_PATH_MIX_SEC0 0x0b51 +#define WCD934X_CDC_RX0_RX_PATH_MIX_SEC1 0x0b52 +#define WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL 0x0b53 +#define WCD934X_CDC_RX1_RX_PATH_CTL 0x0b55 +#define WCD934X_CDC_RX1_RX_PATH_CFG0 0x0b56 +#define WCD934X_CDC_RX1_RX_PATH_CFG1 0x0b57 +#define WCD934X_CDC_RX1_RX_PATH_CFG2 0x0b58 +#define WCD934X_CDC_RX1_RX_VOL_CTL 0x0b59 +#define WCD934X_CDC_RX1_RX_PATH_MIX_CTL 0x0b5a +#define WCD934X_CDC_RX1_RX_PATH_MIX_CFG 0x0b5b +#define WCD934X_CDC_RX1_RX_VOL_MIX_CTL 0x0b5c +#define WCD934X_CDC_RX1_RX_PATH_SEC0 0x0b5d +#define WCD934X_CDC_RX1_RX_PATH_SEC1 0x0b5e +#define WCD934X_CDC_RX1_RX_PATH_SEC2 0x0b5f +#define WCD934X_CDC_RX1_RX_PATH_SEC3 0x0b60 +#define WCD934X_CDC_RX1_RX_PATH_SEC4 0x0b61 +#define WCD934X_CDC_RX1_RX_PATH_SEC5 0x0b62 +#define WCD934X_CDC_RX1_RX_PATH_SEC6 0x0b63 +#define WCD934X_CDC_RX1_RX_PATH_SEC7 0x0b64 +#define WCD934X_CDC_RX1_RX_PATH_MIX_SEC0 0x0b65 +#define WCD934X_CDC_RX1_RX_PATH_MIX_SEC1 0x0b66 +#define WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL 0x0b67 +#define WCD934X_CDC_RX2_RX_PATH_CTL 0x0b69 +#define WCD934X_CDC_RX2_RX_PATH_CFG0 0x0b6a +#define WCD934X_CDC_RX2_RX_PATH_CFG1 0x0b6b +#define WCD934X_CDC_RX2_RX_PATH_CFG2 0x0b6c +#define WCD934X_CDC_RX2_RX_VOL_CTL 0x0b6d +#define WCD934X_CDC_RX2_RX_PATH_MIX_CTL 0x0b6e +#define WCD934X_CDC_RX2_RX_PATH_MIX_CFG 0x0b6f +#define WCD934X_CDC_RX2_RX_VOL_MIX_CTL 0x0b70 +#define WCD934X_CDC_RX2_RX_PATH_SEC0 0x0b71 +#define WCD934X_CDC_RX2_RX_PATH_SEC1 0x0b72 +#define WCD934X_CDC_RX2_RX_PATH_SEC2 0x0b73 +#define WCD934X_CDC_RX2_RX_PATH_SEC3 0x0b74 +#define WCD934X_CDC_RX2_RX_PATH_SEC4 0x0b75 +#define WCD934X_CDC_RX2_RX_PATH_SEC5 0x0b76 +#define WCD934X_CDC_RX2_RX_PATH_SEC6 0x0b77 +#define WCD934X_CDC_RX2_RX_PATH_SEC7 0x0b78 +#define WCD934X_CDC_RX2_RX_PATH_MIX_SEC0 0x0b79 +#define WCD934X_CDC_RX2_RX_PATH_MIX_SEC1 0x0b7a +#define WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL 0x0b7b +#define WCD934X_CDC_RX3_RX_PATH_CTL 0x0b7d +#define WCD934X_CDC_RX3_RX_PATH_CFG0 0x0b7e +#define WCD934X_CDC_RX3_RX_PATH_CFG1 0x0b7f +#define WCD934X_CDC_RX3_RX_PATH_CFG2 0x0b80 +#define WCD934X_CDC_RX3_RX_VOL_CTL 0x0b81 +#define WCD934X_CDC_RX3_RX_PATH_MIX_CTL 0x0b82 +#define WCD934X_CDC_RX3_RX_PATH_MIX_CFG 0x0b83 +#define WCD934X_CDC_RX3_RX_VOL_MIX_CTL 0x0b84 +#define WCD934X_CDC_RX3_RX_PATH_SEC0 0x0b85 +#define WCD934X_CDC_RX3_RX_PATH_SEC1 0x0b86 +#define WCD934X_CDC_RX3_RX_PATH_SEC2 0x0b87 +#define WCD934X_CDC_RX3_RX_PATH_SEC3 0x0b88 +#define WCD934X_CDC_RX3_RX_PATH_SEC5 0x0b8a +#define WCD934X_CDC_RX3_RX_PATH_SEC6 0x0b8b +#define WCD934X_CDC_RX3_RX_PATH_SEC7 0x0b8c +#define WCD934X_CDC_RX3_RX_PATH_MIX_SEC0 0x0b8d +#define WCD934X_CDC_RX3_RX_PATH_MIX_SEC1 0x0b8e +#define WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL 0x0b8f +#define WCD934X_CDC_RX4_RX_PATH_CTL 0x0b91 +#define WCD934X_CDC_RX4_RX_PATH_CFG0 0x0b92 +#define WCD934X_CDC_RX4_RX_PATH_CFG1 0x0b93 +#define WCD934X_CDC_RX4_RX_PATH_CFG2 0x0b94 +#define WCD934X_CDC_RX4_RX_VOL_CTL 0x0b95 +#define WCD934X_CDC_RX4_RX_PATH_MIX_CTL 0x0b96 +#define WCD934X_CDC_RX4_RX_PATH_MIX_CFG 0x0b97 +#define WCD934X_CDC_RX4_RX_VOL_MIX_CTL 0x0b98 +#define WCD934X_CDC_RX4_RX_PATH_SEC0 0x0b99 +#define WCD934X_CDC_RX4_RX_PATH_SEC1 0x0b9a +#define WCD934X_CDC_RX4_RX_PATH_SEC2 0x0b9b +#define WCD934X_CDC_RX4_RX_PATH_SEC3 0x0b9c +#define WCD934X_CDC_RX4_RX_PATH_SEC5 0x0b9e +#define WCD934X_CDC_RX4_RX_PATH_SEC6 0x0b9f +#define WCD934X_CDC_RX4_RX_PATH_SEC7 0x0ba0 +#define WCD934X_CDC_RX4_RX_PATH_MIX_SEC0 0x0ba1 +#define WCD934X_CDC_RX4_RX_PATH_MIX_SEC1 0x0ba2 +#define WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL 0x0ba3 +#define WCD934X_CDC_RX7_RX_PATH_CTL 0x0bcd +#define WCD934X_CDC_RX7_RX_PATH_CFG0 0x0bce +#define WCD934X_CDC_RX7_RX_PATH_CFG1 0x0bcf +#define WCD934X_CDC_RX7_RX_PATH_CFG2 0x0bd0 +#define WCD934X_CDC_RX7_RX_VOL_CTL 0x0bd1 +#define WCD934X_CDC_RX7_RX_PATH_MIX_CTL 0x0bd2 +#define WCD934X_CDC_RX7_RX_PATH_MIX_CFG 0x0bd3 +#define WCD934X_CDC_RX7_RX_VOL_MIX_CTL 0x0bd4 +#define WCD934X_CDC_RX7_RX_PATH_SEC0 0x0bd5 +#define WCD934X_CDC_RX7_RX_PATH_SEC1 0x0bd6 +#define WCD934X_CDC_RX7_RX_PATH_SEC2 0x0bd7 +#define WCD934X_CDC_RX7_RX_PATH_SEC3 0x0bd8 +#define WCD934X_CDC_RX7_RX_PATH_SEC5 0x0bda +#define WCD934X_CDC_RX7_RX_PATH_SEC6 0x0bdb +#define WCD934X_CDC_RX7_RX_PATH_SEC7 0x0bdc +#define WCD934X_CDC_RX7_RX_PATH_MIX_SEC0 0x0bdd +#define WCD934X_CDC_RX7_RX_PATH_MIX_SEC1 0x0bde +#define WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL 0x0bdf +#define WCD934X_CDC_RX8_RX_PATH_CTL 0x0be1 +#define WCD934X_CDC_RX8_RX_PATH_CFG0 0x0be2 +#define WCD934X_CDC_RX8_RX_PATH_CFG1 0x0be3 +#define WCD934X_CDC_RX8_RX_PATH_CFG2 0x0be4 +#define WCD934X_CDC_RX8_RX_VOL_CTL 0x0be5 +#define WCD934X_CDC_RX8_RX_PATH_MIX_CTL 0x0be6 +#define WCD934X_CDC_RX8_RX_PATH_MIX_CFG 0x0be7 +#define WCD934X_CDC_RX8_RX_VOL_MIX_CTL 0x0be8 +#define WCD934X_CDC_RX8_RX_PATH_SEC0 0x0be9 +#define WCD934X_CDC_RX8_RX_PATH_SEC1 0x0bea +#define WCD934X_CDC_RX8_RX_PATH_SEC2 0x0beb +#define WCD934X_CDC_RX8_RX_PATH_SEC3 0x0bec +#define WCD934X_CDC_RX8_RX_PATH_SEC5 0x0bee +#define WCD934X_CDC_RX8_RX_PATH_SEC6 0x0bef +#define WCD934X_CDC_RX8_RX_PATH_SEC7 0x0bf0 +#define WCD934X_CDC_RX8_RX_PATH_MIX_SEC0 0x0bf1 +#define WCD934X_CDC_RX8_RX_PATH_MIX_SEC1 0x0bf2 +#define WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL 0x0bf3 +#define WCD934X_PAGE12_PAGE_REGISTER 0x0c00 +#define WCD934X_CDC_CLSH_CRC 0x0c01 +#define WCD934X_CDC_CLSH_DLY_CTRL 0x0c02 +#define WCD934X_CDC_CLSH_DECAY_CTRL 0x0c03 +#define WCD934X_CDC_CLSH_HPH_V_PA 0x0c04 +#define WCD934X_CDC_CLSH_EAR_V_PA 0x0c05 +#define WCD934X_CDC_CLSH_HPH_V_HD 0x0c06 +#define WCD934X_CDC_CLSH_EAR_V_HD 0x0c07 +#define WCD934X_CDC_CLSH_K1_MSB 0x0c08 +#define WCD934X_CDC_CLSH_K1_LSB 0x0c09 +#define WCD934X_CDC_CLSH_K2_MSB 0x0c0a +#define WCD934X_CDC_CLSH_K2_LSB 0x0c0b +#define WCD934X_CDC_CLSH_IDLE_CTRL 0x0c0c +#define WCD934X_CDC_CLSH_IDLE_HPH 0x0c0d +#define WCD934X_CDC_CLSH_IDLE_EAR 0x0c0e +#define WCD934X_CDC_CLSH_TEST0 0x0c0f +#define WCD934X_CDC_CLSH_TEST1 0x0c10 +#define WCD934X_CDC_CLSH_OVR_VREF 0x0c11 +#define WCD934X_CDC_BOOST0_BOOST_PATH_CTL 0x0c19 +#define WCD934X_CDC_BOOST0_BOOST_CTL 0x0c1a +#define WCD934X_CDC_BOOST0_BOOST_CFG1 0x0c1b +#define WCD934X_CDC_BOOST0_BOOST_CFG2 0x0c1c +#define WCD934X_CDC_BOOST1_BOOST_PATH_CTL 0x0c21 +#define WCD934X_CDC_BOOST1_BOOST_CTL 0x0c22 +#define WCD934X_CDC_BOOST1_BOOST_CFG1 0x0c23 +#define WCD934X_CDC_BOOST1_BOOST_CFG2 0x0c24 +#define WCD934X_CDC_VBAT_VBAT_PATH_CTL 0x0c3d +#define WCD934X_CDC_VBAT_VBAT_CFG 0x0c3e +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL1 0x0c3f +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL2 0x0c40 +#define WCD934X_CDC_VBAT_VBAT_ADC_CAL3 0x0c41 +#define WCD934X_CDC_VBAT_VBAT_PK_EST1 0x0c42 +#define WCD934X_CDC_VBAT_VBAT_PK_EST2 0x0c43 +#define WCD934X_CDC_VBAT_VBAT_PK_EST3 0x0c44 +#define WCD934X_CDC_VBAT_VBAT_RF_PROC1 0x0c45 +#define WCD934X_CDC_VBAT_VBAT_RF_PROC2 0x0c46 +#define WCD934X_CDC_VBAT_VBAT_TAC1 0x0c47 +#define WCD934X_CDC_VBAT_VBAT_TAC2 0x0c48 +#define WCD934X_CDC_VBAT_VBAT_TAC3 0x0c49 +#define WCD934X_CDC_VBAT_VBAT_TAC4 0x0c4a +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD1 0x0c4b +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD2 0x0c4c +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD3 0x0c4d +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD4 0x0c4e +#define WCD934X_CDC_VBAT_VBAT_DEBUG1 0x0c4f +#define WCD934X_CDC_VBAT_VBAT_GAIN_UPD_MON 0x0c50 +#define WCD934X_CDC_VBAT_VBAT_GAIN_MON_VAL 0x0c51 +#define WCD934X_CDC_VBAT_VBAT_BAN 0x0c52 +#define WCD934X_MIXING_ASRC0_CLK_RST_CTL 0x0c55 +#define WCD934X_MIXING_ASRC0_CTL0 0x0c56 +#define WCD934X_MIXING_ASRC0_CTL1 0x0c57 +#define WCD934X_MIXING_ASRC0_FIFO_CTL 0x0c58 +#define WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB 0x0c59 +#define WCD934X_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB 0x0c5a +#define WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB 0x0c5b +#define WCD934X_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB 0x0c5c +#define WCD934X_MIXING_ASRC0_STATUS_FIFO 0x0c5d +#define WCD934X_MIXING_ASRC1_CLK_RST_CTL 0x0c61 +#define WCD934X_MIXING_ASRC1_CTL0 0x0c62 +#define WCD934X_MIXING_ASRC1_CTL1 0x0c63 +#define WCD934X_MIXING_ASRC1_FIFO_CTL 0x0c64 +#define WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB 0x0c65 +#define WCD934X_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB 0x0c66 +#define WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB 0x0c67 +#define WCD934X_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB 0x0c68 +#define WCD934X_MIXING_ASRC1_STATUS_FIFO 0x0c69 +#define WCD934X_MIXING_ASRC2_CLK_RST_CTL 0x0c6d +#define WCD934X_MIXING_ASRC2_CTL0 0x0c6e +#define WCD934X_MIXING_ASRC2_CTL1 0x0c6f +#define WCD934X_MIXING_ASRC2_FIFO_CTL 0x0c70 +#define WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB 0x0c71 +#define WCD934X_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB 0x0c72 +#define WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB 0x0c73 +#define WCD934X_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB 0x0c74 +#define WCD934X_MIXING_ASRC2_STATUS_FIFO 0x0c75 +#define WCD934X_MIXING_ASRC3_CLK_RST_CTL 0x0c79 +#define WCD934X_MIXING_ASRC3_CTL0 0x0c7a +#define WCD934X_MIXING_ASRC3_CTL1 0x0c7b +#define WCD934X_MIXING_ASRC3_FIFO_CTL 0x0c7c +#define WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB 0x0c7d +#define WCD934X_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB 0x0c7e +#define WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB 0x0c7f +#define WCD934X_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB 0x0c80 +#define WCD934X_MIXING_ASRC3_STATUS_FIFO 0x0c81 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_0 0x0c85 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_1 0x0c86 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_2 0x0c87 +#define WCD934X_SWR_AHB_BRIDGE_WR_DATA_3 0x0c88 +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0 0x0c89 +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_1 0x0c8a +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_2 0x0c8b +#define WCD934X_SWR_AHB_BRIDGE_WR_ADDR_3 0x0c8c +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_0 0x0c8d +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_1 0x0c8e +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_2 0x0c8f +#define WCD934X_SWR_AHB_BRIDGE_RD_ADDR_3 0x0c90 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_0 0x0c91 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_1 0x0c92 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_2 0x0c93 +#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_3 0x0c94 +#define WCD934X_SWR_AHB_BRIDGE_ACCESS_CFG 0x0c95 +#define WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS 0x0c96 +#define WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL 0x0cb5 +#define WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 0x0cb6 +#define WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL 0x0cb9 +#define WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CFG1 0x0cba +#define WCD934X_SIDETONE_ASRC0_CLK_RST_CTL 0x0cbd +#define WCD934X_SIDETONE_ASRC0_CTL0 0x0cbe +#define WCD934X_SIDETONE_ASRC0_CTL1 0x0cbf +#define WCD934X_SIDETONE_ASRC0_FIFO_CTL 0x0cc0 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB 0x0cc1 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB 0x0cc2 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB 0x0cc3 +#define WCD934X_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB 0x0cc4 +#define WCD934X_SIDETONE_ASRC0_STATUS_FIFO 0x0cc5 +#define WCD934X_SIDETONE_ASRC1_CLK_RST_CTL 0x0cc9 +#define WCD934X_SIDETONE_ASRC1_CTL0 0x0cca +#define WCD934X_SIDETONE_ASRC1_CTL1 0x0ccb +#define WCD934X_SIDETONE_ASRC1_FIFO_CTL 0x0ccc +#define WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_LSB 0x0ccd +#define WCD934X_SIDETONE_ASRC1_STATUS_FMIN_CNTR_MSB 0x0cce +#define WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_LSB 0x0ccf +#define WCD934X_SIDETONE_ASRC1_STATUS_FMAX_CNTR_MSB 0x0cd0 +#define WCD934X_SIDETONE_ASRC1_STATUS_FIFO 0x0cd1 +#define WCD934X_EC_REF_HQ0_EC_REF_HQ_PATH_CTL 0x0cd5 +#define WCD934X_EC_REF_HQ0_EC_REF_HQ_CFG0 0x0cd6 +#define WCD934X_EC_REF_HQ1_EC_REF_HQ_PATH_CTL 0x0cdd +#define WCD934X_EC_REF_HQ1_EC_REF_HQ_CFG0 0x0cde +#define WCD934X_EC_ASRC0_CLK_RST_CTL 0x0ce5 +#define WCD934X_EC_ASRC0_CTL0 0x0ce6 +#define WCD934X_EC_ASRC0_CTL1 0x0ce7 +#define WCD934X_EC_ASRC0_FIFO_CTL 0x0ce8 +#define WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_LSB 0x0ce9 +#define WCD934X_EC_ASRC0_STATUS_FMIN_CNTR_MSB 0x0cea +#define WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_LSB 0x0ceb +#define WCD934X_EC_ASRC0_STATUS_FMAX_CNTR_MSB 0x0cec +#define WCD934X_EC_ASRC0_STATUS_FIFO 0x0ced +#define WCD934X_EC_ASRC1_CLK_RST_CTL 0x0cf1 +#define WCD934X_EC_ASRC1_CTL0 0x0cf2 +#define WCD934X_EC_ASRC1_CTL1 0x0cf3 +#define WCD934X_EC_ASRC1_FIFO_CTL 0x0cf4 +#define WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_LSB 0x0cf5 +#define WCD934X_EC_ASRC1_STATUS_FMIN_CNTR_MSB 0x0cf6 +#define WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_LSB 0x0cf7 +#define WCD934X_EC_ASRC1_STATUS_FMAX_CNTR_MSB 0x0cf8 +#define WCD934X_EC_ASRC1_STATUS_FIFO 0x0cf9 +#define WCD934X_PAGE13_PAGE_REGISTER 0x0d00 +#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0 0x0d01 +#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1 0x0d02 +#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0 0x0d03 +#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1 0x0d04 +#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0 0x0d05 +#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1 0x0d06 +#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0 0x0d07 +#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1 0x0d08 +#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0 0x0d09 +#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1 0x0d0a +#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0 0x0d0f +#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1 0x0d10 +#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0 0x0d11 +#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1 0x0d12 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0 0x0d13 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1 0x0d14 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2 0x0d15 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3 0x0d16 +#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4 0x0d17 +#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 0x0d18 +#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 0x0d19 +#define WCD934X_CDC_RX_INP_MUX_ANC_CFG0 0x0d1a +#define WCD934X_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 0x0d1b +#define WCD934X_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 0x0d1c +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 0x0d1d +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 0x0d1e +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0 0x0d1f +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1 0x0d20 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0 0x0d21 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1 0x0d22 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0 0x0d23 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1 0x0d25 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 0x0d26 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0 0x0d27 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0 0x0d28 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0 0x0d29 +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0 0x0d2a +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0 0x0d2b +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0 0x0d2c +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0 0x0d2d +#define WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0 0x0d2e +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 0x0d31 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 0x0d32 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 0x0d33 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 0x0d34 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0 0x0d35 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1 0x0d36 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2 0x0d37 +#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3 0x0d38 +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0 0x0d3a +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1 0x0d3b +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2 0x0d3c +#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3 0x0d3d +#define WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41 +#define WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42 +#define WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL 0x0d43 +#define WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL 0x0d44 +#define WCD934X_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL 0x0d45 +#define WCD934X_CDC_CLK_RST_CTRL_GFM_CONTROL 0x0d46 +#define WCD934X_CDC_PROX_DETECT_PROX_CTL 0x0d49 +#define WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD0 0x0d4a +#define WCD934X_CDC_PROX_DETECT_PROX_POLL_PERIOD1 0x0d4b +#define WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB 0x0d4c +#define WCD934X_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB 0x0d4d +#define WCD934X_CDC_PROX_DETECT_PROX_STATUS 0x0d4e +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_CTRL 0x0d4f +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB 0x0d50 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB 0x0d51 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD 0x0d52 +#define WCD934X_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD 0x0d53 +#define WCD934X_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT 0x0d54 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL 0x0d55 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL 0x0d56 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL 0x0d57 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL 0x0d58 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL 0x0d59 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL 0x0d5a +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL 0x0d5b +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL 0x0d5c +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL 0x0d5d +#define WCD934X_CDC_SIDETONE_IIR0_IIR_CTL 0x0d5e +#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL 0x0d5f +#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL 0x0d60 +#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL 0x0d61 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL 0x0d65 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL 0x0d66 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL 0x0d67 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL 0x0d68 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL 0x0d69 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL 0x0d6a +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL 0x0d6b +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL 0x0d6c +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL 0x0d6d +#define WCD934X_CDC_SIDETONE_IIR1_IIR_CTL 0x0d6e +#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL 0x0d6f +#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL 0x0d70 +#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL 0x0d71 +#define WCD934X_CDC_TOP_TOP_CFG0 0x0d81 +#define WCD934X_CDC_TOP_TOP_CFG1 0x0d82 +#define WCD934X_CDC_TOP_TOP_CFG7 0x0d88 +#define WCD934X_CDC_TOP_HPHL_COMP_WR_LSB 0x0d89 +#define WCD934X_CDC_TOP_HPHL_COMP_WR_MSB 0x0d8a +#define WCD934X_CDC_TOP_HPHL_COMP_LUT 0x0d8b +#define WCD934X_CDC_TOP_HPHL_COMP_RD_LSB 0x0d8c +#define WCD934X_CDC_TOP_HPHL_COMP_RD_MSB 0x0d8d +#define WCD934X_CDC_TOP_HPHR_COMP_WR_LSB 0x0d8e +#define WCD934X_CDC_TOP_HPHR_COMP_WR_MSB 0x0d8f +#define WCD934X_CDC_TOP_HPHR_COMP_LUT 0x0d90 +#define WCD934X_CDC_TOP_HPHR_COMP_RD_LSB 0x0d91 +#define WCD934X_CDC_TOP_HPHR_COMP_RD_MSB 0x0d92 +#define WCD934X_CDC_TOP_DIFFL_COMP_WR_LSB 0x0d93 +#define WCD934X_CDC_TOP_DIFFL_COMP_WR_MSB 0x0d94 +#define WCD934X_CDC_TOP_DIFFL_COMP_LUT 0x0d95 +#define WCD934X_CDC_TOP_DIFFL_COMP_RD_LSB 0x0d96 +#define WCD934X_CDC_TOP_DIFFL_COMP_RD_MSB 0x0d97 +#define WCD934X_CDC_TOP_DIFFR_COMP_WR_LSB 0x0d98 +#define WCD934X_CDC_TOP_DIFFR_COMP_WR_MSB 0x0d99 +#define WCD934X_CDC_TOP_DIFFR_COMP_LUT 0x0d9a +#define WCD934X_CDC_TOP_DIFFR_COMP_RD_LSB 0x0d9b +#define WCD934X_CDC_TOP_DIFFR_COMP_RD_MSB 0x0d9c +#define WCD934X_CDC_DSD0_PATH_CTL 0x0db1 +#define WCD934X_CDC_DSD0_CFG0 0x0db2 +#define WCD934X_CDC_DSD0_CFG1 0x0db3 +#define WCD934X_CDC_DSD0_CFG2 0x0db4 +#define WCD934X_CDC_DSD0_CFG3 0x0db5 +#define WCD934X_CDC_DSD0_CFG4 0x0db6 +#define WCD934X_CDC_DSD0_CFG5 0x0db7 +#define WCD934X_CDC_DSD1_PATH_CTL 0x0dc1 +#define WCD934X_CDC_DSD1_CFG0 0x0dc2 +#define WCD934X_CDC_DSD1_CFG1 0x0dc3 +#define WCD934X_CDC_DSD1_CFG2 0x0dc4 +#define WCD934X_CDC_DSD1_CFG3 0x0dc5 +#define WCD934X_CDC_DSD1_CFG4 0x0dc6 +#define WCD934X_CDC_DSD1_CFG5 0x0dc7 +#define WCD934X_CDC_RX_IDLE_DET_PATH_CTL 0x0dd1 +#define WCD934X_CDC_RX_IDLE_DET_CFG0 0x0dd2 +#define WCD934X_CDC_RX_IDLE_DET_CFG1 0x0dd3 +#define WCD934X_CDC_RX_IDLE_DET_CFG2 0x0dd4 +#define WCD934X_CDC_RX_IDLE_DET_CFG3 0x0dd5 +#define WCD934X_PAGE14_PAGE_REGISTER 0x0e00 +#define WCD934X_CDC_RATE_EST0_RE_CLK_RST_CTL 0x0e01 +#define WCD934X_CDC_RATE_EST0_RE_CTL 0x0e02 +#define WCD934X_CDC_RATE_EST0_RE_PULSE_SUPR_CTL 0x0e03 +#define WCD934X_CDC_RATE_EST0_RE_TIMER 0x0e04 +#define WCD934X_CDC_RATE_EST0_RE_BW_SW 0x0e05 +#define WCD934X_CDC_RATE_EST0_RE_THRESH 0x0e06 +#define WCD934X_CDC_RATE_EST0_RE_STATUS 0x0e07 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_CTRL 0x0e09 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_TIMER2 0x0e0c +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW1 0x0e0d +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW2 0x0e0e +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW3 0x0e0f +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW4 0x0e10 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_OFFSET_BW5 0x0e11 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW1 0x0e12 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW2 0x0e13 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW3 0x0e14 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW4 0x0e15 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMIT_BW5 0x0e16 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW1 0x0e17 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW2 0x0e18 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW3 0x0e19 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW4 0x0e1a +#define WCD934X_CDC_RATE_EST0_RE_DIAG_LIMITD1_BW5 0x0e1b +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW1 0x0e1c +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW2 0x0e1d +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW3 0x0e1e +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW4 0x0e1f +#define WCD934X_CDC_RATE_EST0_RE_DIAG_HYST_BW5 0x0e20 +#define WCD934X_CDC_RATE_EST0_RE_RMAX_DIAG 0x0e21 +#define WCD934X_CDC_RATE_EST0_RE_RMIN_DIAG 0x0e22 +#define WCD934X_CDC_RATE_EST0_RE_PH_DET 0x0e23 +#define WCD934X_CDC_RATE_EST0_RE_DIAG_CLR 0x0e24 +#define WCD934X_CDC_RATE_EST0_RE_MB_SW_STATE 0x0e25 +#define WCD934X_CDC_RATE_EST0_RE_MAST_DIAG_STATE 0x0e26 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_7_0 0x0e27 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_15_8 0x0e28 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_23_16 0x0e29 +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_31_24 0x0e2a +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_39_32 0x0e2b +#define WCD934X_CDC_RATE_EST0_RE_RATE_OUT_40_43 0x0e2c +#define WCD934X_CDC_RATE_EST1_RE_CLK_RST_CTL 0x0e31 +#define WCD934X_CDC_RATE_EST1_RE_CTL 0x0e32 +#define WCD934X_CDC_RATE_EST1_RE_PULSE_SUPR_CTL 0x0e33 +#define WCD934X_CDC_RATE_EST1_RE_TIMER 0x0e34 +#define WCD934X_CDC_RATE_EST1_RE_BW_SW 0x0e35 +#define WCD934X_CDC_RATE_EST1_RE_THRESH 0x0e36 +#define WCD934X_CDC_RATE_EST1_RE_STATUS 0x0e37 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_CTRL 0x0e39 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_TIMER2 0x0e3c +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW1 0x0e3d +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW2 0x0e3e +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW3 0x0e3f +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW4 0x0e40 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_OFFSET_BW5 0x0e41 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW1 0x0e42 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW2 0x0e43 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW3 0x0e44 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW4 0x0e45 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMIT_BW5 0x0e46 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW1 0x0e47 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW2 0x0e48 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW3 0x0e49 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW4 0x0e4a +#define WCD934X_CDC_RATE_EST1_RE_DIAG_LIMITD1_BW5 0x0e4b +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW1 0x0e4c +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW2 0x0e4d +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW3 0x0e4e +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW4 0x0e4f +#define WCD934X_CDC_RATE_EST1_RE_DIAG_HYST_BW5 0x0e50 +#define WCD934X_CDC_RATE_EST1_RE_RMAX_DIAG 0x0e51 +#define WCD934X_CDC_RATE_EST1_RE_RMIN_DIAG 0x0e52 +#define WCD934X_CDC_RATE_EST1_RE_PH_DET 0x0e53 +#define WCD934X_CDC_RATE_EST1_RE_DIAG_CLR 0x0e54 +#define WCD934X_CDC_RATE_EST1_RE_MB_SW_STATE 0x0e55 +#define WCD934X_CDC_RATE_EST1_RE_MAST_DIAG_STATE 0x0e56 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_7_0 0x0e57 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_15_8 0x0e58 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_23_16 0x0e59 +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_31_24 0x0e5a +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_39_32 0x0e5b +#define WCD934X_CDC_RATE_EST1_RE_RATE_OUT_40_43 0x0e5c +#define WCD934X_CDC_RATE_EST2_RE_CLK_RST_CTL 0x0e61 +#define WCD934X_CDC_RATE_EST2_RE_CTL 0x0e62 +#define WCD934X_CDC_RATE_EST2_RE_PULSE_SUPR_CTL 0x0e63 +#define WCD934X_CDC_RATE_EST2_RE_TIMER 0x0e64 +#define WCD934X_CDC_RATE_EST2_RE_BW_SW 0x0e65 +#define WCD934X_CDC_RATE_EST2_RE_THRESH 0x0e66 +#define WCD934X_CDC_RATE_EST2_RE_STATUS 0x0e67 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_CTRL 0x0e69 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_TIMER2 0x0e6c +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW1 0x0e6d +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW2 0x0e6e +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW3 0x0e6f +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW4 0x0e70 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_OFFSET_BW5 0x0e71 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW1 0x0e72 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW2 0x0e73 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW3 0x0e74 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW4 0x0e75 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMIT_BW5 0x0e76 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW1 0x0e77 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW2 0x0e78 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW3 0x0e79 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW4 0x0e7a +#define WCD934X_CDC_RATE_EST2_RE_DIAG_LIMITD1_BW5 0x0e7b +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW1 0x0e7c +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW2 0x0e7d +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW3 0x0e7e +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW4 0x0e7f +#define WCD934X_CDC_RATE_EST2_RE_DIAG_HYST_BW5 0x0e80 +#define WCD934X_CDC_RATE_EST2_RE_RMAX_DIAG 0x0e81 +#define WCD934X_CDC_RATE_EST2_RE_RMIN_DIAG 0x0e82 +#define WCD934X_CDC_RATE_EST2_RE_PH_DET 0x0e83 +#define WCD934X_CDC_RATE_EST2_RE_DIAG_CLR 0x0e84 +#define WCD934X_CDC_RATE_EST2_RE_MB_SW_STATE 0x0e85 +#define WCD934X_CDC_RATE_EST2_RE_MAST_DIAG_STATE 0x0e86 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_7_0 0x0e87 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_15_8 0x0e88 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_23_16 0x0e89 +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_31_24 0x0e8a +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_39_32 0x0e8b +#define WCD934X_CDC_RATE_EST2_RE_RATE_OUT_40_43 0x0e8c +#define WCD934X_CDC_RATE_EST3_RE_CLK_RST_CTL 0x0e91 +#define WCD934X_CDC_RATE_EST3_RE_CTL 0x0e92 +#define WCD934X_CDC_RATE_EST3_RE_PULSE_SUPR_CTL 0x0e93 +#define WCD934X_CDC_RATE_EST3_RE_TIMER 0x0e94 +#define WCD934X_CDC_RATE_EST3_RE_BW_SW 0x0e95 +#define WCD934X_CDC_RATE_EST3_RE_THRESH 0x0e96 +#define WCD934X_CDC_RATE_EST3_RE_STATUS 0x0e97 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_CTRL 0x0e99 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_TIMER2 0x0e9c +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW1 0x0e9d +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW2 0x0e9e +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW3 0x0e9f +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW4 0x0ea0 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_OFFSET_BW5 0x0ea1 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW1 0x0ea2 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW2 0x0ea3 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW3 0x0ea4 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW4 0x0ea5 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMIT_BW5 0x0ea6 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW1 0x0ea7 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW2 0x0ea8 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW3 0x0ea9 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW4 0x0eaa +#define WCD934X_CDC_RATE_EST3_RE_DIAG_LIMITD1_BW5 0x0eab +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW1 0x0eac +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW2 0x0ead +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW3 0x0eae +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW4 0x0eaf +#define WCD934X_CDC_RATE_EST3_RE_DIAG_HYST_BW5 0x0eb0 +#define WCD934X_CDC_RATE_EST3_RE_RMAX_DIAG 0x0eb1 +#define WCD934X_CDC_RATE_EST3_RE_RMIN_DIAG 0x0eb2 +#define WCD934X_CDC_RATE_EST3_RE_PH_DET 0x0eb3 +#define WCD934X_CDC_RATE_EST3_RE_DIAG_CLR 0x0eb4 +#define WCD934X_CDC_RATE_EST3_RE_MB_SW_STATE 0x0eb5 +#define WCD934X_CDC_RATE_EST3_RE_MAST_DIAG_STATE 0x0eb6 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_7_0 0x0eb7 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_15_8 0x0eb8 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_23_16 0x0eb9 +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_31_24 0x0eba +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_39_32 0x0ebb +#define WCD934X_CDC_RATE_EST3_RE_RATE_OUT_40_43 0x0ebc +#define WCD934X_PAGE15_PAGE_REGISTER 0x0f00 +#define WCD934X_SPLINE_SRC0_CLK_RST_CTL_0 0x0f01 +#define WCD934X_SPLINE_SRC0_STATUS 0x0f02 +#define WCD934X_SPLINE_SRC1_CLK_RST_CTL_0 0x0f19 +#define WCD934X_SPLINE_SRC1_STATUS 0x0f1a +#define WCD934X_SPLINE_SRC2_CLK_RST_CTL_0 0x0f31 +#define WCD934X_SPLINE_SRC2_STATUS 0x0f32 +#define WCD934X_SPLINE_SRC3_CLK_RST_CTL_0 0x0f49 +#define WCD934X_SPLINE_SRC3_STATUS 0x0f4a +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG0 0x0fa1 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG1 0x0fa2 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG2 0x0fa3 +#define WCD934X_CDC_DEBUG_DSD0_DEBUG_CFG3 0x0fa4 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG0 0x0fa5 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG1 0x0fa6 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG2 0x0fa7 +#define WCD934X_CDC_DEBUG_DSD1_DEBUG_CFG3 0x0fa8 +#define WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG0 0x0fa9 +#define WCD934X_CDC_DEBUG_SPLINE_SRC_DEBUG_CFG1 0x0faa +#define WCD934X_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0 0x0fab +#define WCD934X_CDC_DEBUG_ANC0_RC0_FIFO_CTL 0x0fac +#define WCD934X_CDC_DEBUG_ANC0_RC1_FIFO_CTL 0x0fad +#define WCD934X_CDC_DEBUG_ANC1_RC0_FIFO_CTL 0x0fae +#define WCD934X_CDC_DEBUG_ANC1_RC1_FIFO_CTL 0x0faf +#define WCD934X_CDC_DEBUG_ANC_RC_RST_DBG_CNTR 0x0fb0 +#define WCD934X_PAGE80_PAGE_REGISTER 0x5000 +#define WCD934X_CODEC_CPR_WR_DATA_0 0x5001 +#define WCD934X_CODEC_CPR_WR_DATA_1 0x5002 +#define WCD934X_CODEC_CPR_WR_DATA_2 0x5003 +#define WCD934X_CODEC_CPR_WR_DATA_3 0x5004 +#define WCD934X_CODEC_CPR_WR_ADDR_0 0x5005 +#define WCD934X_CODEC_CPR_WR_ADDR_1 0x5006 +#define WCD934X_CODEC_CPR_WR_ADDR_2 0x5007 +#define WCD934X_CODEC_CPR_WR_ADDR_3 0x5008 +#define WCD934X_CODEC_CPR_RD_ADDR_0 0x5009 +#define WCD934X_CODEC_CPR_RD_ADDR_1 0x500a +#define WCD934X_CODEC_CPR_RD_ADDR_2 0x500b +#define WCD934X_CODEC_CPR_RD_ADDR_3 0x500c +#define WCD934X_CODEC_CPR_RD_DATA_0 0x500d +#define WCD934X_CODEC_CPR_RD_DATA_1 0x500e +#define WCD934X_CODEC_CPR_RD_DATA_2 0x500f +#define WCD934X_CODEC_CPR_RD_DATA_3 0x5010 +#define WCD934X_CODEC_CPR_ACCESS_CFG 0x5011 +#define WCD934X_CODEC_CPR_ACCESS_STATUS 0x5012 +#define WCD934X_CODEC_CPR_NOM_CX_VDD 0x5021 +#define WCD934X_CODEC_CPR_SVS_CX_VDD 0x5022 +#define WCD934X_CODEC_CPR_SVS2_CX_VDD 0x5023 +#define WCD934X_CODEC_CPR_NOM_MX_VDD 0x5024 +#define WCD934X_CODEC_CPR_SVS_MX_VDD 0x5025 +#define WCD934X_CODEC_CPR_SVS2_MX_VDD 0x5026 +#define WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD 0x5027 +#define WCD934X_CODEC_CPR_MAX_SVS2_STEP 0x5028 +#define WCD934X_CODEC_CPR_CTL 0x5029 +#define WCD934X_CODEC_CPR_SW_MODECHNG_STATUS 0x502a +#define WCD934X_CODEC_CPR_SW_MODECHNG_START 0x502b +#define WCD934X_CODEC_CPR_CPR_STATUS 0x502c +#define WCD934X_PAGE128_PAGE_REGISTER 0x8000 +#define WCD934X_TLMM_BIST_MODE_PINCFG 0x8001 +#define WCD934X_TLMM_RF_PA_ON_PINCFG 0x8002 +#define WCD934X_TLMM_INTR1_PINCFG 0x8003 +#define WCD934X_TLMM_INTR2_PINCFG 0x8004 +#define WCD934X_TLMM_SWR_DATA_PINCFG 0x8005 +#define WCD934X_TLMM_SWR_CLK_PINCFG 0x8006 +#define WCD934X_TLMM_I2S_2_SCK_PINCFG 0x8007 +#define WCD934X_TLMM_SLIMBUS_DATA1_PINCFG 0x8008 +#define WCD934X_TLMM_SLIMBUS_DATA2_PINCFG 0x8009 +#define WCD934X_TLMM_SLIMBUS_CLK_PINCFG 0x800a +#define WCD934X_TLMM_I2C_CLK_PINCFG 0x800b +#define WCD934X_TLMM_I2C_DATA_PINCFG 0x800c +#define WCD934X_TLMM_I2S_0_RX_PINCFG 0x800d +#define WCD934X_TLMM_I2S_0_TX_PINCFG 0x800e +#define WCD934X_TLMM_I2S_0_SCK_PINCFG 0x800f +#define WCD934X_TLMM_I2S_0_WS_PINCFG 0x8010 +#define WCD934X_TLMM_I2S_1_RX_PINCFG 0x8011 +#define WCD934X_TLMM_I2S_1_TX_PINCFG 0x8012 +#define WCD934X_TLMM_I2S_1_SCK_PINCFG 0x8013 +#define WCD934X_TLMM_I2S_1_WS_PINCFG 0x8014 +#define WCD934X_TLMM_DMIC1_CLK_PINCFG 0x8015 +#define WCD934X_TLMM_DMIC1_DATA_PINCFG 0x8016 +#define WCD934X_TLMM_DMIC2_CLK_PINCFG 0x8017 +#define WCD934X_TLMM_DMIC2_DATA_PINCFG 0x8018 +#define WCD934X_TLMM_DMIC3_CLK_PINCFG 0x8019 +#define WCD934X_TLMM_DMIC3_DATA_PINCFG 0x801a +#define WCD934X_TLMM_JTCK_PINCFG 0x801b +#define WCD934X_TLMM_GPIO1_PINCFG 0x801c +#define WCD934X_TLMM_GPIO2_PINCFG 0x801d +#define WCD934X_TLMM_GPIO3_PINCFG 0x801e +#define WCD934X_TLMM_GPIO4_PINCFG 0x801f +#define WCD934X_TLMM_SPI_S_CSN_PINCFG 0x8020 +#define WCD934X_TLMM_SPI_S_CLK_PINCFG 0x8021 +#define WCD934X_TLMM_SPI_S_DOUT_PINCFG 0x8022 +#define WCD934X_TLMM_SPI_S_DIN_PINCFG 0x8023 +#define WCD934X_TLMM_BA_N_PINCFG 0x8024 +#define WCD934X_TLMM_GPIO0_PINCFG 0x8025 +#define WCD934X_TLMM_I2S_2_RX_PINCFG 0x8026 +#define WCD934X_TLMM_I2S_2_WS_PINCFG 0x8027 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_0 0x8031 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_1 0x8032 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_2 0x8033 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_3 0x8034 +#define WCD934X_TEST_DEBUG_PIN_CTL_OE_4 0x8035 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_0 0x8036 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_1 0x8037 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_2 0x8038 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_3 0x8039 +#define WCD934X_TEST_DEBUG_PIN_CTL_DATA_4 0x803a +#define WCD934X_TEST_DEBUG_PAD_DRVCTL_0 0x803b +#define WCD934X_TEST_DEBUG_PAD_DRVCTL_1 0x803c +#define WCD934X_TEST_DEBUG_PIN_STATUS 0x803d +#define WCD934X_TEST_DEBUG_NPL_DLY_TEST_1 0x803e +#define WCD934X_TEST_DEBUG_NPL_DLY_TEST_2 0x803f +#define WCD934X_TEST_DEBUG_MEM_CTRL 0x8040 +#define WCD934X_TEST_DEBUG_DEBUG_BUS_SEL 0x8041 +#define WCD934X_TEST_DEBUG_DEBUG_JTAG 0x8042 +#define WCD934X_TEST_DEBUG_DEBUG_EN_1 0x8043 +#define WCD934X_TEST_DEBUG_DEBUG_EN_2 0x8044 +#define WCD934X_TEST_DEBUG_DEBUG_EN_3 0x8045 +#define WCD934X_TEST_DEBUG_DEBUG_EN_4 0x8046 +#define WCD934X_TEST_DEBUG_DEBUG_EN_5 0x8047 +#define WCD934X_TEST_DEBUG_ANA_DTEST_DIR 0x804a +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_0 0x804b +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_1 0x804c +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_2 0x804d +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_3 0x804e +#define WCD934X_TEST_DEBUG_PAD_INP_DISABLE_4 0x804f +#define WCD934X_TEST_DEBUG_SYSMEM_CTRL 0x8050 +#define WCD934X_TEST_DEBUG_SOC_SW_PWR_SEQ_DELAY 0x8051 +#define WCD934X_TEST_DEBUG_LVAL_NOM_LOW 0x8052 +#define WCD934X_TEST_DEBUG_LVAL_NOM_HIGH 0x8053 +#define WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_LOW 0x8054 +#define WCD934X_TEST_DEBUG_LVAL_SVS_SVS2_HIGH 0x8055 +#define WCD934X_TEST_DEBUG_SPI_SLAVE_CHAR 0x8056 +#define WCD934X_TEST_DEBUG_CODEC_DIAGS 0x8057 +#define WCD934X_MAX_REGISTER 0x80FF + +/* SLIMBUS Slave Registers */ +#define WCD934X_SLIM_PGD_PORT_INT_RX_EN0 (0x30) +#define WCD934X_SLIM_PGD_PORT_INT_TX_EN0 (0x32) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define WCD934X_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +#endif diff --git a/include/linux/mfd/wcd9xxx/Kbuild b/include/linux/mfd/wcd9xxx/Kbuild new file mode 100755 index 000000000000..8e55965bbe7e --- /dev/null +++ b/include/linux/mfd/wcd9xxx/Kbuild @@ -0,0 +1,2 @@ +header-y += wcd9xxx_registers.h +header-y += wcd9320_registers.h diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h new file mode 100644 index 000000000000..6eb8c1893a53 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/core.h @@ -0,0 +1,437 @@ +/* Copyright (c) 2011-2017, 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 __MFD_TABLA_CORE_H__ +#define __MFD_TABLA_CORE_H__ + +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/of_irq.h> +#include <linux/interrupt.h> +#include <linux/pm_qos.h> + +#define WCD9XXX_MAX_IRQ_REGS 4 +#define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8) +#define WCD9XXX_SLIM_NUM_PORT_REG 3 +#define TABLA_VERSION_1_0 0 +#define TABLA_VERSION_1_1 1 +#define TABLA_VERSION_2_0 2 +#define TABLA_IS_1_X(ver) \ + (((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0) +#define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0) + +#define WCD9XXX_SUPPLY_BUCK_NAME "cdc-vdd-buck" + +#define SITAR_VERSION_1P0 0 +#define SITAR_VERSION_1P1 1 +#define SITAR_IS_1P0(ver) \ + ((ver == SITAR_VERSION_1P0) ? 1 : 0) +#define SITAR_IS_1P1(ver) \ + ((ver == SITAR_VERSION_1P1) ? 1 : 0) + +#define TAIKO_VERSION_1_0 1 +#define TAIKO_IS_1_0(ver) \ + ((ver == TAIKO_VERSION_1_0) ? 1 : 0) + +#define TAPAN_VERSION_1_0 0 +#define TAPAN_IS_1_0(ver) \ + ((ver == TAPAN_VERSION_1_0) ? 1 : 0) + +#define TOMTOM_VERSION_1_0 1 +#define TOMTOM_IS_1_0(ver) \ + ((ver == TOMTOM_VERSION_1_0) ? 1 : 0) + +#define TASHA_VERSION_1_0 0 +#define TASHA_VERSION_1_1 1 +#define TASHA_VERSION_2_0 2 + +#define TASHA_IS_1_0(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_1_0) ? 1 : 0) : 0) + +#define TASHA_IS_1_1(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_1_1) ? 1 : 0) : 0) + +#define TASHA_IS_2_0(wcd) \ + ((wcd->type == WCD9335 || wcd->type == WCD9326) ? \ + ((wcd->version == TASHA_VERSION_2_0) ? 1 : 0) : 0) + +/* + * As fine version info cannot be retrieved before tavil probe. + * Define three coarse versions for possible future use before tavil probe. + */ +#define TAVIL_VERSION_1_0 0 +#define TAVIL_VERSION_1_1 1 +#define TAVIL_VERSION_WCD9340_1_0 2 +#define TAVIL_VERSION_WCD9341_1_0 3 +#define TAVIL_VERSION_WCD9340_1_1 4 +#define TAVIL_VERSION_WCD9341_1_1 5 + +#define TAVIL_IS_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_1_0 || \ + wcd->version == TAVIL_VERSION_WCD9340_1_0 || \ + wcd->version == TAVIL_VERSION_WCD9341_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_1_1 || \ + wcd->version == TAVIL_VERSION_WCD9340_1_1 || \ + wcd->version == TAVIL_VERSION_WCD9341_1_1) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9340_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9340_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9341_1_0(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9341_1_0) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9340_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9340_1_1) ? 1 : 0) : 0) +#define TAVIL_IS_WCD9341_1_1(wcd) \ + ((wcd->type == WCD934X) ? \ + ((wcd->version == TAVIL_VERSION_WCD9341_1_1) ? 1 : 0) : 0) + +#define IS_CODEC_TYPE(wcd, wcdtype) \ + ((wcd->type == wcdtype) ? true : false) +#define IS_CODEC_VERSION(wcd, wcdversion) \ + ((wcd->version == wcdversion) ? true : false) + +enum { + CDC_V_1_0, + CDC_V_1_1, + CDC_V_2_0, +}; + +enum codec_variant { + WCD9XXX, + WCD9330, + WCD9335, + WCD9326, + WCD934X, +}; + +enum wcd9xxx_slim_slave_addr_type { + WCD9XXX_SLIM_SLAVE_ADDR_TYPE_0, + WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1, +}; + +enum wcd9xxx_pm_state { + WCD9XXX_PM_SLEEPABLE, + WCD9XXX_PM_AWAKE, + WCD9XXX_PM_ASLEEP, +}; + +enum { + WCD9XXX_INTR_STATUS_BASE = 0, + WCD9XXX_INTR_CLEAR_BASE, + WCD9XXX_INTR_MASK_BASE, + WCD9XXX_INTR_LEVEL_BASE, + WCD9XXX_INTR_CLR_COMMIT, + WCD9XXX_INTR_REG_MAX, +}; + +enum wcd9xxx_intf_status { + WCD9XXX_INTERFACE_TYPE_PROBING, + WCD9XXX_INTERFACE_TYPE_SLIMBUS, + WCD9XXX_INTERFACE_TYPE_I2C, +}; + +enum { + /* INTR_REG 0 */ + WCD9XXX_IRQ_SLIMBUS = 0, + WCD9XXX_IRQ_MBHC_REMOVAL, + WCD9XXX_IRQ_MBHC_SHORT_TERM, + WCD9XXX_IRQ_MBHC_PRESS, + WCD9XXX_IRQ_MBHC_RELEASE, + WCD9XXX_IRQ_MBHC_POTENTIAL, + WCD9XXX_IRQ_MBHC_INSERTION, + WCD9XXX_IRQ_BG_PRECHARGE, + /* INTR_REG 1 */ + WCD9XXX_IRQ_PA1_STARTUP, + WCD9XXX_IRQ_PA2_STARTUP, + WCD9XXX_IRQ_PA3_STARTUP, + WCD9XXX_IRQ_PA4_STARTUP, + WCD9306_IRQ_HPH_PA_OCPR_FAULT = WCD9XXX_IRQ_PA4_STARTUP, + WCD9XXX_IRQ_PA5_STARTUP, + WCD9XXX_IRQ_MICBIAS1_PRECHARGE, + WCD9306_IRQ_HPH_PA_OCPL_FAULT = WCD9XXX_IRQ_MICBIAS1_PRECHARGE, + WCD9XXX_IRQ_MICBIAS2_PRECHARGE, + WCD9XXX_IRQ_MICBIAS3_PRECHARGE, + /* INTR_REG 2 */ + WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, + WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, + WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, + WCD9XXX_IRQ_HPH_L_PA_STARTUP, + WCD9XXX_IRQ_HPH_R_PA_STARTUP, + WCD9320_IRQ_EAR_PA_STARTUP, + WCD9306_IRQ_MBHC_JACK_SWITCH = WCD9320_IRQ_EAR_PA_STARTUP, + WCD9310_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_0 = WCD9310_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_1, + WCD9330_IRQ_SVASS_ERR_EXCEPTION = WCD9310_NUM_IRQS, + WCD9330_IRQ_MBHC_JACK_SWITCH, + /* INTR_REG 3 */ + WCD9XXX_IRQ_MAD_AUDIO, + WCD9XXX_IRQ_MAD_ULTRASOUND, + WCD9XXX_IRQ_MAD_BEACON, + WCD9XXX_IRQ_SPEAKER_CLIPPING, + WCD9320_IRQ_MBHC_JACK_SWITCH, + WCD9306_NUM_IRQS, + WCD9XXX_IRQ_VBAT_MONITOR_ATTACK = WCD9306_NUM_IRQS, + WCD9XXX_IRQ_VBAT_MONITOR_RELEASE, + WCD9XXX_NUM_IRQS, + /* WCD9330 INTR1_REG 3*/ + WCD9330_IRQ_SVASS_ENGINE = WCD9XXX_IRQ_MAD_AUDIO, + WCD9330_IRQ_MAD_AUDIO, + WCD9330_IRQ_MAD_ULTRASOUND, + WCD9330_IRQ_MAD_BEACON, + WCD9330_IRQ_SPEAKER1_CLIPPING, + WCD9330_IRQ_SPEAKER2_CLIPPING, + WCD9330_IRQ_VBAT_MONITOR_ATTACK, + WCD9330_IRQ_VBAT_MONITOR_RELEASE, + WCD9330_NUM_IRQS, + WCD9XXX_IRQ_RESERVED_2 = WCD9330_NUM_IRQS, +}; + +enum { + TABLA_NUM_IRQS = WCD9310_NUM_IRQS, + SITAR_NUM_IRQS = WCD9310_NUM_IRQS, + TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS, + TAPAN_NUM_IRQS = WCD9306_NUM_IRQS, + TOMTOM_NUM_IRQS = WCD9330_NUM_IRQS, +}; + +struct intr_data { + int intr_num; + bool clear_first; +}; + +struct wcd9xxx_core_resource { + struct mutex irq_lock; + struct mutex nested_irq_lock; + + enum wcd9xxx_pm_state pm_state; + struct mutex pm_lock; + /* pm_wq notifies change of pm_state */ + wait_queue_head_t pm_wq; + struct pm_qos_request pm_qos_req; + int wlock_holders; + + + /* holds the table of interrupts per codec */ + const struct intr_data *intr_table; + int intr_table_size; + unsigned int irq_base; + unsigned int irq; + u8 irq_masks_cur[WCD9XXX_MAX_IRQ_REGS]; + u8 irq_masks_cache[WCD9XXX_MAX_IRQ_REGS]; + bool irq_level_high[WCD9XXX_MAX_NUM_IRQS]; + int num_irqs; + int num_irq_regs; + u16 intr_reg[WCD9XXX_INTR_REG_MAX]; + struct regmap *wcd_core_regmap; + + /* Pointer to parent container data structure */ + void *parent; + + struct device *dev; + struct irq_domain *domain; +}; + +/* + * data structure for Slimbus and I2S channel. + * Some of fields are only used in smilbus mode + */ +struct wcd9xxx_ch { + u32 sph; /* share channel handle - slimbus only */ + u32 ch_num; /* + * vitrual channel number, such as 128 -144. + * apply for slimbus only + */ + u16 ch_h; /* chanel handle - slimbus only */ + u16 port; /* + * tabla port for RX and TX + * such as 0-9 for TX and 10 -16 for RX + * apply for both i2s and slimbus + */ + u16 shift; /* + * shift bit for RX and TX + * apply for both i2s and slimbus + */ + struct list_head list; /* + * channel link list + * apply for both i2s and slimbus + */ +}; + +struct wcd9xxx_codec_dai_data { + u32 rate; /* sample rate */ + u32 bit_width; /* sit width 16,24,32 */ + struct list_head wcd9xxx_ch_list; /* channel list */ + u16 grph; /* slimbus group handle */ + unsigned long ch_mask; + wait_queue_head_t dai_wait; + bool bus_down_in_recovery; +}; + +#define WCD9XXX_CH(xport, xshift) \ + {.port = xport, .shift = xshift} + +enum wcd9xxx_chipid_major { + TABLA_MAJOR = cpu_to_le16(0x100), + SITAR_MAJOR = cpu_to_le16(0x101), + TAIKO_MAJOR = cpu_to_le16(0x102), + TAPAN_MAJOR = cpu_to_le16(0x103), + TOMTOM_MAJOR = cpu_to_le16(0x105), + TASHA_MAJOR = cpu_to_le16(0x0), + TASHA2P0_MAJOR = cpu_to_le16(0x107), + TAVIL_MAJOR = cpu_to_le16(0x108), +}; + +enum codec_power_states { + WCD_REGION_POWER_COLLAPSE_REMOVE, + WCD_REGION_POWER_COLLAPSE_BEGIN, + WCD_REGION_POWER_DOWN, +}; + +enum wcd_power_regions { + WCD9XXX_DIG_CORE_REGION_1, + WCD9XXX_MAX_PWR_REGIONS, +}; + +struct wcd9xxx_codec_type { + u16 id_major; + u16 id_minor; + struct mfd_cell *dev; + int size; + int num_irqs; + int version; /* -1 to retrive version from chip version register */ + enum wcd9xxx_slim_slave_addr_type slim_slave_type; + u16 i2c_chip_status; + const struct intr_data *intr_tbl; + int intr_tbl_size; + u16 intr_reg[WCD9XXX_INTR_REG_MAX]; +}; + +struct wcd9xxx_power_region { + enum codec_power_states power_state; + u16 pwr_collapse_reg_min; + u16 pwr_collapse_reg_max; +}; + +struct wcd9xxx { + struct device *dev; + struct slim_device *slim; + struct slim_device *slim_slave; + struct mutex io_lock; + struct mutex xfer_lock; + struct mutex reset_lock; + u8 version; + + int reset_gpio; + struct device_node *wcd_rst_np; + + int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *dest, bool interface_reg); + int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src, bool interface_reg); + int (*multi_reg_write)(struct wcd9xxx *wcd9xxx, const void *data, + size_t count); + int (*dev_down)(struct wcd9xxx *wcd9xxx); + int (*post_reset)(struct wcd9xxx *wcd9xxx); + + void *ssr_priv; + bool dev_up; + + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + + struct wcd9xxx_core_resource core_res; + + u16 id_minor; + u16 id_major; + + /* Slimbus or I2S port */ + u32 num_rx_port; + u32 num_tx_port; + struct wcd9xxx_ch *rx_chs; + struct wcd9xxx_ch *tx_chs; + u32 mclk_rate; + enum codec_variant type; + struct regmap *regmap; + + struct wcd9xxx_codec_type *codec_type; + bool prev_pg_valid; + u8 prev_pg; + u8 avoid_cdc_rstlow; + struct wcd9xxx_power_region *wcd9xxx_pwr[WCD9XXX_MAX_PWR_REGIONS]; +}; + +struct wcd9xxx_reg_val { + unsigned short reg; /* register address */ + u8 *buf; /* buffer to be written to reg. addr */ + int bytes; /* number of bytes to be written */ +}; + +int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); +int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, + u8 val); +int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la); +int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, + int bytes, void *src); +int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, + u32 bw_ops, bool commit); +int wcd9xxx_set_power_state(struct wcd9xxx *, enum codec_power_states, + enum wcd_power_regions); +int wcd9xxx_get_current_power_state(struct wcd9xxx *, + enum wcd_power_regions); + +int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg); + +int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_reg_val *bulk_reg, + unsigned int size, bool interface); + +extern int wcd9xxx_core_res_init( + struct wcd9xxx_core_resource*, + int, int, struct regmap *); + +extern void wcd9xxx_core_res_deinit( + struct wcd9xxx_core_resource *); + +extern int wcd9xxx_core_res_suspend( + struct wcd9xxx_core_resource *, + pm_message_t); + +extern int wcd9xxx_core_res_resume( + struct wcd9xxx_core_resource *); + +extern int wcd9xxx_core_irq_init( + struct wcd9xxx_core_resource*); + +extern int wcd9xxx_assign_irq(struct wcd9xxx_core_resource*, + unsigned int, + unsigned int); + +extern enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void); +extern void wcd9xxx_set_intf_type(enum wcd9xxx_intf_status); + +extern enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg( + struct wcd9xxx_core_resource *, + enum wcd9xxx_pm_state, + enum wcd9xxx_pm_state); +static inline int __init wcd9xxx_irq_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#endif diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h new file mode 100755 index 000000000000..7bf2bff2f173 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/pdata.h @@ -0,0 +1,197 @@ +/* Copyright (c) 2011-2016, 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 __MFD_WCD9XXX_PDATA_H__ + +#define __MFD_WCD9XXX_PDATA_H__ + +#include <linux/slimbus/slimbus.h> +#include <linux/mfd/msm-cdc-supply.h> + +#define MICBIAS_EXT_BYP_CAP 0x00 +#define MICBIAS_NO_EXT_BYP_CAP 0x01 + +#define SITAR_LDOH_1P95_V 0x0 +#define SITAR_LDOH_2P35_V 0x1 +#define SITAR_LDOH_2P75_V 0x2 +#define SITAR_LDOH_2P85_V 0x3 + +#define SITAR_CFILT1_SEL 0x0 +#define SITAR_CFILT2_SEL 0x1 +#define SITAR_CFILT3_SEL 0x2 + +#define WCD9XXX_LDOH_1P95_V 0x0 +#define WCD9XXX_LDOH_2P35_V 0x1 +#define WCD9XXX_LDOH_2P75_V 0x2 +#define WCD9XXX_LDOH_2P85_V 0x3 +#define WCD9XXX_LDOH_3P0_V 0x3 + +#define TABLA_LDOH_1P95_V 0x0 +#define TABLA_LDOH_2P35_V 0x1 +#define TABLA_LDOH_2P75_V 0x2 +#define TABLA_LDOH_2P85_V 0x3 + +#define TABLA_CFILT1_SEL 0x0 +#define TABLA_CFILT2_SEL 0x1 +#define TABLA_CFILT3_SEL 0x2 + +#define MAX_AMIC_CHANNEL 7 + +#define TABLA_OCP_300_MA 0x0 +#define TABLA_OCP_350_MA 0x2 +#define TABLA_OCP_365_MA 0x3 +#define TABLA_OCP_150_MA 0x4 +#define TABLA_OCP_190_MA 0x6 +#define TABLA_OCP_220_MA 0x7 + +#define TABLA_DCYCLE_255 0x0 +#define TABLA_DCYCLE_511 0x1 +#define TABLA_DCYCLE_767 0x2 +#define TABLA_DCYCLE_1023 0x3 +#define TABLA_DCYCLE_1279 0x4 +#define TABLA_DCYCLE_1535 0x5 +#define TABLA_DCYCLE_1791 0x6 +#define TABLA_DCYCLE_2047 0x7 +#define TABLA_DCYCLE_2303 0x8 +#define TABLA_DCYCLE_2559 0x9 +#define TABLA_DCYCLE_2815 0xA +#define TABLA_DCYCLE_3071 0xB +#define TABLA_DCYCLE_3327 0xC +#define TABLA_DCYCLE_3583 0xD +#define TABLA_DCYCLE_3839 0xE +#define TABLA_DCYCLE_4095 0xF + +#define WCD9XXX_MCLK_CLK_12P288MHZ 12288000 +#define WCD9XXX_MCLK_CLK_9P6HZ 9600000 + +/* Only valid for 9.6 MHz mclk */ +#define WCD9XXX_DMIC_SAMPLE_RATE_600KHZ 600000 +#define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000 +#define WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ 3200000 +#define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000 + +/* Only valid for 12.288 MHz mclk */ +#define WCD9XXX_DMIC_SAMPLE_RATE_768KHZ 768000 +#define WCD9XXX_DMIC_SAMPLE_RATE_2P048MHZ 2048000 +#define WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ 3072000 +#define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000 +#define WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ 6144000 + +#define WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED 0 + +#define WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED 0 + +struct wcd9xxx_amic { + /*legacy mode, txfe_enable and txfe_buff take 7 input + * each bit represent the channel / TXFE number + * and numbered as below + * bit 0 = channel 1 / TXFE1_ENABLE / TXFE1_BUFF + * bit 1 = channel 2 / TXFE2_ENABLE / TXFE2_BUFF + * ... + * bit 7 = channel 7 / TXFE7_ENABLE / TXFE7_BUFF + */ + u8 legacy_mode:MAX_AMIC_CHANNEL; + u8 txfe_enable:MAX_AMIC_CHANNEL; + u8 txfe_buff:MAX_AMIC_CHANNEL; + u8 use_pdata:MAX_AMIC_CHANNEL; +}; + +/* Each micbias can be assigned to one of three cfilters + * Vbatt_min >= .15V + ldoh_v + * ldoh_v >= .15v + cfiltx_mv + * If ldoh_v = 1.95 160 mv < cfiltx_mv < 1800 mv + * If ldoh_v = 2.35 200 mv < cfiltx_mv < 2200 mv + * If ldoh_v = 2.75 240 mv < cfiltx_mv < 2600 mv + * If ldoh_v = 2.85 250 mv < cfiltx_mv < 2700 mv + */ + +struct wcd9xxx_micbias_setting { + u8 ldoh_v; + u32 cfilt1_mv; /* in mv */ + u32 cfilt2_mv; /* in mv */ + u32 cfilt3_mv; /* in mv */ + u32 micb1_mv; + u32 micb2_mv; + u32 micb3_mv; + u32 micb4_mv; + /* Different WCD9xxx series codecs may not + * have 4 mic biases. If a codec has fewer + * mic biases, some of these properties will + * not be used. + */ + u8 bias1_cfilt_sel; + u8 bias2_cfilt_sel; + u8 bias3_cfilt_sel; + u8 bias4_cfilt_sel; + u8 bias1_cap_mode; + u8 bias2_cap_mode; + u8 bias3_cap_mode; + u8 bias4_cap_mode; + bool bias2_is_headset_only; +}; + +struct wcd9xxx_ocp_setting { + unsigned int use_pdata:1; /* 0 - use sys default as recommended */ + unsigned int num_attempts:4; /* up to 15 attempts */ + unsigned int run_time:4; /* in duty cycle */ + unsigned int wait_time:4; /* in duty cycle */ + unsigned int hph_ocp_limit:3; /* Headphone OCP current limit */ +}; + +#define WCD9XXX_MAX_REGULATOR 9 +/* + * format : TABLA_<POWER_SUPPLY_PIN_NAME>_CUR_MAX + * + * <POWER_SUPPLY_PIN_NAME> from Tabla objective spec +*/ + +#define WCD9XXX_CDC_VDDA_CP_CUR_MAX 500000 +#define WCD9XXX_CDC_VDDA_RX_CUR_MAX 20000 +#define WCD9XXX_CDC_VDDA_TX_CUR_MAX 20000 +#define WCD9XXX_VDDIO_CDC_CUR_MAX 5000 + +#define WCD9XXX_VDDD_CDC_D_CUR_MAX 5000 +#define WCD9XXX_VDDD_CDC_A_CUR_MAX 5000 + +#define WCD9XXX_VDD_SPKDRV_NAME "cdc-vdd-spkdrv" +#define WCD9XXX_VDD_SPKDRV2_NAME "cdc-vdd-spkdrv-2" + +struct wcd9xxx_regulator { + const char *name; + int min_uV; + int max_uV; + int optimum_uA; + bool ondemand; + struct regulator *regulator; +}; + +struct wcd9xxx_pdata { + int irq; + int irq_base; + int num_irqs; + int reset_gpio; + struct device_node *wcd_rst_np; + struct wcd9xxx_amic amic_settings; + struct slim_device slimbus_slave_device; + struct wcd9xxx_micbias_setting micbias; + struct wcd9xxx_ocp_setting ocp; + struct cdc_regulator *regulator; + int num_supplies; + u32 mclk_rate; + u32 dmic_sample_rate; + u32 mad_dmic_sample_rate; + u32 ecpp_dmic_sample_rate; + u32 dmic_clk_drv; + u16 use_pinctrl; +}; + +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h new file mode 100755 index 000000000000..cec0ce2dd558 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h @@ -0,0 +1,1106 @@ +#ifndef TABLA_CODEC_DIGITAL_H + +#define TABLA_CODEC_DIGITAL_H +#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> + +#define TABLA_A_CHIP_CTL WCD9XXX_A_CHIP_CTL +#define TABLA_A_CHIP_CTL__POR WCD9XXX_A_CHIP_CTL__POR +#define TABLA_A_CHIP_STATUS WCD9XXX_A_CHIP_STATUS +#define TABLA_A_CHIP_STATUS__POR WCD9XXX_A_CHIP_STATUS__POR +#define TABLA_A_CHIP_ID_BYTE_0 WCD9XXX_A_CHIP_ID_BYTE_0 +#define TABLA_A_CHIP_ID_BYTE_0__POR WCD9XXX_A_CHIP_ID_BYTE_0__POR +#define TABLA_A_CHIP_ID_BYTE_1 WCD9XXX_A_CHIP_ID_BYTE_1 +#define TABLA_A_CHIP_ID_BYTE_1__POR WCD9XXX_A_CHIP_ID_BYTE_1__POR +#define TABLA_A_CHIP_ID_BYTE_2 WCD9XXX_A_CHIP_ID_BYTE_2 +#define TABLA_A_CHIP_ID_BYTE_2__POR WCD9XXX_A_CHIP_ID_BYTE_2__POR +#define TABLA_A_CHIP_ID_BYTE_3 WCD9XXX_A_CHIP_ID_BYTE_3 +#define TABLA_A_CHIP_ID_BYTE_3__POR WCD9XXX_A_CHIP_ID_BYTE_3__POR +#define TABLA_A_CHIP_VERSION WCD9XXX_A_CHIP_VERSION +#define TABLA_A_CHIP_VERSION__POR WCD9XXX_A_CHIP_VERSION__POR +#define TABLA_A_SB_VERSION WCD9XXX_A_SB_VERSION +#define TABLA_A_SB_VERSION__POR WCD9XXX_A_SB_VERSION__POR +#define TABLA_A_SLAVE_ID_1 WCD9XXX_A_SLAVE_ID_1 +#define TABLA_A_SLAVE_ID_1__POR WCD9XXX_A_SLAVE_ID_1__POR +#define TABLA_A_SLAVE_ID_2 WCD9XXX_A_SLAVE_ID_2 +#define TABLA_A_SLAVE_ID_2__POR WCD9XXX_A_SLAVE_ID_2__POR +#define TABLA_A_SLAVE_ID_3 WCD9XXX_A_SLAVE_ID_3 +#define TABLA_A_SLAVE_ID_3__POR WCD9XXX_A_SLAVE_ID_3__POR +#define TABLA_A_PIN_CTL_OE0 (0x10) +#define TABLA_A_PIN_CTL_OE0__POR (0x00000000) +#define TABLA_A_PIN_CTL_OE1 (0x11) +#define TABLA_A_PIN_CTL_OE1__POR (0x00000000) +#define TABLA_A_PIN_CTL_DATA0 (0x12) +#define TABLA_A_PIN_CTL_DATA0__POR (0x00000000) +#define TABLA_A_PIN_CTL_DATA1 (0x13) +#define TABLA_A_PIN_CTL_DATA1__POR (0x00000000) +#define TABLA_A_HDRIVE_GENERIC (0x18) +#define TABLA_A_HDRIVE_GENERIC__POR (0x00000000) +#define TABLA_A_HDRIVE_OVERRIDE (0x19) +#define TABLA_A_HDRIVE_OVERRIDE__POR (0x00000008) +#define TABLA_A_ANA_CSR_WAIT_STATE (0x20) +#define TABLA_A_ANA_CSR_WAIT_STATE__POR (0x00000044) +#define TABLA_A_PROCESS_MONITOR_CTL0 (0x40) +#define TABLA_A_PROCESS_MONITOR_CTL0__POR (0x00000080) +#define TABLA_A_PROCESS_MONITOR_CTL1 (0x41) +#define TABLA_A_PROCESS_MONITOR_CTL1__POR (0x00000000) +#define TABLA_A_PROCESS_MONITOR_CTL2 (0x42) +#define TABLA_A_PROCESS_MONITOR_CTL2__POR (0x00000000) +#define TABLA_A_PROCESS_MONITOR_CTL3 (0x43) +#define TABLA_A_PROCESS_MONITOR_CTL3__POR (0x00000001) +#define TABLA_A_QFUSE_CTL (0x48) +#define TABLA_A_QFUSE_CTL__POR (0x00000000) +#define TABLA_A_QFUSE_STATUS (0x49) +#define TABLA_A_QFUSE_STATUS__POR (0x00000000) +#define TABLA_A_QFUSE_DATA_OUT0 (0x4A) +#define TABLA_A_QFUSE_DATA_OUT0__POR (0x00000000) +#define TABLA_A_QFUSE_DATA_OUT1 (0x4B) +#define TABLA_A_QFUSE_DATA_OUT1__POR (0x00000000) +#define TABLA_A_QFUSE_DATA_OUT2 (0x4C) +#define TABLA_A_QFUSE_DATA_OUT2__POR (0x00000000) +#define TABLA_A_QFUSE_DATA_OUT3 (0x4D) +#define TABLA_A_QFUSE_DATA_OUT3__POR (0x00000000) +#define TABLA_A_CDC_CTL WCD9XXX_A_CDC_CTL +#define TABLA_A_CDC_CTL__POR WCD9XXX_A_CDC_CTL__POR +#define TABLA_A_LEAKAGE_CTL WCD9XXX_A_LEAKAGE_CTL +#define TABLA_A_LEAKAGE_CTL__POR WCD9XXX_A_LEAKAGE_CTL__POR +#define TABLA_A_INTR_MODE (0x90) +#define TABLA_A_INTR_MODE__POR (0x00000000) +#define TABLA_A_INTR_MASK0 (0x94) +#define TABLA_A_INTR_MASK0__POR (0x000000ff) +#define TABLA_A_INTR_MASK1 (0x95) +#define TABLA_A_INTR_MASK1__POR (0x000000ff) +#define TABLA_A_INTR_MASK2 (0x96) +#define TABLA_A_INTR_MASK2__POR (0x000000ff) +#define TABLA_A_INTR_STATUS0 (0x98) +#define TABLA_A_INTR_STATUS0__POR (0x00000000) +#define TABLA_A_INTR_STATUS1 (0x99) +#define TABLA_A_INTR_STATUS1__POR (0x00000000) +#define TABLA_A_INTR_STATUS2 (0x9A) +#define TABLA_A_INTR_STATUS2__POR (0x00000000) +#define TABLA_A_INTR_CLEAR0 (0x9C) +#define TABLA_A_INTR_CLEAR0__POR (0x00000000) +#define TABLA_A_INTR_CLEAR1 (0x9D) +#define TABLA_A_INTR_CLEAR1__POR (0x00000000) +#define TABLA_A_INTR_CLEAR2 (0x9E) +#define TABLA_A_INTR_CLEAR2__POR (0x00000000) +#define TABLA_A_INTR_LEVEL0 (0xA0) +#define TABLA_A_INTR_LEVEL0__POR (0x00000001) +#define TABLA_A_INTR_LEVEL1 (0xA1) +#define TABLA_A_INTR_LEVEL1__POR (0x00000000) +#define TABLA_A_INTR_LEVEL2 (0xA2) +#define TABLA_A_INTR_LEVEL2__POR (0x00000000) +#define TABLA_A_INTR_TEST0 (0xA4) +#define TABLA_A_INTR_TEST0__POR (0x00000000) +#define TABLA_A_INTR_TEST1 (0xA5) +#define TABLA_A_INTR_TEST1__POR (0x00000000) +#define TABLA_A_INTR_TEST2 (0xA6) +#define TABLA_A_INTR_TEST2__POR (0x00000000) +#define TABLA_A_INTR_SET0 (0xA8) +#define TABLA_A_INTR_SET0__POR (0x00000000) +#define TABLA_A_INTR_SET1 (0xA9) +#define TABLA_A_INTR_SET1__POR (0x00000000) +#define TABLA_A_INTR_SET2 (0xAA) +#define TABLA_A_INTR_SET2__POR (0x00000000) +#define TABLA_A_CDC_TX_I2S_SCK_MODE (0xC0) +#define TABLA_A_CDC_TX_I2S_SCK_MODE__POR (0x00000000) +#define TABLA_A_CDC_TX_I2S_WS_MODE (0xC1) +#define TABLA_A_CDC_TX_I2S_WS_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_DATA0_MODE (0xC4) +#define TABLA_A_CDC_DMIC_DATA0_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_CLK0_MODE (0xC5) +#define TABLA_A_CDC_DMIC_CLK0_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_DATA1_MODE (0xC6) +#define TABLA_A_CDC_DMIC_DATA1_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_CLK1_MODE (0xC7) +#define TABLA_A_CDC_DMIC_CLK1_MODE__POR (0x00000000) +#define TABLA_A_CDC_RX_I2S_SCK_MODE (0xC8) +#define TABLA_A_CDC_RX_I2S_SCK_MODE__POR (0x00000000) +#define TABLA_A_CDC_RX_I2S_WS_MODE (0xC9) +#define TABLA_A_CDC_RX_I2S_WS_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_DATA2_MODE (0xCA) +#define TABLA_A_CDC_DMIC_DATA2_MODE__POR (0x00000000) +#define TABLA_A_CDC_DMIC_CLK2_MODE (0xCB) +#define TABLA_A_CDC_DMIC_CLK2_MODE__POR (0x00000000) +#define TABLA_A_CDC_INTR_MODE (0xCC) +#define TABLA_A_CDC_INTR_MODE__POR (0x00000000) +#define TABLA_A_BIAS_REF_CTL (0x0100) +#define TABLA_A_BIAS_REF_CTL__POR (0x0000001C) +#define TABLA_A_BIAS_CENTRAL_BG_CTL (0x0101) +#define TABLA_A_BIAS_CENTRAL_BG_CTL__POR (0x00000050) +#define TABLA_A_BIAS_PRECHRG_CTL (0x0102) +#define TABLA_A_BIAS_PRECHRG_CTL__POR (0x00000007) +#define TABLA_A_BIAS_CURR_CTL_1 (0x0103) +#define TABLA_A_BIAS_CURR_CTL_1__POR (0x00000052) +#define TABLA_A_BIAS_CURR_CTL_2 (0x0104) +#define TABLA_A_BIAS_CURR_CTL_2__POR (0x00000000) +#define TABLA_A_BIAS_CONFIG_MODE_BG_CTL (0x0105) +#define TABLA_A_BIAS_CONFIG_MODE_BG_CTL__POR (0x00000016) +#define TABLA_A_BIAS_BG_STATUS (0x0106) +#define TABLA_A_BIAS_BG_STATUS__POR (0x00000000) +#define TABLA_A_CLK_BUFF_EN1 (0x0108) +#define TABLA_A_CLK_BUFF_EN1__POR (0x00000004) +#define TABLA_A_CLK_BUFF_EN2 (0x0109) +#define TABLA_A_CLK_BUFF_EN2__POR (0x00000002) +#define TABLA_A_LDO_H_MODE_1 (0x0110) +#define TABLA_A_LDO_H_MODE_1__POR (0x00000065) +#define TABLA_A_LDO_H_MODE_2 (0x0111) +#define TABLA_A_LDO_H_MODE_2__POR (0x000000A8) +#define TABLA_A_LDO_H_LOOP_CTL (0x0112) +#define TABLA_A_LDO_H_LOOP_CTL__POR (0x0000006B) +#define TABLA_A_LDO_H_COMP_1 (0x0113) +#define TABLA_A_LDO_H_COMP_1__POR (0x00000084) +#define TABLA_A_LDO_H_COMP_2 (0x0114) +#define TABLA_A_LDO_H_COMP_2__POR (0x000000E0) +#define TABLA_A_LDO_H_BIAS_1 (0x0115) +#define TABLA_A_LDO_H_BIAS_1__POR (0x0000006D) +#define TABLA_A_LDO_H_BIAS_2 (0x0116) +#define TABLA_A_LDO_H_BIAS_2__POR (0x000000A5) +#define TABLA_A_LDO_H_BIAS_3 (0x0117) +#define TABLA_A_LDO_H_BIAS_3__POR (0x00000060) +#define TABLA_A_LDO_L_MODE_1 (0x0118) +#define TABLA_A_LDO_L_MODE_1__POR (0x00000028) +#define TABLA_A_LDO_L_MODE_2 (0x0119) +#define TABLA_A_LDO_L_MODE_2__POR (0x000000A8) +#define TABLA_A_LDO_L_LOOP_CTL (0x011A) +#define TABLA_A_LDO_L_LOOP_CTL__POR (0x0000006D) +#define TABLA_A_LDO_L_COMP_1 (0x011B) +#define TABLA_A_LDO_L_COMP_1__POR (0x00000031) +#define TABLA_A_LDO_L_COMP_2 (0x011C) +#define TABLA_A_LDO_L_COMP_2__POR (0x000000A0) +#define TABLA_A_LDO_L_BIAS_1 (0x011D) +#define TABLA_A_LDO_L_BIAS_1__POR (0x0000006D) +#define TABLA_A_LDO_L_BIAS_2 (0x011E) +#define TABLA_A_LDO_L_BIAS_2__POR (0x00000065) +#define TABLA_A_LDO_L_BIAS_3 (0x011F) +#define TABLA_A_LDO_L_BIAS_3__POR (0x00000050) +#define TABLA_A_MICB_CFILT_1_CTL (0x0128) +#define TABLA_A_MICB_CFILT_1_CTL__POR (0x00000040) +#define TABLA_A_MICB_CFILT_1_VAL (0x0129) +#define TABLA_A_MICB_CFILT_1_VAL__POR (0x00000080) +#define TABLA_A_MICB_CFILT_1_PRECHRG (0x012A) +#define TABLA_A_MICB_CFILT_1_PRECHRG__POR (0x00000038) +#define TABLA_A_MICB_1_CTL (0x012B) +#define TABLA_A_MICB_1_CTL__POR (0x00000016) +#define TABLA_A_MICB_1_INT_RBIAS (0x012C) +#define TABLA_A_MICB_1_INT_RBIAS__POR (0x00000000) +#define TABLA_A_MICB_1_MBHC (0x012D) +#define TABLA_A_MICB_1_MBHC__POR (0x00000001) +#define TABLA_A_MICB_CFILT_2_CTL (0x012E) +#define TABLA_A_MICB_CFILT_2_CTL__POR (0x00000040) +#define TABLA_A_MICB_CFILT_2_VAL (0x012F) +#define TABLA_A_MICB_CFILT_2_VAL__POR (0x00000080) +#define TABLA_A_MICB_CFILT_2_PRECHRG (0x0130) +#define TABLA_A_MICB_CFILT_2_PRECHRG__POR (0x00000038) +#define TABLA_A_MICB_2_CTL (0x0131) +#define TABLA_A_MICB_2_CTL__POR (0x00000016) +#define TABLA_A_MICB_2_INT_RBIAS (0x0132) +#define TABLA_A_MICB_2_INT_RBIAS__POR (0x00000000) +#define TABLA_A_MICB_2_MBHC (0x0133) +#define TABLA_A_MICB_2_MBHC__POR (0x00000000) +#define TABLA_A_MICB_CFILT_3_CTL (0x0134) +#define TABLA_A_MICB_CFILT_3_CTL__POR (0x00000040) +#define TABLA_A_MICB_CFILT_3_VAL (0x0135) +#define TABLA_A_MICB_CFILT_3_VAL__POR (0x00000080) +#define TABLA_A_MICB_CFILT_3_PRECHRG (0x0136) +#define TABLA_A_MICB_CFILT_3_PRECHRG__POR (0x00000038) +#define TABLA_A_MICB_3_CTL (0x0137) +#define TABLA_A_MICB_3_CTL__POR (0x00000016) +#define TABLA_A_MICB_3_INT_RBIAS (0x0138) +#define TABLA_A_MICB_3_INT_RBIAS__POR (0x00000000) +#define TABLA_A_MICB_3_MBHC (0x0139) +#define TABLA_A_MICB_3_MBHC__POR (0x00000000) +#define TABLA_1_A_MICB_4_CTL (0x013A) +#define TABLA_2_A_MICB_4_CTL (0x013D) +#define TABLA_A_MICB_4_CTL__POR (0x00000016) +#define TABLA_1_A_MICB_4_INT_RBIAS (0x013B) +#define TABLA_2_A_MICB_4_INT_RBIAS (0x013E) +#define TABLA_A_MICB_4_INT_RBIAS__POR (0x00000000) +#define TABLA_1_A_MICB_4_MBHC (0x013C) +#define TABLA_2_A_MICB_4_MBHC (0x013F) +#define TABLA_A_MICB_4_MBHC__POR (0x00000001) +#define TABLA_A_TX_COM_BIAS (0x014C) +#define TABLA_A_TX_COM_BIAS__POR (0x000000E0) +#define TABLA_A_MBHC_SCALING_MUX_1 (0x014E) +#define TABLA_A_MBHC_SCALING_MUX_1__POR (0x00000000) +#define TABLA_A_MBHC_SCALING_MUX_2 (0x014F) +#define TABLA_A_MBHC_SCALING_MUX_2__POR (0x00000080) +#define TABLA_A_TX_SUP_SWITCH_CTRL_1 (0x0151) +#define TABLA_A_TX_SUP_SWITCH_CTRL_1__POR (0x00000000) +#define TABLA_A_TX_SUP_SWITCH_CTRL_2 (0x0152) +#define TABLA_A_TX_SUP_SWITCH_CTRL_2__POR (0x00000080) +#define TABLA_A_TX_1_2_EN (0x0153) +#define TABLA_A_TX_1_2_EN__POR (0x00000000) +#define TABLA_A_TX_1_2_TEST_EN (0x0154) +#define TABLA_A_TX_1_2_TEST_EN__POR (0x000000CC) +#define TABLA_A_TX_1_2_ADC_CH1 (0x0155) +#define TABLA_A_TX_1_2_ADC_CH1__POR (0x00000044) +#define TABLA_A_TX_1_2_ADC_CH2 (0x0156) +#define TABLA_A_TX_1_2_ADC_CH2__POR (0x00000044) +#define TABLA_A_TX_1_2_ATEST_REFCTRL (0x0157) +#define TABLA_A_TX_1_2_ATEST_REFCTRL__POR (0x00000000) +#define TABLA_A_TX_1_2_TEST_CTL (0x0158) +#define TABLA_A_TX_1_2_TEST_CTL__POR (0x00000038) +#define TABLA_A_TX_1_2_TEST_BLOCK_EN (0x0159) +#define TABLA_A_TX_1_2_TEST_BLOCK_EN__POR (0x000000FF) +#define TABLA_A_TX_1_2_TXFE_CLKDIV (0x015A) +#define TABLA_A_TX_1_2_TXFE_CLKDIV__POR (0x000000EE) +#define TABLA_A_TX_1_2_SAR_ERR_CH1 (0x015B) +#define TABLA_A_TX_1_2_SAR_ERR_CH1__POR (0x00000000) +#define TABLA_A_TX_1_2_SAR_ERR_CH2 (0x015C) +#define TABLA_A_TX_1_2_SAR_ERR_CH2__POR (0x00000000) +#define TABLA_A_TX_3_4_EN (0x015D) +#define TABLA_A_TX_3_4_EN__POR (0x00000000) +#define TABLA_A_TX_3_4_TEST_EN (0x015E) +#define TABLA_A_TX_3_4_TEST_EN__POR (0x000000CC) +#define TABLA_A_TX_3_4_ADC_CH3 (0x015F) +#define TABLA_A_TX_3_4_ADC_CH3__POR (0x00000044) +#define TABLA_A_TX_3_4_ADC_CH4 (0x0160) +#define TABLA_A_TX_3_4_ADC_CH4__POR (0x00000044) +#define TABLA_A_TX_3_4_ATEST_REFCTRL (0x0161) +#define TABLA_A_TX_3_4_ATEST_REFCTRL__POR (0x00000000) +#define TABLA_A_TX_3_4_TEST_CTL (0x0162) +#define TABLA_A_TX_3_4_TEST_CTL__POR (0x00000038) +#define TABLA_A_TX_3_4_TEST_BLOCK_EN (0x0163) +#define TABLA_A_TX_3_4_TEST_BLOCK_EN__POR (0x000000FF) +#define TABLA_A_TX_3_4_TXFE_CKDIV (0x0164) +#define TABLA_A_TX_3_4_TXFE_CKDIV__POR (0x000000EE) +#define TABLA_A_TX_3_4_SAR_ERR_CH3 (0x0165) +#define TABLA_A_TX_3_4_SAR_ERR_CH3__POR (0x00000000) +#define TABLA_A_TX_3_4_SAR_ERR_CH4 (0x0166) +#define TABLA_A_TX_3_4_SAR_ERR_CH4__POR (0x00000000) +#define TABLA_A_TX_5_6_EN (0x0167) +#define TABLA_A_TX_5_6_EN__POR (0x00000011) +#define TABLA_A_TX_5_6_TEST_EN (0x0168) +#define TABLA_A_TX_5_6_TEST_EN__POR (0x000000CC) +#define TABLA_A_TX_5_6_ADC_CH5 (0x0169) +#define TABLA_A_TX_5_6_ADC_CH5__POR (0x00000044) +#define TABLA_A_TX_5_6_ADC_CH6 (0x016A) +#define TABLA_A_TX_5_6_ADC_CH6__POR (0x00000044) +#define TABLA_A_TX_5_6_ATEST_REFCTRL (0x016B) +#define TABLA_A_TX_5_6_ATEST_REFCTRL__POR (0x00000000) +#define TABLA_A_TX_5_6_TEST_CTL (0x016C) +#define TABLA_A_TX_5_6_TEST_CTL__POR (0x00000038) +#define TABLA_A_TX_5_6_TEST_BLOCK_EN (0x016D) +#define TABLA_A_TX_5_6_TEST_BLOCK_EN__POR (0x000000FF) +#define TABLA_A_TX_5_6_TXFE_CKDIV (0x016E) +#define TABLA_A_TX_5_6_TXFE_CKDIV__POR (0x000000EE) +#define TABLA_A_TX_5_6_SAR_ERR_CH5 (0x016F) +#define TABLA_A_TX_5_6_SAR_ERR_CH5__POR (0x00000000) +#define TABLA_A_TX_5_6_SAR_ERR_CH6 (0x0170) +#define TABLA_A_TX_5_6_SAR_ERR_CH6__POR (0x00000000) +#define TABLA_A_TX_7_MBHC_EN (0x0171) +#define TABLA_A_TX_7_MBHC_EN__POR (0x0000000C) +#define TABLA_A_TX_7_MBHC_ATEST_REFCTRL (0x0172) +#define TABLA_A_TX_7_MBHC_ATEST_REFCTRL__POR (0x00000000) +#define TABLA_A_TX_7_MBHC_ADC (0x0173) +#define TABLA_A_TX_7_MBHC_ADC__POR (0x00000044) +#define TABLA_A_TX_7_MBHC_TEST_CTL (0x0174) +#define TABLA_A_TX_7_MBHC_TEST_CTL__POR (0x00000038) +#define TABLA_A_TX_7_MBHC_SAR_ERR (0x0175) +#define TABLA_A_TX_7_MBHC_SAR_ERR__POR (0x00000000) +#define TABLA_A_TX_7_TXFE_CLKDIV (0x0176) +#define TABLA_A_TX_7_TXFE_CLKDIV__POR (0x0000001C) +#define TABLA_A_AUX_COM_CTL (0x0180) +#define TABLA_A_AUX_COM_CTL__POR (0x00000034) +#define TABLA_A_AUX_COM_ATEST (0x0181) +#define TABLA_A_AUX_COM_ATEST__POR (0x00000000) +#define TABLA_A_AUX_L_EN (0x0182) +#define TABLA_A_AUX_L_EN__POR (0x00000000) +#define TABLA_A_AUX_L_GAIN (0x0183) +#define TABLA_A_AUX_L_GAIN__POR (0x0000001F) +#define TABLA_A_AUX_L_PA_CONN (0x0184) +#define TABLA_A_AUX_L_PA_CONN__POR (0x00000000) +#define TABLA_A_AUX_L_PA_CONN_INV (0x0185) +#define TABLA_A_AUX_L_PA_CONN_INV__POR (0x00000000) +#define TABLA_A_AUX_R_EN (0x0186) +#define TABLA_A_AUX_R_EN__POR (0x00000000) +#define TABLA_A_AUX_R_GAIN (0x0187) +#define TABLA_A_AUX_R_GAIN__POR (0x0000001F) +#define TABLA_A_AUX_R_PA_CONN (0x0188) +#define TABLA_A_AUX_R_PA_CONN__POR (0x00000000) +#define TABLA_A_AUX_R_PA_CONN_INV (0x0189) +#define TABLA_A_AUX_R_PA_CONN_INV__POR (0x00000000) +#define TABLA_A_CP_EN (0x0192) +#define TABLA_A_CP_EN__POR (0x000000E6) +#define TABLA_A_CP_CLK (0x0193) +#define TABLA_A_CP_CLK__POR (0x00000029) +#define TABLA_A_CP_STATIC (0x0194) +#define TABLA_A_CP_STATIC__POR (0x00000010) +#define TABLA_A_CP_DCC1 (0x0195) +#define TABLA_A_CP_DCC1__POR (0x00000052) +#define TABLA_A_CP_DCC3 (0x0196) +#define TABLA_A_CP_DCC3__POR (0x00000001) +#define TABLA_A_CP_ATEST (0x0197) +#define TABLA_A_CP_ATEST__POR (0x00000000) +#define TABLA_A_CP_DTEST (0x0198) +#define TABLA_A_CP_DTEST__POR (0x00000000) +#define TABLA_A_RX_COM_TIMER_DIV (0x019E) +#define TABLA_A_RX_COM_TIMER_DIV__POR (0x000000E8) +#define TABLA_A_RX_COM_OCP_CTL (0x019F) +#define TABLA_A_RX_COM_OCP_CTL__POR (0x0000001F) +#define TABLA_A_RX_COM_OCP_COUNT (0x01A0) +#define TABLA_A_RX_COM_OCP_COUNT__POR (0x00000077) +#define TABLA_A_RX_COM_DAC_CTL (0x01A1) +#define TABLA_A_RX_COM_DAC_CTL__POR (0x00000000) +#define TABLA_A_RX_COM_BIAS (0x01A2) +#define TABLA_A_RX_COM_BIAS__POR (0x00000000) +#define TABLA_A_RX_HPH_BIAS_PA (0x01A6) +#define TABLA_A_RX_HPH_BIAS_PA__POR (0x000000AA) +#define TABLA_A_RX_HPH_BIAS_LDO (0x01A7) +#define TABLA_A_RX_HPH_BIAS_LDO__POR (0x00000086) +#define TABLA_A_RX_HPH_BIAS_CNP (0x01A8) +#define TABLA_A_RX_HPH_BIAS_CNP__POR (0x0000008A) +#define TABLA_A_RX_HPH_BIAS_WG (0x01A9) +#define TABLA_A_RX_HPH_BIAS_WG__POR (0x00000060) +#define TABLA_A_RX_HPH_OCP_CTL (0x01AA) +#define TABLA_A_RX_HPH_OCP_CTL__POR (0x000000E8) +#define TABLA_A_RX_HPH_CNP_EN (0x01AB) +#define TABLA_A_RX_HPH_CNP_EN__POR (0x00000080) +#define TABLA_A_RX_HPH_CNP_WG_CTL (0x01AC) +#define TABLA_A_RX_HPH_CNP_WG_CTL__POR (0x000000DC) +#define TABLA_A_RX_HPH_CNP_WG_TIME (0x01AD) +#define TABLA_A_RX_HPH_CNP_WG_TIME__POR (0x00000028) +#define TABLA_A_RX_HPH_L_GAIN (0x01AE) +#define TABLA_A_RX_HPH_L_GAIN__POR (0x00000000) +#define TABLA_A_RX_HPH_L_TEST (0x01AF) +#define TABLA_A_RX_HPH_L_TEST__POR (0x00000001) +#define TABLA_A_RX_HPH_L_PA_CTL (0x01B0) +#define TABLA_A_RX_HPH_L_PA_CTL__POR (0x00000040) +#define TABLA_A_RX_HPH_L_DAC_CTL (0x01B1) +#define TABLA_A_RX_HPH_L_DAC_CTL__POR (0x00000000) +#define TABLA_A_RX_HPH_L_ATEST (0x01B2) +#define TABLA_A_RX_HPH_L_ATEST__POR (0x00000000) +#define TABLA_A_RX_HPH_L_STATUS (0x01B3) +#define TABLA_A_RX_HPH_L_STATUS__POR (0x00000004) +#define TABLA_A_RX_HPH_R_GAIN (0x01B4) +#define TABLA_A_RX_HPH_R_GAIN__POR (0x00000000) +#define TABLA_A_RX_HPH_R_TEST (0x01B5) +#define TABLA_A_RX_HPH_R_TEST__POR (0x00000001) +#define TABLA_A_RX_HPH_R_PA_CTL (0x01B6) +#define TABLA_A_RX_HPH_R_PA_CTL__POR (0x00000040) +#define TABLA_A_RX_HPH_R_DAC_CTL (0x01B7) +#define TABLA_A_RX_HPH_R_DAC_CTL__POR (0x00000000) +#define TABLA_A_RX_HPH_R_ATEST (0x01B8) +#define TABLA_A_RX_HPH_R_ATEST__POR (0x00000000) +#define TABLA_A_RX_HPH_R_STATUS (0x01B9) +#define TABLA_A_RX_HPH_R_STATUS__POR (0x00000004) +#define TABLA_A_RX_EAR_BIAS_PA (0x01BA) +#define TABLA_A_RX_EAR_BIAS_PA__POR (0x000000AA) +#define TABLA_A_RX_EAR_BIAS_CMBUFF (0x01BB) +#define TABLA_A_RX_EAR_BIAS_CMBUFF__POR (0x000000A0) +#define TABLA_A_RX_EAR_EN (0x01BC) +#define TABLA_A_RX_EAR_EN__POR (0x00000000) +#define TABLA_A_RX_EAR_GAIN (0x01BD) +#define TABLA_A_RX_EAR_GAIN__POR (0x00000008) +#define TABLA_A_RX_EAR_CMBUFF (0x01BE) +#define TABLA_A_RX_EAR_CMBUFF__POR (0x00000000) +#define TABLA_A_RX_EAR_ICTL (0x01BF) +#define TABLA_A_RX_EAR_ICTL__POR (0x00000040) +#define TABLA_A_RX_EAR_CCOMP (0x01C0) +#define TABLA_A_RX_EAR_CCOMP__POR (0x00000008) +#define TABLA_A_RX_EAR_VCM (0x01C1) +#define TABLA_A_RX_EAR_VCM__POR (0x00000000) +#define TABLA_A_RX_EAR_CNP (0x01C2) +#define TABLA_A_RX_EAR_CNP__POR (0x00000080) +#define TABLA_A_RX_EAR_ATEST (0x01C3) +#define TABLA_A_RX_EAR_ATEST__POR (0x00000000) +#define TABLA_A_RX_EAR_STATUS (0x01C5) +#define TABLA_A_RX_EAR_STATUS__POR (0x00000004) +#define TABLA_A_RX_LINE_BIAS_PA (0x01C6) +#define TABLA_A_RX_LINE_BIAS_PA__POR (0x000000AA) +#define TABLA_A_RX_LINE_BIAS_DAC (0x01C7) +#define TABLA_A_RX_LINE_BIAS_DAC__POR (0x000000A0) +#define TABLA_A_RX_LINE_BIAS_CNP (0x01C8) +#define TABLA_A_RX_LINE_BIAS_CNP__POR (0x0000003A) +#define TABLA_A_RX_LINE_COM (0x01C9) +#define TABLA_A_RX_LINE_COM__POR (0x00000000) +#define TABLA_A_RX_LINE_CNP_EN (0x01CA) +#define TABLA_A_RX_LINE_CNP_EN__POR (0x00000080) +#define TABLA_A_RX_LINE_CNP_WG_CTL (0x01CB) +#define TABLA_A_RX_LINE_CNP_WG_CTL__POR (0x0000001C) +#define TABLA_A_RX_LINE_CNP_WG_TIME (0x01CC) +#define TABLA_A_RX_LINE_CNP_WG_TIME__POR (0x00000064) +#define TABLA_A_RX_LINE_1_GAIN (0x01CD) +#define TABLA_A_RX_LINE_1_GAIN__POR (0x00000000) +#define TABLA_A_RX_LINE_1_TEST (0x01CE) +#define TABLA_A_RX_LINE_1_TEST__POR (0x00000000) +#define TABLA_A_RX_LINE_1_DAC_CTL (0x01CF) +#define TABLA_A_RX_LINE_1_DAC_CTL__POR (0x0000000C) +#define TABLA_A_RX_LINE_1_STATUS (0x01D0) +#define TABLA_A_RX_LINE_1_STATUS__POR (0x00000000) +#define TABLA_A_RX_LINE_2_GAIN (0x01D1) +#define TABLA_A_RX_LINE_2_GAIN__POR (0x00000000) +#define TABLA_A_RX_LINE_2_TEST (0x01D2) +#define TABLA_A_RX_LINE_2_TEST__POR (0x00000000) +#define TABLA_A_RX_LINE_2_DAC_CTL (0x01D3) +#define TABLA_A_RX_LINE_2_DAC_CTL__POR (0x0000000C) +#define TABLA_A_RX_LINE_2_STATUS (0x01D4) +#define TABLA_A_RX_LINE_2_STATUS__POR (0x00000000) +#define TABLA_A_RX_LINE_3_GAIN (0x01D5) +#define TABLA_A_RX_LINE_3_GAIN__POR (0x00000000) +#define TABLA_A_RX_LINE_3_TEST (0x01D6) +#define TABLA_A_RX_LINE_3_TEST__POR (0x00000000) +#define TABLA_A_RX_LINE_3_DAC_CTL (0x01D7) +#define TABLA_A_RX_LINE_3_DAC_CTL__POR (0x0000000C) +#define TABLA_A_RX_LINE_3_STATUS (0x01D8) +#define TABLA_A_RX_LINE_3_STATUS__POR (0x00000000) +#define TABLA_A_RX_LINE_4_GAIN (0x01D9) +#define TABLA_A_RX_LINE_4_GAIN__POR (0x00000000) +#define TABLA_A_RX_LINE_4_TEST (0x01DA) +#define TABLA_A_RX_LINE_4_TEST__POR (0x00000000) +#define TABLA_A_RX_LINE_4_DAC_CTL (0x01DB) +#define TABLA_A_RX_LINE_4_DAC_CTL__POR (0x0000000C) +#define TABLA_A_RX_LINE_4_STATUS (0x01DC) +#define TABLA_A_RX_LINE_4_STATUS__POR (0x00000000) +#define TABLA_A_RX_LINE_5_GAIN (0x01DD) +#define TABLA_A_RX_LINE_5_GAIN__POR (0x00000000) +#define TABLA_A_RX_LINE_5_TEST (0x01DE) +#define TABLA_A_RX_LINE_5_TEST__POR (0x00000000) +#define TABLA_A_RX_LINE_5_DAC_CTL (0x01DF) +#define TABLA_A_RX_LINE_5_DAC_CTL__POR (0x0000000C) +#define TABLA_A_RX_LINE_5_STATUS (0x01E0) +#define TABLA_A_RX_LINE_5_STATUS__POR (0x00000000) +#define TABLA_A_RX_LINE_CNP_DBG (0x01EC) +#define TABLA_A_RX_LINE_CNP_DBG__POR (0x00000000) +#define TABLA_A_MBHC_HPH (0x01ED) +#define TABLA_A_MBHC_HPH__POR (0x00000048) +#define TABLA_A_CONFIG_MODE_FREQ (0x01F7) +#define TABLA_A_CONFIG_MODE_FREQ__POR (0x00000047) +#define TABLA_A_CONFIG_MODE_TEST (0x01F8) +#define TABLA_A_CONFIG_MODE_TEST__POR (0x0000000A) +#define TABLA_A_CONFIG_MODE_STATUS (0x01F9) +#define TABLA_A_CONFIG_MODE_STATUS__POR (0x0000001C) +#define TABLA_A_CONFIG_MODE_TUNER (0x01FA) +#define TABLA_A_CONFIG_MODE_TUNER__POR (0x00000000) +#define TABLA_A_CDC_ANC1_CTL (0x00000200) +#define TABLA_A_CDC_ANC1_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_CTL (0x00000280) +#define TABLA_A_CDC_ANC2_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_SHIFT (0x00000201) +#define TABLA_A_CDC_ANC1_SHIFT__POR (0x00000000) +#define TABLA_A_CDC_ANC2_SHIFT (0x00000281) +#define TABLA_A_CDC_ANC2_SHIFT__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT1_B1_CTL (0x00000202) +#define TABLA_A_CDC_ANC1_FILT1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT1_B1_CTL (0x00000282) +#define TABLA_A_CDC_ANC2_FILT1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT1_B2_CTL (0x00000203) +#define TABLA_A_CDC_ANC1_FILT1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT1_B2_CTL (0x00000283) +#define TABLA_A_CDC_ANC2_FILT1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT1_B3_CTL (0x00000204) +#define TABLA_A_CDC_ANC1_FILT1_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT1_B3_CTL (0x00000284) +#define TABLA_A_CDC_ANC2_FILT1_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT1_B4_CTL (0x00000205) +#define TABLA_A_CDC_ANC1_FILT1_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT1_B4_CTL (0x00000285) +#define TABLA_A_CDC_ANC2_FILT1_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT2_B1_CTL (0x00000206) +#define TABLA_A_CDC_ANC1_FILT2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT2_B1_CTL (0x00000286) +#define TABLA_A_CDC_ANC2_FILT2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT2_B2_CTL (0x00000207) +#define TABLA_A_CDC_ANC1_FILT2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT2_B2_CTL (0x00000287) +#define TABLA_A_CDC_ANC2_FILT2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT2_B3_CTL (0x00000208) +#define TABLA_A_CDC_ANC1_FILT2_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT2_B3_CTL (0x00000288) +#define TABLA_A_CDC_ANC2_FILT2_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_SPARE (0x00000209) +#define TABLA_A_CDC_ANC1_SPARE__POR (0x00000000) +#define TABLA_A_CDC_ANC2_SPARE (0x00000289) +#define TABLA_A_CDC_ANC2_SPARE__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT3_CTL (0x0000020A) +#define TABLA_A_CDC_ANC1_FILT3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT3_CTL (0x0000028A) +#define TABLA_A_CDC_ANC2_FILT3_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC1_FILT4_CTL (0x0000020B) +#define TABLA_A_CDC_ANC1_FILT4_CTL__POR (0x00000000) +#define TABLA_A_CDC_ANC2_FILT4_CTL (0x0000028B) +#define TABLA_A_CDC_ANC2_FILT4_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX1_VOL_CTL_TIMER (0x00000220) +#define TABLA_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX2_VOL_CTL_TIMER (0x00000228) +#define TABLA_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX3_VOL_CTL_TIMER (0x00000230) +#define TABLA_A_CDC_TX3_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX4_VOL_CTL_TIMER (0x00000238) +#define TABLA_A_CDC_TX4_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX5_VOL_CTL_TIMER (0x00000240) +#define TABLA_A_CDC_TX5_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX6_VOL_CTL_TIMER (0x00000248) +#define TABLA_A_CDC_TX6_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX7_VOL_CTL_TIMER (0x00000250) +#define TABLA_A_CDC_TX7_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX8_VOL_CTL_TIMER (0x00000258) +#define TABLA_A_CDC_TX8_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX9_VOL_CTL_TIMER (0x00000260) +#define TABLA_A_CDC_TX9_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX10_VOL_CTL_TIMER (0x00000268) +#define TABLA_A_CDC_TX10_VOL_CTL_TIMER__POR (0x00000000) +#define TABLA_A_CDC_TX1_VOL_CTL_GAIN (0x00000221) +#define TABLA_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX2_VOL_CTL_GAIN (0x00000229) +#define TABLA_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX3_VOL_CTL_GAIN (0x00000231) +#define TABLA_A_CDC_TX3_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX4_VOL_CTL_GAIN (0x00000239) +#define TABLA_A_CDC_TX4_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX5_VOL_CTL_GAIN (0x00000241) +#define TABLA_A_CDC_TX5_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX6_VOL_CTL_GAIN (0x00000249) +#define TABLA_A_CDC_TX6_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX7_VOL_CTL_GAIN (0x00000251) +#define TABLA_A_CDC_TX7_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX8_VOL_CTL_GAIN (0x00000259) +#define TABLA_A_CDC_TX8_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX9_VOL_CTL_GAIN (0x00000261) +#define TABLA_A_CDC_TX9_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX10_VOL_CTL_GAIN (0x00000269) +#define TABLA_A_CDC_TX10_VOL_CTL_GAIN__POR (0x00000000) +#define TABLA_A_CDC_TX1_VOL_CTL_CFG (0x00000222) +#define TABLA_A_CDC_TX1_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX2_VOL_CTL_CFG (0x0000022A) +#define TABLA_A_CDC_TX2_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX3_VOL_CTL_CFG (0x00000232) +#define TABLA_A_CDC_TX3_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX4_VOL_CTL_CFG (0x0000023A) +#define TABLA_A_CDC_TX4_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX5_VOL_CTL_CFG (0x00000242) +#define TABLA_A_CDC_TX5_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX6_VOL_CTL_CFG (0x0000024A) +#define TABLA_A_CDC_TX6_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX7_VOL_CTL_CFG (0x00000252) +#define TABLA_A_CDC_TX7_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX8_VOL_CTL_CFG (0x0000025A) +#define TABLA_A_CDC_TX8_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX9_VOL_CTL_CFG (0x00000262) +#define TABLA_A_CDC_TX9_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX10_VOL_CTL_CFG (0x0000026A) +#define TABLA_A_CDC_TX10_VOL_CTL_CFG__POR (0x00000000) +#define TABLA_A_CDC_TX1_MUX_CTL (0x00000223) +#define TABLA_A_CDC_TX1_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX2_MUX_CTL (0x0000022B) +#define TABLA_A_CDC_TX2_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX3_MUX_CTL (0x00000233) +#define TABLA_A_CDC_TX3_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX4_MUX_CTL (0x0000023B) +#define TABLA_A_CDC_TX4_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX5_MUX_CTL (0x00000243) +#define TABLA_A_CDC_TX5_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX6_MUX_CTL (0x0000024B) +#define TABLA_A_CDC_TX6_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX7_MUX_CTL (0x00000253) +#define TABLA_A_CDC_TX7_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX8_MUX_CTL (0x0000025B) +#define TABLA_A_CDC_TX8_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX9_MUX_CTL (0x00000263) +#define TABLA_A_CDC_TX9_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX10_MUX_CTL (0x0000026B) +#define TABLA_A_CDC_TX10_MUX_CTL__POR (0x00000008) +#define TABLA_A_CDC_TX1_CLK_FS_CTL (0x00000224) +#define TABLA_A_CDC_TX1_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX2_CLK_FS_CTL (0x0000022C) +#define TABLA_A_CDC_TX2_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX3_CLK_FS_CTL (0x00000234) +#define TABLA_A_CDC_TX3_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX4_CLK_FS_CTL (0x0000023C) +#define TABLA_A_CDC_TX4_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX5_CLK_FS_CTL (0x00000244) +#define TABLA_A_CDC_TX5_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX6_CLK_FS_CTL (0x0000024C) +#define TABLA_A_CDC_TX6_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX7_CLK_FS_CTL (0x00000254) +#define TABLA_A_CDC_TX7_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX8_CLK_FS_CTL (0x0000025C) +#define TABLA_A_CDC_TX8_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX9_CLK_FS_CTL (0x00000264) +#define TABLA_A_CDC_TX9_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX10_CLK_FS_CTL (0x0000026C) +#define TABLA_A_CDC_TX10_CLK_FS_CTL__POR (0x00000003) +#define TABLA_A_CDC_TX1_DMIC_CTL (0x00000225) +#define TABLA_A_CDC_TX1_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX2_DMIC_CTL (0x0000022D) +#define TABLA_A_CDC_TX2_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX3_DMIC_CTL (0x00000235) +#define TABLA_A_CDC_TX3_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX4_DMIC_CTL (0x0000023D) +#define TABLA_A_CDC_TX4_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX5_DMIC_CTL (0x00000245) +#define TABLA_A_CDC_TX5_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX6_DMIC_CTL (0x0000024D) +#define TABLA_A_CDC_TX6_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX7_DMIC_CTL (0x00000255) +#define TABLA_A_CDC_TX7_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX8_DMIC_CTL (0x0000025D) +#define TABLA_A_CDC_TX8_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX9_DMIC_CTL (0x00000265) +#define TABLA_A_CDC_TX9_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_TX10_DMIC_CTL (0x0000026D) +#define TABLA_A_CDC_TX10_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_SRC1_PDA_CFG (0x000002A0) +#define TABLA_A_CDC_SRC1_PDA_CFG__POR (0x00000000) +#define TABLA_A_CDC_SRC2_PDA_CFG (0x000002A8) +#define TABLA_A_CDC_SRC2_PDA_CFG__POR (0x00000000) +#define TABLA_A_CDC_SRC1_FS_CTL (0x000002A1) +#define TABLA_A_CDC_SRC1_FS_CTL__POR (0x0000001b) +#define TABLA_A_CDC_SRC2_FS_CTL (0x000002A9) +#define TABLA_A_CDC_SRC2_FS_CTL__POR (0x0000001b) +#define TABLA_A_CDC_RX1_B1_CTL (0x000002B0) +#define TABLA_A_CDC_RX1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_B1_CTL (0x000002B8) +#define TABLA_A_CDC_RX2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_B1_CTL (0x000002C0) +#define TABLA_A_CDC_RX3_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_B1_CTL (0x000002C8) +#define TABLA_A_CDC_RX4_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_B1_CTL (0x000002D0) +#define TABLA_A_CDC_RX5_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_B1_CTL (0x000002D8) +#define TABLA_A_CDC_RX6_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_B1_CTL (0x000002E0) +#define TABLA_A_CDC_RX7_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_B2_CTL (0x000002B1) +#define TABLA_A_CDC_RX1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_B2_CTL (0x000002B9) +#define TABLA_A_CDC_RX2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_B2_CTL (0x000002C1) +#define TABLA_A_CDC_RX3_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_B2_CTL (0x000002C9) +#define TABLA_A_CDC_RX4_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_B2_CTL (0x000002D1) +#define TABLA_A_CDC_RX5_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_B2_CTL (0x000002D9) +#define TABLA_A_CDC_RX6_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_B2_CTL (0x000002E1) +#define TABLA_A_CDC_RX7_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_B3_CTL (0x000002B2) +#define TABLA_A_CDC_RX1_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_B3_CTL (0x000002BA) +#define TABLA_A_CDC_RX2_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_B3_CTL (0x000002C2) +#define TABLA_A_CDC_RX3_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_B3_CTL (0x000002CA) +#define TABLA_A_CDC_RX4_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_B3_CTL (0x000002D2) +#define TABLA_A_CDC_RX5_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_B3_CTL (0x000002DA) +#define TABLA_A_CDC_RX6_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_B3_CTL (0x000002E2) +#define TABLA_A_CDC_RX7_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_B4_CTL (0x000002B3) +#define TABLA_A_CDC_RX1_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_B4_CTL (0x000002BB) +#define TABLA_A_CDC_RX2_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_B4_CTL (0x000002C3) +#define TABLA_A_CDC_RX3_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_B4_CTL (0x000002CB) +#define TABLA_A_CDC_RX4_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_B4_CTL (0x000002D3) +#define TABLA_A_CDC_RX5_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_B4_CTL (0x000002DB) +#define TABLA_A_CDC_RX6_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_B4_CTL (0x000002E3) +#define TABLA_A_CDC_RX7_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_B5_CTL (0x000002B4) +#define TABLA_A_CDC_RX1_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX2_B5_CTL (0x000002BC) +#define TABLA_A_CDC_RX2_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX3_B5_CTL (0x000002C4) +#define TABLA_A_CDC_RX3_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX4_B5_CTL (0x000002CC) +#define TABLA_A_CDC_RX4_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX5_B5_CTL (0x000002D4) +#define TABLA_A_CDC_RX5_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX6_B5_CTL (0x000002DC) +#define TABLA_A_CDC_RX6_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX7_B5_CTL (0x000002E4) +#define TABLA_A_CDC_RX7_B5_CTL__POR (0x00000060) +#define TABLA_A_CDC_RX1_B6_CTL (0x000002B5) +#define TABLA_A_CDC_RX1_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_B6_CTL (0x000002BD) +#define TABLA_A_CDC_RX2_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_B6_CTL (0x000002C5) +#define TABLA_A_CDC_RX3_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_B6_CTL (0x000002CD) +#define TABLA_A_CDC_RX4_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_B6_CTL (0x000002D5) +#define TABLA_A_CDC_RX5_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_B6_CTL (0x000002DD) +#define TABLA_A_CDC_RX6_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_B6_CTL (0x000002E5) +#define TABLA_A_CDC_RX7_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_VOL_CTL_B1_CTL (0x000002B6) +#define TABLA_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_VOL_CTL_B1_CTL (0x000002BE) +#define TABLA_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_VOL_CTL_B1_CTL (0x000002C6) +#define TABLA_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_VOL_CTL_B1_CTL (0x000002CE) +#define TABLA_A_CDC_RX4_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_VOL_CTL_B1_CTL (0x000002D6) +#define TABLA_A_CDC_RX5_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_VOL_CTL_B1_CTL (0x000002DE) +#define TABLA_A_CDC_RX6_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_VOL_CTL_B1_CTL (0x000002E6) +#define TABLA_A_CDC_RX7_VOL_CTL_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX1_VOL_CTL_B2_CTL (0x000002B7) +#define TABLA_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX2_VOL_CTL_B2_CTL (0x000002BF) +#define TABLA_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX3_VOL_CTL_B2_CTL (0x000002C7) +#define TABLA_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX4_VOL_CTL_B2_CTL (0x000002CF) +#define TABLA_A_CDC_RX4_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX5_VOL_CTL_B2_CTL (0x000002D7) +#define TABLA_A_CDC_RX5_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX6_VOL_CTL_B2_CTL (0x000002DF) +#define TABLA_A_CDC_RX6_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_RX7_VOL_CTL_B2_CTL (0x000002E7) +#define TABLA_A_CDC_RX7_VOL_CTL_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_ANC_RESET_CTL (0x00000300) +#define TABLA_A_CDC_CLK_ANC_RESET_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_RX_RESET_CTL (0x00000301) +#define TABLA_A_CDC_CLK_RX_RESET_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_TX_RESET_B1_CTL (0x00000302) +#define TABLA_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_TX_RESET_B2_CTL (0x00000303) +#define TABLA_A_CDC_CLK_TX_RESET_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_DMIC_CTL (0x00000304) +#define TABLA_A_CDC_CLK_DMIC_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_RX_I2S_CTL (0x00000305) +#define TABLA_A_CDC_CLK_RX_I2S_CTL__POR (0x00000003) +#define TABLA_A_CDC_CLK_TX_I2S_CTL (0x00000306) +#define TABLA_A_CDC_CLK_TX_I2S_CTL__POR (0x00000003) +#define TABLA_A_CDC_CLK_OTHR_RESET_CTL (0x00000307) +#define TABLA_A_CDC_CLK_OTHR_RESET_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x00000308) +#define TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL (0x00000309) +#define TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_OTHR_CTL (0x0000030A) +#define TABLA_A_CDC_CLK_OTHR_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_RDAC_CLK_EN_CTL (0x0000030B) +#define TABLA_A_CDC_CLK_RDAC_CLK_EN_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_ANC_CLK_EN_CTL (0x0000030C) +#define TABLA_A_CDC_CLK_ANC_CLK_EN_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_RX_B1_CTL (0x0000030D) +#define TABLA_A_CDC_CLK_RX_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_RX_B2_CTL (0x0000030E) +#define TABLA_A_CDC_CLK_RX_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_MCLK_CTL (0x0000030F) +#define TABLA_A_CDC_CLK_MCLK_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_PDM_CTL (0x00000310) +#define TABLA_A_CDC_CLK_PDM_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLK_SD_CTL (0x00000311) +#define TABLA_A_CDC_CLK_SD_CTL__POR (0x00000000) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B1_CTL (0x00000320) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B1_CTL__POR (0x00000007) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B2_CTL (0x00000321) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B2_CTL__POR (0x00000013) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B3_CTL (0x00000322) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B3_CTL__POR (0x00000053) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B4_CTL (0x00000323) +#define TABLA_A_CDC_CLSG_FREQ_THRESH_B4_CTL__POR (0x0000007f) +#define TABLA_A_CDC_CLSG_GAIN_THRESH_CTL (0x00000324) +#define TABLA_A_CDC_CLSG_GAIN_THRESH_CTL__POR (0x00000026) +#define TABLA_A_CDC_CLSG_TIMER_B1_CFG (0x00000325) +#define TABLA_A_CDC_CLSG_TIMER_B1_CFG__POR (0x0000000a) +#define TABLA_A_CDC_CLSG_TIMER_B2_CFG (0x00000326) +#define TABLA_A_CDC_CLSG_TIMER_B2_CFG__POR (0x00000000) +#define TABLA_A_CDC_CLSG_CTL (0x00000327) +#define TABLA_A_CDC_CLSG_CTL__POR (0x00000013) +#define TABLA_A_CDC_IIR1_GAIN_B1_CTL (0x00000340) +#define TABLA_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B1_CTL (0x00000350) +#define TABLA_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B2_CTL (0x00000341) +#define TABLA_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B2_CTL (0x00000351) +#define TABLA_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B3_CTL (0x00000342) +#define TABLA_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B3_CTL (0x00000352) +#define TABLA_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B4_CTL (0x00000343) +#define TABLA_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B4_CTL (0x00000353) +#define TABLA_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B5_CTL (0x00000344) +#define TABLA_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B5_CTL (0x00000354) +#define TABLA_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B6_CTL (0x00000345) +#define TABLA_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B6_CTL (0x00000355) +#define TABLA_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B7_CTL (0x00000346) +#define TABLA_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B7_CTL (0x00000356) +#define TABLA_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_B8_CTL (0x00000347) +#define TABLA_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_B8_CTL (0x00000357) +#define TABLA_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_CTL (0x00000348) +#define TABLA_A_CDC_IIR1_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_CTL (0x00000358) +#define TABLA_A_CDC_IIR2_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_GAIN_TIMER_CTL (0x00000349) +#define TABLA_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_GAIN_TIMER_CTL (0x00000359) +#define TABLA_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_COEF_B1_CTL (0x0000034A) +#define TABLA_A_CDC_IIR1_COEF_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_COEF_B1_CTL (0x0000035A) +#define TABLA_A_CDC_IIR2_COEF_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_COEF_B2_CTL (0x0000034B) +#define TABLA_A_CDC_IIR1_COEF_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_COEF_B2_CTL (0x0000035B) +#define TABLA_A_CDC_IIR2_COEF_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_COEF_B3_CTL (0x0000034C) +#define TABLA_A_CDC_IIR1_COEF_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_COEF_B3_CTL (0x0000035C) +#define TABLA_A_CDC_IIR2_COEF_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_COEF_B4_CTL (0x0000034D) +#define TABLA_A_CDC_IIR1_COEF_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_COEF_B4_CTL (0x0000035D) +#define TABLA_A_CDC_IIR2_COEF_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR1_COEF_B5_CTL (0x0000034E) +#define TABLA_A_CDC_IIR1_COEF_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_IIR2_COEF_B5_CTL (0x0000035E) +#define TABLA_A_CDC_IIR2_COEF_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_TOP_GAIN_UPDATE (0x00000360) +#define TABLA_A_CDC_TOP_GAIN_UPDATE__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B1_CTL (0x00000368) +#define TABLA_A_CDC_DEBUG_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B2_CTL (0x00000369) +#define TABLA_A_CDC_DEBUG_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B3_CTL (0x0000036A) +#define TABLA_A_CDC_DEBUG_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B4_CTL (0x0000036B) +#define TABLA_A_CDC_DEBUG_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B5_CTL (0x0000036C) +#define TABLA_A_CDC_DEBUG_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_DEBUG_B6_CTL (0x0000036D) +#define TABLA_A_CDC_DEBUG_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_COMP1_B1_CTL (0x00000370) +#define TABLA_A_CDC_COMP1_B1_CTL__POR (0x00000030) +#define TABLA_A_CDC_COMP1_B2_CTL (0x00000371) +#define TABLA_A_CDC_COMP1_B2_CTL__POR (0x000000B5) +#define TABLA_A_CDC_COMP1_B3_CTL (0x00000372) +#define TABLA_A_CDC_COMP1_B3_CTL__POR (0x00000028) +#define TABLA_A_CDC_COMP1_B4_CTL (0x00000373) +#define TABLA_A_CDC_COMP1_B4_CTL__POR (0x0000003C) +#define TABLA_A_CDC_COMP1_B5_CTL (0x00000374) +#define TABLA_A_CDC_COMP1_B5_CTL__POR (0x0000001F) +#define TABLA_A_CDC_COMP1_B6_CTL (0x00000375) +#define TABLA_A_CDC_COMP1_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS (0x00000376) +#define TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x00000000) +#define TABLA_A_CDC_COMP1_FS_CFG (0x00000377) +#define TABLA_A_CDC_COMP1_FS_CFG__POR (0x0000001B) +#define TABLA_A_CDC_COMP2_B1_CTL (0x00000378) +#define TABLA_A_CDC_COMP2_B1_CTL__POR (0x00000030) +#define TABLA_A_CDC_COMP2_B2_CTL (0x00000379) +#define TABLA_A_CDC_COMP2_B2_CTL__POR (0x000000B5) +#define TABLA_A_CDC_COMP2_B3_CTL (0x0000037A) +#define TABLA_A_CDC_COMP2_B3_CTL__POR (0x00000028) +#define TABLA_A_CDC_COMP2_B4_CTL (0x0000037B) +#define TABLA_A_CDC_COMP2_B4_CTL__POR (0x0000003C) +#define TABLA_A_CDC_COMP2_B5_CTL (0x0000037C) +#define TABLA_A_CDC_COMP2_B5_CTL__POR (0x0000001F) +#define TABLA_A_CDC_COMP2_B6_CTL (0x0000037D) +#define TABLA_A_CDC_COMP2_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS (0x0000037E) +#define TABLA_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x00000000) +#define TABLA_A_CDC_COMP2_FS_CFG (0x0000037F) +#define TABLA_A_CDC_COMP2_FS_CFG__POR (0x0000001B) +#define TABLA_A_CDC_CONN_RX1_B1_CTL (0x00000380) +#define TABLA_A_CDC_CONN_RX1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX1_B2_CTL (0x00000381) +#define TABLA_A_CDC_CONN_RX1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX1_B3_CTL (0x00000382) +#define TABLA_A_CDC_CONN_RX1_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX2_B1_CTL (0x00000383) +#define TABLA_A_CDC_CONN_RX2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX2_B2_CTL (0x00000384) +#define TABLA_A_CDC_CONN_RX2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX2_B3_CTL (0x00000385) +#define TABLA_A_CDC_CONN_RX2_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX3_B1_CTL (0x00000386) +#define TABLA_A_CDC_CONN_RX3_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX3_B2_CTL (0x00000387) +#define TABLA_A_CDC_CONN_RX3_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX3_B3_CTL (0x00000388) +#define TABLA_A_CDC_CONN_RX3_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX4_B1_CTL (0x00000389) +#define TABLA_A_CDC_CONN_RX4_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX4_B2_CTL (0x0000038A) +#define TABLA_A_CDC_CONN_RX4_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX5_B1_CTL (0x0000038B) +#define TABLA_A_CDC_CONN_RX5_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX5_B2_CTL (0x0000038C) +#define TABLA_A_CDC_CONN_RX5_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX6_B1_CTL (0x0000038D) +#define TABLA_A_CDC_CONN_RX6_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX6_B2_CTL (0x0000038E) +#define TABLA_A_CDC_CONN_RX6_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX7_B1_CTL (0x0000038F) +#define TABLA_A_CDC_CONN_RX7_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX7_B2_CTL (0x00000390) +#define TABLA_A_CDC_CONN_RX7_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_ANC_B1_CTL (0x00000391) +#define TABLA_A_CDC_CONN_ANC_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_ANC_B2_CTL (0x00000392) +#define TABLA_A_CDC_CONN_ANC_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_B1_CTL (0x00000393) +#define TABLA_A_CDC_CONN_TX_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_B2_CTL (0x00000394) +#define TABLA_A_CDC_CONN_TX_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_B3_CTL (0x00000395) +#define TABLA_A_CDC_CONN_TX_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_B4_CTL (0x00000396) +#define TABLA_A_CDC_CONN_TX_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ1_B1_CTL (0x00000397) +#define TABLA_A_CDC_CONN_EQ1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ1_B2_CTL (0x00000398) +#define TABLA_A_CDC_CONN_EQ1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ1_B3_CTL (0x00000399) +#define TABLA_A_CDC_CONN_EQ1_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ1_B4_CTL (0x0000039A) +#define TABLA_A_CDC_CONN_EQ1_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ2_B1_CTL (0x0000039B) +#define TABLA_A_CDC_CONN_EQ2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ2_B2_CTL (0x0000039C) +#define TABLA_A_CDC_CONN_EQ2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ2_B3_CTL (0x0000039D) +#define TABLA_A_CDC_CONN_EQ2_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_EQ2_B4_CTL (0x0000039E) +#define TABLA_A_CDC_CONN_EQ2_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_SRC1_B1_CTL (0x0000039F) +#define TABLA_A_CDC_CONN_SRC1_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_SRC1_B2_CTL (0x000003A0) +#define TABLA_A_CDC_CONN_SRC1_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_SRC2_B1_CTL (0x000003A1) +#define TABLA_A_CDC_CONN_SRC2_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_SRC2_B2_CTL (0x000003A2) +#define TABLA_A_CDC_CONN_SRC2_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B1_CTL (0x000003A3) +#define TABLA_A_CDC_CONN_TX_SB_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B2_CTL (0x000003A4) +#define TABLA_A_CDC_CONN_TX_SB_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B3_CTL (0x000003A5) +#define TABLA_A_CDC_CONN_TX_SB_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B4_CTL (0x000003A6) +#define TABLA_A_CDC_CONN_TX_SB_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B5_CTL (0x000003A7) +#define TABLA_A_CDC_CONN_TX_SB_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B6_CTL (0x000003A8) +#define TABLA_A_CDC_CONN_TX_SB_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B7_CTL (0x000003A9) +#define TABLA_A_CDC_CONN_TX_SB_B7_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B8_CTL (0x000003AA) +#define TABLA_A_CDC_CONN_TX_SB_B8_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B9_CTL (0x000003AB) +#define TABLA_A_CDC_CONN_TX_SB_B9_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B10_CTL (0x000003AC) +#define TABLA_A_CDC_CONN_TX_SB_B10_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_TX_SB_B11_CTL (0x000003AD) +#define TABLA_A_CDC_CONN_TX_SB_B11_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX_SB_B1_CTL (0x000003AE) +#define TABLA_A_CDC_CONN_RX_SB_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_RX_SB_B2_CTL (0x000003AF) +#define TABLA_A_CDC_CONN_RX_SB_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_CLSG_CTL (0x000003B0) +#define TABLA_A_CDC_CONN_CLSG_CTL__POR (0x00000000) +#define TABLA_A_CDC_CONN_SPARE (0x000003B1) +#define TABLA_A_CDC_CONN_SPARE__POR (0x00000000) +#define TABLA_A_CDC_MBHC_EN_CTL (0x000003C0) +#define TABLA_A_CDC_MBHC_EN_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_FEATURE_B1_CFG (0x000003C1) +#define TABLA_A_CDC_MBHC_FEATURE_B1_CFG__POR (0x00000000) +#define TABLA_A_CDC_MBHC_FEATURE_B2_CFG (0x000003C2) +#define TABLA_A_CDC_MBHC_FEATURE_B2_CFG__POR (0x00000006) +#define TABLA_A_CDC_MBHC_TIMER_B1_CTL (0x000003C3) +#define TABLA_A_CDC_MBHC_TIMER_B1_CTL__POR (0x00000003) +#define TABLA_A_CDC_MBHC_TIMER_B2_CTL (0x000003C4) +#define TABLA_A_CDC_MBHC_TIMER_B2_CTL__POR (0x00000009) +#define TABLA_A_CDC_MBHC_TIMER_B3_CTL (0x000003C5) +#define TABLA_A_CDC_MBHC_TIMER_B3_CTL__POR (0x0000001e) +#define TABLA_A_CDC_MBHC_TIMER_B4_CTL (0x000003C6) +#define TABLA_A_CDC_MBHC_TIMER_B4_CTL__POR (0x00000045) +#define TABLA_A_CDC_MBHC_TIMER_B5_CTL (0x000003C7) +#define TABLA_A_CDC_MBHC_TIMER_B5_CTL__POR (0x00000004) +#define TABLA_A_CDC_MBHC_TIMER_B6_CTL (0x000003C8) +#define TABLA_A_CDC_MBHC_TIMER_B6_CTL__POR (0x00000078) +#define TABLA_A_CDC_MBHC_B1_STATUS (0x000003C9) +#define TABLA_A_CDC_MBHC_B1_STATUS__POR (0x00000000) +#define TABLA_A_CDC_MBHC_B2_STATUS (0x000003CA) +#define TABLA_A_CDC_MBHC_B2_STATUS__POR (0x00000000) +#define TABLA_A_CDC_MBHC_B3_STATUS (0x000003CB) +#define TABLA_A_CDC_MBHC_B3_STATUS__POR (0x00000000) +#define TABLA_A_CDC_MBHC_B4_STATUS (0x000003CC) +#define TABLA_A_CDC_MBHC_B4_STATUS__POR (0x00000000) +#define TABLA_A_CDC_MBHC_B5_STATUS (0x000003CD) +#define TABLA_A_CDC_MBHC_B5_STATUS__POR (0x00000000) +#define TABLA_A_CDC_MBHC_B1_CTL (0x000003CE) +#define TABLA_A_CDC_MBHC_B1_CTL__POR (0x000000c0) +#define TABLA_A_CDC_MBHC_B2_CTL (0x000003CF) +#define TABLA_A_CDC_MBHC_B2_CTL__POR (0x0000005d) +#define TABLA_A_CDC_MBHC_VOLT_B1_CTL (0x000003D0) +#define TABLA_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B2_CTL (0x000003D1) +#define TABLA_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B3_CTL (0x000003D2) +#define TABLA_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B4_CTL (0x000003D3) +#define TABLA_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B5_CTL (0x000003D4) +#define TABLA_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B6_CTL (0x000003D5) +#define TABLA_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B7_CTL (0x000003D6) +#define TABLA_A_CDC_MBHC_VOLT_B7_CTL__POR (0x000000ff) +#define TABLA_A_CDC_MBHC_VOLT_B8_CTL (0x000003D7) +#define TABLA_A_CDC_MBHC_VOLT_B8_CTL__POR (0x00000007) +#define TABLA_A_CDC_MBHC_VOLT_B9_CTL (0x000003D8) +#define TABLA_A_CDC_MBHC_VOLT_B9_CTL__POR (0x000000ff) +#define TABLA_A_CDC_MBHC_VOLT_B10_CTL (0x000003D9) +#define TABLA_A_CDC_MBHC_VOLT_B10_CTL__POR (0x0000007f) +#define TABLA_A_CDC_MBHC_VOLT_B11_CTL (0x000003DA) +#define TABLA_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_VOLT_B12_CTL (0x000003DB) +#define TABLA_A_CDC_MBHC_VOLT_B12_CTL__POR (0x00000080) +#define TABLA_A_CDC_MBHC_CLK_CTL (0x000003DC) +#define TABLA_A_CDC_MBHC_CLK_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_INT_CTL (0x000003DD) +#define TABLA_A_CDC_MBHC_INT_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_DEBUG_CTL (0x000003DE) +#define TABLA_A_CDC_MBHC_DEBUG_CTL__POR (0x00000000) +#define TABLA_A_CDC_MBHC_SPARE (0x000003DF) +#define TABLA_A_CDC_MBHC_SPARE__POR (0x00000000) + + +/* SLIMBUS Slave Registers */ +#define TABLA_SLIM_PGD_PORT_INT_EN0 (0x30) +#define TABLA_SLIM_PGD_PORT_INT_STATUS0 (0x34) +#define TABLA_SLIM_PGD_PORT_INT_CLR0 (0x38) +#define TABLA_SLIM_PGD_PORT_INT_SOURCE0 (0x60) + +/* Macros for Packing Register Writes into a U32 */ +#define TABLA_PACKED_REG_SIZE sizeof(u32) + +#define TABLA_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\ + ((mask & 0xff) << 8)|((reg & 0xffff) << 16)) + +#define TABLA_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0); + +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9330_registers.h b/include/linux/mfd/wcd9xxx/wcd9330_registers.h new file mode 100755 index 000000000000..c37d25f3f528 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9330_registers.h @@ -0,0 +1,1626 @@ +/* Copyright (c) 2014, 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 WCD9330_REGISTERS_H +#define WCD9330_REGISTERS_H + +#include <linux/types.h> + +#define TOMTOM_A_CHIP_CTL (0x000) +#define TOMTOM_A_CHIP_CTL__POR (0x38) +#define TOMTOM_A_CHIP_STATUS (0x001) +#define TOMTOM_A_CHIP_STATUS__POR (0x00) +#define TOMTOM_A_CHIP_ID_BYTE_0 (0x004) +#define TOMTOM_A_CHIP_ID_BYTE_0__POR (0x00) +#define TOMTOM_A_CHIP_ID_BYTE_1 (0x005) +#define TOMTOM_A_CHIP_ID_BYTE_1__POR (0x00) +#define TOMTOM_A_CHIP_ID_BYTE_2 (0x006) +#define TOMTOM_A_CHIP_ID_BYTE_2__POR (0x05) +#define TOMTOM_A_CHIP_ID_BYTE_3 (0x007) +#define TOMTOM_A_CHIP_ID_BYTE_3__POR (0x01) +#define TOMTOM_A_CHIP_I2C_SLAVE_ID (0x008) +#define TOMTOM_A_CHIP_I2C_SLAVE_ID__POR (0x01) +#define TOMTOM_A_SLAVE_ID_1 (0x00C) +#define TOMTOM_A_SLAVE_ID_1__POR (0x77) +#define TOMTOM_A_SLAVE_ID_2 (0x00D) +#define TOMTOM_A_SLAVE_ID_2__POR (0x66) +#define TOMTOM_A_SLAVE_ID_3 (0x00E) +#define TOMTOM_A_SLAVE_ID_3__POR (0x55) +#define TOMTOM_A_PIN_CTL_OE0 (0x010) +#define TOMTOM_A_PIN_CTL_OE0__POR (0x00) +#define TOMTOM_A_PIN_CTL_OE1 (0x011) +#define TOMTOM_A_PIN_CTL_OE1__POR (0x00) +#define TOMTOM_A_PIN_CTL_OE2 (0x012) +#define TOMTOM_A_PIN_CTL_OE2__POR (0x00) +#define TOMTOM_A_PIN_CTL_DATA0 (0x013) +#define TOMTOM_A_PIN_CTL_DATA0__POR (0x00) +#define TOMTOM_A_PIN_CTL_DATA1 (0x014) +#define TOMTOM_A_PIN_CTL_DATA1__POR (0x00) +#define TOMTOM_A_PIN_CTL_DATA2 (0x015) +#define TOMTOM_A_PIN_CTL_DATA2__POR (0x00) +#define TOMTOM_A_HDRIVE_GENERIC (0x018) +#define TOMTOM_A_HDRIVE_GENERIC__POR (0x00) +#define TOMTOM_A_HDRIVE_OVERRIDE (0x019) +#define TOMTOM_A_HDRIVE_OVERRIDE__POR (0x08) +#define TOMTOM_A_ANA_CSR_WAIT_STATE (0x01C) +#define TOMTOM_A_ANA_CSR_WAIT_STATE__POR (0x44) +#define TOMTOM_A_PROCESS_MONITOR_CTL0 (0x020) +#define TOMTOM_A_PROCESS_MONITOR_CTL0__POR (0x80) +#define TOMTOM_A_PROCESS_MONITOR_CTL1 (0x021) +#define TOMTOM_A_PROCESS_MONITOR_CTL1__POR (0x00) +#define TOMTOM_A_PROCESS_MONITOR_CTL2 (0x022) +#define TOMTOM_A_PROCESS_MONITOR_CTL2__POR (0x00) +#define TOMTOM_A_PROCESS_MONITOR_CTL3 (0x023) +#define TOMTOM_A_PROCESS_MONITOR_CTL3__POR (0x01) +#define TOMTOM_A_QFUSE_CTL (0x028) +#define TOMTOM_A_QFUSE_CTL__POR (0x00) +#define TOMTOM_A_QFUSE_STATUS (0x029) +#define TOMTOM_A_QFUSE_STATUS__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT0 (0x02A) +#define TOMTOM_A_QFUSE_DATA_OUT0__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT1 (0x02B) +#define TOMTOM_A_QFUSE_DATA_OUT1__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT2 (0x02C) +#define TOMTOM_A_QFUSE_DATA_OUT2__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT3 (0x02D) +#define TOMTOM_A_QFUSE_DATA_OUT3__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT4 (0x02E) +#define TOMTOM_A_QFUSE_DATA_OUT4__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT5 (0x02F) +#define TOMTOM_A_QFUSE_DATA_OUT5__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT6 (0x030) +#define TOMTOM_A_QFUSE_DATA_OUT6__POR (0x00) +#define TOMTOM_A_QFUSE_DATA_OUT7 (0x031) +#define TOMTOM_A_QFUSE_DATA_OUT7__POR (0x00) +#define TOMTOM_A_CDC_CTL (0x034) +#define TOMTOM_A_CDC_CTL__POR (0x00) +#define TOMTOM_A_LEAKAGE_CTL (0x03C) +#define TOMTOM_A_LEAKAGE_CTL__POR (0x04) +#define TOMTOM_A_SVASS_MEM_PTR0 (0x044) +#define TOMTOM_A_SVASS_MEM_PTR0__POR (0x00) +#define TOMTOM_A_SVASS_MEM_PTR1 (0x045) +#define TOMTOM_A_SVASS_MEM_PTR1__POR (0x00) +#define TOMTOM_A_SVASS_MEM_PTR2 (0x046) +#define TOMTOM_A_SVASS_MEM_PTR2__POR (0x00) +#define TOMTOM_A_SVASS_MEM_CTL (0x048) +#define TOMTOM_A_SVASS_MEM_CTL__POR (0x04) +#define TOMTOM_A_SVASS_MEM_BANK (0x049) +#define TOMTOM_A_SVASS_MEM_BANK__POR (0x00) +#define TOMTOM_A_DMIC_B1_CTL (0x04A) +#define TOMTOM_A_DMIC_B1_CTL__POR (0x00) +#define TOMTOM_A_DMIC_B2_CTL (0x04B) +#define TOMTOM_A_DMIC_B2_CTL__POR (0x00) +#define TOMTOM_A_SVASS_CLKRST_CTL (0x04C) +#define TOMTOM_A_SVASS_CLKRST_CTL__POR (0x00) +#define TOMTOM_A_SVASS_CPAR_CFG (0x04D) +#define TOMTOM_A_SVASS_CPAR_CFG__POR (0x00) +#define TOMTOM_A_SVASS_BUF_RDY_INT_PERIOD (0x04E) +#define TOMTOM_A_SVASS_BUF_RDY_INT_PERIOD__POR (0x14) +#define TOMTOM_A_SVASS_CPAR_WDOG_CFG (0x04F) +#define TOMTOM_A_SVASS_CPAR_WDOG_CFG__POR (0x00) +#define TOMTOM_A_SVASS_CFG (0x050) +#define TOMTOM_A_SVASS_CFG__POR (0x01) +#define TOMTOM_A_SVASS_SPE_CFG (0x051) +#define TOMTOM_A_SVASS_SPE_CFG__POR (0x04) +#define TOMTOM_A_SVASS_STATUS (0x052) +#define TOMTOM_A_SVASS_STATUS__POR (0x00) +#define TOMTOM_A_SVASS_INT_MASK (0x053) +#define TOMTOM_A_SVASS_INT_MASK__POR (0x3F) +#define TOMTOM_A_SVASS_INT_STATUS (0x054) +#define TOMTOM_A_SVASS_INT_STATUS__POR (0x00) +#define TOMTOM_A_SVASS_INT_CLR (0x055) +#define TOMTOM_A_SVASS_INT_CLR__POR (0x00) +#define TOMTOM_A_SVASS_DEBUG (0x056) +#define TOMTOM_A_SVASS_DEBUG__POR (0x00) +#define TOMTOM_A_SVASS_SPE_BKUP_INT (0x057) +#define TOMTOM_A_SVASS_SPE_BKUP_INT__POR (0x00) +#define TOMTOM_A_SVASS_MEM_ACC (0x058) +#define TOMTOM_A_SVASS_MEM_ACC__POR (0x00) +#define TOMTOM_A_MEM_LEAKAGE_CTL (0x059) +#define TOMTOM_A_MEM_LEAKAGE_CTL__POR (0x04) +#define TOMTOM_A_SVASS_SPE_INBOX_TRG (0x05A) +#define TOMTOM_A_SVASS_SPE_INBOX_TRG__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_0 (0x060) +#define TOMTOM_A_SVASS_SPE_INBOX_0__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_1 (0x061) +#define TOMTOM_A_SVASS_SPE_INBOX_1__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_2 (0x062) +#define TOMTOM_A_SVASS_SPE_INBOX_2__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_3 (0x063) +#define TOMTOM_A_SVASS_SPE_INBOX_3__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_4 (0x064) +#define TOMTOM_A_SVASS_SPE_INBOX_4__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_5 (0x065) +#define TOMTOM_A_SVASS_SPE_INBOX_5__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_6 (0x066) +#define TOMTOM_A_SVASS_SPE_INBOX_6__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_7 (0x067) +#define TOMTOM_A_SVASS_SPE_INBOX_7__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_8 (0x068) +#define TOMTOM_A_SVASS_SPE_INBOX_8__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_9 (0x069) +#define TOMTOM_A_SVASS_SPE_INBOX_9__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_10 (0x06A) +#define TOMTOM_A_SVASS_SPE_INBOX_10__POR (0x00) +#define TOMTOM_A_SVASS_SPE_INBOX_11 (0x06B) +#define TOMTOM_A_SVASS_SPE_INBOX_11__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_0 (0x070) +#define TOMTOM_A_SVASS_SPE_OUTBOX_0__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_1 (0x071) +#define TOMTOM_A_SVASS_SPE_OUTBOX_1__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_2 (0x072) +#define TOMTOM_A_SVASS_SPE_OUTBOX_2__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_3 (0x073) +#define TOMTOM_A_SVASS_SPE_OUTBOX_3__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_4 (0x074) +#define TOMTOM_A_SVASS_SPE_OUTBOX_4__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_5 (0x075) +#define TOMTOM_A_SVASS_SPE_OUTBOX_5__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_6 (0x076) +#define TOMTOM_A_SVASS_SPE_OUTBOX_6__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_7 (0x077) +#define TOMTOM_A_SVASS_SPE_OUTBOX_7__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_8 (0x078) +#define TOMTOM_A_SVASS_SPE_OUTBOX_8__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_9 (0x079) +#define TOMTOM_A_SVASS_SPE_OUTBOX_9__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_10 (0x07A) +#define TOMTOM_A_SVASS_SPE_OUTBOX_10__POR (0x00) +#define TOMTOM_A_SVASS_SPE_OUTBOX_11 (0x07B) +#define TOMTOM_A_SVASS_SPE_OUTBOX_11__POR (0x00) +#define TOMTOM_A_INTR_MODE (0x090) +#define TOMTOM_A_INTR_MODE__POR (0x00) +#define TOMTOM_A_INTR1_MASK0 (0x094) +#define TOMTOM_A_INTR1_MASK0__POR (0xFF) +#define TOMTOM_A_INTR1_MASK1 (0x095) +#define TOMTOM_A_INTR1_MASK1__POR (0xFF) +#define TOMTOM_A_INTR1_MASK2 (0x096) +#define TOMTOM_A_INTR1_MASK2__POR (0xFF) +#define TOMTOM_A_INTR1_MASK3 (0x097) +#define TOMTOM_A_INTR1_MASK3__POR (0xFF) +#define TOMTOM_A_INTR1_STATUS0 (0x098) +#define TOMTOM_A_INTR1_STATUS0__POR (0x00) +#define TOMTOM_A_INTR1_STATUS1 (0x099) +#define TOMTOM_A_INTR1_STATUS1__POR (0x00) +#define TOMTOM_A_INTR1_STATUS2 (0x09A) +#define TOMTOM_A_INTR1_STATUS2__POR (0x00) +#define TOMTOM_A_INTR1_STATUS3 (0x09B) +#define TOMTOM_A_INTR1_STATUS3__POR (0x00) +#define TOMTOM_A_INTR1_CLEAR0 (0x09C) +#define TOMTOM_A_INTR1_CLEAR0__POR (0x00) +#define TOMTOM_A_INTR1_CLEAR1 (0x09D) +#define TOMTOM_A_INTR1_CLEAR1__POR (0x00) +#define TOMTOM_A_INTR1_CLEAR2 (0x09E) +#define TOMTOM_A_INTR1_CLEAR2__POR (0x00) +#define TOMTOM_A_INTR1_CLEAR3 (0x09F) +#define TOMTOM_A_INTR1_CLEAR3__POR (0x00) +#define TOMTOM_A_INTR1_LEVEL0 (0x0A0) +#define TOMTOM_A_INTR1_LEVEL0__POR (0x01) +#define TOMTOM_A_INTR1_LEVEL1 (0x0A1) +#define TOMTOM_A_INTR1_LEVEL1__POR (0x00) +#define TOMTOM_A_INTR1_LEVEL2 (0x0A2) +#define TOMTOM_A_INTR1_LEVEL2__POR (0x40) +#define TOMTOM_A_INTR1_LEVEL3 (0x0A3) +#define TOMTOM_A_INTR1_LEVEL3__POR (0x00) +#define TOMTOM_A_INTR1_TEST0 (0x0A4) +#define TOMTOM_A_INTR1_TEST0__POR (0x00) +#define TOMTOM_A_INTR1_TEST1 (0x0A5) +#define TOMTOM_A_INTR1_TEST1__POR (0x00) +#define TOMTOM_A_INTR1_TEST2 (0x0A6) +#define TOMTOM_A_INTR1_TEST2__POR (0x00) +#define TOMTOM_A_INTR1_TEST3 (0x0A7) +#define TOMTOM_A_INTR1_TEST3__POR (0x00) +#define TOMTOM_A_INTR1_SET0 (0x0A8) +#define TOMTOM_A_INTR1_SET0__POR (0x00) +#define TOMTOM_A_INTR1_SET1 (0x0A9) +#define TOMTOM_A_INTR1_SET1__POR (0x00) +#define TOMTOM_A_INTR1_SET2 (0x0AA) +#define TOMTOM_A_INTR1_SET2__POR (0x00) +#define TOMTOM_A_INTR1_SET3 (0x0AB) +#define TOMTOM_A_INTR1_SET3__POR (0x00) +#define TOMTOM_A_INTR2_MASK0 (0x0B0) +#define TOMTOM_A_INTR2_MASK0__POR (0xFF) +#define TOMTOM_A_INTR2_STATUS0 (0x0B2) +#define TOMTOM_A_INTR2_STATUS0__POR (0x00) +#define TOMTOM_A_INTR2_CLEAR0 (0x0B4) +#define TOMTOM_A_INTR2_CLEAR0__POR (0x00) +#define TOMTOM_A_INTR2_LEVEL0 (0x0B6) +#define TOMTOM_A_INTR2_LEVEL0__POR (0x00) +#define TOMTOM_A_INTR2_TEST0 (0x0B8) +#define TOMTOM_A_INTR2_TEST0__POR (0x00) +#define TOMTOM_A_INTR2_SET0 (0x0BA) +#define TOMTOM_A_INTR2_SET0__POR (0x00) +#define TOMTOM_A_CDC_TX_I2S_SCK_MODE (0x0C0) +#define TOMTOM_A_CDC_TX_I2S_SCK_MODE__POR (0x00) +#define TOMTOM_A_CDC_TX_I2S_WS_MODE (0x0C1) +#define TOMTOM_A_CDC_TX_I2S_WS_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_DATA0_MODE (0x0C4) +#define TOMTOM_A_CDC_DMIC_DATA0_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_CLK0_MODE (0x0C5) +#define TOMTOM_A_CDC_DMIC_CLK0_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_DATA1_MODE (0x0C6) +#define TOMTOM_A_CDC_DMIC_DATA1_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_CLK1_MODE (0x0C7) +#define TOMTOM_A_CDC_DMIC_CLK1_MODE__POR (0x00) +#define TOMTOM_A_CDC_RX_I2S_SCK_MODE (0x0C8) +#define TOMTOM_A_CDC_RX_I2S_SCK_MODE__POR (0x00) +#define TOMTOM_A_CDC_RX_I2S_WS_MODE (0x0C9) +#define TOMTOM_A_CDC_RX_I2S_WS_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_DATA2_MODE (0x0CA) +#define TOMTOM_A_CDC_DMIC_DATA2_MODE__POR (0x00) +#define TOMTOM_A_CDC_DMIC_CLK2_MODE (0x0CB) +#define TOMTOM_A_CDC_DMIC_CLK2_MODE__POR (0x00) +#define TOMTOM_A_CDC_INTR1_MODE (0x0CC) +#define TOMTOM_A_CDC_INTR1_MODE__POR (0x00) +#define TOMTOM_A_CDC_SB_NRZ_SEL_MODE (0x0CD) +#define TOMTOM_A_CDC_SB_NRZ_SEL_MODE__POR (0x00) +#define TOMTOM_A_CDC_INTR2_MODE (0x0CE) +#define TOMTOM_A_CDC_INTR2_MODE__POR (0x00) +#define TOMTOM_A_CDC_RF_PA_ON_MODE (0x0CF) +#define TOMTOM_A_CDC_RF_PA_ON_MODE__POR (0x00) +#define TOMTOM_A_CDC_BOOST_MODE (0x0D0) +#define TOMTOM_A_CDC_BOOST_MODE__POR (0x00) +#define TOMTOM_A_CDC_JTCK_MODE (0x0D1) +#define TOMTOM_A_CDC_JTCK_MODE__POR (0x00) +#define TOMTOM_A_CDC_JTDI_MODE (0x0D2) +#define TOMTOM_A_CDC_JTDI_MODE__POR (0x00) +#define TOMTOM_A_CDC_JTMS_MODE (0x0D3) +#define TOMTOM_A_CDC_JTMS_MODE__POR (0x00) +#define TOMTOM_A_CDC_JTDO_MODE (0x0D4) +#define TOMTOM_A_CDC_JTDO_MODE__POR (0x00) +#define TOMTOM_A_CDC_JTRST_MODE (0x0D5) +#define TOMTOM_A_CDC_JTRST_MODE__POR (0x00) +#define TOMTOM_A_CDC_BIST_MODE_MODE (0x0D6) +#define TOMTOM_A_CDC_BIST_MODE_MODE__POR (0x00) +#define TOMTOM_A_CDC_MAD_MAIN_CTL_1 (0x0E0) +#define TOMTOM_A_CDC_MAD_MAIN_CTL_1__POR (0x00) +#define TOMTOM_A_CDC_MAD_MAIN_CTL_2 (0x0E1) +#define TOMTOM_A_CDC_MAD_MAIN_CTL_2__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_1 (0x0E2) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_1__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_2 (0x0E3) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_2__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_3 (0x0E4) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_3__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_4 (0x0E5) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_4__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_5 (0x0E6) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_5__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_6 (0x0E7) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_6__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_7 (0x0E8) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_7__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_8 (0x0E9) +#define TOMTOM_A_CDC_MAD_AUDIO_CTL_8__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_IIR_CTL_PTR (0x0EA) +#define TOMTOM_A_CDC_MAD_AUDIO_IIR_CTL_PTR__POR (0x00) +#define TOMTOM_A_CDC_MAD_AUDIO_IIR_CTL_VAL (0x0EB) +#define TOMTOM_A_CDC_MAD_AUDIO_IIR_CTL_VAL__POR (0x40) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_1 (0x0EC) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_1__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_2 (0x0ED) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_2__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_3 (0x0EE) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_3__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_4 (0x0EF) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_4__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_5 (0x0F0) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_5__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_6 (0x0F1) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_6__POR (0x00) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_7 (0x0F2) +#define TOMTOM_A_CDC_MAD_ULTR_CTL_7__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_1 (0x0F3) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_1__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_2 (0x0F4) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_2__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_3 (0x0F5) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_3__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_4 (0x0F6) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_4__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_5 (0x0F7) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_5__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_6 (0x0F8) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_6__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_7 (0x0F9) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_7__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_8 (0x0FA) +#define TOMTOM_A_CDC_MAD_BEACON_CTL_8__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_IIR_CTL_PTR (0x0FB) +#define TOMTOM_A_CDC_MAD_BEACON_IIR_CTL_PTR__POR (0x00) +#define TOMTOM_A_CDC_MAD_BEACON_IIR_CTL_VAL (0x0FC) +#define TOMTOM_A_CDC_MAD_BEACON_IIR_CTL_VAL__POR (0x00) +#define TOMTOM_A_CDC_MAD_INP_SEL (0x0FD) +#define TOMTOM_A_CDC_MAD_INP_SEL__POR (0x00) +#define TOMTOM_A_BIAS_REF_CTL (0x100) +#define TOMTOM_A_BIAS_REF_CTL__POR (0x1C) +#define TOMTOM_A_BIAS_CENTRAL_BG_CTL (0x101) +#define TOMTOM_A_BIAS_CENTRAL_BG_CTL__POR (0x50) +#define TOMTOM_A_BIAS_PRECHRG_CTL (0x102) +#define TOMTOM_A_BIAS_PRECHRG_CTL__POR (0x07) +#define TOMTOM_A_BIAS_CURR_CTL_1 (0x103) +#define TOMTOM_A_BIAS_CURR_CTL_1__POR (0x52) +#define TOMTOM_A_BIAS_CURR_CTL_2 (0x104) +#define TOMTOM_A_BIAS_CURR_CTL_2__POR (0x00) +#define TOMTOM_A_BIAS_OSC_BG_CTL (0x105) +#define TOMTOM_A_BIAS_OSC_BG_CTL__POR (0x36) +#define TOMTOM_A_CLK_BUFF_EN1 (0x108) +#define TOMTOM_A_CLK_BUFF_EN1__POR (0x04) +#define TOMTOM_A_CLK_BUFF_EN2 (0x109) +#define TOMTOM_A_CLK_BUFF_EN2__POR (0x02) +#define TOMTOM_A_LDO_L_MODE_1 (0x10A) +#define TOMTOM_A_LDO_L_MODE_1__POR (0x08) +#define TOMTOM_A_LDO_L_MODE_2 (0x10B) +#define TOMTOM_A_LDO_L_MODE_2__POR (0x50) +#define TOMTOM_A_LDO_L_CTRL_1 (0x10C) +#define TOMTOM_A_LDO_L_CTRL_1__POR (0x70) +#define TOMTOM_A_LDO_L_CTRL_2 (0x10D) +#define TOMTOM_A_LDO_L_CTRL_2__POR (0x55) +#define TOMTOM_A_LDO_L_CTRL_3 (0x10E) +#define TOMTOM_A_LDO_L_CTRL_3__POR (0x56) +#define TOMTOM_A_LDO_L_CTRL_4 (0x10F) +#define TOMTOM_A_LDO_L_CTRL_4__POR (0x55) +#define TOMTOM_A_LDO_H_MODE_1 (0x110) +#define TOMTOM_A_LDO_H_MODE_1__POR (0x65) +#define TOMTOM_A_LDO_H_MODE_2 (0x111) +#define TOMTOM_A_LDO_H_MODE_2__POR (0xA8) +#define TOMTOM_A_LDO_H_LOOP_CTL (0x112) +#define TOMTOM_A_LDO_H_LOOP_CTL__POR (0x6B) +#define TOMTOM_A_LDO_H_COMP_1 (0x113) +#define TOMTOM_A_LDO_H_COMP_1__POR (0x84) +#define TOMTOM_A_LDO_H_COMP_2 (0x114) +#define TOMTOM_A_LDO_H_COMP_2__POR (0xE0) +#define TOMTOM_A_LDO_H_BIAS_1 (0x115) +#define TOMTOM_A_LDO_H_BIAS_1__POR (0x6D) +#define TOMTOM_A_LDO_H_BIAS_2 (0x116) +#define TOMTOM_A_LDO_H_BIAS_2__POR (0xA5) +#define TOMTOM_A_LDO_H_BIAS_3 (0x117) +#define TOMTOM_A_LDO_H_BIAS_3__POR (0x60) +#define TOMTOM_A_VBAT_CLK (0x118) +#define TOMTOM_A_VBAT_CLK__POR (0x03) +#define TOMTOM_A_VBAT_LOOP (0x119) +#define TOMTOM_A_VBAT_LOOP__POR (0x02) +#define TOMTOM_A_VBAT_REF (0x11A) +#define TOMTOM_A_VBAT_REF__POR (0x20) +#define TOMTOM_A_VBAT_ADC_TEST (0x11B) +#define TOMTOM_A_VBAT_ADC_TEST__POR (0x00) +#define TOMTOM_A_VBAT_FE (0x11C) +#define TOMTOM_A_VBAT_FE__POR (0x48) +#define TOMTOM_A_VBAT_BIAS_1 (0x11D) +#define TOMTOM_A_VBAT_BIAS_1__POR (0x03) +#define TOMTOM_A_VBAT_BIAS_2 (0x11E) +#define TOMTOM_A_VBAT_BIAS_2__POR (0x00) +#define TOMTOM_A_VBAT_ADC_DATA_MSB (0x11F) +#define TOMTOM_A_VBAT_ADC_DATA_MSB__POR (0x00) +#define TOMTOM_A_VBAT_ADC_DATA_LSB (0x120) +#define TOMTOM_A_VBAT_ADC_DATA_LSB__POR (0x00) +#define TOMTOM_A_FLL_NREF (0x121) +#define TOMTOM_A_FLL_NREF__POR (0x12) +#define TOMTOM_A_FLL_KDCO_TUNE (0x122) +#define TOMTOM_A_FLL_KDCO_TUNE__POR (0x05) +#define TOMTOM_A_FLL_LOCK_THRESH (0x123) +#define TOMTOM_A_FLL_LOCK_THRESH__POR (0xC2) +#define TOMTOM_A_FLL_LOCK_DET_COUNT (0x124) +#define TOMTOM_A_FLL_LOCK_DET_COUNT__POR (0x40) +#define TOMTOM_A_FLL_DAC_THRESHOLD (0x125) +#define TOMTOM_A_FLL_DAC_THRESHOLD__POR (0xC8) +#define TOMTOM_A_FLL_TEST_DCO_FREERUN (0x126) +#define TOMTOM_A_FLL_TEST_DCO_FREERUN__POR (0x00) +#define TOMTOM_A_FLL_TEST_ENABLE (0x127) +#define TOMTOM_A_FLL_TEST_ENABLE__POR (0x00) +#define TOMTOM_A_MICB_CFILT_1_CTL (0x128) +#define TOMTOM_A_MICB_CFILT_1_CTL__POR (0x40) +#define TOMTOM_A_MICB_CFILT_1_VAL (0x129) +#define TOMTOM_A_MICB_CFILT_1_VAL__POR (0x80) +#define TOMTOM_A_MICB_CFILT_1_PRECHRG (0x12A) +#define TOMTOM_A_MICB_CFILT_1_PRECHRG__POR (0x38) +#define TOMTOM_A_MICB_1_CTL (0x12B) +#define TOMTOM_A_MICB_1_CTL__POR (0x16) +#define TOMTOM_A_MICB_1_INT_RBIAS (0x12C) +#define TOMTOM_A_MICB_1_INT_RBIAS__POR (0x24) +#define TOMTOM_A_MICB_1_MBHC (0x12D) +#define TOMTOM_A_MICB_1_MBHC__POR (0x01) +#define TOMTOM_A_MICB_CFILT_2_CTL (0x12E) +#define TOMTOM_A_MICB_CFILT_2_CTL__POR (0x41) +#define TOMTOM_A_MICB_CFILT_2_VAL (0x12F) +#define TOMTOM_A_MICB_CFILT_2_VAL__POR (0x80) +#define TOMTOM_A_MICB_CFILT_2_PRECHRG (0x130) +#define TOMTOM_A_MICB_CFILT_2_PRECHRG__POR (0x38) +#define TOMTOM_A_MICB_2_CTL (0x131) +#define TOMTOM_A_MICB_2_CTL__POR (0x16) +#define TOMTOM_A_MICB_2_INT_RBIAS (0x132) +#define TOMTOM_A_MICB_2_INT_RBIAS__POR (0x24) +#define TOMTOM_A_MICB_2_MBHC (0x133) +#define TOMTOM_A_MICB_2_MBHC__POR (0x02) +#define TOMTOM_A_MICB_CFILT_3_CTL (0x134) +#define TOMTOM_A_MICB_CFILT_3_CTL__POR (0x40) +#define TOMTOM_A_MICB_CFILT_3_VAL (0x135) +#define TOMTOM_A_MICB_CFILT_3_VAL__POR (0x80) +#define TOMTOM_A_MICB_CFILT_3_PRECHRG (0x136) +#define TOMTOM_A_MICB_CFILT_3_PRECHRG__POR (0x38) +#define TOMTOM_A_MICB_3_CTL (0x137) +#define TOMTOM_A_MICB_3_CTL__POR (0x16) +#define TOMTOM_A_MICB_3_INT_RBIAS (0x138) +#define TOMTOM_A_MICB_3_INT_RBIAS__POR (0x24) +#define TOMTOM_A_MICB_3_MBHC (0x139) +#define TOMTOM_A_MICB_3_MBHC__POR (0x00) +#define TOMTOM_A_MICB_4_CTL (0x13A) +#define TOMTOM_A_MICB_4_CTL__POR (0x16) +#define TOMTOM_A_MICB_4_INT_RBIAS (0x13B) +#define TOMTOM_A_MICB_4_INT_RBIAS__POR (0x24) +#define TOMTOM_A_MICB_4_MBHC (0x13C) +#define TOMTOM_A_MICB_4_MBHC__POR (0x01) +#define TOMTOM_A_SPKR_DRV2_EN (0x13D) +#define TOMTOM_A_SPKR_DRV2_EN__POR (0x6F) +#define TOMTOM_A_SPKR_DRV2_GAIN (0x13E) +#define TOMTOM_A_SPKR_DRV2_GAIN__POR (0x00) +#define TOMTOM_A_SPKR_DRV2_DAC_CTL (0x13F) +#define TOMTOM_A_SPKR_DRV2_DAC_CTL__POR (0x04) +#define TOMTOM_A_SPKR_DRV2_OCP_CTL (0x140) +#define TOMTOM_A_SPKR_DRV2_OCP_CTL__POR (0x97) +#define TOMTOM_A_SPKR_DRV2_CLIP_DET (0x141) +#define TOMTOM_A_SPKR_DRV2_CLIP_DET__POR (0x01) +#define TOMTOM_A_SPKR_DRV2_DBG_DAC (0x142) +#define TOMTOM_A_SPKR_DRV2_DBG_DAC__POR (0x05) +#define TOMTOM_A_SPKR_DRV2_DBG_PA (0x143) +#define TOMTOM_A_SPKR_DRV2_DBG_PA__POR (0x18) +#define TOMTOM_A_SPKR_DRV2_DBG_PWRSTG (0x144) +#define TOMTOM_A_SPKR_DRV2_DBG_PWRSTG__POR (0x00) +#define TOMTOM_A_SPKR_DRV2_BIAS_LDO (0x145) +#define TOMTOM_A_SPKR_DRV2_BIAS_LDO__POR (0x45) +#define TOMTOM_A_SPKR_DRV2_BIAS_INT (0x146) +#define TOMTOM_A_SPKR_DRV2_BIAS_INT__POR (0xA5) +#define TOMTOM_A_SPKR_DRV2_BIAS_PA (0x147) +#define TOMTOM_A_SPKR_DRV2_BIAS_PA__POR (0x55) +#define TOMTOM_A_SPKR_DRV2_STATUS_OCP (0x148) +#define TOMTOM_A_SPKR_DRV2_STATUS_OCP__POR (0x00) +#define TOMTOM_A_SPKR_DRV2_STATUS_PA (0x149) +#define TOMTOM_A_SPKR_DRV2_STATUS_PA__POR (0x00) +#define TOMTOM_A_MBHC_INSERT_DETECT (0x14A) +#define TOMTOM_A_MBHC_INSERT_DETECT__POR (0x00) +#define TOMTOM_A_MBHC_INSERT_DET_STATUS (0x14B) +#define TOMTOM_A_MBHC_INSERT_DET_STATUS__POR (0x00) +#define TOMTOM_A_TX_COM_BIAS (0x14C) +#define TOMTOM_A_TX_COM_BIAS__POR (0xF0) +#define TOMTOM_A_MBHC_INSERT_DETECT2 (0x14D) +#define TOMTOM_A_MBHC_INSERT_DETECT2__POR (0xD0) +#define TOMTOM_A_MBHC_SCALING_MUX_1 (0x14E) +#define TOMTOM_A_MBHC_SCALING_MUX_1__POR (0x00) +#define TOMTOM_A_MBHC_SCALING_MUX_2 (0x14F) +#define TOMTOM_A_MBHC_SCALING_MUX_2__POR (0x80) +#define TOMTOM_A_MAD_ANA_CTRL (0x150) +#define TOMTOM_A_MAD_ANA_CTRL__POR (0xF1) +#define TOMTOM_A_TX_SUP_SWITCH_CTRL_1 (0x151) +#define TOMTOM_A_TX_SUP_SWITCH_CTRL_1__POR (0x00) +#define TOMTOM_A_TX_SUP_SWITCH_CTRL_2 (0x152) +#define TOMTOM_A_TX_SUP_SWITCH_CTRL_2__POR (0x80) +#define TOMTOM_A_TX_1_GAIN (0x153) +#define TOMTOM_A_TX_1_GAIN__POR (0x02) +#define TOMTOM_A_TX_1_2_TEST_EN (0x154) +#define TOMTOM_A_TX_1_2_TEST_EN__POR (0xCC) +#define TOMTOM_A_TX_2_GAIN (0x155) +#define TOMTOM_A_TX_2_GAIN__POR (0x02) +#define TOMTOM_A_TX_1_2_ADC_IB (0x156) +#define TOMTOM_A_TX_1_2_ADC_IB__POR (0x44) +#define TOMTOM_A_TX_1_2_ATEST_REFCTRL (0x157) +#define TOMTOM_A_TX_1_2_ATEST_REFCTRL__POR (0x00) +#define TOMTOM_A_TX_1_2_TEST_CTL (0x158) +#define TOMTOM_A_TX_1_2_TEST_CTL__POR (0x38) +#define TOMTOM_A_TX_1_2_TEST_BLOCK_EN (0x159) +#define TOMTOM_A_TX_1_2_TEST_BLOCK_EN__POR (0xFC) +#define TOMTOM_A_TX_1_2_TXFE_CLKDIV (0x15A) +#define TOMTOM_A_TX_1_2_TXFE_CLKDIV__POR (0x55) +#define TOMTOM_A_TX_1_2_SAR_ERR_CH1 (0x15B) +#define TOMTOM_A_TX_1_2_SAR_ERR_CH1__POR (0x00) +#define TOMTOM_A_TX_1_2_SAR_ERR_CH2 (0x15C) +#define TOMTOM_A_TX_1_2_SAR_ERR_CH2__POR (0x00) +#define TOMTOM_A_TX_3_GAIN (0x15D) +#define TOMTOM_A_TX_3_GAIN__POR (0x02) +#define TOMTOM_A_TX_3_4_TEST_EN (0x15E) +#define TOMTOM_A_TX_3_4_TEST_EN__POR (0xCC) +#define TOMTOM_A_TX_4_GAIN (0x15F) +#define TOMTOM_A_TX_4_GAIN__POR (0x02) +#define TOMTOM_A_TX_3_4_ADC_IB (0x160) +#define TOMTOM_A_TX_3_4_ADC_IB__POR (0x44) +#define TOMTOM_A_TX_3_4_ATEST_REFCTRL (0x161) +#define TOMTOM_A_TX_3_4_ATEST_REFCTRL__POR (0x00) +#define TOMTOM_A_TX_3_4_TEST_CTL (0x162) +#define TOMTOM_A_TX_3_4_TEST_CTL__POR (0x38) +#define TOMTOM_A_TX_3_4_TEST_BLOCK_EN (0x163) +#define TOMTOM_A_TX_3_4_TEST_BLOCK_EN__POR (0xFC) +#define TOMTOM_A_TX_3_4_TXFE_CKDIV (0x164) +#define TOMTOM_A_TX_3_4_TXFE_CKDIV__POR (0x55) +#define TOMTOM_A_TX_3_4_SAR_ERR_CH3 (0x165) +#define TOMTOM_A_TX_3_4_SAR_ERR_CH3__POR (0x00) +#define TOMTOM_A_TX_3_4_SAR_ERR_CH4 (0x166) +#define TOMTOM_A_TX_3_4_SAR_ERR_CH4__POR (0x00) +#define TOMTOM_A_TX_5_GAIN (0x167) +#define TOMTOM_A_TX_5_GAIN__POR (0x02) +#define TOMTOM_A_TX_5_6_TEST_EN (0x168) +#define TOMTOM_A_TX_5_6_TEST_EN__POR (0xCC) +#define TOMTOM_A_TX_6_GAIN (0x169) +#define TOMTOM_A_TX_6_GAIN__POR (0x02) +#define TOMTOM_A_TX_5_6_ADC_IB (0x16A) +#define TOMTOM_A_TX_5_6_ADC_IB__POR (0x44) +#define TOMTOM_A_TX_5_6_ATEST_REFCTRL (0x16B) +#define TOMTOM_A_TX_5_6_ATEST_REFCTRL__POR (0x00) +#define TOMTOM_A_TX_5_6_TEST_CTL (0x16C) +#define TOMTOM_A_TX_5_6_TEST_CTL__POR (0x38) +#define TOMTOM_A_TX_5_6_TEST_BLOCK_EN (0x16D) +#define TOMTOM_A_TX_5_6_TEST_BLOCK_EN__POR (0xFC) +#define TOMTOM_A_TX_5_6_TXFE_CKDIV (0x16E) +#define TOMTOM_A_TX_5_6_TXFE_CKDIV__POR (0x55) +#define TOMTOM_A_TX_5_6_SAR_ERR_CH5 (0x16F) +#define TOMTOM_A_TX_5_6_SAR_ERR_CH5__POR (0x00) +#define TOMTOM_A_TX_5_6_SAR_ERR_CH6 (0x170) +#define TOMTOM_A_TX_5_6_SAR_ERR_CH6__POR (0x00) +#define TOMTOM_A_TX_7_MBHC_EN (0x171) +#define TOMTOM_A_TX_7_MBHC_EN__POR (0x0C) +#define TOMTOM_A_TX_7_MBHC_ATEST_REFCTRL (0x172) +#define TOMTOM_A_TX_7_MBHC_ATEST_REFCTRL__POR (0x00) +#define TOMTOM_A_TX_7_MBHC_ADC (0x173) +#define TOMTOM_A_TX_7_MBHC_ADC__POR (0x44) +#define TOMTOM_A_TX_7_MBHC_TEST_CTL (0x174) +#define TOMTOM_A_TX_7_MBHC_TEST_CTL__POR (0x38) +#define TOMTOM_A_TX_7_MBHC_SAR_ERR (0x175) +#define TOMTOM_A_TX_7_MBHC_SAR_ERR__POR (0x00) +#define TOMTOM_A_TX_7_TXFE_CLKDIV (0x176) +#define TOMTOM_A_TX_7_TXFE_CLKDIV__POR (0x8B) +#define TOMTOM_A_RCO_CTRL (0x177) +#define TOMTOM_A_RCO_CTRL__POR (0x00) +#define TOMTOM_A_RCO_CALIBRATION_CTRL1 (0x178) +#define TOMTOM_A_RCO_CALIBRATION_CTRL1__POR (0x00) +#define TOMTOM_A_RCO_CALIBRATION_CTRL2 (0x179) +#define TOMTOM_A_RCO_CALIBRATION_CTRL2__POR (0x00) +#define TOMTOM_A_RCO_CALIBRATION_CTRL3 (0x17A) +#define TOMTOM_A_RCO_CALIBRATION_CTRL3__POR (0x00) +#define TOMTOM_A_RCO_TEST_CTRL (0x17B) +#define TOMTOM_A_RCO_TEST_CTRL__POR (0x00) +#define TOMTOM_A_RCO_CALIBRATION_RESULT1 (0x17C) +#define TOMTOM_A_RCO_CALIBRATION_RESULT1__POR (0x00) +#define TOMTOM_A_RCO_CALIBRATION_RESULT2 (0x17D) +#define TOMTOM_A_RCO_CALIBRATION_RESULT2__POR (0x00) +#define TOMTOM_A_BUCK_MODE_1 (0x181) +#define TOMTOM_A_BUCK_MODE_1__POR (0x21) +#define TOMTOM_A_BUCK_MODE_2 (0x182) +#define TOMTOM_A_BUCK_MODE_2__POR (0xFF) +#define TOMTOM_A_BUCK_MODE_3 (0x183) +#define TOMTOM_A_BUCK_MODE_3__POR (0xCE) +#define TOMTOM_A_BUCK_MODE_4 (0x184) +#define TOMTOM_A_BUCK_MODE_4__POR (0x3A) +#define TOMTOM_A_BUCK_MODE_5 (0x185) +#define TOMTOM_A_BUCK_MODE_5__POR (0x00) +#define TOMTOM_A_BUCK_CTRL_VCL_1 (0x186) +#define TOMTOM_A_BUCK_CTRL_VCL_1__POR (0x08) +#define TOMTOM_A_BUCK_CTRL_VCL_2 (0x187) +#define TOMTOM_A_BUCK_CTRL_VCL_2__POR (0xA3) +#define TOMTOM_A_BUCK_CTRL_VCL_3 (0x188) +#define TOMTOM_A_BUCK_CTRL_VCL_3__POR (0x82) +#define TOMTOM_A_BUCK_CTRL_CCL_1 (0x189) +#define TOMTOM_A_BUCK_CTRL_CCL_1__POR (0x5B) +#define TOMTOM_A_BUCK_CTRL_CCL_2 (0x18A) +#define TOMTOM_A_BUCK_CTRL_CCL_2__POR (0xDC) +#define TOMTOM_A_BUCK_CTRL_CCL_3 (0x18B) +#define TOMTOM_A_BUCK_CTRL_CCL_3__POR (0x6A) +#define TOMTOM_A_BUCK_CTRL_CCL_4 (0x18C) +#define TOMTOM_A_BUCK_CTRL_CCL_4__POR (0x51) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_1 (0x18D) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_1__POR (0x50) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_2 (0x18E) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_2__POR (0x64) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_3 (0x18F) +#define TOMTOM_A_BUCK_CTRL_PWM_DRVR_3__POR (0x77) +#define TOMTOM_A_BUCK_TMUX_A_D (0x190) +#define TOMTOM_A_BUCK_TMUX_A_D__POR (0x00) +#define TOMTOM_A_NCP_BUCKREF (0x191) +#define TOMTOM_A_NCP_BUCKREF__POR (0x00) +#define TOMTOM_A_NCP_EN (0x192) +#define TOMTOM_A_NCP_EN__POR (0xFE) +#define TOMTOM_A_NCP_CLK (0x193) +#define TOMTOM_A_NCP_CLK__POR (0x94) +#define TOMTOM_A_NCP_STATIC (0x194) +#define TOMTOM_A_NCP_STATIC__POR (0x28) +#define TOMTOM_A_NCP_VTH_LOW (0x195) +#define TOMTOM_A_NCP_VTH_LOW__POR (0x88) +#define TOMTOM_A_NCP_VTH_HIGH (0x196) +#define TOMTOM_A_NCP_VTH_HIGH__POR (0xA0) +#define TOMTOM_A_NCP_ATEST (0x197) +#define TOMTOM_A_NCP_ATEST__POR (0x00) +#define TOMTOM_A_NCP_DTEST (0x198) +#define TOMTOM_A_NCP_DTEST__POR (0x10) +#define TOMTOM_A_NCP_DLY1 (0x199) +#define TOMTOM_A_NCP_DLY1__POR (0x06) +#define TOMTOM_A_NCP_DLY2 (0x19A) +#define TOMTOM_A_NCP_DLY2__POR (0x06) +#define TOMTOM_A_RX_AUX_SW_CTL (0x19B) +#define TOMTOM_A_RX_AUX_SW_CTL__POR (0x00) +#define TOMTOM_A_RX_PA_AUX_IN_CONN (0x19C) +#define TOMTOM_A_RX_PA_AUX_IN_CONN__POR (0x00) +#define TOMTOM_A_RX_COM_TIMER_DIV (0x19E) +#define TOMTOM_A_RX_COM_TIMER_DIV__POR (0xE8) +#define TOMTOM_A_RX_COM_OCP_CTL (0x19F) +#define TOMTOM_A_RX_COM_OCP_CTL__POR (0x1F) +#define TOMTOM_A_RX_COM_OCP_COUNT (0x1A0) +#define TOMTOM_A_RX_COM_OCP_COUNT__POR (0x77) +#define TOMTOM_A_RX_COM_DAC_CTL (0x1A1) +#define TOMTOM_A_RX_COM_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_COM_BIAS (0x1A2) +#define TOMTOM_A_RX_COM_BIAS__POR (0x20) +#define TOMTOM_A_RX_HPH_AUTO_CHOP (0x1A4) +#define TOMTOM_A_RX_HPH_AUTO_CHOP__POR (0x38) +#define TOMTOM_A_RX_HPH_CHOP_CTL (0x1A5) +#define TOMTOM_A_RX_HPH_CHOP_CTL__POR (0xA4) +#define TOMTOM_A_RX_HPH_BIAS_PA (0x1A6) +#define TOMTOM_A_RX_HPH_BIAS_PA__POR (0x7A) +#define TOMTOM_A_RX_HPH_BIAS_LDO (0x1A7) +#define TOMTOM_A_RX_HPH_BIAS_LDO__POR (0x87) +#define TOMTOM_A_RX_HPH_BIAS_CNP (0x1A8) +#define TOMTOM_A_RX_HPH_BIAS_CNP__POR (0x8A) +#define TOMTOM_A_RX_HPH_BIAS_WG_OCP (0x1A9) +#define TOMTOM_A_RX_HPH_BIAS_WG_OCP__POR (0x2A) +#define TOMTOM_A_RX_HPH_OCP_CTL (0x1AA) +#define TOMTOM_A_RX_HPH_OCP_CTL__POR (0x69) +#define TOMTOM_A_RX_HPH_CNP_EN (0x1AB) +#define TOMTOM_A_RX_HPH_CNP_EN__POR (0x80) +#define TOMTOM_A_RX_HPH_CNP_WG_CTL (0x1AC) +#define TOMTOM_A_RX_HPH_CNP_WG_CTL__POR (0xDA) +#define TOMTOM_A_RX_HPH_CNP_WG_TIME (0x1AD) +#define TOMTOM_A_RX_HPH_CNP_WG_TIME__POR (0x15) +#define TOMTOM_A_RX_HPH_L_GAIN (0x1AE) +#define TOMTOM_A_RX_HPH_L_GAIN__POR (0xC0) +#define TOMTOM_A_RX_HPH_L_TEST (0x1AF) +#define TOMTOM_A_RX_HPH_L_TEST__POR (0x02) +#define TOMTOM_A_RX_HPH_L_PA_CTL (0x1B0) +#define TOMTOM_A_RX_HPH_L_PA_CTL__POR (0x42) +#define TOMTOM_A_RX_HPH_L_DAC_CTL (0x1B1) +#define TOMTOM_A_RX_HPH_L_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_HPH_L_ATEST (0x1B2) +#define TOMTOM_A_RX_HPH_L_ATEST__POR (0x00) +#define TOMTOM_A_RX_HPH_L_STATUS (0x1B3) +#define TOMTOM_A_RX_HPH_L_STATUS__POR (0x00) +#define TOMTOM_A_RX_HPH_R_GAIN (0x1B4) +#define TOMTOM_A_RX_HPH_R_GAIN__POR (0x00) +#define TOMTOM_A_RX_HPH_R_TEST (0x1B5) +#define TOMTOM_A_RX_HPH_R_TEST__POR (0x02) +#define TOMTOM_A_RX_HPH_R_PA_CTL (0x1B6) +#define TOMTOM_A_RX_HPH_R_PA_CTL__POR (0x42) +#define TOMTOM_A_RX_HPH_R_DAC_CTL (0x1B7) +#define TOMTOM_A_RX_HPH_R_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_HPH_R_ATEST (0x1B8) +#define TOMTOM_A_RX_HPH_R_ATEST__POR (0x00) +#define TOMTOM_A_RX_HPH_R_STATUS (0x1B9) +#define TOMTOM_A_RX_HPH_R_STATUS__POR (0x00) +#define TOMTOM_A_RX_EAR_BIAS_PA (0x1BA) +#define TOMTOM_A_RX_EAR_BIAS_PA__POR (0x76) +#define TOMTOM_A_RX_EAR_BIAS_CMBUFF (0x1BB) +#define TOMTOM_A_RX_EAR_BIAS_CMBUFF__POR (0xA0) +#define TOMTOM_A_RX_EAR_EN (0x1BC) +#define TOMTOM_A_RX_EAR_EN__POR (0x00) +#define TOMTOM_A_RX_EAR_GAIN (0x1BD) +#define TOMTOM_A_RX_EAR_GAIN__POR (0x02) +#define TOMTOM_A_RX_EAR_CMBUFF (0x1BE) +#define TOMTOM_A_RX_EAR_CMBUFF__POR (0x05) +#define TOMTOM_A_RX_EAR_ICTL (0x1BF) +#define TOMTOM_A_RX_EAR_ICTL__POR (0x40) +#define TOMTOM_A_RX_EAR_CCOMP (0x1C0) +#define TOMTOM_A_RX_EAR_CCOMP__POR (0x08) +#define TOMTOM_A_RX_EAR_VCM (0x1C1) +#define TOMTOM_A_RX_EAR_VCM__POR (0x03) +#define TOMTOM_A_RX_EAR_CNP (0x1C2) +#define TOMTOM_A_RX_EAR_CNP__POR (0xC0) +#define TOMTOM_A_RX_EAR_DAC_CTL_ATEST (0x1C3) +#define TOMTOM_A_RX_EAR_DAC_CTL_ATEST__POR (0x00) +#define TOMTOM_A_RX_EAR_STATUS (0x1C5) +#define TOMTOM_A_RX_EAR_STATUS__POR (0x04) +#define TOMTOM_A_RX_LINE_BIAS_PA (0x1C6) +#define TOMTOM_A_RX_LINE_BIAS_PA__POR (0x78) +#define TOMTOM_A_RX_BUCK_BIAS1 (0x1C7) +#define TOMTOM_A_RX_BUCK_BIAS1__POR (0x42) +#define TOMTOM_A_RX_BUCK_BIAS2 (0x1C8) +#define TOMTOM_A_RX_BUCK_BIAS2__POR (0x84) +#define TOMTOM_A_RX_LINE_COM (0x1C9) +#define TOMTOM_A_RX_LINE_COM__POR (0x80) +#define TOMTOM_A_RX_LINE_CNP_EN (0x1CA) +#define TOMTOM_A_RX_LINE_CNP_EN__POR (0x00) +#define TOMTOM_A_RX_LINE_CNP_WG_CTL (0x1CB) +#define TOMTOM_A_RX_LINE_CNP_WG_CTL__POR (0x00) +#define TOMTOM_A_RX_LINE_CNP_WG_TIME (0x1CC) +#define TOMTOM_A_RX_LINE_CNP_WG_TIME__POR (0x04) +#define TOMTOM_A_RX_LINE_1_GAIN (0x1CD) +#define TOMTOM_A_RX_LINE_1_GAIN__POR (0x00) +#define TOMTOM_A_RX_LINE_1_TEST (0x1CE) +#define TOMTOM_A_RX_LINE_1_TEST__POR (0x02) +#define TOMTOM_A_RX_LINE_1_DAC_CTL (0x1CF) +#define TOMTOM_A_RX_LINE_1_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_LINE_1_STATUS (0x1D0) +#define TOMTOM_A_RX_LINE_1_STATUS__POR (0x00) +#define TOMTOM_A_RX_LINE_2_GAIN (0x1D1) +#define TOMTOM_A_RX_LINE_2_GAIN__POR (0x00) +#define TOMTOM_A_RX_LINE_2_TEST (0x1D2) +#define TOMTOM_A_RX_LINE_2_TEST__POR (0x02) +#define TOMTOM_A_RX_LINE_2_DAC_CTL (0x1D3) +#define TOMTOM_A_RX_LINE_2_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_LINE_2_STATUS (0x1D4) +#define TOMTOM_A_RX_LINE_2_STATUS__POR (0x00) +#define TOMTOM_A_RX_LINE_3_GAIN (0x1D5) +#define TOMTOM_A_RX_LINE_3_GAIN__POR (0x00) +#define TOMTOM_A_RX_LINE_3_TEST (0x1D6) +#define TOMTOM_A_RX_LINE_3_TEST__POR (0x02) +#define TOMTOM_A_RX_LINE_3_DAC_CTL (0x1D7) +#define TOMTOM_A_RX_LINE_3_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_LINE_3_STATUS (0x1D8) +#define TOMTOM_A_RX_LINE_3_STATUS__POR (0x00) +#define TOMTOM_A_RX_LINE_4_GAIN (0x1D9) +#define TOMTOM_A_RX_LINE_4_GAIN__POR (0x00) +#define TOMTOM_A_RX_LINE_4_TEST (0x1DA) +#define TOMTOM_A_RX_LINE_4_TEST__POR (0x02) +#define TOMTOM_A_RX_LINE_4_DAC_CTL (0x1DB) +#define TOMTOM_A_RX_LINE_4_DAC_CTL__POR (0x00) +#define TOMTOM_A_RX_LINE_4_STATUS (0x1DC) +#define TOMTOM_A_RX_LINE_4_STATUS__POR (0x00) +#define TOMTOM_A_RX_LINE_CNP_DBG (0x1DD) +#define TOMTOM_A_RX_LINE_CNP_DBG__POR (0x00) +#define TOMTOM_A_SPKR_DRV1_EN (0x1DF) +#define TOMTOM_A_SPKR_DRV1_EN__POR (0x6F) +#define TOMTOM_A_SPKR_DRV1_GAIN (0x1E0) +#define TOMTOM_A_SPKR_DRV1_GAIN__POR (0x00) +#define TOMTOM_A_SPKR_DRV1_DAC_CTL (0x1E1) +#define TOMTOM_A_SPKR_DRV1_DAC_CTL__POR (0x04) +#define TOMTOM_A_SPKR_DRV1_OCP_CTL (0x1E2) +#define TOMTOM_A_SPKR_DRV1_OCP_CTL__POR (0x97) +#define TOMTOM_A_SPKR_DRV1_CLIP_DET (0x1E3) +#define TOMTOM_A_SPKR_DRV1_CLIP_DET__POR (0x01) +#define TOMTOM_A_SPKR_DRV1_IEC (0x1E4) +#define TOMTOM_A_SPKR_DRV1_IEC__POR (0x00) +#define TOMTOM_A_SPKR_DRV1_DBG_DAC (0x1E5) +#define TOMTOM_A_SPKR_DRV1_DBG_DAC__POR (0x05) +#define TOMTOM_A_SPKR_DRV1_DBG_PA (0x1E6) +#define TOMTOM_A_SPKR_DRV1_DBG_PA__POR (0x18) +#define TOMTOM_A_SPKR_DRV1_DBG_PWRSTG (0x1E7) +#define TOMTOM_A_SPKR_DRV1_DBG_PWRSTG__POR (0x00) +#define TOMTOM_A_SPKR_DRV1_BIAS_LDO (0x1E8) +#define TOMTOM_A_SPKR_DRV1_BIAS_LDO__POR (0x45) +#define TOMTOM_A_SPKR_DRV1_BIAS_INT (0x1E9) +#define TOMTOM_A_SPKR_DRV1_BIAS_INT__POR (0xA5) +#define TOMTOM_A_SPKR_DRV1_BIAS_PA (0x1EA) +#define TOMTOM_A_SPKR_DRV1_BIAS_PA__POR (0x55) +#define TOMTOM_A_SPKR_DRV1_STATUS_OCP (0x1EB) +#define TOMTOM_A_SPKR_DRV1_STATUS_OCP__POR (0x00) +#define TOMTOM_A_SPKR_DRV1_STATUS_PA (0x1EC) +#define TOMTOM_A_SPKR_DRV1_STATUS_PA__POR (0x00) +#define TOMTOM_A_SPKR1_PROT_EN (0x1ED) +#define TOMTOM_A_SPKR1_PROT_EN__POR (0x00) +#define TOMTOM_A_SPKR1_PROT_ADC_TEST_EN (0x1EE) +#define TOMTOM_A_SPKR1_PROT_ADC_TEST_EN__POR (0x44) +#define TOMTOM_A_SPKR1_PROT_ATEST (0x1EF) +#define TOMTOM_A_SPKR1_PROT_ATEST__POR (0x00) +#define TOMTOM_A_SPKR1_PROT_LDO_CTRL (0x1F0) +#define TOMTOM_A_SPKR1_PROT_LDO_CTRL__POR (0x00) +#define TOMTOM_A_SPKR1_PROT_ISENSE_CTRL (0x1F1) +#define TOMTOM_A_SPKR1_PROT_ISENSE_CTRL__POR (0x00) +#define TOMTOM_A_SPKR1_PROT_VSENSE_CTRL (0x1F2) +#define TOMTOM_A_SPKR1_PROT_VSENSE_CTRL__POR (0x00) +#define TOMTOM_A_SPKR2_PROT_EN (0x1F3) +#define TOMTOM_A_SPKR2_PROT_EN__POR (0x00) +#define TOMTOM_A_SPKR2_PROT_ADC_TEST_EN (0x1F4) +#define TOMTOM_A_SPKR2_PROT_ADC_TEST_EN__POR (0x44) +#define TOMTOM_A_SPKR2_PROT_ATEST (0x1F5) +#define TOMTOM_A_SPKR2_PROT_ATEST__POR (0x00) +#define TOMTOM_A_SPKR2_PROT_LDO_CTRL (0x1F6) +#define TOMTOM_A_SPKR2_PROT_LDO_CTRL__POR (0x00) +#define TOMTOM_A_SPKR2_PROT_ISENSE_CTRL (0x1F7) +#define TOMTOM_A_SPKR2_PROT_ISENSE_CTRL__POR (0x00) +#define TOMTOM_A_SPKR2_PROT_VSENSE_CTRL (0x1F8) +#define TOMTOM_A_SPKR2_PROT_VSENSE_CTRL__POR (0x00) +#define TOMTOM_A_MBHC_HPH (0x1FE) +#define TOMTOM_A_MBHC_HPH__POR (0x44) +#define TOMTOM_A_CDC_ANC1_B1_CTL (0x200) +#define TOMTOM_A_CDC_ANC1_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_B1_CTL (0x280) +#define TOMTOM_A_CDC_ANC2_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_SHIFT (0x201) +#define TOMTOM_A_CDC_ANC1_SHIFT__POR (0x00) +#define TOMTOM_A_CDC_ANC2_SHIFT (0x281) +#define TOMTOM_A_CDC_ANC2_SHIFT__POR (0x00) +#define TOMTOM_A_CDC_ANC1_IIR_B1_CTL (0x202) +#define TOMTOM_A_CDC_ANC1_IIR_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_IIR_B1_CTL (0x282) +#define TOMTOM_A_CDC_ANC2_IIR_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_IIR_B2_CTL (0x203) +#define TOMTOM_A_CDC_ANC1_IIR_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_IIR_B2_CTL (0x283) +#define TOMTOM_A_CDC_ANC2_IIR_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_IIR_B3_CTL (0x204) +#define TOMTOM_A_CDC_ANC1_IIR_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_IIR_B3_CTL (0x284) +#define TOMTOM_A_CDC_ANC2_IIR_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_LPF_B1_CTL (0x206) +#define TOMTOM_A_CDC_ANC1_LPF_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_LPF_B1_CTL (0x286) +#define TOMTOM_A_CDC_ANC2_LPF_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_LPF_B2_CTL (0x207) +#define TOMTOM_A_CDC_ANC1_LPF_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_LPF_B2_CTL (0x287) +#define TOMTOM_A_CDC_ANC2_LPF_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_SPARE (0x209) +#define TOMTOM_A_CDC_ANC1_SPARE__POR (0x00) +#define TOMTOM_A_CDC_ANC2_SPARE (0x289) +#define TOMTOM_A_CDC_ANC2_SPARE__POR (0x00) +#define TOMTOM_A_CDC_ANC1_SMLPF_CTL (0x20A) +#define TOMTOM_A_CDC_ANC1_SMLPF_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_SMLPF_CTL (0x28A) +#define TOMTOM_A_CDC_ANC2_SMLPF_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_DCFLT_CTL (0x20B) +#define TOMTOM_A_CDC_ANC1_DCFLT_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_DCFLT_CTL (0x28B) +#define TOMTOM_A_CDC_ANC2_DCFLT_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_GAIN_CTL (0x20C) +#define TOMTOM_A_CDC_ANC1_GAIN_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_GAIN_CTL (0x28C) +#define TOMTOM_A_CDC_ANC2_GAIN_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC1_B2_CTL (0x20D) +#define TOMTOM_A_CDC_ANC1_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_ANC2_B2_CTL (0x28D) +#define TOMTOM_A_CDC_ANC2_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX1_VOL_CTL_TIMER (0x220) +#define TOMTOM_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX2_VOL_CTL_TIMER (0x228) +#define TOMTOM_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX3_VOL_CTL_TIMER (0x230) +#define TOMTOM_A_CDC_TX3_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX4_VOL_CTL_TIMER (0x238) +#define TOMTOM_A_CDC_TX4_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX5_VOL_CTL_TIMER (0x240) +#define TOMTOM_A_CDC_TX5_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX6_VOL_CTL_TIMER (0x248) +#define TOMTOM_A_CDC_TX6_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX7_VOL_CTL_TIMER (0x250) +#define TOMTOM_A_CDC_TX7_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX8_VOL_CTL_TIMER (0x258) +#define TOMTOM_A_CDC_TX8_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX9_VOL_CTL_TIMER (0x260) +#define TOMTOM_A_CDC_TX9_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX10_VOL_CTL_TIMER (0x268) +#define TOMTOM_A_CDC_TX10_VOL_CTL_TIMER__POR (0x00) +#define TOMTOM_A_CDC_TX1_VOL_CTL_GAIN (0x221) +#define TOMTOM_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX2_VOL_CTL_GAIN (0x229) +#define TOMTOM_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX3_VOL_CTL_GAIN (0x231) +#define TOMTOM_A_CDC_TX3_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX4_VOL_CTL_GAIN (0x239) +#define TOMTOM_A_CDC_TX4_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX5_VOL_CTL_GAIN (0x241) +#define TOMTOM_A_CDC_TX5_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX6_VOL_CTL_GAIN (0x249) +#define TOMTOM_A_CDC_TX6_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX7_VOL_CTL_GAIN (0x251) +#define TOMTOM_A_CDC_TX7_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX8_VOL_CTL_GAIN (0x259) +#define TOMTOM_A_CDC_TX8_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX9_VOL_CTL_GAIN (0x261) +#define TOMTOM_A_CDC_TX9_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX10_VOL_CTL_GAIN (0x269) +#define TOMTOM_A_CDC_TX10_VOL_CTL_GAIN__POR (0x00) +#define TOMTOM_A_CDC_TX1_VOL_CTL_CFG (0x222) +#define TOMTOM_A_CDC_TX1_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX2_VOL_CTL_CFG (0x22A) +#define TOMTOM_A_CDC_TX2_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX3_VOL_CTL_CFG (0x232) +#define TOMTOM_A_CDC_TX3_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX4_VOL_CTL_CFG (0x23A) +#define TOMTOM_A_CDC_TX4_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX5_VOL_CTL_CFG (0x242) +#define TOMTOM_A_CDC_TX5_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX6_VOL_CTL_CFG (0x24A) +#define TOMTOM_A_CDC_TX6_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX7_VOL_CTL_CFG (0x252) +#define TOMTOM_A_CDC_TX7_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX8_VOL_CTL_CFG (0x25A) +#define TOMTOM_A_CDC_TX8_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX9_VOL_CTL_CFG (0x262) +#define TOMTOM_A_CDC_TX9_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX10_VOL_CTL_CFG (0x26A) +#define TOMTOM_A_CDC_TX10_VOL_CTL_CFG__POR (0x00) +#define TOMTOM_A_CDC_TX1_MUX_CTL (0x223) +#define TOMTOM_A_CDC_TX1_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX2_MUX_CTL (0x22B) +#define TOMTOM_A_CDC_TX2_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX3_MUX_CTL (0x233) +#define TOMTOM_A_CDC_TX3_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX4_MUX_CTL (0x23B) +#define TOMTOM_A_CDC_TX4_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX5_MUX_CTL (0x243) +#define TOMTOM_A_CDC_TX5_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX6_MUX_CTL (0x24B) +#define TOMTOM_A_CDC_TX6_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX7_MUX_CTL (0x253) +#define TOMTOM_A_CDC_TX7_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX8_MUX_CTL (0x25B) +#define TOMTOM_A_CDC_TX8_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX9_MUX_CTL (0x263) +#define TOMTOM_A_CDC_TX9_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX10_MUX_CTL (0x26B) +#define TOMTOM_A_CDC_TX10_MUX_CTL__POR (0x48) +#define TOMTOM_A_CDC_TX1_CLK_FS_CTL (0x224) +#define TOMTOM_A_CDC_TX1_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX2_CLK_FS_CTL (0x22C) +#define TOMTOM_A_CDC_TX2_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX3_CLK_FS_CTL (0x234) +#define TOMTOM_A_CDC_TX3_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX4_CLK_FS_CTL (0x23C) +#define TOMTOM_A_CDC_TX4_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX5_CLK_FS_CTL (0x244) +#define TOMTOM_A_CDC_TX5_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX6_CLK_FS_CTL (0x24C) +#define TOMTOM_A_CDC_TX6_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX7_CLK_FS_CTL (0x254) +#define TOMTOM_A_CDC_TX7_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX8_CLK_FS_CTL (0x25C) +#define TOMTOM_A_CDC_TX8_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX9_CLK_FS_CTL (0x264) +#define TOMTOM_A_CDC_TX9_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX10_CLK_FS_CTL (0x26C) +#define TOMTOM_A_CDC_TX10_CLK_FS_CTL__POR (0x03) +#define TOMTOM_A_CDC_TX1_DMIC_CTL (0x225) +#define TOMTOM_A_CDC_TX1_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX2_DMIC_CTL (0x22D) +#define TOMTOM_A_CDC_TX2_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX3_DMIC_CTL (0x235) +#define TOMTOM_A_CDC_TX3_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX4_DMIC_CTL (0x23D) +#define TOMTOM_A_CDC_TX4_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX5_DMIC_CTL (0x245) +#define TOMTOM_A_CDC_TX5_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX6_DMIC_CTL (0x24D) +#define TOMTOM_A_CDC_TX6_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX7_DMIC_CTL (0x255) +#define TOMTOM_A_CDC_TX7_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX8_DMIC_CTL (0x25D) +#define TOMTOM_A_CDC_TX8_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX9_DMIC_CTL (0x265) +#define TOMTOM_A_CDC_TX9_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_TX10_DMIC_CTL (0x26D) +#define TOMTOM_A_CDC_TX10_DMIC_CTL__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL0 (0x270) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL0__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL1 (0x271) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL1__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL2 (0x272) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL2__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL3 (0x273) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL3__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL4 (0x274) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL4__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL5 (0x275) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL5__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL6 (0x276) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL6__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL7 (0x277) +#define TOMTOM_A_CDC_SPKR_CLIPDET_VAL7__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B1_CTL (0x278) +#define TOMTOM_A_CDC_DEBUG_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B2_CTL (0x279) +#define TOMTOM_A_CDC_DEBUG_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B3_CTL (0x27A) +#define TOMTOM_A_CDC_DEBUG_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B4_CTL (0x27B) +#define TOMTOM_A_CDC_DEBUG_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B5_CTL (0x27C) +#define TOMTOM_A_CDC_DEBUG_B5_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B6_CTL (0x27D) +#define TOMTOM_A_CDC_DEBUG_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_DEBUG_B7_CTL (0x27E) +#define TOMTOM_A_CDC_DEBUG_B7_CTL__POR (0x00) +#define TOMTOM_A_CDC_SRC1_PDA_CFG (0x2A0) +#define TOMTOM_A_CDC_SRC1_PDA_CFG__POR (0x00) +#define TOMTOM_A_CDC_SRC2_PDA_CFG (0x2A8) +#define TOMTOM_A_CDC_SRC2_PDA_CFG__POR (0x00) +#define TOMTOM_A_CDC_SRC1_FS_CTL (0x2A1) +#define TOMTOM_A_CDC_SRC1_FS_CTL__POR (0x1B) +#define TOMTOM_A_CDC_SRC2_FS_CTL (0x2A9) +#define TOMTOM_A_CDC_SRC2_FS_CTL__POR (0x1B) +#define TOMTOM_A_CDC_RX1_B1_CTL (0x2B0) +#define TOMTOM_A_CDC_RX1_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX2_B1_CTL (0x2B8) +#define TOMTOM_A_CDC_RX2_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX3_B1_CTL (0x2C0) +#define TOMTOM_A_CDC_RX3_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX4_B1_CTL (0x2C8) +#define TOMTOM_A_CDC_RX4_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX5_B1_CTL (0x2D0) +#define TOMTOM_A_CDC_RX5_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX6_B1_CTL (0x2D8) +#define TOMTOM_A_CDC_RX6_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX7_B1_CTL (0x2E0) +#define TOMTOM_A_CDC_RX7_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX1_B2_CTL (0x2B1) +#define TOMTOM_A_CDC_RX1_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX2_B2_CTL (0x2B9) +#define TOMTOM_A_CDC_RX2_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX3_B2_CTL (0x2C1) +#define TOMTOM_A_CDC_RX3_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX4_B2_CTL (0x2C9) +#define TOMTOM_A_CDC_RX4_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX5_B2_CTL (0x2D1) +#define TOMTOM_A_CDC_RX5_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX6_B2_CTL (0x2D9) +#define TOMTOM_A_CDC_RX6_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX7_B2_CTL (0x2E1) +#define TOMTOM_A_CDC_RX7_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX1_B3_CTL (0x2B2) +#define TOMTOM_A_CDC_RX1_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX2_B3_CTL (0x2BA) +#define TOMTOM_A_CDC_RX2_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX3_B3_CTL (0x2C2) +#define TOMTOM_A_CDC_RX3_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX4_B3_CTL (0x2CA) +#define TOMTOM_A_CDC_RX4_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX5_B3_CTL (0x2D2) +#define TOMTOM_A_CDC_RX5_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX6_B3_CTL (0x2DA) +#define TOMTOM_A_CDC_RX6_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX7_B3_CTL (0x2E2) +#define TOMTOM_A_CDC_RX7_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX1_B4_CTL (0x2B3) +#define TOMTOM_A_CDC_RX1_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX2_B4_CTL (0x2BB) +#define TOMTOM_A_CDC_RX2_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX3_B4_CTL (0x2C3) +#define TOMTOM_A_CDC_RX3_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX4_B4_CTL (0x2CB) +#define TOMTOM_A_CDC_RX4_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX5_B4_CTL (0x2D3) +#define TOMTOM_A_CDC_RX5_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX6_B4_CTL (0x2DB) +#define TOMTOM_A_CDC_RX6_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX7_B4_CTL (0x2E3) +#define TOMTOM_A_CDC_RX7_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX1_B5_CTL (0x2B4) +#define TOMTOM_A_CDC_RX1_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX2_B5_CTL (0x2BC) +#define TOMTOM_A_CDC_RX2_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX3_B5_CTL (0x2C4) +#define TOMTOM_A_CDC_RX3_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX4_B5_CTL (0x2CC) +#define TOMTOM_A_CDC_RX4_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX5_B5_CTL (0x2D4) +#define TOMTOM_A_CDC_RX5_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX6_B5_CTL (0x2DC) +#define TOMTOM_A_CDC_RX6_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX7_B5_CTL (0x2E4) +#define TOMTOM_A_CDC_RX7_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX1_B6_CTL (0x2B5) +#define TOMTOM_A_CDC_RX1_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX2_B6_CTL (0x2BD) +#define TOMTOM_A_CDC_RX2_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX3_B6_CTL (0x2C5) +#define TOMTOM_A_CDC_RX3_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX4_B6_CTL (0x2CD) +#define TOMTOM_A_CDC_RX4_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX5_B6_CTL (0x2D5) +#define TOMTOM_A_CDC_RX5_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX6_B6_CTL (0x2DD) +#define TOMTOM_A_CDC_RX6_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX7_B6_CTL (0x2E5) +#define TOMTOM_A_CDC_RX7_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX1_VOL_CTL_B1_CTL (0x2B6) +#define TOMTOM_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX2_VOL_CTL_B1_CTL (0x2BE) +#define TOMTOM_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX3_VOL_CTL_B1_CTL (0x2C6) +#define TOMTOM_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX4_VOL_CTL_B1_CTL (0x2CE) +#define TOMTOM_A_CDC_RX4_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX5_VOL_CTL_B1_CTL (0x2D6) +#define TOMTOM_A_CDC_RX5_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX6_VOL_CTL_B1_CTL (0x2DE) +#define TOMTOM_A_CDC_RX6_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX7_VOL_CTL_B1_CTL (0x2E6) +#define TOMTOM_A_CDC_RX7_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX1_VOL_CTL_B2_CTL (0x2B7) +#define TOMTOM_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX2_VOL_CTL_B2_CTL (0x2BF) +#define TOMTOM_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX3_VOL_CTL_B2_CTL (0x2C7) +#define TOMTOM_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX4_VOL_CTL_B2_CTL (0x2CF) +#define TOMTOM_A_CDC_RX4_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX5_VOL_CTL_B2_CTL (0x2D7) +#define TOMTOM_A_CDC_RX5_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX6_VOL_CTL_B2_CTL (0x2DF) +#define TOMTOM_A_CDC_RX6_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX7_VOL_CTL_B2_CTL (0x2E7) +#define TOMTOM_A_CDC_RX7_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_VBAT_CFG (0x2E8) +#define TOMTOM_A_CDC_VBAT_CFG__POR (0x1A) +#define TOMTOM_A_CDC_VBAT_ADC_CAL1 (0x2E9) +#define TOMTOM_A_CDC_VBAT_ADC_CAL1__POR (0x00) +#define TOMTOM_A_CDC_VBAT_ADC_CAL2 (0x2EA) +#define TOMTOM_A_CDC_VBAT_ADC_CAL2__POR (0x00) +#define TOMTOM_A_CDC_VBAT_ADC_CAL3 (0x2EB) +#define TOMTOM_A_CDC_VBAT_ADC_CAL3__POR (0x04) +#define TOMTOM_A_CDC_VBAT_PK_EST1 (0x2EC) +#define TOMTOM_A_CDC_VBAT_PK_EST1__POR (0xE0) +#define TOMTOM_A_CDC_VBAT_PK_EST2 (0x2ED) +#define TOMTOM_A_CDC_VBAT_PK_EST2__POR (0x01) +#define TOMTOM_A_CDC_VBAT_PK_EST3 (0x2EE) +#define TOMTOM_A_CDC_VBAT_PK_EST3__POR (0x40) +#define TOMTOM_A_CDC_VBAT_RF_PROC1 (0x2EF) +#define TOMTOM_A_CDC_VBAT_RF_PROC1__POR (0x2A) +#define TOMTOM_A_CDC_VBAT_RF_PROC2 (0x2F0) +#define TOMTOM_A_CDC_VBAT_RF_PROC2__POR (0x86) +#define TOMTOM_A_CDC_VBAT_TAC1 (0x2F1) +#define TOMTOM_A_CDC_VBAT_TAC1__POR (0x70) +#define TOMTOM_A_CDC_VBAT_TAC2 (0x2F2) +#define TOMTOM_A_CDC_VBAT_TAC2__POR (0x18) +#define TOMTOM_A_CDC_VBAT_TAC3 (0x2F3) +#define TOMTOM_A_CDC_VBAT_TAC3__POR (0x18) +#define TOMTOM_A_CDC_VBAT_TAC4 (0x2F4) +#define TOMTOM_A_CDC_VBAT_TAC4__POR (0x03) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD1 (0x2F5) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD1__POR (0x01) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD2 (0x2F6) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD2__POR (0x00) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD3 (0x2F7) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD3__POR (0x64) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD4 (0x2F8) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD4__POR (0x01) +#define TOMTOM_A_CDC_VBAT_DEBUG1 (0x2F9) +#define TOMTOM_A_CDC_VBAT_DEBUG1__POR (0x00) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD_MON (0x2FA) +#define TOMTOM_A_CDC_VBAT_GAIN_UPD_MON__POR (0x00) +#define TOMTOM_A_CDC_VBAT_GAIN_MON_VAL (0x2FB) +#define TOMTOM_A_CDC_VBAT_GAIN_MON_VAL__POR (0x00) +#define TOMTOM_A_CDC_CLK_ANC_RESET_CTL (0x300) +#define TOMTOM_A_CDC_CLK_ANC_RESET_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_RX_RESET_CTL (0x301) +#define TOMTOM_A_CDC_CLK_RX_RESET_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_TX_RESET_B1_CTL (0x302) +#define TOMTOM_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_TX_RESET_B2_CTL (0x303) +#define TOMTOM_A_CDC_CLK_TX_RESET_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_RX_I2S_CTL (0x306) +#define TOMTOM_A_CDC_CLK_RX_I2S_CTL__POR (0x03) +#define TOMTOM_A_CDC_CLK_TX_I2S_CTL (0x307) +#define TOMTOM_A_CDC_CLK_TX_I2S_CTL__POR (0x03) +#define TOMTOM_A_CDC_CLK_OTHR_RESET_B1_CTL (0x308) +#define TOMTOM_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_OTHR_RESET_B2_CTL (0x309) +#define TOMTOM_A_CDC_CLK_OTHR_RESET_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x30A) +#define TOMTOM_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_TX_CLK_EN_B2_CTL (0x30B) +#define TOMTOM_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_OTHR_CTL (0x30C) +#define TOMTOM_A_CDC_CLK_OTHR_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_ANC_CLK_EN_CTL (0x30E) +#define TOMTOM_A_CDC_CLK_ANC_CLK_EN_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_RX_B1_CTL (0x30F) +#define TOMTOM_A_CDC_CLK_RX_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_RX_B2_CTL (0x310) +#define TOMTOM_A_CDC_CLK_RX_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_MCLK_CTL (0x311) +#define TOMTOM_A_CDC_CLK_MCLK_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_PDM_CTL (0x312) +#define TOMTOM_A_CDC_CLK_PDM_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLK_SD_CTL (0x313) +#define TOMTOM_A_CDC_CLK_SD_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLSH_B1_CTL (0x320) +#define TOMTOM_A_CDC_CLSH_B1_CTL__POR (0xE4) +#define TOMTOM_A_CDC_CLSH_B2_CTL (0x321) +#define TOMTOM_A_CDC_CLSH_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLSH_B3_CTL (0x322) +#define TOMTOM_A_CDC_CLSH_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLSH_BUCK_NCP_VARS (0x323) +#define TOMTOM_A_CDC_CLSH_BUCK_NCP_VARS__POR (0x00) +#define TOMTOM_A_CDC_CLSH_IDLE_HPH_THSD (0x324) +#define TOMTOM_A_CDC_CLSH_IDLE_HPH_THSD__POR (0x12) +#define TOMTOM_A_CDC_CLSH_IDLE_EAR_THSD (0x325) +#define TOMTOM_A_CDC_CLSH_IDLE_EAR_THSD__POR (0x0C) +#define TOMTOM_A_CDC_CLSH_FCLKONLY_HPH_THSD (0x326) +#define TOMTOM_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR (0x18) +#define TOMTOM_A_CDC_CLSH_FCLKONLY_EAR_THSD (0x327) +#define TOMTOM_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR (0x23) +#define TOMTOM_A_CDC_CLSH_K_ADDR (0x328) +#define TOMTOM_A_CDC_CLSH_K_ADDR__POR (0x00) +#define TOMTOM_A_CDC_CLSH_K_DATA (0x329) +#define TOMTOM_A_CDC_CLSH_K_DATA__POR (0xA4) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_HPH_L (0x32A) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_HPH_L__POR (0xD7) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_HPH_U (0x32B) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_HPH_U__POR (0x05) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_EAR_L (0x32C) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_EAR_L__POR (0x60) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_EAR_U (0x32D) +#define TOMTOM_A_CDC_CLSH_I_PA_FACT_EAR_U__POR (0x09) +#define TOMTOM_A_CDC_CLSH_V_PA_HD_EAR (0x32E) +#define TOMTOM_A_CDC_CLSH_V_PA_HD_EAR__POR (0x00) +#define TOMTOM_A_CDC_CLSH_V_PA_HD_HPH (0x32F) +#define TOMTOM_A_CDC_CLSH_V_PA_HD_HPH__POR (0x00) +#define TOMTOM_A_CDC_CLSH_V_PA_MIN_EAR (0x330) +#define TOMTOM_A_CDC_CLSH_V_PA_MIN_EAR__POR (0x00) +#define TOMTOM_A_CDC_CLSH_V_PA_MIN_HPH (0x331) +#define TOMTOM_A_CDC_CLSH_V_PA_MIN_HPH__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B1_CTL (0x340) +#define TOMTOM_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B1_CTL (0x350) +#define TOMTOM_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B2_CTL (0x341) +#define TOMTOM_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B2_CTL (0x351) +#define TOMTOM_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B3_CTL (0x342) +#define TOMTOM_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B3_CTL (0x352) +#define TOMTOM_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B4_CTL (0x343) +#define TOMTOM_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B4_CTL (0x353) +#define TOMTOM_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B5_CTL (0x344) +#define TOMTOM_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B5_CTL (0x354) +#define TOMTOM_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B6_CTL (0x345) +#define TOMTOM_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B6_CTL (0x355) +#define TOMTOM_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B7_CTL (0x346) +#define TOMTOM_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B7_CTL (0x356) +#define TOMTOM_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_GAIN_B8_CTL (0x347) +#define TOMTOM_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_B8_CTL (0x357) +#define TOMTOM_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_CTL (0x348) +#define TOMTOM_A_CDC_IIR1_CTL__POR (0x40) +#define TOMTOM_A_CDC_IIR2_CTL (0x358) +#define TOMTOM_A_CDC_IIR2_CTL__POR (0x40) +#define TOMTOM_A_CDC_IIR1_GAIN_TIMER_CTL (0x349) +#define TOMTOM_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_GAIN_TIMER_CTL (0x359) +#define TOMTOM_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_COEF_B1_CTL (0x34A) +#define TOMTOM_A_CDC_IIR1_COEF_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_COEF_B1_CTL (0x35A) +#define TOMTOM_A_CDC_IIR2_COEF_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR1_COEF_B2_CTL (0x34B) +#define TOMTOM_A_CDC_IIR1_COEF_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_IIR2_COEF_B2_CTL (0x35B) +#define TOMTOM_A_CDC_IIR2_COEF_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_TOP_GAIN_UPDATE (0x360) +#define TOMTOM_A_CDC_TOP_GAIN_UPDATE__POR (0x00) +#define TOMTOM_A_CDC_PA_RAMP_B1_CTL (0x361) +#define TOMTOM_A_CDC_PA_RAMP_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_PA_RAMP_B2_CTL (0x362) +#define TOMTOM_A_CDC_PA_RAMP_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_PA_RAMP_B3_CTL (0x363) +#define TOMTOM_A_CDC_PA_RAMP_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_PA_RAMP_B4_CTL (0x364) +#define TOMTOM_A_CDC_PA_RAMP_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_SPKR_CLIPDET_B1_CTL (0x365) +#define TOMTOM_A_CDC_SPKR_CLIPDET_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_B1_CTL (0x366) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_COMP0_B1_CTL (0x368) +#define TOMTOM_A_CDC_COMP0_B1_CTL__POR (0x30) +#define TOMTOM_A_CDC_COMP1_B1_CTL (0x370) +#define TOMTOM_A_CDC_COMP1_B1_CTL__POR (0x30) +#define TOMTOM_A_CDC_COMP2_B1_CTL (0x378) +#define TOMTOM_A_CDC_COMP2_B1_CTL__POR (0x30) +#define TOMTOM_A_CDC_COMP0_B2_CTL (0x369) +#define TOMTOM_A_CDC_COMP0_B2_CTL__POR (0xB5) +#define TOMTOM_A_CDC_COMP1_B2_CTL (0x371) +#define TOMTOM_A_CDC_COMP1_B2_CTL__POR (0xB5) +#define TOMTOM_A_CDC_COMP2_B2_CTL (0x379) +#define TOMTOM_A_CDC_COMP2_B2_CTL__POR (0xB5) +#define TOMTOM_A_CDC_COMP0_B3_CTL (0x36A) +#define TOMTOM_A_CDC_COMP0_B3_CTL__POR (0x28) +#define TOMTOM_A_CDC_COMP1_B3_CTL (0x372) +#define TOMTOM_A_CDC_COMP1_B3_CTL__POR (0x28) +#define TOMTOM_A_CDC_COMP2_B3_CTL (0x37A) +#define TOMTOM_A_CDC_COMP2_B3_CTL__POR (0x28) +#define TOMTOM_A_CDC_COMP0_B4_CTL (0x36B) +#define TOMTOM_A_CDC_COMP0_B4_CTL__POR (0x37) +#define TOMTOM_A_CDC_COMP1_B4_CTL (0x373) +#define TOMTOM_A_CDC_COMP1_B4_CTL__POR (0x37) +#define TOMTOM_A_CDC_COMP2_B4_CTL (0x37B) +#define TOMTOM_A_CDC_COMP2_B4_CTL__POR (0x37) +#define TOMTOM_A_CDC_COMP0_B5_CTL (0x36C) +#define TOMTOM_A_CDC_COMP0_B5_CTL__POR (0x7F) +#define TOMTOM_A_CDC_COMP1_B5_CTL (0x374) +#define TOMTOM_A_CDC_COMP1_B5_CTL__POR (0x7F) +#define TOMTOM_A_CDC_COMP2_B5_CTL (0x37C) +#define TOMTOM_A_CDC_COMP2_B5_CTL__POR (0x7F) +#define TOMTOM_A_CDC_COMP0_B6_CTL (0x36D) +#define TOMTOM_A_CDC_COMP0_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_COMP1_B6_CTL (0x375) +#define TOMTOM_A_CDC_COMP1_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_COMP2_B6_CTL (0x37D) +#define TOMTOM_A_CDC_COMP2_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_COMP0_SHUT_DOWN_STATUS (0x36E) +#define TOMTOM_A_CDC_COMP0_SHUT_DOWN_STATUS__POR (0x03) +#define TOMTOM_A_CDC_COMP1_SHUT_DOWN_STATUS (0x376) +#define TOMTOM_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x03) +#define TOMTOM_A_CDC_COMP2_SHUT_DOWN_STATUS (0x37E) +#define TOMTOM_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x03) +#define TOMTOM_A_CDC_COMP0_FS_CFG (0x36F) +#define TOMTOM_A_CDC_COMP0_FS_CFG__POR (0x03) +#define TOMTOM_A_CDC_COMP1_FS_CFG (0x377) +#define TOMTOM_A_CDC_COMP1_FS_CFG__POR (0x03) +#define TOMTOM_A_CDC_COMP2_FS_CFG (0x37F) +#define TOMTOM_A_CDC_COMP2_FS_CFG__POR (0x03) +#define TOMTOM_A_CDC_CONN_RX1_B1_CTL (0x380) +#define TOMTOM_A_CDC_CONN_RX1_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX1_B2_CTL (0x381) +#define TOMTOM_A_CDC_CONN_RX1_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX1_B3_CTL (0x382) +#define TOMTOM_A_CDC_CONN_RX1_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX2_B1_CTL (0x383) +#define TOMTOM_A_CDC_CONN_RX2_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX2_B2_CTL (0x384) +#define TOMTOM_A_CDC_CONN_RX2_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX2_B3_CTL (0x385) +#define TOMTOM_A_CDC_CONN_RX2_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX3_B1_CTL (0x386) +#define TOMTOM_A_CDC_CONN_RX3_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX3_B2_CTL (0x387) +#define TOMTOM_A_CDC_CONN_RX3_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX4_B1_CTL (0x388) +#define TOMTOM_A_CDC_CONN_RX4_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX4_B2_CTL (0x389) +#define TOMTOM_A_CDC_CONN_RX4_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX5_B1_CTL (0x38A) +#define TOMTOM_A_CDC_CONN_RX5_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX5_B2_CTL (0x38B) +#define TOMTOM_A_CDC_CONN_RX5_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX6_B1_CTL (0x38C) +#define TOMTOM_A_CDC_CONN_RX6_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX6_B2_CTL (0x38D) +#define TOMTOM_A_CDC_CONN_RX6_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX7_B1_CTL (0x38E) +#define TOMTOM_A_CDC_CONN_RX7_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX7_B2_CTL (0x38F) +#define TOMTOM_A_CDC_CONN_RX7_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX7_B3_CTL (0x390) +#define TOMTOM_A_CDC_CONN_RX7_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_ANC_B1_CTL (0x391) +#define TOMTOM_A_CDC_CONN_ANC_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_ANC_B2_CTL (0x392) +#define TOMTOM_A_CDC_CONN_ANC_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_B1_CTL (0x393) +#define TOMTOM_A_CDC_CONN_TX_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_B2_CTL (0x394) +#define TOMTOM_A_CDC_CONN_TX_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_B3_CTL (0x395) +#define TOMTOM_A_CDC_CONN_TX_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_B4_CTL (0x396) +#define TOMTOM_A_CDC_CONN_TX_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ1_B1_CTL (0x397) +#define TOMTOM_A_CDC_CONN_EQ1_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ1_B2_CTL (0x398) +#define TOMTOM_A_CDC_CONN_EQ1_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ1_B3_CTL (0x399) +#define TOMTOM_A_CDC_CONN_EQ1_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ1_B4_CTL (0x39A) +#define TOMTOM_A_CDC_CONN_EQ1_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ2_B1_CTL (0x39B) +#define TOMTOM_A_CDC_CONN_EQ2_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ2_B2_CTL (0x39C) +#define TOMTOM_A_CDC_CONN_EQ2_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ2_B3_CTL (0x39D) +#define TOMTOM_A_CDC_CONN_EQ2_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_EQ2_B4_CTL (0x39E) +#define TOMTOM_A_CDC_CONN_EQ2_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_SRC1_B1_CTL (0x39F) +#define TOMTOM_A_CDC_CONN_SRC1_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_SRC1_B2_CTL (0x3A0) +#define TOMTOM_A_CDC_CONN_SRC1_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_SRC2_B1_CTL (0x3A1) +#define TOMTOM_A_CDC_CONN_SRC2_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_SRC2_B2_CTL (0x3A2) +#define TOMTOM_A_CDC_CONN_SRC2_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B1_CTL (0x3A3) +#define TOMTOM_A_CDC_CONN_TX_SB_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B2_CTL (0x3A4) +#define TOMTOM_A_CDC_CONN_TX_SB_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B3_CTL (0x3A5) +#define TOMTOM_A_CDC_CONN_TX_SB_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B4_CTL (0x3A6) +#define TOMTOM_A_CDC_CONN_TX_SB_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B5_CTL (0x3A7) +#define TOMTOM_A_CDC_CONN_TX_SB_B5_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B6_CTL (0x3A8) +#define TOMTOM_A_CDC_CONN_TX_SB_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B7_CTL (0x3A9) +#define TOMTOM_A_CDC_CONN_TX_SB_B7_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B8_CTL (0x3AA) +#define TOMTOM_A_CDC_CONN_TX_SB_B8_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B9_CTL (0x3AB) +#define TOMTOM_A_CDC_CONN_TX_SB_B9_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B10_CTL (0x3AC) +#define TOMTOM_A_CDC_CONN_TX_SB_B10_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_TX_SB_B11_CTL (0x3AD) +#define TOMTOM_A_CDC_CONN_TX_SB_B11_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX_SB_B1_CTL (0x3AE) +#define TOMTOM_A_CDC_CONN_RX_SB_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_RX_SB_B2_CTL (0x3AF) +#define TOMTOM_A_CDC_CONN_RX_SB_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_CLSH_CTL (0x3B0) +#define TOMTOM_A_CDC_CONN_CLSH_CTL__POR (0x00) +#define TOMTOM_A_CDC_CONN_MISC (0x3B1) +#define TOMTOM_A_CDC_CONN_MISC__POR (0x01) +#define TOMTOM_A_CDC_CONN_RX8_B1_CTL (0x3B3) +#define TOMTOM_A_CDC_CONN_RX8_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_B1_CTL (0x3B4) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_B1_CTL__POR (0x81) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_CLIP_LEVEL_ADJUST (0x3B5) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_CLIP_LEVEL_ADJUST__POR (0x00) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_MIN_CLIP_THRESHOLD (0x3B6) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_MIN_CLIP_THRESHOLD__POR (0xFF) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_THRESHOLD_STATUS (0x3B7) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_THRESHOLD_STATUS__POR (0x00) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_SAMPLE_MARK (0x3B8) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_SAMPLE_MARK__POR (0x04) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_BOOST_GATING (0x3B9) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR_BOOST_GATING__POR (0x04) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_B1_CTL (0x3BA) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_B1_CTL__POR (0x81) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_CLIP_LEVEL_ADJUST (0x3BB) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_CLIP_LEVEL_ADJUST__POR (0x00) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_MIN_CLIP_THRESHOLD (0x3BC) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_MIN_CLIP_THRESHOLD__POR (0xFF) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_THRESHOLD_STATUS (0x3BD) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_THRESHOLD_STATUS__POR (0x00) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_SAMPLE_MARK (0x3BE) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_SAMPLE_MARK__POR (0x04) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_BOOST_GATING (0x3BF) +#define TOMTOM_A_CDC_CLIP_ADJ_SPKR2_BOOST_GATING__POR (0x04) +#define TOMTOM_A_CDC_MBHC_EN_CTL (0x3C0) +#define TOMTOM_A_CDC_MBHC_EN_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_FIR_B1_CFG (0x3C1) +#define TOMTOM_A_CDC_MBHC_FIR_B1_CFG__POR (0x00) +#define TOMTOM_A_CDC_MBHC_FIR_B2_CFG (0x3C2) +#define TOMTOM_A_CDC_MBHC_FIR_B2_CFG__POR (0x06) +#define TOMTOM_A_CDC_MBHC_TIMER_B1_CTL (0x3C3) +#define TOMTOM_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03) +#define TOMTOM_A_CDC_MBHC_TIMER_B2_CTL (0x3C4) +#define TOMTOM_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09) +#define TOMTOM_A_CDC_MBHC_TIMER_B3_CTL (0x3C5) +#define TOMTOM_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E) +#define TOMTOM_A_CDC_MBHC_TIMER_B4_CTL (0x3C6) +#define TOMTOM_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45) +#define TOMTOM_A_CDC_MBHC_TIMER_B5_CTL (0x3C7) +#define TOMTOM_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04) +#define TOMTOM_A_CDC_MBHC_TIMER_B6_CTL (0x3C8) +#define TOMTOM_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78) +#define TOMTOM_A_CDC_MBHC_B1_STATUS (0x3C9) +#define TOMTOM_A_CDC_MBHC_B1_STATUS__POR (0x00) +#define TOMTOM_A_CDC_MBHC_B2_STATUS (0x3CA) +#define TOMTOM_A_CDC_MBHC_B2_STATUS__POR (0x00) +#define TOMTOM_A_CDC_MBHC_B3_STATUS (0x3CB) +#define TOMTOM_A_CDC_MBHC_B3_STATUS__POR (0x00) +#define TOMTOM_A_CDC_MBHC_B4_STATUS (0x3CC) +#define TOMTOM_A_CDC_MBHC_B4_STATUS__POR (0x00) +#define TOMTOM_A_CDC_MBHC_B5_STATUS (0x3CD) +#define TOMTOM_A_CDC_MBHC_B5_STATUS__POR (0x00) +#define TOMTOM_A_CDC_MBHC_B1_CTL (0x3CE) +#define TOMTOM_A_CDC_MBHC_B1_CTL__POR (0xC0) +#define TOMTOM_A_CDC_MBHC_B2_CTL (0x3CF) +#define TOMTOM_A_CDC_MBHC_B2_CTL__POR (0x5D) +#define TOMTOM_A_CDC_MBHC_VOLT_B1_CTL (0x3D0) +#define TOMTOM_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B2_CTL (0x3D1) +#define TOMTOM_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B3_CTL (0x3D2) +#define TOMTOM_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B4_CTL (0x3D3) +#define TOMTOM_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B5_CTL (0x3D4) +#define TOMTOM_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B6_CTL (0x3D5) +#define TOMTOM_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B7_CTL (0x3D6) +#define TOMTOM_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF) +#define TOMTOM_A_CDC_MBHC_VOLT_B8_CTL (0x3D7) +#define TOMTOM_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07) +#define TOMTOM_A_CDC_MBHC_VOLT_B9_CTL (0x3D8) +#define TOMTOM_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF) +#define TOMTOM_A_CDC_MBHC_VOLT_B10_CTL (0x3D9) +#define TOMTOM_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F) +#define TOMTOM_A_CDC_MBHC_VOLT_B11_CTL (0x3DA) +#define TOMTOM_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_VOLT_B12_CTL (0x3DB) +#define TOMTOM_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80) +#define TOMTOM_A_CDC_MBHC_CLK_CTL (0x3DC) +#define TOMTOM_A_CDC_MBHC_CLK_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_INT_CTL (0x3DD) +#define TOMTOM_A_CDC_MBHC_INT_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_DEBUG_CTL (0x3DE) +#define TOMTOM_A_CDC_MBHC_DEBUG_CTL__POR (0x00) +#define TOMTOM_A_CDC_MBHC_SPARE (0x3DF) +#define TOMTOM_A_CDC_MBHC_SPARE__POR (0x00) +#define TOMTOM_A_CDC_RX8_B1_CTL (0x3E0) +#define TOMTOM_A_CDC_RX8_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX8_B2_CTL (0x3E1) +#define TOMTOM_A_CDC_RX8_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX8_B3_CTL (0x3E2) +#define TOMTOM_A_CDC_RX8_B3_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX8_B4_CTL (0x3E3) +#define TOMTOM_A_CDC_RX8_B4_CTL__POR (0x0B) +#define TOMTOM_A_CDC_RX8_B5_CTL (0x3E4) +#define TOMTOM_A_CDC_RX8_B5_CTL__POR (0x78) +#define TOMTOM_A_CDC_RX8_B6_CTL (0x3E5) +#define TOMTOM_A_CDC_RX8_B6_CTL__POR (0x80) +#define TOMTOM_A_CDC_RX8_VOL_CTL_B1_CTL (0x3E6) +#define TOMTOM_A_CDC_RX8_VOL_CTL_B1_CTL__POR (0x00) +#define TOMTOM_A_CDC_RX8_VOL_CTL_B2_CTL (0x3E7) +#define TOMTOM_A_CDC_RX8_VOL_CTL_B2_CTL__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL0 (0x3E8) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL0__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL1 (0x3E9) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL1__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL2 (0x3EA) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL2__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL3 (0x3EB) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL3__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL4 (0x3EC) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL4__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL5 (0x3ED) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL5__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL6 (0x3EE) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL6__POR (0x00) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL7 (0x3EF) +#define TOMTOM_A_CDC_SPKR2_CLIPDET_VAL7__POR (0x00) +#define TOMTOM_A_CDC_BOOST_MODE_CTL (0x3F0) +#define TOMTOM_A_CDC_BOOST_MODE_CTL__POR (0x00) +#define TOMTOM_A_CDC_BOOST_THRESHOLD (0x3F1) +#define TOMTOM_A_CDC_BOOST_THRESHOLD__POR (0x02) +#define TOMTOM_A_CDC_BOOST_TAP_SEL (0x3F2) +#define TOMTOM_A_CDC_BOOST_TAP_SEL__POR (0x00) +#define TOMTOM_A_CDC_BOOST_HOLD_TIME (0x3F3) +#define TOMTOM_A_CDC_BOOST_HOLD_TIME__POR (0x02) +#define TOMTOM_A_CDC_BOOST_TRGR_EN (0x3F4) +#define TOMTOM_A_CDC_BOOST_TRGR_EN__POR (0x00) + +/* SLIMBUS Slave Registers */ +#define TOMTOM_SLIM_PGD_PORT_INT_EN0 (0x30) +#define TOMTOM_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34) +#define TOMTOM_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35) +#define TOMTOM_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36) +#define TOMTOM_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37) +#define TOMTOM_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38) +#define TOMTOM_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39) +#define TOMTOM_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A) +#define TOMTOM_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B) +#define TOMTOM_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60) +#define TOMTOM_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70) + +/* Macros for Packing Register Writes into a U32 */ +#define TOMTOM_PACKED_REG_SIZE sizeof(u32) + +#define TOMTOM_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\ + ((mask & 0xff) << 8)|((reg & 0xffff) << 16)) +#define TOMTOM_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \ + do { \ + ((reg) = ((packed >> 16) & (0xffff))); \ + ((mask) = ((packed >> 8) & (0xff))); \ + ((val) = ((packed) & (0xff))); \ + } while (0) + +#define TOMTOM_SB_PGD_PORT_TX_BASE 0x50 +#define TOMTOM_SB_PGD_PORT_RX_BASE 0x40 +#define WCD9330_MAX_REGISTER 0x3FF +extern const u8 tomtom_reg_readable[WCD9330_MAX_REGISTER + 1]; +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h b/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h new file mode 100644 index 000000000000..f1b7a4320ad1 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-irq.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2016, 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. + */ + +#include <linux/types.h> +#include <linux/mfd/wcd9xxx/core.h> + +#ifndef __MFD_WCD9XXX_IRQ_H +#define __MFD_WCD9XXX_IRQ_H +bool wcd9xxx_lock_sleep(struct wcd9xxx_core_resource *); +void wcd9xxx_unlock_sleep(struct wcd9xxx_core_resource *); +void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *); +void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *); +int wcd9xxx_request_irq(struct wcd9xxx_core_resource *, int, + irq_handler_t, const char *, void *); + +void wcd9xxx_free_irq(struct wcd9xxx_core_resource *, int, void*); +void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *, int); +void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *, int); +void wcd9xxx_disable_irq_sync(struct wcd9xxx_core_resource *, int); + +int wcd9xxx_irq_init(struct wcd9xxx_core_resource *); +void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *); +#endif diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h new file mode 100755 index 000000000000..96fdb00a2e03 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h @@ -0,0 +1,119 @@ +/* Copyright (c) 2012-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 __WCD9310_SLIMSLAVE_H_ +#define __WCD9310_SLIMSLAVE_H_ + +#include <linux/slimbus/slimbus.h> +#include <linux/mfd/wcd9xxx/core.h> + + +/* + * client is expected to give port ids in the range of + * 1-10 for pre Taiko Tx ports and 1-16 for Taiko + * 1-7 for pre Taiko Rx ports and 1-16 for Tako, + * we need to add offset for getting the absolute slave + * port id before configuring the HW + */ +#define TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10 +#define TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 16 + +#define SLIM_MAX_TX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \ + TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS +#define TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \ + TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7 +#define TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 13 + +#define SLIM_MAX_RX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS + +#define SLIM_MAX_REG_ADDR (0x180 + 4 * (SLIM_MAX_RX_PORTS)) + +#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \ + TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS +#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \ + TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS + +#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 16 +#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 31 + +#define TABLA_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 9 +#define TAIKO_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 15 + +/* below details are taken from SLIMBUS slave SWI */ +#define SB_PGD_PORT_BASE 0x000 + +#define SB_PGD_PORT_CFG_BYTE_ADDR(offset, port_num) \ + (SB_PGD_PORT_BASE + offset + (1 * port_num)) + +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0(port_num) \ + (SB_PGD_PORT_BASE + 0x100 + 4*port_num) +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_START_PORT_ID 0 +#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID 7 + +#define SB_PGD_TX_PORT_MULTI_CHANNEL_1(port_num) \ + (SB_PGD_PORT_BASE + 0x101 + 4*port_num) +#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID 8 + +#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(offset, port_num) \ + (SB_PGD_PORT_BASE + offset + (4 * port_num)) + +/* slave port water mark level + * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes) + */ +#define SLAVE_PORT_WATER_MARK_6BYTES 0 +#define SLAVE_PORT_WATER_MARK_9BYTES 1 +#define SLAVE_PORT_WATER_MARK_12BYTES 2 +#define SLAVE_PORT_WATER_MARK_15BYTES 3 +#define SLAVE_PORT_WATER_MARK_SHIFT 1 +#define SLAVE_PORT_ENABLE 1 +#define SLAVE_PORT_DISABLE 0 +#define WATER_MARK_VAL \ + ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \ + (SLAVE_PORT_ENABLE)) +#define BASE_CH_NUM 128 + + +int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, + u8 wcd9xxx_pgd_la, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot); + +int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx); + +int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph); +int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, + unsigned int rate, unsigned int bit_width, + u16 *grph); +int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx, + unsigned int *rx_ch, + unsigned int *tx_ch); +int wcd9xxx_get_slave_port(unsigned int ch_num); +int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx, + struct list_head *wcd9xxx_ch_list, u16 grph); +int wcd9xxx_rx_vport_validation(u32 port_id, + struct list_head *codec_dai_list); +int wcd9xxx_tx_vport_validation(u32 vtable, u32 port_id, + struct wcd9xxx_codec_dai_data *codec_dai, + u32 num_codec_dais); +#endif /* __WCD9310_SLIMSLAVE_H_ */ diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h b/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h new file mode 100644 index 000000000000..7c35d7fecc50 --- /dev/null +++ b/include/linux/mfd/wcd9xxx/wcd9xxx-utils.h @@ -0,0 +1,141 @@ +/* Copyright (c) 2016, 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 __WCD9XXX_UTILS_H__ +#define __WCD9XXX_UTILS_H__ + +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/regmap.h> +#include <linux/mfd/wcd9xxx/pdata.h> +#include <linux/mfd/wcd9xxx/core.h> + +struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev); +int wcd9xxx_bringup(struct device *dev); +int wcd9xxx_bringdown(struct device *dev); +struct regmap *wcd9xxx_regmap_init(struct device *, + const struct regmap_config *); +int wcd9xxx_reset(struct device *dev); +int wcd9xxx_reset_low(struct device *dev); +int wcd9xxx_get_codec_info(struct device *dev); + +typedef int (*codec_bringup_fn)(struct wcd9xxx *); +typedef int (*codec_bringdown_fn)(struct wcd9xxx *); +typedef int (*codec_type_fn)(struct wcd9xxx *, + struct wcd9xxx_codec_type *); + +#ifdef CONFIG_WCD934X_CODEC +extern int wcd934x_bringup(struct wcd9xxx *wcd9xxx); +extern int wcd934x_bringdown(struct wcd9xxx *wcd9xxx); +extern int wcd934x_get_codec_info(struct wcd9xxx *, + struct wcd9xxx_codec_type *); +#endif + +#ifdef CONFIG_WCD9335_CODEC +extern int wcd9335_bringup(struct wcd9xxx *wcd9xxx); +extern int wcd9335_bringdown(struct wcd9xxx *wcd9xxx); +extern int wcd9335_get_codec_info(struct wcd9xxx *, + struct wcd9xxx_codec_type *); +#endif + +#ifdef CONFIG_WCD9330_CODEC +extern int wcd9330_bringup(struct wcd9xxx *wcd9xxx); +extern int wcd9330_bringdown(struct wcd9xxx *wcd9xxx); +extern int wcd9330_get_codec_info(struct wcd9xxx *, + struct wcd9xxx_codec_type *); +#endif + +static inline codec_bringdown_fn wcd9xxx_bringdown_fn(int type) +{ + codec_bringdown_fn cdc_bdown_fn; + + switch (type) { +#ifdef CONFIG_WCD934X_CODEC + case WCD934X: + cdc_bdown_fn = wcd934x_bringdown; + break; +#endif +#ifdef CONFIG_WCD9335_CODEC + case WCD9335: + cdc_bdown_fn = wcd9335_bringdown; + break; +#endif +#ifdef CONFIG_WCD9330_CODEC + case WCD9330: + cdc_bdown_fn = wcd9330_bringdown; + break; +#endif + default: + cdc_bdown_fn = NULL; + break; + } + + return cdc_bdown_fn; +} + +static inline codec_bringup_fn wcd9xxx_bringup_fn(int type) +{ + codec_bringup_fn cdc_bup_fn; + + switch (type) { +#ifdef CONFIG_WCD934X_CODEC + case WCD934X: + cdc_bup_fn = wcd934x_bringup; + break; +#endif +#ifdef CONFIG_WCD9335_CODEC + case WCD9335: + cdc_bup_fn = wcd9335_bringup; + break; +#endif +#ifdef CONFIG_WCD9330_CODEC + case WCD9330: + cdc_bup_fn = wcd9330_bringup; + break; +#endif + default: + cdc_bup_fn = NULL; + break; + } + + return cdc_bup_fn; +} + +static inline codec_type_fn wcd9xxx_get_codec_info_fn(int type) +{ + codec_type_fn cdc_type_fn; + + switch (type) { +#ifdef CONFIG_WCD934X_CODEC + case WCD934X: + cdc_type_fn = wcd934x_get_codec_info; + break; +#endif +#ifdef CONFIG_WCD9335_CODEC + case WCD9335: + cdc_type_fn = wcd9335_get_codec_info; + break; +#endif +#ifdef CONFIG_WCD9330_CODEC + case WCD9330: + cdc_type_fn = wcd9330_get_codec_info; + break; +#endif + default: + cdc_type_fn = NULL; + break; + } + + return cdc_type_fn; +} +#endif + diff --git a/include/linux/migrate.h b/include/linux/migrate.h index cac1c0904d5f..43d5deb0c4cc 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -23,9 +23,13 @@ enum migrate_reason { MR_SYSCALL, /* also applies to cpusets */ MR_MEMPOLICY_MBIND, MR_NUMA_MISPLACED, - MR_CMA + MR_CMA, + MR_TYPES }; +/* In mm/debug.c; also keep sync with include/trace/events/migrate.h */ +extern char *migrate_reason_names[MR_TYPES]; + #ifdef CONFIG_MIGRATION extern void putback_movable_pages(struct list_head *l); @@ -33,6 +37,8 @@ extern int migrate_page(struct address_space *, struct page *, struct page *, enum migrate_mode); extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free, unsigned long private, enum migrate_mode mode, int reason); +extern int isolate_movable_page(struct page *page, isolate_mode_t mode); +extern void putback_movable_page(struct page *page); extern int migrate_prep(void); extern int migrate_prep_local(void); @@ -65,6 +71,21 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, #endif /* CONFIG_MIGRATION */ +#ifdef CONFIG_COMPACTION +extern int PageMovable(struct page *page); +extern void __SetPageMovable(struct page *page, struct address_space *mapping); +extern void __ClearPageMovable(struct page *page); +#else +static inline int PageMovable(struct page *page) { return 0; }; +static inline void __SetPageMovable(struct page *page, + struct address_space *mapping) +{ +} +static inline void __ClearPageMovable(struct page *page) +{ +} +#endif + #ifdef CONFIG_NUMA_BALANCING extern bool pmd_trans_migrating(pmd_t pmd); extern int migrate_misplaced_page(struct page *page, diff --git a/include/linux/mm.h b/include/linux/mm.h index a24043be7991..b6ad99903617 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -29,6 +29,7 @@ struct file_ra_state; struct user_struct; struct writeback_control; struct bdi_writeback; +struct super_block; #ifndef CONFIG_NEED_MULTIPLE_NODES /* Don't use mapnrs, do it properly */ extern unsigned long max_mapnr; @@ -393,16 +394,16 @@ unsigned long vmalloc_to_pfn(const void *addr); * On nommu, vmalloc/vfree wrap through kmalloc/kfree directly, so there * is no special casing required. */ -static inline int is_vmalloc_addr(const void *x) -{ -#ifdef CONFIG_MMU - unsigned long addr = (unsigned long)x; - return addr >= VMALLOC_START && addr < VMALLOC_END; +#ifdef CONFIG_MMU +extern int is_vmalloc_addr(const void *x); #else +static inline int is_vmalloc_addr(const void *x) +{ return 0; -#endif } +#endif + #ifdef CONFIG_MMU extern int is_vmalloc_or_module_addr(const void *x); #else @@ -557,7 +558,6 @@ void put_page(struct page *page); void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); -int split_free_page(struct page *page); /* * Compound pages have a destructor function. Provide a @@ -1023,6 +1023,7 @@ static inline int page_mapped(struct page *page) { return atomic_read(&(page)->_mapcount) >= 0; } +struct address_space *page_mapping(struct page *page); /* * Return true only if the page has been allocated with @@ -2012,8 +2013,11 @@ vm_unmapped_area(struct vm_unmapped_area_info *info) /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); +extern void truncate_inode_pages_fill_zero(struct address_space *, loff_t); extern void truncate_inode_pages_range(struct address_space *, loff_t lstart, loff_t lend); +extern void truncate_inode_pages_range_fill_zero(struct address_space *, + loff_t lstart, loff_t lend); extern void truncate_inode_pages_final(struct address_space *); /* generic vm_area_ops exported for stackable file systems */ @@ -2026,7 +2030,7 @@ int write_one_page(struct page *page, int wait); void task_dirty_inc(struct task_struct *tsk); /* readahead.c */ -#define VM_MAX_READAHEAD 128 /* kbytes */ +#define VM_MAX_READAHEAD CONFIG_VM_MAX_READAHEAD /* kbytes */ #define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ int force_page_cache_readahead(struct address_space *mapping, struct file *filp, @@ -2196,6 +2200,17 @@ static inline void vm_stat_account(struct mm_struct *mm, } #endif /* CONFIG_PROC_FS */ +#ifdef CONFIG_PAGE_POISONING +extern bool page_poisoning_enabled(void); +extern void kernel_poison_pages(struct page *page, int numpages, int enable); +extern bool page_is_poisoned(struct page *page); +#else +static inline bool page_poisoning_enabled(void) { return false; } +static inline void kernel_poison_pages(struct page *page, int numpages, + int enable) { } +static inline bool page_is_poisoned(struct page *page) { return false; } +#endif + #ifdef CONFIG_DEBUG_PAGEALLOC extern bool _debug_pagealloc_enabled; extern void __kernel_map_pages(struct page *page, int numpages, int enable); @@ -2253,6 +2268,8 @@ int drop_caches_sysctl_handler(struct ctl_table *, int, void drop_slab(void); void drop_slab_node(int nid); +void drop_pagecache_sb(struct super_block *sb, void *unused); + #ifndef CONFIG_MMU #define randomize_va_space 0 #else @@ -2347,7 +2364,6 @@ extern void copy_user_huge_page(struct page *dst, struct page *src, #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ extern struct page_ext_operations debug_guardpage_ops; -extern struct page_ext_operations page_poisoning_ops; #ifdef CONFIG_DEBUG_PAGEALLOC extern unsigned int _debug_guardpage_minorder; @@ -2385,5 +2401,19 @@ void __init setup_nr_node_ids(void); static inline void setup_nr_node_ids(void) {} #endif +#ifdef CONFIG_PROCESS_RECLAIM +struct reclaim_param { + struct vm_area_struct *vma; + /* Number of pages scanned */ + int nr_scanned; + /* max pages to reclaim */ + int nr_to_reclaim; + /* pages reclaimed */ + int nr_reclaimed; +}; +extern struct reclaim_param reclaim_task_anon(struct task_struct *task, + int nr_to_reclaim); +#endif + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index e368ab06d63d..29c17fae9bbf 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -208,6 +208,10 @@ struct page { not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ +#ifdef CONFIG_BLK_DEV_IO_TRACE + struct task_struct *tsk_dirty; /* task that sets this page dirty */ +#endif + #ifdef CONFIG_KMEMCHECK /* * kmemcheck wants to track the status of each byte in a page; this @@ -524,6 +528,10 @@ struct mm_struct { #ifdef CONFIG_HUGETLB_PAGE atomic_long_t hugetlb_usage; #endif +#ifdef CONFIG_MSM_APP_SETTINGS + int app_setting; +#endif + struct work_struct async_put_work; }; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8f23fb2c5ed2..8e76f46adde3 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -12,7 +12,11 @@ #include <linux/device.h> #include <linux/mmc/core.h> +#include <linux/mmc/mmc.h> #include <linux/mod_devicetable.h> +#include <linux/notifier.h> + +#define MMC_CARD_CMDQ_BLK_SIZE 512 struct mmc_cid { unsigned int manfid; @@ -52,6 +56,7 @@ struct mmc_ext_csd { u8 sec_feature_support; u8 rel_sectors; u8 rel_param; + bool enhanced_rpmb_supported; u8 part_config; u8 cache_ctrl; u8 rst_n_function; @@ -83,11 +88,13 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - bool man_bkops_en; /* manual bkops enable bit */ + u8 bkops_en; /* bkops enable */ unsigned int data_sector_size; /* 512 bytes or 4KB */ unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ bool boot_ro_lockable; + u8 raw_ext_csd_cmdq; /* 15 */ + u8 raw_ext_csd_cache_ctrl; /* 33 */ bool ffu_capable; /* Firmware upgrade support */ #define MMC_FIRMWARE_LEN 8 u8 fwrev[MMC_FIRMWARE_LEN]; /* FW version */ @@ -95,6 +102,10 @@ struct mmc_ext_csd { u8 raw_partition_support; /* 160 */ u8 raw_rpmb_size_mult; /* 168 */ u8 raw_erased_mem_count; /* 181 */ + u8 raw_ext_csd_bus_width; /* 183 */ + u8 strobe_support; /* 184 */ +#define MMC_STROBE_SUPPORT (1 << 0) + u8 raw_ext_csd_hs_timing; /* 185 */ u8 raw_ext_csd_structure; /* 194 */ u8 raw_card_type; /* 196 */ u8 raw_driver_strength; /* 197 */ @@ -116,12 +127,19 @@ struct mmc_ext_csd { u8 raw_pwr_cl_ddr_52_195; /* 238 */ u8 raw_pwr_cl_ddr_52_360; /* 239 */ u8 raw_pwr_cl_ddr_200_360; /* 253 */ + u8 cache_flush_policy; /* 240 */ +#define MMC_BKOPS_URGENCY_MASK 0x3 u8 raw_bkops_status; /* 246 */ u8 raw_sectors[4]; /* 212 - 4 bytes */ u8 pre_eol_info; /* 267 */ u8 device_life_time_est_typ_a; /* 268 */ u8 device_life_time_est_typ_b; /* 269 */ + u8 cmdq_depth; /* 307 */ + u8 cmdq_support; /* 308 */ + u8 barrier_support; /* 486 */ + u8 barrier_en; + u8 fw_version; /* 254 */ unsigned int feature_support; #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ }; @@ -192,7 +210,8 @@ struct sdio_cccr { wide_bus:1, high_power:1, high_speed:1, - disable_cd:1; + disable_cd:1, + async_intr_sup:1; }; struct sdio_cis { @@ -221,6 +240,28 @@ enum mmc_blk_status { MMC_BLK_NEW_REQUEST, }; +enum mmc_packed_stop_reasons { + EXCEEDS_SEGMENTS = 0, + EXCEEDS_SECTORS, + WRONG_DATA_DIR, + FLUSH_OR_DISCARD, + EMPTY_QUEUE, + REL_WRITE, + THRESHOLD, + LARGE_SEC_ALIGN, + RANDOM, + FUA, + MAX_REASONS, +}; + +struct mmc_wr_pack_stats { + u32 *packing_events; + u32 pack_stop_reason[MAX_REASONS]; + spinlock_t lock; + bool enabled; + bool print_in_read; +}; + /* The number of MMC physical partitions. These consist of: * boot partitions (2), general purpose partitions (4) and * RPMB partition (1) in MMC v4.4. @@ -245,6 +286,62 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_RPMB (1<<3) }; +enum { + MMC_BKOPS_NO_OP, + MMC_BKOPS_NOT_CRITICAL, + MMC_BKOPS_PERF_IMPACT, + MMC_BKOPS_CRITICAL, + MMC_BKOPS_NUM_SEVERITY_LEVELS, +}; + +/** + * struct mmc_bkops_stats - BKOPS statistics + * @lock: spinlock used for synchronizing the debugfs and the runtime accesses + * to this structure. No need to call with spin_lock_irq api + * @manual_start: number of times START_BKOPS was sent to the device + * @hpi: number of times HPI was sent to the device + * @auto_start: number of times AUTO_EN was set to 1 + * @auto_stop: number of times AUTO_EN was set to 0 + * @level: number of times the device reported the need for each level of + * bkops handling + * @enabled: control over whether statistics should be gathered + * + * This structure is used to collect statistics regarding the bkops + * configuration and use-patterns. It is collected during runtime and can be + * shown to the user via a debugfs entry. + */ +struct mmc_bkops_stats { + spinlock_t lock; + unsigned int manual_start; + unsigned int hpi; + unsigned int auto_start; + unsigned int auto_stop; + unsigned int level[MMC_BKOPS_NUM_SEVERITY_LEVELS]; + bool enabled; +}; + +/** + * struct mmc_bkops_info - BKOPS data + * @stats: statistic information regarding bkops + * @needs_check: indication whether need to check with the device + * whether it requires handling of BKOPS (CMD8) + * @needs_manual: indication whether have to send START_BKOPS + * to the device + */ +struct mmc_bkops_info { + struct mmc_bkops_stats stats; + bool needs_check; + bool needs_bkops; + u32 retry_counter; +}; + +enum mmc_pon_type { + MMC_LONG_PON = 1, + MMC_SHRT_PON, +}; + +#define MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD 6 /* microseconds */ + /* * MMC device */ @@ -252,6 +349,10 @@ struct mmc_card { struct mmc_host *host; /* the host this device belongs to */ struct device dev; /* the device */ u32 ocr; /* the current OCR setting */ + unsigned long clk_scaling_lowest; /* lowest scaleable + * frequency */ + unsigned long clk_scaling_highest; /* highest scaleable + * frequency */ unsigned int rca; /* relative card address of device */ unsigned int type; /* card type */ #define MMC_TYPE_MMC 0 /* MMC card */ @@ -264,14 +365,17 @@ struct mmc_card { #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ -#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ +#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing manual BKOPS */ #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ +#define MMC_STATE_CMDQ (1<<12) /* card is in cmd queue mode */ +#define MMC_STATE_AUTO_BKOPS (1<<13) /* card is doing auto BKOPS */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ /* for byte mode */ #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ /* (missing CIA registers) */ +#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */ #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ @@ -282,7 +386,17 @@ struct mmc_card { #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */ #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ + /* byte mode */ +#define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ +#define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ + /* broken due to HPI feature */ +#define MMC_QUIRK_CACHE_DISABLE (1 << 15) /* prevent cache enable */ +#define MMC_QUIRK_QCA6574_SETTINGS (1 << 16) /* QCA6574 card settings*/ +#define MMC_QUIRK_QCA9377_SETTINGS (1 << 17) /* QCA9377 card settings*/ + +/* Make sure CMDQ is empty before queuing DCMD */ +#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD (1 << 17) unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ @@ -316,6 +430,15 @@ struct mmc_card { struct dentry *debugfs_root; struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ unsigned int nr_parts; + unsigned int part_curr; + + struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ + struct notifier_block reboot_notify; + enum mmc_pon_type pon_type; + bool cmdq_init; + struct mmc_bkops_info bkops; + bool err_in_sdr104; + bool sdr104_blocked; }; /* @@ -356,19 +479,43 @@ struct mmc_fixup { /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */ u16 cis_vendor, cis_device; + /* MMC-specific field, You can use EXT_CSD_REV_ANY here of course */ + unsigned int ext_csd_rev; + void (*vendor_fixup)(struct mmc_card *card, int data); int data; }; +#define CID_MANFID_SANDISK 0x2 +#define CID_MANFID_TOSHIBA 0x11 +#define CID_MANFID_MICRON 0x13 +#define CID_MANFID_SAMSUNG 0x15 +#define CID_MANFID_KINGSTON 0x70 +#define CID_MANFID_HYNIX 0x90 + #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) #define CID_NAME_ANY (NULL) +#define EXT_CSD_REV_ANY (-1u) #define END_FIXUP { NULL } +/* extended CSD mapping to mmc version */ +enum mmc_version_ext_csd_rev { + MMC_V4_0, + MMC_V4_1, + MMC_V4_2, + MMC_V4_41 = 5, + MMC_V4_5, + MMC_V4_51 = MMC_V4_5, + MMC_V5_0, + MMC_V5_01 = MMC_V5_0, + MMC_V5_1 +}; + #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ _cis_vendor, _cis_device, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ { \ .name = (_name), \ .manfid = (_manfid), \ @@ -379,23 +526,30 @@ struct mmc_fixup { .cis_device = (_cis_device), \ .vendor_fixup = (_fixup), \ .data = (_data), \ + .ext_csd_rev = (_ext_csd_rev), \ } #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ _FIXUP_EXT(_name, _manfid, \ _oemid, _rev_start, _rev_end, \ SDIO_ANY_ID, SDIO_ANY_ID, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ - MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data) + MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ + EXT_CSD_REV_ANY) + +#define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \ + _ext_csd_rev) \ + MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ + _ext_csd_rev) #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ CID_OEMID_ANY, 0, -1ull, \ _vendor, _device, \ - _fixup, _data) \ + _fixup, _data, EXT_CSD_REV_ANY) \ #define cid_rev(hwrev, fwrev, year, month) \ (((u64) hwrev) << 40 | \ @@ -434,6 +588,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) +#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) +#define mmc_card_doing_auto_bkops(c) ((c)->state & MMC_STATE_AUTO_BKOPS) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -444,6 +600,12 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) +#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) +#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) +#define mmc_card_set_auto_bkops(c) ((c)->state |= MMC_STATE_AUTO_BKOPS) +#define mmc_card_clr_auto_bkops(c) ((c)->state &= ~MMC_STATE_AUTO_BKOPS) + +#define mmc_card_strobe(c) (((c)->ext_csd).strobe_support & MMC_STROBE_SUPPORT) /* * Quirk add/remove for MMC products. @@ -514,10 +676,37 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; } +static inline bool mmc_card_support_auto_bkops(const struct mmc_card *c) +{ + return c->ext_csd.rev >= MMC_V5_1; +} + +static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) +{ + return c->ext_csd.bkops_en & EXT_CSD_BKOPS_MANUAL_EN; +} + +static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) +{ + return c->ext_csd.bkops_en & EXT_CSD_BKOPS_AUTO_EN; +} + +static inline bool mmc_enable_qca6574_settings(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_QCA6574_SETTINGS; +} + +static inline bool mmc_enable_qca9377_settings(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_QCA9377_SETTINGS; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) +#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev) +#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d) /* * MMC device driver (e.g., Flash card, I/O card...) @@ -534,5 +723,9 @@ extern void mmc_unregister_driver(struct mmc_driver *); extern void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table); - +extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics( + struct mmc_card *card); +extern void mmc_blk_init_packed_statistics(struct mmc_card *card); +extern int mmc_send_pon(struct mmc_card *card); +extern void mmc_blk_cmdq_req_done(struct mmc_request *mrq); #endif /* LINUX_MMC_CARD_H */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 0860efd6e1be..ef3e628388cf 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -8,6 +8,7 @@ #ifndef LINUX_MMC_CORE_H #define LINUX_MMC_CORE_H +#include <uapi/linux/mmc/core.h> #include <linux/interrupt.h> #include <linux/completion.h> @@ -23,38 +24,6 @@ struct mmc_command { #define MMC_CMD23_ARG_TAG_REQ (1 << 29) u32 resp[4]; unsigned int flags; /* expected response type */ -#define MMC_RSP_PRESENT (1 << 0) -#define MMC_RSP_136 (1 << 1) /* 136 bit response */ -#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ -#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ -#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ - -#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */ -#define MMC_CMD_AC (0 << 5) -#define MMC_CMD_ADTC (1 << 5) -#define MMC_CMD_BC (2 << 5) -#define MMC_CMD_BCR (3 << 5) - -#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */ -#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */ -#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */ -#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */ - -/* - * These are the native response types, and correspond to valid bit - * patterns of the above flags. One additional valid pattern - * is all zeros, which means we don't expect a response. - */ -#define MMC_RSP_NONE (0) -#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) -#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R4 (MMC_RSP_PRESENT) -#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) -#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) -#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) - #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) /* @@ -98,6 +67,8 @@ struct mmc_command { unsigned int busy_timeout; /* busy detect timeout in ms */ /* Set this flag only for blocking sanitize request */ bool sanitize_busy; + /* Set this flag only for blocking bkops request */ + bool bkops_busy; struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ @@ -124,6 +95,7 @@ struct mmc_data { int sg_count; /* mapped sg entries */ struct scatterlist *sg; /* I/O scatter list */ s32 host_cookie; /* host private data */ + bool fault_injected; /* fault injected */ }; struct mmc_host; @@ -136,14 +108,49 @@ struct mmc_request { struct completion completion; void (*done)(struct mmc_request *);/* completion function */ struct mmc_host *host; - ktime_t io_start; + struct mmc_cmdq_req *cmdq_req; + struct request *req; + ktime_t io_start; #ifdef CONFIG_BLOCK - int lat_hist_enabled; + int lat_hist_enabled; #endif }; +struct mmc_bus_ops { + void (*remove)(struct mmc_host *); + void (*detect)(struct mmc_host *); + int (*pre_suspend)(struct mmc_host *); + int (*suspend)(struct mmc_host *); + int (*resume)(struct mmc_host *); + int (*runtime_suspend)(struct mmc_host *); + int (*runtime_resume)(struct mmc_host *); + int (*runtime_idle)(struct mmc_host *); + int (*power_save)(struct mmc_host *); + int (*power_restore)(struct mmc_host *); + int (*alive)(struct mmc_host *); + int (*shutdown)(struct mmc_host *); + int (*reset)(struct mmc_host *); + int (*change_bus_speed)(struct mmc_host *, unsigned long *); + int (*pre_hibernate)(struct mmc_host *); + int (*post_hibernate)(struct mmc_host *); +}; + struct mmc_card; struct mmc_async_req; +struct mmc_cmdq_req; + +extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); +extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); +extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host); +extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err); +extern int mmc_cmdq_start_req(struct mmc_host *host, + struct mmc_cmdq_req *cmdq_req); +extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); +extern int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, + struct mmc_cmdq_req *cmdq_req); +extern int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, + struct mmc_card *card, unsigned int from, unsigned int nr, + unsigned int arg); extern int mmc_stop_bkops(struct mmc_card *); extern int mmc_read_bkops_status(struct mmc_card *); @@ -155,10 +162,17 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); -extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); +extern void mmc_check_bkops(struct mmc_card *card); +extern void mmc_start_manual_bkops(struct mmc_card *card); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); +extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, + u8 value, unsigned int timeout_ms, + bool use_busy_signal, bool ignore_timeout); extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); +extern int mmc_set_auto_bkops(struct mmc_card *card, bool enable); +extern int mmc_suspend_clk_scaling(struct mmc_host *host); +extern void mmc_flush_detect_work(struct mmc_host *); #define MMC_ERASE_ARG 0x00000000 #define MMC_SECURE_ERASE_ARG 0x80000000 @@ -185,6 +199,7 @@ extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, bool is_rel_write); extern int mmc_hw_reset(struct mmc_host *host); +extern int mmc_cmdq_hw_reset(struct mmc_host *host); extern int mmc_can_reset(struct mmc_card *card); extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); @@ -192,14 +207,27 @@ extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); extern void mmc_release_host(struct mmc_host *host); +extern int mmc_try_claim_host(struct mmc_host *host, unsigned int delay); extern void mmc_get_card(struct mmc_card *card); extern void mmc_put_card(struct mmc_card *card); +extern void __mmc_put_card(struct mmc_card *card); +extern void mmc_set_ios(struct mmc_host *host); extern int mmc_flush_cache(struct mmc_card *); +extern int mmc_cache_barrier(struct mmc_card *); extern int mmc_detect_card_removed(struct mmc_host *host); +extern void mmc_blk_init_bkops_statistics(struct mmc_card *card); + +extern void mmc_deferred_scaling(struct mmc_host *host); +extern void mmc_cmdq_clk_scaling_start_busy(struct mmc_host *host, + bool lock_needed); +extern void mmc_cmdq_clk_scaling_stop_busy(struct mmc_host *host, + bool lock_needed, bool is_cmdq_dcmd); +extern int mmc_recovery_fallback_lower_speed(struct mmc_host *host); + /** * mmc_claim_host - exclusively claim a host * @host: mmc host to claim diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 46e91d4fce7e..2dff3db6e4f3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -15,15 +15,21 @@ #include <linux/timer.h> #include <linux/sched.h> #include <linux/device.h> +#include <linux/devfreq.h> #include <linux/fault-inject.h> #include <linux/blkdev.h> #include <linux/mmc/core.h> #include <linux/mmc/card.h> #include <linux/mmc/pm.h> +#include <linux/mmc/ring_buffer.h> + +#define MMC_AUTOSUSPEND_DELAY_MS 3000 struct mmc_ios { unsigned int clock; /* clock rate */ + unsigned int old_rate; /* saved clock rate */ + unsigned long clk_ts; /* time stamp of last updated clock */ unsigned short vdd; /* vdd stores the bit number of the selected voltage range from below. */ @@ -78,9 +84,35 @@ struct mmc_ios { #define MMC_SET_DRIVER_TYPE_A 1 #define MMC_SET_DRIVER_TYPE_C 2 #define MMC_SET_DRIVER_TYPE_D 3 + + bool enhanced_strobe; /* hs400es selection */ +}; + +/* states to represent load on the host */ +enum mmc_load { + MMC_LOAD_HIGH, + MMC_LOAD_LOW, +}; + +struct mmc_cmdq_host_ops { + int (*init)(struct mmc_host *host); + int (*enable)(struct mmc_host *host); + void (*disable)(struct mmc_host *host, bool soft); + int (*request)(struct mmc_host *host, struct mmc_request *mrq); + void (*post_req)(struct mmc_host *host, int tag, int err); + int (*halt)(struct mmc_host *host, bool halt); + void (*reset)(struct mmc_host *host, bool soft); + void (*dumpstate)(struct mmc_host *host); }; struct mmc_host_ops { + int (*init)(struct mmc_host *host); + /* + * 'enable' is called when the host is claimed and 'disable' is called + * when the host is released. 'enable' and 'disable' are deprecated. + */ + int (*enable)(struct mmc_host *host); + int (*disable)(struct mmc_host *host); /* * It is optional for the host to implement pre_req and post_req in * order to support double buffering of requests (prepare one @@ -133,6 +165,7 @@ struct mmc_host_ops { /* Prepare HS400 target operating frequency depending host driver */ int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); + int (*enhanced_strobe)(struct mmc_host *host); int (*select_drive_strength)(struct mmc_card *card, unsigned int max_dtr, int host_drv, int card_drv, int *drv_type); @@ -145,11 +178,46 @@ struct mmc_host_ops { */ int (*multi_io_quirk)(struct mmc_card *card, unsigned int direction, int blk_size); + + unsigned long (*get_max_frequency)(struct mmc_host *host); + unsigned long (*get_min_frequency)(struct mmc_host *host); + + int (*notify_load)(struct mmc_host *, enum mmc_load); + void (*notify_halt)(struct mmc_host *mmc, bool halt); + void (*force_err_irq)(struct mmc_host *host, u64 errmask); + int (*check_temp)(struct mmc_host *host); + int (*reg_temp_callback)(struct mmc_host *host); + int (*dereg_temp_callback)(struct mmc_host *host); }; struct mmc_card; struct device; +struct mmc_cmdq_req { + unsigned int cmd_flags; + u32 blk_addr; + /* active mmc request */ + struct mmc_request mrq; + struct mmc_data data; + struct mmc_command cmd; +#define DCMD (1 << 0) +#define QBR (1 << 1) +#define DIR (1 << 2) +#define PRIO (1 << 3) +#define REL_WR (1 << 4) +#define DAT_TAG (1 << 5) +#define FORCED_PRG (1 << 6) + unsigned int cmdq_req_flags; + + unsigned int resp_idx; + unsigned int resp_arg; + unsigned int dev_pend_tasks; + bool resp_err; + bool skip_err_handling; + int tag; /* used for command queuing */ + u8 ctx_id; +}; + struct mmc_async_req { /* active mmc request */ struct mmc_request *mrq; @@ -176,6 +244,33 @@ struct mmc_slot { void *handler_priv; }; + +/** + * mmc_cmdq_context_info - describes the contexts of cmdq + * @active_reqs requests being processed + * @data_active_reqs data requests being processed + * @curr_state state of cmdq engine + * @cmdq_ctx_lock acquire this before accessing this structure + * @queue_empty_wq workqueue for waiting for all + * the outstanding requests to be completed + * @wait waiting for all conditions described in + * mmc_cmdq_ready_wait to be satisified before + * issuing the new request to LLD. + */ +struct mmc_cmdq_context_info { + unsigned long active_reqs; /* in-flight requests */ + unsigned long data_active_reqs; /* in-flight data requests */ + unsigned long curr_state; +#define CMDQ_STATE_ERR 0 +#define CMDQ_STATE_DCMD_ACTIVE 1 +#define CMDQ_STATE_HALT 2 +#define CMDQ_STATE_CQ_DISABLE 3 +#define CMDQ_STATE_REQ_TIMED_OUT 4 + wait_queue_head_t queue_empty_wq; + wait_queue_head_t wait; + int active_small_sector_read_reqs; +}; + /** * mmc_context_info - synchronization details for mmc context * @is_done_rcv wake up reason was done request @@ -200,11 +295,70 @@ struct mmc_supply { struct regulator *vqmmc; /* Optional Vccq supply */ }; +enum dev_state { + DEV_SUSPENDING = 1, + DEV_SUSPENDED, + DEV_RESUMED, +}; + +/** + * struct mmc_devfeq_clk_scaling - main context for MMC clock scaling logic + * + * @lock: spinlock to protect statistics + * @devfreq: struct that represent mmc-host as a client for devfreq + * @devfreq_profile: MMC device profile, mostly polling interval and callbacks + * @ondemand_gov_data: struct supplied to ondemmand governor (thresholds) + * @state: load state, can be HIGH or LOW. used to notify mmc_host_ops callback + * @start_busy: timestamped armed once a data request is started + * @measure_interval_start: timestamped armed once a measure interval started + * @devfreq_abort: flag to sync between different contexts relevant to devfreq + * @skip_clk_scale_freq_update: flag that enable/disable frequency change + * @freq_table_sz: table size of frequencies supplied to devfreq + * @freq_table: frequencies table supplied to devfreq + * @curr_freq: current frequency + * @polling_delay_ms: polling interval for status collection used by devfreq + * @upthreshold: up-threshold supplied to ondemand governor + * @downthreshold: down-threshold supplied to ondemand governor + * @need_freq_change: flag indicating if a frequency change is required + * @clk_scaling_in_progress: flag indicating if there's ongoing frequency change + * @is_busy_started: flag indicating if a request is handled by the HW + * @enable: flag indicating if the clock scaling logic is enabled for this host + */ +struct mmc_devfeq_clk_scaling { + spinlock_t lock; + struct devfreq *devfreq; + struct devfreq_dev_profile devfreq_profile; + struct devfreq_simple_ondemand_data ondemand_gov_data; + enum mmc_load state; + ktime_t start_busy; + ktime_t measure_interval_start; + atomic_t devfreq_abort; + bool skip_clk_scale_freq_update; + int freq_table_sz; + int pltfm_freq_table_sz; + u32 *freq_table; + u32 *pltfm_freq_table; + unsigned long total_busy_time_us; + unsigned long target_freq; + unsigned long curr_freq; + unsigned long polling_delay_ms; + unsigned int upthreshold; + unsigned int downthreshold; + unsigned int lower_bus_speed_mode; +#define MMC_SCALING_LOWER_DDR52_MODE 1 + bool need_freq_change; + bool clk_scaling_in_progress; + bool is_busy_started; + bool enable; +}; + struct mmc_host { struct device *parent; struct device class_dev; + struct mmc_devfeq_clk_scaling clk_scaling; int index; const struct mmc_host_ops *ops; + const struct mmc_cmdq_host_ops *cmdq_ops; struct mmc_pwrseq *pwrseq; unsigned int f_min; unsigned int f_max; @@ -268,6 +422,7 @@ struct mmc_host { #define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ u32 caps2; /* More host capabilities */ + u32 cached_caps2; #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ #define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ @@ -290,9 +445,33 @@ struct mmc_host { #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ +#define MMC_CAP2_PACKED_WR_CONTROL (1 << 19) /* Allow write packing control */ +#define MMC_CAP2_CLK_SCALE (1 << 20) /* Allow dynamic clk scaling */ +/* Allows Asynchronous SDIO irq while card is in 4-bit mode */ +#define MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE (1 << 21) +/* Some hosts need additional tuning */ +#define MMC_CAP2_HS400_POST_TUNING (1 << 22) +#define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ +#define MMC_CAP2_CMD_QUEUE (1 << 26) /* support eMMC command queue */ +#define MMC_CAP2_SANITIZE (1 << 27) /* Support Sanitize */ +#define MMC_CAP2_SLEEP_AWAKE (1 << 28) /* Use Sleep/Awake (CMD5) */ +/* use max discard ignoring max_busy_timeout parameter */ +#define MMC_CAP2_MAX_DISCARD_SIZE (1 << 29) mmc_pm_flag_t pm_caps; /* supported pm features */ +#ifdef CONFIG_MMC_CLKGATE + int clk_requests; /* internal reference counter */ + unsigned int clk_delay; /* number of MCI clk hold cycles */ + bool clk_gated; /* clock gated */ + struct delayed_work clk_gate_work; /* delayed clock gate */ + unsigned int clk_old; /* old clock value cache */ + spinlock_t clk_lock; /* lock for clk fields */ + struct mutex clk_gate_mutex; /* mutex for clock gating */ + struct device_attribute clkgate_delay_attr; + unsigned long clkgate_delay; +#endif + /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_segs; /* see blk_queue_max_segments */ @@ -306,6 +485,7 @@ struct mmc_host { spinlock_t lock; /* lock for claim and bus ops */ struct mmc_ios ios; /* current io bus settings */ + struct mmc_ios cached_ios; /* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; @@ -332,6 +512,7 @@ struct mmc_host { wait_queue_head_t wq; struct task_struct *claimer; /* task that has host claimed */ + struct task_struct *suspend_task; int claim_cnt; /* "claim" nesting count */ struct delayed_work detect; @@ -341,6 +522,11 @@ struct mmc_host { const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ + unsigned int bus_resume_flags; +#define MMC_BUSRESUME_MANUAL_RESUME (1 << 0) +#define MMC_BUSRESUME_NEEDS_RESUME (1 << 1) + bool ignore_bus_resume_flags; + unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; bool sdio_irq_pending; @@ -357,6 +543,8 @@ struct mmc_host { struct dentry *debugfs_root; + bool err_occurred; + struct mmc_async_req *areq; /* active async req */ struct mmc_context_info context_info; /* async synchronization info */ @@ -379,17 +567,52 @@ struct mmc_host { int num_funcs; } embedded_sdio_data; #endif + /* + * Set to 1 to just stop the SDCLK to the card without + * actually disabling the clock from it's source. + */ + bool card_clock_off; + +#ifdef CONFIG_MMC_PERF_PROFILING + struct { + unsigned long rbytes_drv; /* Rd bytes MMC Host */ + unsigned long wbytes_drv; /* Wr bytes MMC Host */ + ktime_t rtime_drv; /* Rd time MMC Host */ + ktime_t wtime_drv; /* Wr time MMC Host */ + ktime_t start; + } perf; + bool perf_enable; +#endif + struct mmc_trace_buffer trace_buf; + enum dev_state dev_status; + bool wakeup_on_idle; + struct mmc_cmdq_context_info cmdq_ctx; + int num_cq_slots; + int dcmd_cq_slot; + bool cmdq_thist_enabled; + /* + * several cmdq supporting host controllers are extensions + * of legacy controllers. This variable can be used to store + * a reference to the cmdq extension of the existing host + * controller. + */ + void *cmdq_private; + struct mmc_request *err_mrq; #ifdef CONFIG_BLOCK int latency_hist_enabled; struct io_latency_state io_lat_read; struct io_latency_state io_lat_write; #endif + bool sdr104_wa; + atomic_t rpmb_req_pending; + struct mutex rpmb_req_mutex; unsigned long private[0] ____cacheline_aligned; }; struct mmc_host *mmc_alloc_host(int extra, struct device *); +extern bool mmc_host_may_gate_card(struct mmc_card *); int mmc_add_host(struct mmc_host *); void mmc_remove_host(struct mmc_host *); void mmc_free_host(struct mmc_host *); @@ -408,11 +631,36 @@ static inline void *mmc_priv(struct mmc_host *host) return (void *)host->private; } +static inline void *mmc_cmdq_private(struct mmc_host *host) +{ + return host->cmdq_private; +} + #define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) #define mmc_dev(x) ((x)->parent) #define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) (dev_name(&(x)->class_dev)) +#define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & \ + MMC_BUSRESUME_NEEDS_RESUME) +#define mmc_bus_manual_resume(host) ((host)->bus_resume_flags & \ + MMC_BUSRESUME_MANUAL_RESUME) + +#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME +static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual) +{ + if (manual) + host->bus_resume_flags |= MMC_BUSRESUME_MANUAL_RESUME; + else + host->bus_resume_flags &= ~MMC_BUSRESUME_MANUAL_RESUME; +} +#else +static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual) +{ +} +#endif + +extern int mmc_resume_bus(struct mmc_host *host); int mmc_power_save_host(struct mmc_host *host); int mmc_power_restore_host(struct mmc_host *host); @@ -485,6 +733,12 @@ static inline int mmc_boot_partition_access(struct mmc_host *host) return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } +static inline bool mmc_card_and_host_support_async_int(struct mmc_host *host) +{ + return (host->card && (host->caps2 & MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE) + && (host->card->cccr.async_intr_sup)); +} + static inline int mmc_host_uhs(struct mmc_host *host) { return host->caps & @@ -493,11 +747,71 @@ static inline int mmc_host_uhs(struct mmc_host *host) MMC_CAP_UHS_DDR50); } +static inline void mmc_host_clear_sdr104(struct mmc_host *host) +{ + host->caps &= ~MMC_CAP_UHS_SDR104; +} + +static inline void mmc_host_set_sdr104(struct mmc_host *host) +{ + host->caps |= MMC_CAP_UHS_SDR104; +} + static inline int mmc_host_packed_wr(struct mmc_host *host) { return host->caps2 & MMC_CAP2_PACKED_WR; } +static inline void mmc_host_set_halt(struct mmc_host *host) +{ + set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + +static inline void mmc_host_clr_halt(struct mmc_host *host) +{ + clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + +static inline int mmc_host_halt(struct mmc_host *host) +{ + return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + +static inline void mmc_host_set_cq_disable(struct mmc_host *host) +{ + set_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + +static inline void mmc_host_clr_cq_disable(struct mmc_host *host) +{ + clear_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + +static inline int mmc_host_cq_disable(struct mmc_host *host) +{ + return test_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + +#ifdef CONFIG_MMC_CLKGATE +void mmc_host_clk_hold(struct mmc_host *host); +void mmc_host_clk_release(struct mmc_host *host); +unsigned int mmc_host_clk_rate(struct mmc_host *host); + +#else +static inline void mmc_host_clk_hold(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_release(struct mmc_host *host) +{ +} + +static inline unsigned int mmc_host_clk_rate(struct mmc_host *host) +{ + return host->ios.clock; +} +#endif + static inline int mmc_card_hs(struct mmc_card *card) { return card->host->ios.timing == MMC_TIMING_SD_HS || @@ -525,6 +839,13 @@ static inline bool mmc_card_hs400(struct mmc_card *card) return card->host->ios.timing == MMC_TIMING_MMC_HS400; } +static inline bool mmc_card_hs400es(struct mmc_card *card) +{ + return card->host->ios.enhanced_strobe; +} + +void mmc_retune_enable(struct mmc_host *host); +void mmc_retune_disable(struct mmc_host *host); void mmc_retune_timer_stop(struct mmc_host *host); static inline void mmc_retune_needed(struct mmc_host *host) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 2c6b1d45626e..307a8e4be91f 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -24,65 +24,12 @@ #ifndef LINUX_MMC_MMC_H #define LINUX_MMC_MMC_H -/* Standard MMC commands (4.1) type argument response */ - /* class 1 */ -#define MMC_GO_IDLE_STATE 0 /* bc */ -#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ -#define MMC_ALL_SEND_CID 2 /* bcr R2 */ -#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ -#define MMC_SET_DSR 4 /* bc [31:16] RCA */ -#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */ -#define MMC_SWITCH 6 /* ac [31:0] See below R1b */ -#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ -#define MMC_SEND_EXT_CSD 8 /* adtc R1 */ -#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ -#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ -#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ -#define MMC_STOP_TRANSMISSION 12 /* ac R1b */ -#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ -#define MMC_BUS_TEST_R 14 /* adtc R1 */ -#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ -#define MMC_BUS_TEST_W 19 /* adtc R1 */ -#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */ -#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */ - - /* class 2 */ -#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ -#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ -#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ -#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ -#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */ - - /* class 3 */ -#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ - - /* class 4 */ -#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ -#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ -#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ -#define MMC_PROGRAM_CID 26 /* adtc R1 */ -#define MMC_PROGRAM_CSD 27 /* adtc R1 */ - - /* class 6 */ -#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ -#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ -#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ - - /* class 5 */ -#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ -#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ -#define MMC_ERASE 38 /* ac R1b */ - - /* class 9 */ -#define MMC_FAST_IO 39 /* ac <Complex> R4 */ -#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ - - /* class 7 */ -#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ - - /* class 8 */ -#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ -#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ +#include <uapi/linux/mmc/mmc.h> + +/* class 11 */ +#define MMC_CMDQ_TASK_MGMT 48 /* ac [31:0] task ID R1b */ +#define DISCARD_QUEUE 0x1 +#define DISCARD_TASK 0x2 static inline bool mmc_op_multi(u32 opcode) { @@ -223,6 +170,7 @@ struct _mmc_csd { * OCR bits are mostly in host.h */ #define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ +#define MMC_CARD_SECTOR_ADDR 0x40000000 /* Card supports sectors */ /* * Card Command Classes (CCC) @@ -272,6 +220,8 @@ struct _mmc_csd { * EXT_CSD fields */ +#define EXT_CSD_CMDQ 15 /* R/W */ +#define EXT_CSD_BARRIER_CTRL 31 /* R/W */ #define EXT_CSD_FLUSH_CACHE 32 /* W */ #define EXT_CSD_CACHE_CTRL 33 /* R/W */ #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ @@ -297,6 +247,7 @@ struct _mmc_csd { #define EXT_CSD_PART_CONFIG 179 /* R/W */ #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ +#define EXT_CSD_STROBE_SUPPORT 184 /* RO */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_POWER_CLASS 187 /* R/W */ #define EXT_CSD_REV 192 /* RO */ @@ -324,6 +275,7 @@ struct _mmc_csd { #define EXT_CSD_PWR_CL_200_360 237 /* RO */ #define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ #define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ +#define EXT_CSD_CACHE_FLUSH_POLICY 240 /* RO */ #define EXT_CSD_BKOPS_STATUS 246 /* RO */ #define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ #define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ @@ -333,6 +285,10 @@ struct _mmc_csd { #define EXT_CSD_PRE_EOL_INFO 267 /* RO */ #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */ #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */ +#define EXT_CSD_CMDQ_DEPTH 307 /* RO */ +#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ +#define EXT_CSD_BARRIER_SUPPORT 486 /* RO */ + #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ @@ -345,7 +301,8 @@ struct _mmc_csd { * EXT_CSD field definitions */ -#define EXT_CSD_WR_REL_PARAM_EN (1<<2) +#define EXT_CSD_WR_REL_PARAM_EN (1<<2) +#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1<<4) #define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) #define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) @@ -389,6 +346,7 @@ struct _mmc_csd { #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ #define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ #define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ +#define EXT_CSD_BUS_WIDTH_STROBE 0x80 /* Card is in 8 bit DDR mode */ #define EXT_CSD_TIMING_BC 0 /* Backwards compatility */ #define EXT_CSD_TIMING_HS 1 /* High speed */ @@ -416,6 +374,9 @@ struct _mmc_csd { #define EXT_CSD_PACKED_EVENT_EN BIT(3) +#define EXT_CSD_BKOPS_MANUAL_EN BIT(0) +#define EXT_CSD_BKOPS_AUTO_EN BIT(1) + /* * EXCEPTION_EVENT_STATUS field */ diff --git a/include/linux/mmc/ring_buffer.h b/include/linux/mmc/ring_buffer.h new file mode 100644 index 000000000000..e6bf163ffcfe --- /dev/null +++ b/include/linux/mmc/ring_buffer.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, 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 __MMC_RING_BUFFER__ +#define __MMC_RING_BUFFER__ + +#include <linux/mmc/card.h> +#include <linux/smp.h> + +#include "core.h" + +#define MMC_TRACE_RBUF_SZ_ORDER 2 /* 2^2 pages */ +#define MMC_TRACE_RBUF_SZ (PAGE_SIZE * (1 << MMC_TRACE_RBUF_SZ_ORDER)) +#define MMC_TRACE_EVENT_SZ 256 +#define MMC_TRACE_RBUF_NUM_EVENTS (MMC_TRACE_RBUF_SZ / MMC_TRACE_EVENT_SZ) + +struct mmc_host; +struct mmc_trace_buffer { + int wr_idx; + bool stop_tracing; + spinlock_t trace_lock; + char *data; +}; + +#ifdef CONFIG_MMC_RING_BUFFER +void mmc_stop_tracing(struct mmc_host *mmc); +void mmc_trace_write(struct mmc_host *mmc, const char *fmt, ...); +void mmc_trace_init(struct mmc_host *mmc); +void mmc_trace_free(struct mmc_host *mmc); +void mmc_dump_trace_buffer(struct mmc_host *mmc, struct seq_file *s); +#else +static inline void mmc_stop_tracing(struct mmc_host *mmc) {} +static inline void mmc_trace_write(struct mmc_host *mmc, + const char *fmt, ...) {} +static inline void mmc_trace_init(struct mmc_host *mmc) {} +static inline void mmc_trace_free(struct mmc_host *mmc) {} +static inline void mmc_dump_trace_buffer(struct mmc_host *mmc, + struct seq_file *s) {} +#endif + +#define MMC_TRACE(mmc, fmt, ...) \ + mmc_trace_write(mmc, fmt, ##__VA_ARGS__) + +#endif /* __MMC_RING_BUFFER__ */ diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index 17446d3c3602..3fc07d701cd1 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -102,6 +102,7 @@ #define SDIO_BUS_WIDTH_1BIT 0x00 #define SDIO_BUS_WIDTH_RESERVED 0x01 #define SDIO_BUS_WIDTH_4BIT 0x02 +#define SDIO_BUS_WIDTH_8BIT 0x03 #define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ #define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ @@ -163,6 +164,10 @@ #define SDIO_DTSx_SET_TYPE_A (1 << SDIO_DRIVE_DTSx_SHIFT) #define SDIO_DTSx_SET_TYPE_C (2 << SDIO_DRIVE_DTSx_SHIFT) #define SDIO_DTSx_SET_TYPE_D (3 << SDIO_DRIVE_DTSx_SHIFT) + +#define SDIO_CCCR_INTERRUPT_EXTENSION 0x16 +#define SDIO_SUPPORT_ASYNC_INTR (1<<0) +#define SDIO_ENABLE_ASYNC_INTR (1<<1) /* * Function Basic Registers (FBR) */ diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 772362adf471..053824b0a412 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -56,4 +56,10 @@ void dump_mm(const struct mm_struct *mm); #define VIRTUAL_BUG_ON(cond) do { } while (0) #endif +#ifdef CONFIG_DEBUG_VM_PGFLAGS +#define VM_BUG_ON_PGFLAGS(cond, page) VM_BUG_ON_PAGE(cond, page) +#else +#define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond) +#endif + #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 30e37183bb1b..f09c5b28ed70 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -39,8 +39,6 @@ enum { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RECLAIMABLE, - MIGRATE_PCPTYPES, /* the number of types on the pcp lists */ - MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES, #ifdef CONFIG_CMA /* * MIGRATE_CMA migration type is designed to mimic the way @@ -57,17 +55,34 @@ enum { */ MIGRATE_CMA, #endif + MIGRATE_PCPTYPES, /* the number of types on the pcp lists */ + MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES, #ifdef CONFIG_MEMORY_ISOLATION MIGRATE_ISOLATE, /* can't allocate from here */ #endif MIGRATE_TYPES }; +/* + * Returns a list which contains the migrate types on to which + * an allocation falls back when the free list for the migrate + * type mtype is depleted. + * The end of the list is delimited by the type MIGRATE_TYPES. + */ +extern int *get_migratetype_fallbacks(int mtype); + +/* In mm/page_alloc.c; keep in sync also with show_migration_types() there */ +extern char * const migratetype_names[MIGRATE_TYPES]; + #ifdef CONFIG_CMA +bool is_cma_pageblock(struct page *page); # define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) +# define get_cma_migrate_type() MIGRATE_CMA # define is_migrate_cma_page(_page) (get_pageblock_migratetype(_page) == MIGRATE_CMA) #else +# define is_cma_pageblock(page) false # define is_migrate_cma(migratetype) false +# define get_cma_migrate_type() MIGRATE_MOVABLE # define is_migrate_cma_page(_page) false #endif @@ -160,6 +175,8 @@ enum zone_stat_item { WORKINGSET_NODERECLAIM, NR_ANON_TRANSPARENT_HUGEPAGES, NR_FREE_CMA_PAGES, + NR_SWAPCACHE, + NR_INDIRECTLY_RECLAIMABLE_BYTES, /* measured in bytes */ NR_VM_ZONE_STAT_ITEMS }; /* @@ -364,10 +381,13 @@ struct zone { struct per_cpu_pageset __percpu *pageset; /* - * This is a per-zone reserve of pages that should not be - * considered dirtyable memory. + * This is a per-zone reserve of pages that are not available + * to userspace allocations. */ - unsigned long dirty_balance_reserve; + unsigned long totalreserve_pages; +#ifdef CONFIG_CMA + bool cma_alloc; +#endif #ifndef CONFIG_SPARSEMEM /* @@ -674,6 +694,12 @@ typedef struct pglist_data { mem_hotplug_begin/end() */ int kswapd_max_order; enum zone_type classzone_idx; +#ifdef CONFIG_COMPACTION + int kcompactd_max_order; + enum zone_type kcompactd_classzone_idx; + wait_queue_head_t kcompactd_wait; + struct task_struct *kcompactd; +#endif #ifdef CONFIG_NUMA_BALANCING /* Lock serializing the migrate rate limiting window */ spinlock_t numabalancing_migrate_lock; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3f3f801ca488..162c0c7544e4 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -291,7 +291,7 @@ struct pcmcia_device_id { #define INPUT_DEVICE_ID_LED_MAX 0x0f #define INPUT_DEVICE_ID_SND_MAX 0x07 #define INPUT_DEVICE_ID_FF_MAX 0x7f -#define INPUT_DEVICE_ID_SW_MAX 0x0f +#define INPUT_DEVICE_ID_SW_MAX 0x20 #define INPUT_DEVICE_ID_MATCH_BUS 1 #define INPUT_DEVICE_ID_MATCH_VENDOR 2 @@ -445,6 +445,16 @@ struct spmi_device_id { kernel_ulong_t driver_data; /* Data private to the driver */ }; +/* soundwire */ + +#define SOUNDWIRE_NAME_SIZE 32 +#define SOUNDWIRE_MODULE_PREFIX "swr:" + +struct swr_device_id { + char name[SOUNDWIRE_NAME_SIZE]; + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + /* dmi */ enum dmi_field { DMI_NONE, @@ -481,6 +491,16 @@ struct dmi_system_id { struct dmi_strmatch matches[4]; void *driver_data; }; + +#define SLIMBUS_NAME_SIZE 32 +#define SLIMBUS_MODULE_PREFIX "slim:" + +struct slim_device_id { + char name[SLIMBUS_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* * struct dmi_device_id appears during expansion of * "MODULE_DEVICE_TABLE(dmi, x)". Compiler doesn't look inside it @@ -657,4 +677,16 @@ struct ulpi_device_id { kernel_ulong_t driver_data; }; +#define MHI_NAME_SIZE 32 + +/** + * struct mhi_device_id - MHI device identification + * @chan: MHI channel name + * @driver_data: driver data + */ +struct mhi_device_id { + const char chan[MHI_NAME_SIZE]; + kernel_ulong_t driver_data; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/msm-bus-board.h b/include/linux/msm-bus-board.h new file mode 100644 index 000000000000..c9d648d38ec4 --- /dev/null +++ b/include/linux/msm-bus-board.h @@ -0,0 +1,198 @@ +/* Copyright (c) 2010-2014, 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 __ASM_ARCH_MSM_BUS_BOARD_H +#define __ASM_ARCH_MSM_BUS_BOARD_H + +#include <linux/types.h> +#include <linux/input.h> + +enum context { + DUAL_CTX, + ACTIVE_CTX, + NUM_CTX +}; + +struct msm_bus_fabric_registration { + unsigned int id; + const char *name; + struct msm_bus_node_info *info; + unsigned int len; + int ahb; + const char *fabclk[NUM_CTX]; + const char *iface_clk; + unsigned int offset; + unsigned int haltid; + unsigned int rpm_enabled; + unsigned int nmasters; + unsigned int nslaves; + unsigned int ntieredslaves; + bool il_flag; + const struct msm_bus_board_algorithm *board_algo; + int hw_sel; + void *hw_data; + uint32_t qos_freq; + uint32_t qos_baseoffset; + u64 nr_lim_thresh; + uint32_t eff_fact; + uint32_t qos_delta; + bool virt; +}; + +struct msm_bus_device_node_registration { + struct msm_bus_node_device_type *info; + unsigned int num_devices; + bool virt; +}; + +enum msm_bus_bw_tier_type { + MSM_BUS_BW_TIER1 = 1, + MSM_BUS_BW_TIER2, + MSM_BUS_BW_COUNT, + MSM_BUS_BW_SIZE = 0x7FFFFFFF, +}; + +struct msm_bus_halt_vector { + uint32_t haltval; + uint32_t haltmask; +}; + +extern struct msm_bus_fabric_registration msm_bus_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_cpss_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8960_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sg_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8064_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8974_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_mmss_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_config_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_vnoc_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9625_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_config_noc_pdata; + +extern int msm_bus_device_match_adhoc(struct device *dev, void *id); + +void msm_bus_rpm_set_mt_mask(void); +int msm_bus_board_rpm_get_il_ids(uint16_t *id); +int msm_bus_board_get_iid(int id); + +#define NFAB_MSM8226 6 +#define NFAB_MSM8610 5 + +/* + * These macros specify the convention followed for allocating + * ids to fabrics, masters and slaves for 8x60. + * + * A node can be identified as a master/slave/fabric by using + * these ids. + */ +#define FABRIC_ID_KEY 1024 +#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1) +#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */ +#define INT_NODE_START 10000 + +#define GET_FABID(id) ((id) & MAX_FAB_KEY) + +#define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1)) +#define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0) +#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid) + +/* + * The following macros are used to format the data for port halt + * and unhalt requests. + */ +#define MSM_BUS_CLK_HALT 0x1 +#define MSM_BUS_CLK_HALT_MASK 0x1 +#define MSM_BUS_CLK_HALT_FIELDSIZE 0x1 +#define MSM_BUS_CLK_UNHALT 0x0 + +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \ + ((master) * (fieldsize)) + +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \ + { \ + (word) &= ~(fieldmask); \ + (word) |= (fieldvalue); \ + } + + +#define MSM_BUS_MASTER_HALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define MSM_BUS_MASTER_UNHALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_UNHALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define RPM_BUS_SLAVE_REQ 0x766c7362 +#define RPM_BUS_MASTER_REQ 0x73616d62 + +enum msm_bus_rpm_slave_field_type { + RPM_SLAVE_FIELD_BW = 0x00007762, +}; + +enum msm_bus_rpm_mas_field_type { + RPM_MASTER_FIELD_BW = 0x00007762, + RPM_MASTER_FIELD_BW_T0 = 0x30747762, + RPM_MASTER_FIELD_BW_T1 = 0x31747762, + RPM_MASTER_FIELD_BW_T2 = 0x32747762, +}; + +#include <dt-bindings/msm/msm-bus-ids.h> + + +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */ diff --git a/include/linux/msm-bus.h b/include/linux/msm-bus.h new file mode 100644 index 000000000000..8ea8c97f4972 --- /dev/null +++ b/include/linux/msm-bus.h @@ -0,0 +1,213 @@ +/* Copyright (c) 2010-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 _ARCH_ARM_MACH_MSM_BUS_H +#define _ARCH_ARM_MACH_MSM_BUS_H + +#include <linux/types.h> +#include <linux/input.h> +#include <linux/platform_device.h> + +/* + * Macros for clients to convert their data to ib and ab + * Ws : Time window over which to transfer the data in SECONDS + * Bs : Size of the data block in bytes + * Per : Recurrence period + * Tb : Throughput bandwidth to prevent stalling + * R : Ratio of actual bandwidth used to Tb + * Ib : Instantaneous bandwidth + * Ab : Arbitrated bandwidth + * + * IB_RECURRBLOCK and AB_RECURRBLOCK: + * These are used if the requirement is to transfer a + * recurring block of data over a known time window. + * + * IB_THROUGHPUTBW and AB_THROUGHPUTBW: + * These are used for CPU style masters. Here the requirement + * is to have minimum throughput bandwidth available to avoid + * stalling. + */ +#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws))) +#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per))) +#define IB_THROUGHPUTBW(Tb) (Tb) +#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R)) + +struct msm_bus_vectors { + int src; /* Master */ + int dst; /* Slave */ + uint64_t ab; /* Arbitrated bandwidth */ + uint64_t ib; /* Instantaneous bandwidth */ +}; + +struct msm_bus_paths { + int num_paths; + struct msm_bus_vectors *vectors; +}; + +struct msm_bus_scale_pdata { + struct msm_bus_paths *usecase; + int num_usecases; + const char *name; + /* + * If the active_only flag is set to 1, the BW request is applied + * only when at least one CPU is active (powered on). If the flag + * is set to 0, then the BW request is always applied irrespective + * of the CPU state. + */ + unsigned int active_only; +}; + +struct msm_bus_client_handle { + char *name; + int mas; + int slv; + int first_hop; + struct device *mas_dev; + u64 cur_act_ib; + u64 cur_act_ab; + u64 cur_slp_ib; + u64 cur_slp_ab; + bool active_only; +}; + +/* Scaling APIs */ + +/* + * This function returns a handle to the client. This should be used to + * call msm_bus_scale_client_update_request. + * The function returns 0 if bus driver is unable to register a client + */ + +#if (defined(CONFIG_QCOM_BUS_SCALING) || defined(CONFIG_QCOM_BUS_TOPOLOGY_ADHOC)) +int __init msm_bus_fabric_init_driver(void); +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); +void msm_bus_scale_unregister_client(uint32_t cl); +int msm_bus_scale_client_update_context(uint32_t cl, bool active_only, + unsigned int ctx_idx); + +struct msm_bus_client_handle* +msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, + bool active_only); +void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); +int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); +int msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, + u64 act_ab, u64 act_ib, u64 slp_ib, u64 slp_ab); +/* AXI Port configuration APIs */ +int msm_bus_axi_porthalt(int master_port); +int msm_bus_axi_portunhalt(int master_port); + +#else +static inline int __init msm_bus_fabric_init_driver(void) { return 0; } +static struct msm_bus_client_handle dummy_cl; + +static inline uint32_t +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) +{ + return 1; +} + +static inline int +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index) +{ + return 0; +} + +static inline int +msm_bus_scale_client_update_context(uint32_t cl, bool active_only, + unsigned int ctx_idx) +{ + return 0; +} + +static inline void +msm_bus_scale_unregister_client(uint32_t cl) +{ +} + +static inline int msm_bus_axi_porthalt(int master_port) +{ + return 0; +} + +static inline int msm_bus_axi_portunhalt(int master_port) +{ + return 0; +} + +static inline struct msm_bus_client_handle* +msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, + bool active_only) +{ + return &dummy_cl; +} + +static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) +{ +} + +static inline int +msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) +{ + return 0; +} + +static inline int +msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab, + u64 act_ib, u64 slp_ib, u64 slp_ab) + +{ + return 0; +} + +#endif + +#if defined(CONFIG_OF) && defined(CONFIG_QCOM_BUS_SCALING) +struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node); +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev); +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata); +#else +static inline struct msm_bus_scale_pdata +*msm_bus_cl_get_pdata(struct platform_device *pdev) +{ + return NULL; +} + +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node) +{ + return NULL; +} + +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata) +{ +} +#endif + +#ifdef CONFIG_DEBUG_BUS_VOTER +int msm_bus_floor_vote_context(const char *name, u64 floor_hz, + bool active_only); +int msm_bus_floor_vote(const char *name, u64 floor_hz); +#else +static inline int msm_bus_floor_vote(const char *name, u64 floor_hz) +{ + return -EINVAL; +} + +static inline int msm_bus_floor_vote_context(const char *name, u64 floor_hz, + bool active_only) +{ + return -EINVAL; +} +#endif /*defined(CONFIG_DEBUG_BUS_VOTER) && defined(CONFIG_BUS_TOPOLOGY_ADHOC)*/ +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/ diff --git a/include/linux/msm-core-interface.h b/include/linux/msm-core-interface.h new file mode 100644 index 000000000000..33bb40829dd7 --- /dev/null +++ b/include/linux/msm-core-interface.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2014, 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. + */ + +#include <uapi/linux/msm-core-interface.h> diff --git a/include/linux/msm-sps.h b/include/linux/msm-sps.h new file mode 100644 index 000000000000..59a7b82d7808 --- /dev/null +++ b/include/linux/msm-sps.h @@ -0,0 +1,1635 @@ +/* Copyright (c) 2011-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. + */ + +/* Smart-Peripheral-Switch (SPS) API. */ + +#ifndef _SPS_H_ +#define _SPS_H_ + +#include <linux/types.h> /* u32 */ + +#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_ARM_LPAE) + +/* Returns upper 4bits of 36bits physical address */ +#define SPS_GET_UPPER_ADDR(addr) ((addr & 0xF00000000ULL) >> 32) + +/* Returns 36bits physical address from 32bit address & + * flags word */ +#define DESC_FULL_ADDR(flags, addr) ((((phys_addr_t)flags & 0xF) << 32) | addr) + +/* Returns flags word with flags and 4bit upper address + * from flags and 36bit physical address */ +#define DESC_FLAG_WORD(flags, addr) (((addr & 0xF00000000ULL) >> 32) | flags) + +#else + +#define SPS_GET_UPPER_ADDR(addr) (0) +#define DESC_FULL_ADDR(flags, addr) (addr) +#define DESC_FLAG_WORD(flags, addr) (flags) + +#endif + +/* Returns upper 4bits of 36bits physical address from + * flags word */ +#define DESC_UPPER_ADDR(flags) ((flags & 0xF)) + +/* Returns lower 32bits of 36bits physical address */ +#define SPS_GET_LOWER_ADDR(addr) ((u32)(addr & 0xFFFFFFFF)) + +/* SPS device handle indicating use of system memory */ +#define SPS_DEV_HANDLE_MEM (~0x0ul>>1) + +/* SPS device handle indicating use of BAM-DMA */ + +/* SPS device handle invalid value */ +#define SPS_DEV_HANDLE_INVALID ((unsigned long)0) + +/* BAM invalid IRQ value */ +#define SPS_IRQ_INVALID 0 + +/* Invalid address value */ +#define SPS_ADDR_INVALID ((unsigned long)0xDEADBEEF) + +/* Invalid peripheral device enumeration class */ +#define SPS_CLASS_INVALID ((unsigned long)-1) + +/* + * This value specifies different configurations for an SPS connection. + * A non-default value instructs the SPS driver to search for the configuration + * in the fixed connection mapping table. + */ +#define SPS_CONFIG_DEFAULT 0 + +/* + * This value instructs the SPS driver to use the default BAM-DMA channel + * threshold + */ +#define SPS_DMA_THRESHOLD_DEFAULT 0 + +/* Flag bits supported by SPS hardware for struct sps_iovec */ +#define SPS_IOVEC_FLAG_INT 0x8000 /* Generate interrupt */ +#define SPS_IOVEC_FLAG_EOT 0x4000 /* Generate end-of-transfer indication */ +#define SPS_IOVEC_FLAG_EOB 0x2000 /* Generate end-of-block indication */ +#define SPS_IOVEC_FLAG_NWD 0x1000 /* notify when done */ +#define SPS_IOVEC_FLAG_CMD 0x0800 /* command descriptor */ +#define SPS_IOVEC_FLAG_LOCK 0x0400 /* pipe lock */ +#define SPS_IOVEC_FLAG_UNLOCK 0x0200 /* pipe unlock */ +#define SPS_IOVEC_FLAG_IMME 0x0100 /* immediate command descriptor */ +#define SPS_IOVEC_FLAG_NO_SUBMIT 0x0020 /* Do not submit descriptor to HW */ +#define SPS_IOVEC_FLAG_DEFAULT 0x0010 /* Use driver default */ + +/* Maximum descriptor/iovec size */ +#define SPS_IOVEC_MAX_SIZE (32 * 1024 - 1) /* 32K-1 bytes due to HW limit */ + +/* BAM device options flags */ + +/* + * BAM will be configured and enabled at boot. Otherwise, BAM will be + * configured and enabled when first pipe connect occurs. + */ +#define SPS_BAM_OPT_ENABLE_AT_BOOT 1UL +/* BAM IRQ is disabled */ +#define SPS_BAM_OPT_IRQ_DISABLED (1UL << 1) +/* BAM peripheral is a BAM-DMA */ +#define SPS_BAM_OPT_BAMDMA (1UL << 2) +/* BAM IRQ is registered for apps wakeup */ +#define SPS_BAM_OPT_IRQ_WAKEUP (1UL << 3) +/* Ignore external block pipe reset */ +#define SPS_BAM_NO_EXT_P_RST (1UL << 4) +/* Don't enable local clock gating */ +#define SPS_BAM_NO_LOCAL_CLK_GATING (1UL << 5) +/* Don't enable writeback cancel*/ +#define SPS_BAM_CANCEL_WB (1UL << 6) +/* BAM uses SMMU */ +#define SPS_BAM_SMMU_EN (1UL << 9) +/* Confirm resource status before access BAM*/ +#define SPS_BAM_RES_CONFIRM (1UL << 7) +/* Hold memory for BAM DMUX */ +#define SPS_BAM_HOLD_MEM (1UL << 8) +/* Use cached write pointer */ +#define SPS_BAM_CACHED_WP (1UL << 10) + +/* BAM device management flags */ + +/* BAM global device control is managed remotely */ +#define SPS_BAM_MGR_DEVICE_REMOTE 1UL +/* BAM device supports multiple execution environments */ +#define SPS_BAM_MGR_MULTI_EE (1UL << 1) +/* BAM pipes are *not* allocated locally */ +#define SPS_BAM_MGR_PIPE_NO_ALLOC (1UL << 2) +/* BAM pipes are *not* configured locally */ +#define SPS_BAM_MGR_PIPE_NO_CONFIG (1UL << 3) +/* BAM pipes are *not* controlled locally */ +#define SPS_BAM_MGR_PIPE_NO_CTRL (1UL << 4) +/* "Globbed" management properties */ +#define SPS_BAM_MGR_NONE \ + (SPS_BAM_MGR_DEVICE_REMOTE | SPS_BAM_MGR_PIPE_NO_ALLOC | \ + SPS_BAM_MGR_PIPE_NO_CONFIG | SPS_BAM_MGR_PIPE_NO_CTRL) +#define SPS_BAM_MGR_LOCAL 0 +#define SPS_BAM_MGR_LOCAL_SHARED SPS_BAM_MGR_MULTI_EE +#define SPS_BAM_MGR_REMOTE_SHARED \ + (SPS_BAM_MGR_DEVICE_REMOTE | SPS_BAM_MGR_MULTI_EE | \ + SPS_BAM_MGR_PIPE_NO_ALLOC) +#define SPS_BAM_MGR_ACCESS_MASK SPS_BAM_MGR_NONE + +/* + * BAM security configuration + */ +#define SPS_BAM_NUM_EES 4 +#define SPS_BAM_SEC_DO_NOT_CONFIG 0 +#define SPS_BAM_SEC_DO_CONFIG 0x0A434553 + +/* BAM pipe selection */ +#define SPS_BAM_PIPE(n) (1UL << (n)) + +/* This enum specifies the operational mode for an SPS connection */ +enum sps_mode { + SPS_MODE_SRC = 0, /* end point is the source (producer) */ + SPS_MODE_DEST, /* end point is the destination (consumer) */ +}; + + +/* + * This enum is a set of bit flag options for SPS connection. + * The enums should be OR'd together to create the option set + * for the SPS connection. + */ +enum sps_option { + /* + * Options to enable specific SPS hardware interrupts. + * These bit flags are also used to indicate interrupt source + * for the SPS_EVENT_IRQ event. + */ + SPS_O_DESC_DONE = 0x00000001, /* Descriptor processed */ + SPS_O_INACTIVE = 0x00000002, /* Inactivity timeout */ + SPS_O_WAKEUP = 0x00000004, /* Peripheral wake up */ + SPS_O_OUT_OF_DESC = 0x00000008,/* Out of descriptors */ + SPS_O_ERROR = 0x00000010, /* Error */ + SPS_O_EOT = 0x00000020, /* End-of-transfer */ + SPS_O_RST_ERROR = 0x00000040, /* Pipe reset unsucessful error */ + SPS_O_HRESP_ERROR = 0x00000080,/* Errorneous Hresponse by AHB MASTER */ + + /* Options to enable hardware features */ + SPS_O_STREAMING = 0x00010000, /* Enable streaming mode (no EOT) */ + /* Use MTI/SETPEND instead of BAM interrupt */ + SPS_O_IRQ_MTI = 0x00020000, + /* NWD bit written with EOT for BAM2BAM producer pipe */ + SPS_O_WRITE_NWD = 0x00040000, + /* EOT set after pipe SW offset advanced */ + SPS_O_LATE_EOT = 0x00080000, + + /* Options to enable software features */ + /* Do not disable a pipe during disconnection */ + SPS_O_NO_DISABLE = 0x00800000, + /* Transfer operation should be polled */ + SPS_O_POLL = 0x01000000, + /* Disable queuing of transfer events for the connection end point */ + SPS_O_NO_Q = 0x02000000, + SPS_O_FLOWOFF = 0x04000000, /* Graceful halt */ + /* SPS_O_WAKEUP will be disabled after triggered */ + SPS_O_WAKEUP_IS_ONESHOT = 0x08000000, + /** + * Client must read each descriptor from the FIFO + * using sps_get_iovec() + */ + SPS_O_ACK_TRANSFERS = 0x10000000, + /* Connection is automatically enabled */ + SPS_O_AUTO_ENABLE = 0x20000000, + /* DISABLE endpoint synchronization for config/enable/disable */ + SPS_O_NO_EP_SYNC = 0x40000000, + /* Allow partial polling duing IRQ mode */ + SPS_O_HYBRID = 0x80000000, +}; + +/** + * This enum specifies BAM DMA channel priority. Clients should use + * SPS_DMA_PRI_DEFAULT unless a specific priority is required. + */ +enum sps_dma_priority { + SPS_DMA_PRI_DEFAULT = 0, + SPS_DMA_PRI_LOW, + SPS_DMA_PRI_MED, + SPS_DMA_PRI_HIGH, +}; + +/* + * This enum specifies the ownership of a connection resource. + * Remote or shared ownership is only possible/meaningful on the processor + * that controls resource. + */ +enum sps_owner { + SPS_OWNER_LOCAL = 0x1, /* Resource is owned by local processor */ + SPS_OWNER_REMOTE = 0x2, /* Resource is owned by a satellite processor */ +}; + +/* This enum indicates the event associated with a client event trigger */ +enum sps_event { + SPS_EVENT_INVALID = 0, + + SPS_EVENT_EOT, /* End-of-transfer */ + SPS_EVENT_DESC_DONE, /* Descriptor processed */ + SPS_EVENT_OUT_OF_DESC, /* Out of descriptors */ + SPS_EVENT_WAKEUP, /* Peripheral wake up */ + SPS_EVENT_FLOWOFF, /* Graceful halt (idle) */ + SPS_EVENT_INACTIVE, /* Inactivity timeout */ + SPS_EVENT_ERROR, /* Error */ + SPS_EVENT_RST_ERROR, /* Pipe Reset unsuccessful */ + SPS_EVENT_HRESP_ERROR, /* Errorneous Hresponse by AHB Master*/ + SPS_EVENT_MAX, +}; + +/* + * This enum specifies the event trigger mode and is an argument for the + * sps_register_event() function. + */ +enum sps_trigger { + /* Trigger with payload for callback */ + SPS_TRIGGER_CALLBACK = 0, + /* Trigger without payload for wait or poll */ + SPS_TRIGGER_WAIT, +}; + +/* + * This enum indicates the desired halting mechanism and is an argument for the + * sps_flow_off() function + */ +enum sps_flow_off { + SPS_FLOWOFF_FORCED = 0, /* Force hardware into halt state */ + /* Allow hardware to empty pipe before halting */ + SPS_FLOWOFF_GRACEFUL, +}; + +/* + * This enum indicates the target memory heap and is an argument for the + * sps_mem_alloc() function. + */ +enum sps_mem { + SPS_MEM_LOCAL = 0, /* SPS subsystem local (pipe) memory */ + SPS_MEM_UC, /* Microcontroller (ARM7) local memory */ +}; + +/* + * This enum indicates a timer control operation and is an argument for the + * sps_timer_ctrl() function. + */ +enum sps_timer_op { + SPS_TIMER_OP_CONFIG = 0, + SPS_TIMER_OP_RESET, +/* SPS_TIMER_OP_START, Not supported by hardware yet */ +/* SPS_TIMER_OP_STOP, Not supported by hardware yet */ + SPS_TIMER_OP_READ, +}; + +/* + * This enum indicates the inactivity timer operating mode and is an + * argument for the sps_timer_ctrl() function. + */ +enum sps_timer_mode { + SPS_TIMER_MODE_ONESHOT = 0, +/* SPS_TIMER_MODE_PERIODIC, Not supported by hardware yet */ +}; + +/* This enum indicates the cases when callback the user of BAM */ +enum sps_callback_case { + SPS_CALLBACK_BAM_ERROR_IRQ = 1, /* BAM ERROR IRQ */ + SPS_CALLBACK_BAM_HRESP_ERR_IRQ, /* Erroneous HResponse */ + SPS_CALLBACK_BAM_TIMER_IRQ, /* Inactivity timer */ + SPS_CALLBACK_BAM_RES_REQ, /* Request resource */ + SPS_CALLBACK_BAM_RES_REL, /* Release resource */ + SPS_CALLBACK_BAM_POLL, /* To poll each pipe */ +}; + +/* + * This enum indicates the command type in a command element + */ +enum sps_command_type { + SPS_WRITE_COMMAND = 0, + SPS_READ_COMMAND, +}; + +/** + * struct msm_sps_platform_data - SPS Platform specific data. + * @bamdma_restricted_pipes - Bitmask of pipes restricted from local use. + * + */ +struct msm_sps_platform_data { + u32 bamdma_restricted_pipes; +}; + +/** + * This data type corresponds to the native I/O vector (BAM descriptor) + * supported by SPS hardware + * + * @addr - Buffer physical address. + * @size - Buffer size in bytes. + * @flags -Flag bitmask (see SPS_IOVEC_FLAG_ #defines). + * + */ +struct sps_iovec { + u32 addr; + u32 size:16; + u32 flags:16; +}; + +/** + * This data type corresponds to the native Command Element + * supported by SPS hardware + * + * @addr - register address. + * @command - command type. + * @data - for write command: content to be written into peripheral register. + * for read command: dest addr to write peripheral register value to. + * @mask - register mask. + * @reserved - for future usage. + * + */ +struct sps_command_element { + u32 addr:24; + u32 command:8; + u32 data; + u32 mask; + u32 reserved; +}; + +/* + * BAM device's security configuation + */ +struct sps_bam_pipe_sec_config_props { + u32 pipe_mask; + u32 vmid; +}; + +struct sps_bam_sec_config_props { + /* Per-EE configuration - This is a pipe bit mask for each EE */ + struct sps_bam_pipe_sec_config_props ees[SPS_BAM_NUM_EES]; +}; + +/** + * This struct defines a BAM device. The client must memset() this struct to + * zero before writing device information. A value of zero for uninitialized + * values will instruct the SPS driver to use general defaults or + * hardware/BIOS supplied values. + * + * + * @options - See SPS_BAM_OPT_* bit flag. + * @phys_addr - BAM base physical address (not peripheral address). + * @virt_addr - BAM base virtual address. + * @virt_size - For virtual mapping. + * @irq - IRQ enum for use in ISR vector install. + * @num_pipes - number of pipes. Can be read from hardware. + * @summing_threshold - BAM event threshold. + * + * @periph_class - Peripheral device enumeration class. + * @periph_dev_id - Peripheral global device ID. + * @periph_phys_addr - Peripheral base physical address, for BAM-DMA only. + * @periph_virt_addr - Peripheral base virtual address. + * @periph_virt_size - Size for virtual mapping. + * + * @callback - callback function for BAM user. + * @user - pointer to user data. + * + * @event_threshold - Pipe event threshold. + * @desc_size - Size (bytes) of descriptor FIFO. + * @data_size - Size (bytes) of data FIFO. + * @desc_mem_id - Heap ID for default descriptor FIFO allocations. + * @data_mem_id - Heap ID for default data FIFO allocations. + * + * @manage - BAM device management flags (see SPS_BAM_MGR_*). + * @restricted_pipes - Bitmask of pipes restricted from local use. + * @ee - Local execution environment index. + * + * @irq_gen_addr - MTI interrupt generation address. This configuration only + * applies to BAM rev 1 and 2 hardware. MTIs are only supported on BAMs when + * global config is controlled by a remote processor. + * NOTE: This address must correspond to the MTI associated with the "irq" IRQ + * enum specified above. + * + * @sec_config - must be set to SPS_BAM_SEC_DO_CONFIG to perform BAM security + * configuration. Only the processor that manages the BAM is allowed to + * perform the configuration. The global (top-level) BAM interrupt will be + * assigned to the EE of the processor that manages the BAM. + * + * @p_sec_config_props - BAM device's security configuation + * + */ +struct sps_bam_props { + + /* BAM device properties. */ + + u32 options; + phys_addr_t phys_addr; + void *virt_addr; + u32 virt_size; + u32 irq; + u32 num_pipes; + u32 summing_threshold; + + /* Peripheral device properties */ + + u32 periph_class; + u32 periph_dev_id; + phys_addr_t periph_phys_addr; + void *periph_virt_addr; + u32 periph_virt_size; + + /* Connection pipe parameter defaults. */ + + u32 event_threshold; + u32 desc_size; + u32 data_size; + u32 desc_mem_id; + u32 data_mem_id; + + /* Feedback to BAM user */ + void (*callback)(enum sps_callback_case, void *); + void *user; + + /* Security properties */ + + u32 manage; + u32 restricted_pipes; + u32 ee; + + /* Log Level property */ + u32 ipc_loglevel; + + /* BAM MTI interrupt generation */ + + u32 irq_gen_addr; + + /* Security configuration properties */ + + u32 sec_config; + struct sps_bam_sec_config_props *p_sec_config_props; + + /* Logging control */ + + bool constrained_logging; + u32 logging_number; +}; + +/** + * This struct specifies memory buffer properties. + * + * @base - Buffer virtual address. + * @phys_base - Buffer physical address. + * @size - Specifies buffer size (or maximum size). + * @min_size - If non-zero, specifies buffer minimum size. + * + */ +struct sps_mem_buffer { + void *base; + phys_addr_t phys_base; + unsigned long iova; + u32 size; + u32 min_size; +}; + +/** + * This struct defines a connection's end point and is used as the argument + * for the sps_connect(), sps_get_config(), and sps_set_config() functions. + * For system mode pipe, use SPS_DEV_HANDLE_MEM for the end point that + * corresponds to system memory. + * + * The client can force SPS to reserve a specific pipe on a BAM. + * If the pipe is in use, the sps_connect/set_config() will fail. + * + * @source - Source BAM. + * @src_pipe_index - BAM pipe index, 0 to 30. + * @destination - Destination BAM. + * @dest_pipe_index - BAM pipe index, 0 to 30. + * + * @mode - specifies which end (source or destination) of the connection will + * be controlled/referenced by the client. + * + * @config - This value is for future use and should be set to + * SPS_CONFIG_DEFAULT or left as default from sps_get_config(). + * + * @options - OR'd connection end point options (see SPS_O defines). + * + * WARNING: The memory provided should be physically contiguous and non-cached. + * The user can use one of the following: + * 1. sps_alloc_mem() - allocated from pipe-memory. + * 2. dma_alloc_coherent() - allocate coherent DMA memory. + * 3. dma_map_single() - for using memory allocated by kmalloc(). + * + * @desc - Descriptor FIFO. + * @data - Data FIFO (BAM-to-BAM mode only). + * + * @event_thresh - Pipe event threshold or derivative. + * @lock_group - The lock group this pipe belongs to. + * + * @sps_reserved - Reserved word - client must not modify. + * + */ +struct sps_connect { + unsigned long source; + unsigned long source_iova; + u32 src_pipe_index; + unsigned long destination; + unsigned long dest_iova; + u32 dest_pipe_index; + + enum sps_mode mode; + + u32 config; + + enum sps_option options; + + struct sps_mem_buffer desc; + struct sps_mem_buffer data; + + u32 event_thresh; + + u32 lock_group; + + /* SETPEND/MTI interrupt generation parameters */ + + u32 irq_gen_addr; + u32 irq_gen_data; + + u32 sps_reserved; + +}; + +/** + * This struct defines a satellite connection's end point. The client of the + * SPS driver on the satellite processor must call sps_get_config() to + * initialize a struct sps_connect, then copy the values from the struct + * sps_satellite to the struct sps_connect before making the sps_connect() + * call to the satellite SPS driver. + * + */ +struct sps_satellite { + /** + * These values must be copied to either the source or destination + * corresponding values in the connect struct. + */ + phys_addr_t dev; + u32 pipe_index; + + /** + * These values must be copied to the corresponding values in the + * connect struct + */ + u32 config; + enum sps_option options; + +}; + +/** + * This struct defines parameters for allocation of a BAM DMA channel. The + * client must memset() this struct to zero before writing allocation + * information. A value of zero for uninitialized values will instruct + * the SPS driver to use defaults or "don't care". + * + * @dev - Associated BAM device handle, or SPS_DEV_HANDLE_DMA. + * + * @src_owner - Source owner processor ID. + * @dest_owner - Destination owner processor ID. + * + */ +struct sps_alloc_dma_chan { + unsigned long dev; + + /* BAM DMA channel configuration parameters */ + + u32 threshold; + enum sps_dma_priority priority; + + /** + * Owner IDs are global host processor identifiers used by the system + * SROT when establishing execution environments. + */ + u32 src_owner; + u32 dest_owner; + +}; + +/** + * This struct defines parameters for an allocated BAM DMA channel. + * + * @dev - BAM DMA device handle. + * @dest_pipe_index - Destination/input/write pipe index. + * @src_pipe_index - Source/output/read pipe index. + * + */ +struct sps_dma_chan { + unsigned long dev; + u32 dest_pipe_index; + u32 src_pipe_index; +}; + +/** + * This struct is an argument passed payload when triggering a callback event + * object registered for an SPS connection end point. + * + * @user - Pointer registered with sps_register_event(). + * + * @event_id - Which event. + * + * @iovec - The associated I/O vector. If the end point is a system-mode + * producer, the size will reflect the actual number of bytes written to the + * buffer by the pipe. NOTE: If this I/O vector was part of a set submitted to + * sps_transfer(), then the vector array itself will be updated with all of + * the actual counts. + * + * @user - Pointer registered with the transfer. + * + */ +struct sps_event_notify { + void *user; + + enum sps_event event_id; + + /* Data associated with the event */ + + union { + /* Data for SPS_EVENT_IRQ */ + struct { + u32 mask; + } irq; + + /* Data for SPS_EVENT_EOT or SPS_EVENT_DESC_DONE */ + + struct { + struct sps_iovec iovec; + void *user; + } transfer; + + /* Data for SPS_EVENT_ERROR */ + + struct { + u32 status; + } err; + + } data; +}; + +/** + * This struct defines a event registration parameters and is used as the + * argument for the sps_register_event() function. + * + * @options - Event options that will trigger the event object. + * @mode - Event trigger mode. + * + * @xfer_done - a pointer to a completion object. NULL if not in use. + * + * @callback - a callback to call on completion. NULL if not in use. + * + * @user - User pointer that will be provided in event callback data. + * + */ +struct sps_register_event { + enum sps_option options; + enum sps_trigger mode; + struct completion *xfer_done; + void (*callback)(struct sps_event_notify *notify); + void *user; +}; + +/** + * This struct defines a system memory transfer's parameters and is used as the + * argument for the sps_transfer() function. + * + * @iovec_phys - Physical address of I/O vectors buffer. + * @iovec - Pointer to I/O vectors buffer. + * @iovec_count - Number of I/O vectors. + * @user - User pointer passed in callback event. + * + */ +struct sps_transfer { + phys_addr_t iovec_phys; + struct sps_iovec *iovec; + u32 iovec_count; + void *user; +}; + +/** + * This struct defines a timer control operation parameters and is used as an + * argument for the sps_timer_ctrl() function. + * + * @op - Timer control operation. + * @timeout_msec - Inactivity timeout (msec). + * + */ +struct sps_timer_ctrl { + enum sps_timer_op op; + + /** + * The following configuration parameters must be set when the timer + * control operation is SPS_TIMER_OP_CONFIG. + */ + enum sps_timer_mode mode; + u32 timeout_msec; +}; + +/** + * This struct defines a timer control operation result and is used as an + * argument for the sps_timer_ctrl() function. + */ +struct sps_timer_result { + u32 current_timer; +}; + + +/*---------------------------------------------------------------------------- + * Functions specific to sps interface + * -------------------------------------------------------------------------*/ +struct sps_pipe; /* Forward declaration */ + +#ifdef CONFIG_SPS +/** + * Register a BAM device + * + * This function registers a BAM device with the SPS driver. For each + *peripheral that includes a BAM, the peripheral driver must register + * the BAM with the SPS driver. + * + * A requirement is that the peripheral driver must remain attached + * to the SPS driver until the BAM is deregistered. Otherwise, the + * system may attempt to unload the SPS driver. BAM registrations would + * be lost. + * + * @bam_props - Pointer to struct for BAM device properties. + * + * @dev_handle - Device handle will be written to this location (output). + * + * @return 0 on success, negative value on error + * + */ +int sps_register_bam_device(const struct sps_bam_props *bam_props, + unsigned long *dev_handle); + +/** + * Deregister a BAM device + * + * This function deregisters a BAM device from the SPS driver. The peripheral + * driver should deregister a BAM when the peripheral driver is shut down or + * when BAM use should be disabled. + * + * A BAM cannot be deregistered if any of its pipes is in an active connection. + * + * When all BAMs have been deregistered, the system is free to unload the + * SPS driver. + * + * @dev_handle - BAM device handle. + * + * @return 0 on success, negative value on error + * + */ +int sps_deregister_bam_device(unsigned long dev_handle); + +/** + * Allocate client state context + * + * This function allocate and initializes a client state context struct. + * + * @return pointer to client state context + * + */ +struct sps_pipe *sps_alloc_endpoint(void); + +/** + * Free client state context + * + * This function de-initializes and free a client state context struct. + * + * @ctx - client context for SPS connection end point + * + * @return 0 on success, negative value on error + * + */ +int sps_free_endpoint(struct sps_pipe *h); + +/** + * Get the configuration parameters for an SPS connection end point + * + * This function retrieves the configuration parameters for an SPS connection + * end point. + * This function may be called before the end point is connected (before + * sps_connect is called). This allows the client to specify parameters before + * the connection is established. + * + * The client must call this function to fill it's struct sps_connect + * struct before modifying values and passing the struct to sps_set_config(). + * + * @h - client context for SPS connection end point + * + * @config - Pointer to buffer for the end point's configuration parameters. + * Must not be NULL. + * + * @return 0 on success, negative value on error + * + */ +int sps_get_config(struct sps_pipe *h, struct sps_connect *config); + +/** + * Allocate memory from the SPS Pipe-Memory. + * + * @h - client context for SPS connection end point + * + * @mem - memory type - N/A. + * + * @mem_buffer - Pointer to struct for allocated memory properties. + * + * @return 0 on success, negative value on error + * + */ +int sps_alloc_mem(struct sps_pipe *h, enum sps_mem mem, + struct sps_mem_buffer *mem_buffer); + +/** + * Free memory from the SPS Pipe-Memory. + * + * @h - client context for SPS connection end point + * + * @mem_buffer - Pointer to struct for allocated memory properties. + * + * @return 0 on success, negative value on error + * + */ +int sps_free_mem(struct sps_pipe *h, struct sps_mem_buffer *mem_buffer); + +/** + * Connect an SPS connection end point + * + * This function creates a connection between two SPS peripherals or between + * an SPS peripheral and the local host processor (via system memory, end + *point SPS_DEV_HANDLE_MEM). Establishing the connection includes + * initialization of the SPS hardware and allocation of any other connection + * resources (buffer memory, etc.). + * + * This function requires the client to specify both the source and + * destination end points of the SPS connection. However, the handle + * returned applies only to the end point of the connection that the client + * controls. The end point under control must be specified by the + * enum sps_mode mode argument, either SPS_MODE_SRC, SPS_MODE_DEST, or + * SPS_MODE_CTL. Note that SPS_MODE_CTL is only supported for I/O + * accelerator connections, and only a limited set of control operations are + * allowed (TBD). + * + * For a connection involving system memory + * (SPS_DEV_HANDLE_MEM), the peripheral end point must be + * specified. For example, SPS_MODE_SRC must be specified for a + * BAM-to-system connection, since the BAM pipe is the data + * producer. + * + * For a specific peripheral-to-peripheral connection, there may be more than + * one required configuration. For example, there might be high-performance + * and low-power configurations for a connection between the two peripherals. + * The config argument allows the client to specify different configurations, + * which may require different system resource allocations and hardware + * initialization. + * + * A client is allowed to create one and only one connection for its + * struct sps_pipe. The handle is used to identify the connection end point + * in subsequent SPS driver calls. A specific connection source or + * destination end point can be associated with one and only one + * struct sps_pipe. + * + * The client must establish an open device handle to the SPS. To do so, the + * client must attach to the SPS driver and open the SPS device by calling + * the following functions. + * + * @h - client context for SPS connection end point + * + * @connect - Pointer to connection parameters + * + * @return 0 on success, negative value on error + * + */ +int sps_connect(struct sps_pipe *h, struct sps_connect *connect); + +/** + * Disconnect an SPS connection end point + * + * This function disconnects an SPS connection end point. + * The SPS hardware associated with that end point will be disabled. + * For a connection involving system memory (SPS_DEV_HANDLE_MEM), all + * connection resources are deallocated. For a peripheral-to-peripheral + * connection, the resources associated with the connection will not be + * deallocated until both end points are closed. + * + * The client must call sps_connect() for the handle before calling + * this function. + * + * @h - client context for SPS connection end point + * + * @return 0 on success, negative value on error + * + */ +int sps_disconnect(struct sps_pipe *h); + +/** + * Register an event object for an SPS connection end point + * + * This function registers a callback event object for an SPS connection end + *point. The registered event object will be triggered for the set of + * events specified in reg->options that are enabled for the end point. + * + * There can only be one registered event object for each event. If an event + * object is already registered for an event, it will be replaced. If + *reg->event handle is NULL, then any registered event object for the + * event will be deregistered. Option bits in reg->options not associated + * with events are ignored. + * + * The client must call sps_connect() for the handle before calling + * this function. + * + * @h - client context for SPS connection end point + * + * @reg - Pointer to event registration parameters + * + * @return 0 on success, negative value on error + * + */ +int sps_register_event(struct sps_pipe *h, struct sps_register_event *reg); + +/** + * Perform a single DMA transfer on an SPS connection end point + * + * This function submits a DMA transfer request consisting of a single buffer + * for an SPS connection end point associated with a peripheral-to/from-memory + * connection. The request will be submitted immediately to hardware if the + * hardware is idle (data flow off, no other pending transfers). Otherwise, it + * will be queued for later handling in the SPS driver work loop. + * + * The data buffer must be DMA ready. The client is responsible for insuring + *physically contiguous memory, cache maintenance, and memory barrier. For + * more information, see Appendix A. + * + * The client must not modify the data buffer until the completion indication is + * received. + * + * This function cannot be used if transfer queuing is disabled (see option + * SPS_O_NO_Q). The client must set the SPS_O_EOT option to receive a callback + * event trigger when the transfer is complete. The SPS driver will insure the + * appropriate flags in the I/O vectors are set to generate the completion + * indication. + * + * The return value from this function may indicate that an error occurred. + * Possible causes include invalid arguments. + * + * @h - client context for SPS connection end point + * + * @addr - Physical address of buffer to transfer. + * + * WARNING: The memory provided should be physically contiguous and + * non-cached. + * + * The user can use one of the following: + * 1. sps_alloc_mem() - allocated from pipe-memory. + * 2. dma_alloc_coherent() - allocate DMA memory. + * 3. dma_map_single() for memory allocated by kmalloc(). + * + * @size - Size in bytes of buffer to transfer + * + * @user - User pointer that will be returned to user as part of + * event payload + * + * @return 0 on success, negative value on error + * + */ +int sps_transfer_one(struct sps_pipe *h, phys_addr_t addr, u32 size, + void *user, u32 flags); + +/** + * Read event queue for an SPS connection end point + * + * This function reads event queue for an SPS connection end point. + * + * @h - client context for SPS connection end point + * + * @event - pointer to client's event data buffer + * + * @return 0 on success, negative value on error + * + */ +int sps_get_event(struct sps_pipe *h, struct sps_event_notify *event); + +/** + * Get processed I/O vector (completed transfers) + * + * This function fetches the next processed I/O vector. + * + * @h - client context for SPS connection end point + * + * @iovec - Pointer to I/O vector struct (output). + * This struct will be zeroed if there are no more processed I/O vectors. + * + * @return 0 on success, negative value on error + * + */ +int sps_get_iovec(struct sps_pipe *h, struct sps_iovec *iovec); + +/** + * Enable an SPS connection end point + * + * This function enables an SPS connection end point. + * + * @h - client context for SPS connection end point + * + * @return 0 on success, negative value on error + * + */ +int sps_flow_on(struct sps_pipe *h); + +/** + * Disable an SPS connection end point + * + * This function disables an SPS connection end point. + * + * @h - client context for SPS connection end point + * + * @mode - Desired mode for disabling pipe data flow + * + * @return 0 on success, negative value on error + * + */ +int sps_flow_off(struct sps_pipe *h, enum sps_flow_off mode); + +/** + * Perform a Multiple DMA transfer on an SPS connection end point + * + * This function submits a DMA transfer request for an SPS connection end point + * associated with a peripheral-to/from-memory connection. The request will be + * submitted immediately to hardware if the hardware is idle (data flow off, no + * other pending transfers). Otherwise, it will be queued for later handling in + * the SPS driver work loop. + * + * The data buffers referenced by the I/O vectors must be DMA ready. + * The client is responsible for insuring physically contiguous memory, + * any cache maintenance, and memory barrier. For more information, + * see Appendix A. + * + * The I/O vectors must specify physical addresses for the referenced buffers. + * + * The client must not modify the data buffers referenced by I/O vectors until + * the completion indication is received. + * + * If transfer queuing is disabled (see option SPS_O_NO_Q), the client is + * responsible for setting the appropriate flags in the I/O vectors to generate + * the completion indication. Also, the client is responsible for enabling the + * appropriate connection callback event options for completion indication (see + * sps_connect(), sps_set_config()). + * + * If transfer queuing is enabled, the client must set the SPS_O_EOT option to + * receive a callback event trigger when the transfer is complete. The SPS + * driver will insure the appropriate flags in the I/O vectors are set to + * generate the completion indication. The client must not set any flags in the + * I/O vectors, as this may cause the SPS driver to become out of sync with the + * hardware. + * + * The return value from this function may indicate that an error occurred. + * Possible causes include invalid arguments. If transfer queuing is disabled, + * an error will occur if the pipe is already processing a transfer. + * + * @h - client context for SPS connection end point + * + * @transfer - Pointer to transfer parameter struct + * + * @return 0 on success, negative value on error + * + */ +int sps_transfer(struct sps_pipe *h, struct sps_transfer *transfer); + +/** + * Determine whether an SPS connection end point FIFO is empty + * + * This function returns the empty state of an SPS connection end point. + * + * @h - client context for SPS connection end point + * + * @empty - pointer to client's empty status word (boolean) + * + * @return 0 on success, negative value on error + * + */ +int sps_is_pipe_empty(struct sps_pipe *h, u32 *empty); + +/** + * Reset an SPS BAM device + * + * This function resets an SPS BAM device. + * + * @dev - device handle for the BAM + * + * @return 0 on success, negative value on error + * + */ +int sps_device_reset(unsigned long dev); + +/** + * Set the configuration parameters for an SPS connection end point + * + * This function sets the configuration parameters for an SPS connection + * end point. This function may be called before the end point is connected + * (before sps_connect is called). This allows the client to specify + *parameters before the connection is established. The client is allowed + * to pre-allocate resources and override driver defaults. + * + * The client must call sps_get_config() to fill it's struct sps_connect + * struct before modifying values and passing the struct to this function. + * Only those parameters that differ from the current configuration will + * be processed. + * + * @h - client context for SPS connection end point + * + * @config - Pointer to the end point's new configuration parameters. + * + * @return 0 on success, negative value on error + * + */ +int sps_set_config(struct sps_pipe *h, struct sps_connect *config); + +/** + * Set ownership of an SPS connection end point + * + * This function sets the ownership of an SPS connection end point to + * either local (default) or non-local. This function is used to + * retrieve the struct sps_connect data that must be used by a + * satellite processor when calling sps_connect(). + * + * Non-local ownership is only possible/meaningful on the processor + * that controls resource allocations (apps processor). Setting ownership + * to non-local on a satellite processor will fail. + * + * Setting ownership from non-local to local will succeed only if the + * owning satellite processor has properly brought the end point to + * an idle condition. + * + * This function will succeed if the connection end point is already in + * the specified ownership state. + * + * @h - client context for SPS connection end point + * + * @owner - New ownership of the connection end point + * + * @connect - Pointer to buffer for satellite processor connect data. + * Can be NULL to avoid retrieving the connect data. Will be ignored + * if the end point ownership is set to local. + * + * @return 0 on success, negative value on error + * + */ +int sps_set_owner(struct sps_pipe *h, enum sps_owner owner, + struct sps_satellite *connect); + +#ifdef CONFIG_SPS_SUPPORT_BAMDMA +/** + * Allocate a BAM DMA channel + * + * This function allocates a BAM DMA channel. A "BAM DMA" is a special + * DMA peripheral with a BAM front end. The DMA peripheral acts as a conduit + * for data to flow into a consumer pipe and then out of a producer pipe. + * It's primarily purpose is to serve as a path for interprocessor communication + * that allows each processor to control and protect it's own memory space. + * + * @alloc - Pointer to struct for BAM DMA channel allocation properties. + * + * @chan - Allocated channel information will be written to this + * location (output). + * + * @return 0 on success, negative value on error + * + */ +int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc, + struct sps_dma_chan *chan); + +/** + * Free a BAM DMA channel + * + * This function frees a BAM DMA channel. + * + * @chan - Pointer to information for channel to free + * + * @return 0 on success, negative value on error + * + */ +int sps_free_dma_chan(struct sps_dma_chan *chan); + +/** + * Get the BAM handle for BAM-DMA. + * + * The BAM handle should be use as source/destination in the sps_connect(). + * + * @return handle on success, zero on error + * + */ +unsigned long sps_dma_get_bam_handle(void); + +/** + * Free the BAM handle for BAM-DMA. + * + */ +void sps_dma_free_bam_handle(unsigned long h); +#else +static inline int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc, + struct sps_dma_chan *chan) +{ + return -EPERM; +} + +static inline int sps_free_dma_chan(struct sps_dma_chan *chan) +{ + return -EPERM; +} + +static inline unsigned long sps_dma_get_bam_handle(void) +{ + return 0; +} + +static inline void sps_dma_free_bam_handle(unsigned long h) +{ +} +#endif + +/** + * Get number of free transfer entries for an SPS connection end point + * + * This function returns the number of free transfer entries for an + * SPS connection end point. + * + * @h - client context for SPS connection end point + * + * @count - pointer to count status + * + * @return 0 on success, negative value on error + * + */ +int sps_get_free_count(struct sps_pipe *h, u32 *count); + +/** + * Perform timer control + * + * This function performs timer control operations. + * + * @h - client context for SPS connection end point + * + * @timer_ctrl - Pointer to timer control specification + * + * @timer_result - Pointer to buffer for timer operation result. + * This argument can be NULL if no result is expected for the operation. + * If non-NULL, the current timer value will always provided. + * + * @return 0 on success, negative value on error + * + */ +int sps_timer_ctrl(struct sps_pipe *h, + struct sps_timer_ctrl *timer_ctrl, + struct sps_timer_result *timer_result); + +/** + * Find the handle of a BAM device based on the physical address + * + * This function finds a BAM device in the BAM registration list that + * matches the specified physical address, and returns its handle. + * + * @phys_addr - physical address of the BAM + * + * @h - device handle of the BAM + * + * @return 0 on success, negative value on error + * + */ +int sps_phy2h(phys_addr_t phys_addr, unsigned long *handle); + +/** + * Setup desc/data FIFO for bam-to-bam connection + * + * @mem_buffer - Pointer to struct for allocated memory properties. + * + * @addr - address of FIFO + * + * @size - FIFO size + * + * @use_offset - use address offset instead of absolute address + * + * @return 0 on success, negative value on error + * + */ +int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer, + u32 addr, u32 size, int use_offset); + +/** + * Get the number of unused descriptors in the descriptor FIFO + * of a pipe + * + * @h - client context for SPS connection end point + * + * @desc_num - number of unused descriptors + * + * @return 0 on success, negative value on error + * + */ +int sps_get_unused_desc_num(struct sps_pipe *h, u32 *desc_num); + +/** + * Get the debug info of BAM registers and descriptor FIFOs + * + * @dev - BAM device handle + * + * @option - debugging option + * + * @para - parameter used for an option (such as pipe combination) + * + * @tb_sel - testbus selection + * + * @desc_sel - selection of descriptors + * + * @return 0 on success, negative value on error + * + */ +int sps_get_bam_debug_info(unsigned long dev, u32 option, u32 para, + u32 tb_sel, u32 desc_sel); + +/** + * Vote for or relinquish BAM DMA clock + * + * @clk_on - to turn on or turn off the clock + * + * @return 0 on success, negative value on error + * + */ +int sps_ctrl_bam_dma_clk(bool clk_on); + +/* + * sps_pipe_reset - reset a pipe of a BAM. + * @dev: BAM device handle + * @pipe: pipe index + * + * This function resets a pipe of a BAM. + * + * Return: 0 on success, negative value on error + */ +int sps_pipe_reset(unsigned long dev, u32 pipe); + +/* + * sps_pipe_disable - disable a pipe of a BAM. + * @dev: BAM device handle + * @pipe: pipe index + * + * This function disables a pipe of a BAM. + * + * Return: 0 on success, negative value on error + */ +int sps_pipe_disable(unsigned long dev, u32 pipe); + +/* + * sps_pipe_pending_desc - checking pending descriptor. + * @dev: BAM device handle + * @pipe: pipe index + * @pending: indicate if there is any pending descriptor. + * + * This function checks if a pipe of a BAM has any pending descriptor. + * + * Return: 0 on success, negative value on error + */ +int sps_pipe_pending_desc(unsigned long dev, u32 pipe, bool *pending); + +/* + * sps_bam_process_irq - process IRQ of a BAM. + * @dev: BAM device handle + * + * This function processes any pending IRQ of a BAM. + * + * Return: 0 on success, negative value on error + */ +int sps_bam_process_irq(unsigned long dev); + +/* + * sps_get_bam_addr - get address info of a BAM. + * @dev: BAM device handle + * @base: beginning address + * @size: address range size + * + * This function returns the address info of a BAM. + * + * Return: 0 on success, negative value on error + */ +int sps_get_bam_addr(unsigned long dev, phys_addr_t *base, + u32 *size); + +/* + * sps_pipe_inject_zlt - inject a ZLT with EOT. + * @dev: BAM device handle + * @pipe_index: pipe index + * + * This function injects a ZLT with EOT for a pipe of a BAM. + * + * Return: 0 on success, negative value on error + */ +int sps_pipe_inject_zlt(unsigned long dev, u32 pipe_index); +#else +static inline int sps_register_bam_device(const struct sps_bam_props + *bam_props, unsigned long *dev_handle) +{ + return -EPERM; +} + +static inline int sps_deregister_bam_device(unsigned long dev_handle) +{ + return -EPERM; +} + +static inline struct sps_pipe *sps_alloc_endpoint(void) +{ + return NULL; +} + +static inline int sps_free_endpoint(struct sps_pipe *h) +{ + return -EPERM; +} + +static inline int sps_get_config(struct sps_pipe *h, struct sps_connect *config) +{ + return -EPERM; +} + +static inline int sps_alloc_mem(struct sps_pipe *h, enum sps_mem mem, + struct sps_mem_buffer *mem_buffer) +{ + return -EPERM; +} + +static inline int sps_free_mem(struct sps_pipe *h, + struct sps_mem_buffer *mem_buffer) +{ + return -EPERM; +} + +static inline int sps_connect(struct sps_pipe *h, struct sps_connect *connect) +{ + return -EPERM; +} + +static inline int sps_disconnect(struct sps_pipe *h) +{ + return -EPERM; +} + +static inline int sps_register_event(struct sps_pipe *h, + struct sps_register_event *reg) +{ + return -EPERM; +} + +static inline int sps_transfer_one(struct sps_pipe *h, phys_addr_t addr, + u32 size, void *user, u32 flags) +{ + return -EPERM; +} + +static inline int sps_get_event(struct sps_pipe *h, + struct sps_event_notify *event) +{ + return -EPERM; +} + +static inline int sps_get_iovec(struct sps_pipe *h, struct sps_iovec *iovec) +{ + return -EPERM; +} + +static inline int sps_flow_on(struct sps_pipe *h) +{ + return -EPERM; +} + +static inline int sps_flow_off(struct sps_pipe *h, enum sps_flow_off mode) +{ + return -EPERM; +} + +static inline int sps_transfer(struct sps_pipe *h, + struct sps_transfer *transfer) +{ + return -EPERM; +} + +static inline int sps_is_pipe_empty(struct sps_pipe *h, u32 *empty) +{ + return -EPERM; +} + +static inline int sps_device_reset(unsigned long dev) +{ + return -EPERM; +} + +static inline int sps_set_config(struct sps_pipe *h, struct sps_connect *config) +{ + return -EPERM; +} + +static inline int sps_set_owner(struct sps_pipe *h, enum sps_owner owner, + struct sps_satellite *connect) +{ + return -EPERM; +} + +static inline int sps_get_free_count(struct sps_pipe *h, u32 *count) +{ + return -EPERM; +} + +static inline int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc, + struct sps_dma_chan *chan) +{ + return -EPERM; +} + +static inline int sps_free_dma_chan(struct sps_dma_chan *chan) +{ + return -EPERM; +} + +static inline unsigned long sps_dma_get_bam_handle(void) +{ + return 0; +} + +static inline void sps_dma_free_bam_handle(unsigned long h) +{ +} + +static inline int sps_timer_ctrl(struct sps_pipe *h, + struct sps_timer_ctrl *timer_ctrl, + struct sps_timer_result *timer_result) +{ + return -EPERM; +} + +static inline int sps_phy2h(phys_addr_t phys_addr, unsigned long *handle) +{ + return -EPERM; +} + +static inline int sps_setup_bam2bam_fifo(struct sps_mem_buffer *mem_buffer, + u32 addr, u32 size, int use_offset) +{ + return -EPERM; +} + +static inline int sps_get_unused_desc_num(struct sps_pipe *h, u32 *desc_num) +{ + return -EPERM; +} + +static inline int sps_get_bam_debug_info(unsigned long dev, u32 option, + u32 para, u32 tb_sel, u32 desc_sel) +{ + return -EPERM; +} + +static inline int sps_ctrl_bam_dma_clk(bool clk_on) +{ + return -EPERM; +} + +static inline int sps_pipe_reset(unsigned long dev, u32 pipe) +{ + return -EPERM; +} + +static inline int sps_pipe_disable(unsigned long dev, u32 pipe) +{ + return -EPERM; +} + +static inline int sps_pipe_pending_desc(unsigned long dev, u32 pipe, + bool *pending) +{ + return -EPERM; +} + +static inline int sps_bam_process_irq(unsigned long dev) +{ + return -EPERM; +} + +static inline int sps_get_bam_addr(unsigned long dev, phys_addr_t *base, + u32 *size) +{ + return -EPERM; +} + +static inline int sps_pipe_inject_zlt(unsigned long dev, u32 pipe_index) +{ + return -EPERM; +} +#endif + +#endif /* _SPS_H_ */ diff --git a/include/linux/msm_adreno_devfreq.h b/include/linux/msm_adreno_devfreq.h new file mode 100644 index 000000000000..19acfb4447b2 --- /dev/null +++ b/include/linux/msm_adreno_devfreq.h @@ -0,0 +1,79 @@ +#ifndef MSM_ADRENO_DEVFREQ_H +#define MSM_ADRENO_DEVFREQ_H + +#include <linux/devfreq.h> +#include <linux/notifier.h> + +#define ADRENO_DEVFREQ_NOTIFY_SUBMIT 1 +#define ADRENO_DEVFREQ_NOTIFY_RETIRE 2 +#define ADRENO_DEVFREQ_NOTIFY_IDLE 3 + +struct device; + +int kgsl_devfreq_add_notifier(struct device *, struct notifier_block *); + +int kgsl_devfreq_del_notifier(struct device *, struct notifier_block *); + +/* same as KGSL_MAX_PWRLEVELS */ +#define MSM_ADRENO_MAX_PWRLEVELS 10 + +struct xstats { + u64 ram_time; + u64 ram_wait; + int mod; +}; + +struct devfreq_msm_adreno_tz_data { + struct notifier_block nb; + struct { + s64 total_time; + s64 busy_time; + u32 ctxt_aware_target_pwrlevel; + u32 ctxt_aware_busy_penalty; + } bin; + struct { + u64 total_time; + u64 ram_time; + u64 ram_wait; + u64 gpu_time; + u32 num; + u32 max; + u32 width; + u32 *up; + u32 *down; + u32 *p_up; + u32 *p_down; + unsigned int *index; + uint64_t *ib; + } bus; + unsigned int device_id; + bool is_64; + bool disable_busy_time_burst; + bool ctxt_aware_enable; +}; + +struct msm_adreno_extended_profile { + struct devfreq_msm_adreno_tz_data *private_data; + struct devfreq *bus_devfreq; + struct workqueue_struct *partner_wq; + struct work_struct partner_start_event_ws; + struct work_struct partner_stop_event_ws; + struct work_struct partner_suspend_event_ws; + struct work_struct partner_resume_event_ws; + struct devfreq_dev_profile profile; +}; + +struct msm_busmon_extended_profile { + u32 flag; + unsigned long percent_ab; + unsigned long ab_mbytes; + struct devfreq_msm_adreno_tz_data *private_data; + struct devfreq_dev_profile profile; +}; + +#ifdef CONFIG_DEVFREQ_GOV_QCOM_GPUBW_MON +int devfreq_vbif_update_bw(unsigned long ib, unsigned long ab); +int devfreq_vbif_register_callback(void *); +#endif + +#endif diff --git a/include/linux/msm_audio_ion.h b/include/linux/msm_audio_ion.h new file mode 100644 index 000000000000..9e77ac317c28 --- /dev/null +++ b/include/linux/msm_audio_ion.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2015, 2017 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 _LINUX_MSM_AUDIO_ION_H +#define _LINUX_MSM_AUDIO_ION_H +#include <sound/q6asm-v2.h> +#include <sound/pcm.h> +#include <linux/msm_ion.h> + +enum { + HLOS_TO_ADSP = 1, + ADSP_TO_HLOS, +}; + +#define VMID_CP_ADSP_SHARED 33 + +int msm_audio_ion_alloc(const char *name, struct ion_client **client, + struct ion_handle **handle, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); + +int msm_audio_ion_import(const char *name, struct ion_client **client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); + +int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle); +int msm_audio_ion_mmap(struct audio_buffer *substream, + struct vm_area_struct *vma); + +bool msm_audio_ion_is_smmu_available(void); +int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op); + +struct ion_client *msm_audio_ion_client_create(const char *name); +void msm_audio_ion_client_destroy(struct ion_client *client); +int msm_audio_ion_import_legacy(const char *name, struct ion_client *client, + struct ion_handle **handle, int fd, + unsigned long *ionflag, size_t bufsz, + ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr); +int msm_audio_ion_free_legacy(struct ion_client *client, + struct ion_handle *handle); +u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa); + +int msm_audio_ion_phys_assign(const char *name, struct ion_client **client, + struct ion_handle **handle, + int fd, ion_phys_addr_t *paddr, + size_t *pa_len, u8 assign_type); +int msm_audio_ion_phys_free(struct ion_client *client, + struct ion_handle *handle, + ion_phys_addr_t *paddr, + size_t *pa_len, u8 assign_type); +#endif /* _LINUX_MSM_AUDIO_ION_H */ diff --git a/include/linux/msm_bcl.h b/include/linux/msm_bcl.h new file mode 100644 index 000000000000..3b84f37ed956 --- /dev/null +++ b/include/linux/msm_bcl.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, 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 __MSM_BCL_H +#define __MSM_BCL_H + +#define BCL_NAME_MAX_LEN 20 + +enum bcl_trip_type { + BCL_HIGH_TRIP, + BCL_LOW_TRIP, + BCL_TRIP_MAX, +}; + +enum bcl_param { + BCL_PARAM_VOLTAGE, + BCL_PARAM_CURRENT, + BCL_PARAM_MAX, +}; + +struct bcl_threshold { + int trip_value; + enum bcl_trip_type type; + void *trip_data; + void (*trip_notify) (enum bcl_trip_type, int, void *); +}; +struct bcl_param_data; +struct bcl_driver_ops { + int (*read) (int *); + int (*set_high_trip) (int); + int (*get_high_trip) (int *); + int (*set_low_trip) (int); + int (*get_low_trip) (int *); + int (*disable) (void); + int (*enable) (void); + int (*notify) (struct bcl_param_data *, int, + enum bcl_trip_type); +}; + +struct bcl_param_data { + char name[BCL_NAME_MAX_LEN]; + struct device device; + struct bcl_driver_ops *ops; + int high_trip; + int low_trip; + int last_read_val; + bool registered; + struct kobj_attribute val_attr; + struct kobj_attribute high_trip_attr; + struct kobj_attribute low_trip_attr; + struct attribute_group bcl_attr_gp; + struct bcl_threshold *thresh[BCL_TRIP_MAX]; +}; + +#ifdef CONFIG_MSM_BCL_CTL +struct bcl_param_data *msm_bcl_register_param(enum bcl_param, + struct bcl_driver_ops *, char *); +int msm_bcl_unregister_param(struct bcl_param_data *); +int msm_bcl_enable(void); +int msm_bcl_disable(void); +int msm_bcl_set_threshold(enum bcl_param, enum bcl_trip_type, + struct bcl_threshold *); +int msm_bcl_read(enum bcl_param, int *); +#else +static inline struct bcl_param_data *msm_bcl_register_param( + enum bcl_param param_type, struct bcl_driver_ops *ops, char *name) +{ + return NULL; +} +static inline int msm_bcl_unregister_param(struct bcl_param_data *data) +{ + return -ENOSYS; +} +static inline int msm_bcl_enable(void) +{ + return -ENOSYS; +} +static inline int msm_bcl_disable(void) +{ + return -ENOSYS; +} +static inline int msm_bcl_set_threshold(enum bcl_param param_type, + enum bcl_trip_type type, + struct bcl_threshold *inp_thresh) +{ + return -ENOSYS; +} +static inline int msm_bcl_read(enum bcl_param param_type, int *vbat_value) +{ + return -ENOSYS; +} +#endif + +#endif /*__MSM_BCL_H*/ diff --git a/include/linux/msm_bus_rules.h b/include/linux/msm_bus_rules.h new file mode 100644 index 000000000000..1cc83faa6111 --- /dev/null +++ b/include/linux/msm_bus_rules.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2014-2016, 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 _ARCH_ARM_MACH_MSM_BUS_RULES_H +#define _ARCH_ARM_MACH_MSM_BUS_RULES_H + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/notifier.h> +#include <dt-bindings/msm/msm-bus-rule-ops.h> + +#define MAX_NODES (5) + +struct rule_update_path_info { + u32 id; + u64 ab; + u64 ib; + u64 clk; + bool added; + struct list_head link; +}; + +struct rule_apply_rcm_info { + u32 id; + u64 lim_bw; + int throttle; + bool after_clk_commit; + struct list_head link; +}; + +struct bus_rule_type { + int num_src; + int *src_id; + int src_field; + int op; + u64 thresh; + int num_dst; + int *dst_node; + u64 dst_bw; + int mode; + void *client_data; +}; + +void msm_rule_register(int num_rules, struct bus_rule_type *rule, + struct notifier_block *nb); +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule, + struct notifier_block *nb); +bool msm_rule_update(struct bus_rule_type *old_rule, + struct bus_rule_type *new_rule, + struct notifier_block *nb); +void msm_rule_evaluate_rules(int node); +void print_rules_buf(char *buf, int count); +bool msm_rule_are_rules_registered(void); +#endif /* _ARCH_ARM_MACH_MSM_BUS_RULES_H */ diff --git a/include/linux/msm_dma_iommu_mapping.h b/include/linux/msm_dma_iommu_mapping.h new file mode 100644 index 000000000000..73e69383b9b6 --- /dev/null +++ b/include/linux/msm_dma_iommu_mapping.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2015-2016, 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 _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> + +#ifdef CONFIG_IOMMU_API +/* +* 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, + struct dma_attrs *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 msm_dma_map_sg_attrs(dev, sg, nents, dir, dma_buf, NULL); +} + +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) +{ + DEFINE_DMA_ATTRS(attrs); + + init_dma_attrs(&attrs); + dma_set_attr(DMA_ATTR_NO_DELAYED_UNMAP, &attrs); + return msm_dma_map_sg_attrs(dev, sg, nents, dir, dma_buf, &attrs); +} + +void msm_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents, + enum dma_data_direction dir, struct dma_buf *dma_buf); + +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_IOMMU_API*/ + +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, + struct dma_attrs *attr) +{ + return -EINVAL; +} + +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 void msm_dma_unmap_sg(struct device *dev, + struct scatterlist *sgl, int nents, + enum dma_data_direction dir, + struct dma_buf *dma_buf) +{ +} + +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_IOMMU_API*/ + +#endif diff --git a/include/linux/msm_ep_pcie.h b/include/linux/msm_ep_pcie.h new file mode 100644 index 000000000000..489020097a69 --- /dev/null +++ b/include/linux/msm_ep_pcie.h @@ -0,0 +1,289 @@ +/* Copyright (c) 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 __MSM_EP_PCIE_H +#define __MSM_EP_PCIE_H + +#include <linux/types.h> + +enum ep_pcie_link_status { + EP_PCIE_LINK_DISABLED, + EP_PCIE_LINK_UP, + EP_PCIE_LINK_ENABLED, +}; + +enum ep_pcie_event { + EP_PCIE_EVENT_INVALID = 0, + EP_PCIE_EVENT_PM_D0 = 0x1, + EP_PCIE_EVENT_PM_D3_HOT = 0x2, + EP_PCIE_EVENT_PM_D3_COLD = 0x4, + EP_PCIE_EVENT_PM_RST_DEAST = 0x8, + EP_PCIE_EVENT_LINKDOWN = 0x10, + EP_PCIE_EVENT_LINKUP = 0x20, + EP_PCIE_EVENT_MHI_A7 = 0x40, + EP_PCIE_EVENT_MMIO_WRITE = 0x80, +}; + +enum ep_pcie_irq_event { + EP_PCIE_INT_EVT_LINK_DOWN = 1, + EP_PCIE_INT_EVT_BME, + EP_PCIE_INT_EVT_PM_TURNOFF, + EP_PCIE_INT_EVT_DEBUG, + EP_PCIE_INT_EVT_LTR, + EP_PCIE_INT_EVT_MHI_Q6, + EP_PCIE_INT_EVT_MHI_A7, + EP_PCIE_INT_EVT_DSTATE_CHANGE, + EP_PCIE_INT_EVT_L1SUB_TIMEOUT, + EP_PCIE_INT_EVT_MMIO_WRITE, + EP_PCIE_INT_EVT_CFG_WRITE, + EP_PCIE_INT_EVT_BRIDGE_FLUSH_N, + EP_PCIE_INT_EVT_LINK_UP, + EP_PCIE_INT_EVT_MAX = 13, +}; + +enum ep_pcie_trigger { + EP_PCIE_TRIGGER_CALLBACK, + EP_PCIE_TRIGGER_COMPLETION, +}; + +enum ep_pcie_options { + EP_PCIE_OPT_NULL = 0, + EP_PCIE_OPT_AST_WAKE = 0x1, + EP_PCIE_OPT_POWER_ON = 0x2, + EP_PCIE_OPT_ENUM = 0x4, + EP_PCIE_OPT_ALL = 0xFFFFFFFF, +}; + +struct ep_pcie_notify { + enum ep_pcie_event event; + void *user; + void *data; + u32 options; +}; + +struct ep_pcie_register_event { + u32 events; + void *user; + enum ep_pcie_trigger mode; + void (*callback)(struct ep_pcie_notify *notify); + struct ep_pcie_notify notify; + struct completion *completion; + u32 options; +}; + +struct ep_pcie_iatu { + u32 start; + u32 end; + u32 tgt_lower; + u32 tgt_upper; +}; + +struct ep_pcie_msi_config { + u32 lower; + u32 upper; + u32 data; + u32 msg_num; +}; + +struct ep_pcie_db_config { + u8 base; + u8 end; + u32 tgt_addr; +}; + +struct ep_pcie_hw { + struct list_head node; + u32 device_id; + void **private_data; + int (*register_event)(struct ep_pcie_register_event *reg); + int (*deregister_event)(void); + enum ep_pcie_link_status (*get_linkstatus)(void); + int (*config_outbound_iatu)(struct ep_pcie_iatu entries[], + u32 num_entries); + int (*get_msi_config)(struct ep_pcie_msi_config *cfg); + int (*trigger_msi)(u32 idx); + int (*wakeup_host)(void); + int (*enable_endpoint)(enum ep_pcie_options opt); + int (*disable_endpoint)(void); + int (*config_db_routing)(struct ep_pcie_db_config chdb_cfg, + struct ep_pcie_db_config erdb_cfg); + int (*mask_irq_event)(enum ep_pcie_irq_event event, + bool enable); +}; + +/* + * ep_pcie_register_drv - register HW driver. + * @phandle: PCIe endpoint HW driver handle + * + * This function registers PCIe HW driver to PCIe endpoint service + * layer. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_register_drv(struct ep_pcie_hw *phandle); + + /* + * ep_pcie_deregister_drv - deregister HW driver. + * @phandle: PCIe endpoint HW driver handle + * + * This function deregisters PCIe HW driver to PCIe endpoint service + * layer. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_deregister_drv(struct ep_pcie_hw *phandle); + +/* + * ep_pcie_get_phandle - get PCIe endpoint HW driver handle. + * @id: PCIe endpoint device ID + * + * This function deregisters PCIe HW driver from PCIe endpoint service + * layer. + * + * Return: PCIe endpoint HW driver handle + */ +struct ep_pcie_hw *ep_pcie_get_phandle(u32 id); + +/* + * ep_pcie_register_event - register event with PCIe driver. + * @phandle: PCIe endpoint HW driver handle + * @reg: event structure + * + * This function gives PCIe client driver an option to register + * event with PCIe driver. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_register_event(struct ep_pcie_hw *phandle, + struct ep_pcie_register_event *reg); + +/* + * ep_pcie_deregister_event - deregister event with PCIe driver. + * @phandle: PCIe endpoint HW driver handle + * + * This function gives PCIe client driver an option to deregister + * existing event with PCIe driver. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_deregister_event(struct ep_pcie_hw *phandle); + +/* + * ep_pcie_get_linkstatus - indicate the status of PCIe link. + * @phandle: PCIe endpoint HW driver handle + * + * This function tells PCIe client about the status of PCIe link. + * + * Return: status of PCIe link + */ +enum ep_pcie_link_status ep_pcie_get_linkstatus(struct ep_pcie_hw *phandle); + +/* + * ep_pcie_config_outbound_iatu - configure outbound iATU. + * @entries: iatu entries + * @num_entries: number of iatu entries + * + * This function configures the outbound iATU for PCIe + * client's access to the regions in the host memory which + * are specified by the SW on host side. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_config_outbound_iatu(struct ep_pcie_hw *phandle, + struct ep_pcie_iatu entries[], + u32 num_entries); + +/* + * ep_pcie_get_msi_config - get MSI config info. + * @phandle: PCIe endpoint HW driver handle + * @cfg: pointer to MSI config + * + * This function returns MSI config info. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_get_msi_config(struct ep_pcie_hw *phandle, + struct ep_pcie_msi_config *cfg); + +/* + * ep_pcie_trigger_msi - trigger an MSI. + * @phandle: PCIe endpoint HW driver handle + * @idx: MSI index number + * + * This function allows PCIe client to trigger an MSI + * on host side. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_trigger_msi(struct ep_pcie_hw *phandle, u32 idx); + +/* + * ep_pcie_wakeup_host - wake up the host. + * @phandle: PCIe endpoint HW driver handle + * + * This function asserts WAKE GPIO to wake up the host. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_wakeup_host(struct ep_pcie_hw *phandle); + +/* + * ep_pcie_enable_endpoint - enable PCIe endpoint. + * @phandle: PCIe endpoint HW driver handle + * @opt: endpoint enable options + * + * This function is to enable the PCIe endpoint device. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_enable_endpoint(struct ep_pcie_hw *phandle, + enum ep_pcie_options opt); + +/* + * ep_pcie_disable_endpoint - disable PCIe endpoint. + * @phandle: PCIe endpoint HW driver handle + * + * This function is to disable the PCIe endpoint device. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_disable_endpoint(struct ep_pcie_hw *phandle); + +/* + * ep_pcie_config_db_routing - Configure routing of doorbells to another block. + * @phandle: PCIe endpoint HW driver handle + * @chdb_cfg: channel doorbell config + * @erdb_cfg: event ring doorbell config + * + * This function allows PCIe core to route the doorbells intended + * for another entity via a target address. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_config_db_routing(struct ep_pcie_hw *phandle, + struct ep_pcie_db_config chdb_cfg, + struct ep_pcie_db_config erdb_cfg); + +/* + * ep_pcie_mask_irq_event - enable and disable IRQ event. + * @phandle: PCIe endpoint HW driver handle + * @event: IRQ event + * @enable: true to enable that IRQ event and false to disable + * + * This function is to enable and disable IRQ event. + * + * Return: 0 on success, negative value on error + */ +int ep_pcie_mask_irq_event(struct ep_pcie_hw *phandle, + enum ep_pcie_irq_event event, + bool enable); +#endif diff --git a/include/linux/msm_ext_display.h b/include/linux/msm_ext_display.h new file mode 100644 index 000000000000..9a03b79e09d7 --- /dev/null +++ b/include/linux/msm_ext_display.h @@ -0,0 +1,167 @@ +/* include/linux/msm_ext_display.h + * + * Copyright (c) 2014-2017, 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 _MSM_EXT_DISPLAY_H_ +#define _MSM_EXT_DISPLAY_H_ + +#include <linux/device.h> +#include <linux/platform_device.h> + +#define AUDIO_ACK_SET_ENABLE BIT(5) +#define AUDIO_ACK_ENABLE BIT(4) +#define AUDIO_ACK_CONNECT BIT(0) + +/** + * Flags to be used with the HPD operation of the external display + * interface: + * MSM_EXT_DISP_HPD_AUDIO: audio will be routed to external display + * MSM_EXT_DISP_HPD_VIDEO: video will be routed to external display + * MSM_EXT_DISP_HPD_ASYNC_AUDIO: don't wait audio notification once wake it up + * MSM_EXT_DISP_HPD_ASYNC_VIDEO: don't wait video notification once wake it up + */ +#define MSM_EXT_DISP_HPD_AUDIO BIT(0) +#define MSM_EXT_DISP_HPD_VIDEO BIT(1) +#define MSM_EXT_DISP_HPD_ASYNC_AUDIO BIT(2) +#define MSM_EXT_DISP_HPD_ASYNC_VIDEO BIT(3) + +/** + * struct ext_disp_cable_notify - cable notify handler structure + * @link: a link for the linked list + * @status: current status of HDMI/DP cable connection + * @hpd_notify: callback function to provide cable status + */ +struct ext_disp_cable_notify { + struct list_head link; + int status; + void (*hpd_notify)(struct ext_disp_cable_notify *h); +}; + +struct msm_ext_disp_audio_edid_blk { + u8 *audio_data_blk; + unsigned int audio_data_blk_size; /* in bytes */ + u8 *spk_alloc_data_blk; + unsigned int spk_alloc_data_blk_size; /* in bytes */ +}; + +struct msm_ext_disp_audio_setup_params { + u32 sample_rate_hz; + u32 num_of_channels; + u32 channel_allocation; + u32 level_shift; + bool down_mix; + u32 sample_present; +}; + +/** + * External Display identifier for use to determine which interface + * the audio driver is interacting with. + */ +enum msm_ext_disp_type { + EXT_DISPLAY_TYPE_HDMI, + EXT_DISPLAY_TYPE_DP, + EXT_DISPLAY_TYPE_MAX +}; + +/** + * External Display cable state used by display interface to indicate + * connect/disconnect of interface. + */ +enum msm_ext_disp_cable_state { + EXT_DISPLAY_CABLE_DISCONNECT, + EXT_DISPLAY_CABLE_CONNECT, + EXT_DISPLAY_CABLE_STATE_MAX +}; + +/** + * External Display power state used by display interface to indicate + * power on/off of the interface. + */ +enum msm_ext_disp_power_state { + EXT_DISPLAY_POWER_OFF, + EXT_DISPLAY_POWER_ON, + EXT_DISPLAY_POWER_MAX +}; + +/** + * struct msm_ext_disp_intf_ops - operations exposed to display interface + * @hpd: updates external display interface state + * @notify: acknowledgment to power on or off + */ +struct msm_ext_disp_intf_ops { + int (*hpd)(struct platform_device *pdev, + enum msm_ext_disp_type type, + enum msm_ext_disp_cable_state state, + u32 flags); + int (*notify)(struct platform_device *pdev, + enum msm_ext_disp_cable_state state); + int (*ack)(struct platform_device *pdev, u32 ack); +}; + +/** + * struct msm_ext_disp_audio_codec_ops - operations exposed to audio codec + * @audio_info_setup: configure audio on interface + * @get_audio_edid_blk: retrieve audio edid block + * @cable_status: cable connected/disconnected + * @get_intf_id: id of connected interface + * @acknowledge: acknowledge audio status + * @codec_ready: notify when codec is ready + */ +struct msm_ext_disp_audio_codec_ops { + int (*audio_info_setup)(struct platform_device *pdev, + struct msm_ext_disp_audio_setup_params *params); + int (*get_audio_edid_blk)(struct platform_device *pdev, + struct msm_ext_disp_audio_edid_blk *blk); + int (*cable_status)(struct platform_device *pdev, u32 vote); + int (*get_intf_id)(struct platform_device *pdev); + void (*teardown_done)(struct platform_device *pdev); + int (*acknowledge)(struct platform_device *pdev, u32 ack); + void (*codec_ready)(struct platform_device *pdev); +}; + +/* + * struct msm_ext_disp_init_data - data needed to register the display interface + * @disp: external display type + * @intf_ops: external display interface operations + * @codec_ops: audio codec operations + */ +struct msm_ext_disp_init_data { + enum msm_ext_disp_type type; + struct kobject *kobj; + struct msm_ext_disp_intf_ops intf_ops; + struct msm_ext_disp_audio_codec_ops codec_ops; + struct platform_device *pdev; +}; + +/* + * msm_ext_disp_register_audio_codec() - audio codec registration + * @pdev: platform device pointer + * @codec_ops: audio codec operations + */ +int msm_ext_disp_register_audio_codec(struct platform_device *pdev, + struct msm_ext_disp_audio_codec_ops *ops); + +/* + * msm_hdmi_register_audio_codec() - wrapper for hdmi audio codec registration + * @pdev: platform device pointer + * @codec_ops: audio codec operations + */ +int msm_hdmi_register_audio_codec(struct platform_device *pdev, + struct msm_ext_disp_audio_codec_ops *ops); +/* + * msm_ext_disp_register_intf() - display interface registration + * @init_data: data needed to register the display interface + */ +int msm_ext_disp_register_intf(struct platform_device *pdev, + struct msm_ext_disp_init_data *init_data); + +#endif /*_MSM_EXT_DISPLAY_H_*/ diff --git a/include/linux/msm_gsi.h b/include/linux/msm_gsi.h new file mode 100644 index 000000000000..b95ea88c2424 --- /dev/null +++ b/include/linux/msm_gsi.h @@ -0,0 +1,1290 @@ +/* Copyright (c) 2015-2017, 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 MSM_GSI_H +#define MSM_GSI_H +#include <linux/types.h> + +enum gsi_ver { + GSI_VER_ERR = 0, + GSI_VER_1_0 = 1, + GSI_VER_1_2 = 2, + GSI_VER_1_3 = 3, + GSI_VER_MAX, +}; + +enum gsi_status { + GSI_STATUS_SUCCESS = 0, + GSI_STATUS_ERROR = 1, + GSI_STATUS_RING_INSUFFICIENT_SPACE = 2, + GSI_STATUS_RING_EMPTY = 3, + GSI_STATUS_RES_ALLOC_FAILURE = 4, + GSI_STATUS_BAD_STATE = 5, + GSI_STATUS_INVALID_PARAMS = 6, + GSI_STATUS_UNSUPPORTED_OP = 7, + GSI_STATUS_NODEV = 8, + GSI_STATUS_POLL_EMPTY = 9, + GSI_STATUS_EVT_RING_INCOMPATIBLE = 10, + GSI_STATUS_TIMED_OUT = 11, + GSI_STATUS_AGAIN = 12, +}; + +enum gsi_per_evt { + GSI_PER_EVT_GLOB_ERROR, + GSI_PER_EVT_GLOB_GP1, + GSI_PER_EVT_GLOB_GP2, + GSI_PER_EVT_GLOB_GP3, + GSI_PER_EVT_GENERAL_BREAK_POINT, + GSI_PER_EVT_GENERAL_BUS_ERROR, + GSI_PER_EVT_GENERAL_CMD_FIFO_OVERFLOW, + GSI_PER_EVT_GENERAL_MCS_STACK_OVERFLOW, +}; + +/** + * gsi_per_notify - Peripheral callback info + * + * @user_data: cookie supplied in gsi_register_device + * @evt_id: type of notification + * @err_desc: error related information + * + */ +struct gsi_per_notify { + void *user_data; + enum gsi_per_evt evt_id; + union { + uint16_t err_desc; + } data; +}; + +enum gsi_intr_type { + GSI_INTR_MSI = 0x0, + GSI_INTR_IRQ = 0x1 +}; + + +/** + * gsi_per_props - Peripheral related properties + * + * @gsi: GSI core version + * @ee: EE where this driver and peripheral driver runs + * @intr: control interrupt type + * @intvec: write data for MSI write + * @msi_addr: MSI address + * @irq: IRQ number + * @phys_addr: physical address of GSI block + * @size: register size of GSI block + * @notify_cb: general notification callback + * @req_clk_cb: callback to request peripheral clock + * granted should be set to true if request is completed + * synchronously, false otherwise (peripheral needs + * to call gsi_complete_clk_grant later when request is + * completed) + * if this callback is not provided, then GSI will assume + * peripheral is clocked at all times + * @rel_clk_cb: callback to release peripheral clock + * @user_data: cookie used for notifications + * + * All the callbacks are in interrupt context + * + */ +struct gsi_per_props { + enum gsi_ver ver; + unsigned int ee; + enum gsi_intr_type intr; + uint32_t intvec; + uint64_t msi_addr; + unsigned int irq; + phys_addr_t phys_addr; + unsigned long size; + void (*notify_cb)(struct gsi_per_notify *notify); + void (*req_clk_cb)(void *user_data, bool *granted); + int (*rel_clk_cb)(void *user_data); + void *user_data; +}; + +enum gsi_evt_err { + GSI_EVT_OUT_OF_BUFFERS_ERR = 0x0, + GSI_EVT_OUT_OF_RESOURCES_ERR = 0x1, + GSI_EVT_UNSUPPORTED_INTER_EE_OP_ERR = 0x2, + GSI_EVT_EVT_RING_EMPTY_ERR = 0x3, +}; + +/** + * gsi_evt_err_notify - event ring error callback info + * + * @user_data: cookie supplied in gsi_alloc_evt_ring + * @evt_id: type of error + * @err_desc: more info about the error + * + */ +struct gsi_evt_err_notify { + void *user_data; + enum gsi_evt_err evt_id; + uint16_t err_desc; +}; + +enum gsi_evt_chtype { + GSI_EVT_CHTYPE_MHI_EV = 0x0, + GSI_EVT_CHTYPE_XHCI_EV = 0x1, + GSI_EVT_CHTYPE_GPI_EV = 0x2, + GSI_EVT_CHTYPE_XDCI_EV = 0x3 +}; + +enum gsi_evt_ring_elem_size { + GSI_EVT_RING_RE_SIZE_4B = 4, + GSI_EVT_RING_RE_SIZE_16B = 16, +}; + +/** + * gsi_evt_ring_props - Event ring related properties + * + * @intf: interface type (of the associated channel) + * @intr: interrupt type + * @re_size: size of event ring element + * @ring_len: length of ring in bytes (must be integral multiple of + * re_size) + * @ring_base_addr: physical base address of ring. Address must be aligned to + * ring_len rounded to power of two + * @ring_base_vaddr: virtual base address of ring (set to NULL when not + * applicable) + * @int_modt: cycles base interrupt moderation (32KHz clock) + * @int_modc: interrupt moderation packet counter + * @intvec: write data for MSI write + * @msi_addr: MSI address + * @rp_update_addr: physical address to which event read pointer should be + * written on every event generation. must be set to 0 when + * no update is desdired + * @exclusive: if true, only one GSI channel can be associated with this + * event ring. if false, the event ring can be shared among + * multiple GSI channels but in that case no polling + * (GSI_CHAN_MODE_POLL) is supported on any of those channels + * @err_cb: error notification callback + * @user_data: cookie used for error notifications + * @evchid_valid: is evchid valid? + * @evchid: the event ID that is being specifically requested (this is + * relevant for MHI where doorbell routing requires ERs to be + * physically contiguous) + */ +struct gsi_evt_ring_props { + enum gsi_evt_chtype intf; + enum gsi_intr_type intr; + enum gsi_evt_ring_elem_size re_size; + uint16_t ring_len; + uint64_t ring_base_addr; + void *ring_base_vaddr; + uint16_t int_modt; + uint8_t int_modc; + uint32_t intvec; + uint64_t msi_addr; + uint64_t rp_update_addr; + bool exclusive; + void (*err_cb)(struct gsi_evt_err_notify *notify); + void *user_data; + bool evchid_valid; + uint8_t evchid; +}; + +enum gsi_chan_mode { + GSI_CHAN_MODE_CALLBACK = 0x0, + GSI_CHAN_MODE_POLL = 0x1, +}; + +enum gsi_chan_prot { + GSI_CHAN_PROT_MHI = 0x0, + GSI_CHAN_PROT_XHCI = 0x1, + GSI_CHAN_PROT_GPI = 0x2, + GSI_CHAN_PROT_XDCI = 0x3 +}; + +enum gsi_chan_dir { + GSI_CHAN_DIR_FROM_GSI = 0x0, + GSI_CHAN_DIR_TO_GSI = 0x1 +}; + +enum gsi_max_prefetch { + GSI_ONE_PREFETCH_SEG = 0x0, + GSI_TWO_PREFETCH_SEG = 0x1 +}; + +enum gsi_chan_evt { + GSI_CHAN_EVT_INVALID = 0x0, + GSI_CHAN_EVT_SUCCESS = 0x1, + GSI_CHAN_EVT_EOT = 0x2, + GSI_CHAN_EVT_OVERFLOW = 0x3, + GSI_CHAN_EVT_EOB = 0x4, + GSI_CHAN_EVT_OOB = 0x5, + GSI_CHAN_EVT_DB_MODE = 0x6, + GSI_CHAN_EVT_UNDEFINED = 0x10, + GSI_CHAN_EVT_RE_ERROR = 0x11, +}; + +/** + * gsi_chan_xfer_notify - Channel callback info + * + * @chan_user_data: cookie supplied in gsi_alloc_channel + * @xfer_user_data: cookie of the gsi_xfer_elem that caused the + * event to be generated + * @evt_id: type of event triggered by the associated TRE + * (corresponding to xfer_user_data) + * @bytes_xfered: number of bytes transferred by the associated TRE + * (corresponding to xfer_user_data) + * + */ +struct gsi_chan_xfer_notify { + void *chan_user_data; + void *xfer_user_data; + enum gsi_chan_evt evt_id; + uint16_t bytes_xfered; +}; + +enum gsi_chan_err { + GSI_CHAN_INVALID_TRE_ERR = 0x0, + GSI_CHAN_NON_ALLOCATED_EVT_ACCESS_ERR = 0x1, + GSI_CHAN_OUT_OF_BUFFERS_ERR = 0x2, + GSI_CHAN_OUT_OF_RESOURCES_ERR = 0x3, + GSI_CHAN_UNSUPPORTED_INTER_EE_OP_ERR = 0x4, + GSI_CHAN_HWO_1_ERR = 0x5 +}; + +/** + * gsi_chan_err_notify - Channel general callback info + * + * @chan_user_data: cookie supplied in gsi_alloc_channel + * @evt_id: type of error + * @err_desc: more info about the error + * + */ +struct gsi_chan_err_notify { + void *chan_user_data; + enum gsi_chan_err evt_id; + uint16_t err_desc; +}; + +enum gsi_chan_ring_elem_size { + GSI_CHAN_RE_SIZE_4B = 4, + GSI_CHAN_RE_SIZE_16B = 16, + GSI_CHAN_RE_SIZE_32B = 32, +}; + +enum gsi_chan_use_db_eng { + GSI_CHAN_DIRECT_MODE = 0x0, + GSI_CHAN_DB_MODE = 0x1, +}; + +/** + * gsi_chan_props - Channel related properties + * + * @prot: interface type + * @dir: channel direction + * @ch_id: virtual channel ID + * @evt_ring_hdl: handle of associated event ring. set to ~0 if no + * event ring associated + * @re_size: size of channel ring element + * @ring_len: length of ring in bytes (must be integral multiple of + * re_size) + * @max_re_expected: maximal number of ring elements expected to be queued. + * used for data path statistics gathering. if 0 provided + * ring_len / re_size will be used. + * @ring_base_addr: physical base address of ring. Address must be aligned to + * ring_len rounded to power of two + * @ring_base_vaddr: virtual base address of ring (set to NULL when not + * applicable) + * @use_db_eng: 0 => direct mode (doorbells are written directly to RE + * engine) + * 1 => DB mode (doorbells are written to DB engine) + * @max_prefetch: limit number of pre-fetch segments for channel + * @low_weight: low channel weight (priority of channel for RE engine + * round robin algorithm); must be >= 1 + * @xfer_cb: transfer notification callback, this callback happens + * on event boundaries + * + * e.g. 1 + * + * out TD with 3 REs + * + * RE1: EOT=0, EOB=0, CHAIN=1; + * RE2: EOT=0, EOB=0, CHAIN=1; + * RE3: EOT=1, EOB=0, CHAIN=0; + * + * the callback will be triggered for RE3 using the + * xfer_user_data of that RE + * + * e.g. 2 + * + * in REs + * + * RE1: EOT=1, EOB=0, CHAIN=0; + * RE2: EOT=1, EOB=0, CHAIN=0; + * RE3: EOT=1, EOB=0, CHAIN=0; + * + * received packet consumes all of RE1, RE2 and part of RE3 + * for EOT condition. there will be three callbacks in below + * order + * + * callback for RE1 using GSI_CHAN_EVT_OVERFLOW + * callback for RE2 using GSI_CHAN_EVT_OVERFLOW + * callback for RE3 using GSI_CHAN_EVT_EOT + * + * @err_cb: error notification callback + * @chan_user_data: cookie used for notifications + * + * All the callbacks are in interrupt context + * + */ +struct gsi_chan_props { + enum gsi_chan_prot prot; + enum gsi_chan_dir dir; + uint8_t ch_id; + unsigned long evt_ring_hdl; + enum gsi_chan_ring_elem_size re_size; + uint16_t ring_len; + uint16_t max_re_expected; + uint64_t ring_base_addr; + void *ring_base_vaddr; + enum gsi_chan_use_db_eng use_db_eng; + enum gsi_max_prefetch max_prefetch; + uint8_t low_weight; + void (*xfer_cb)(struct gsi_chan_xfer_notify *notify); + void (*err_cb)(struct gsi_chan_err_notify *notify); + void *chan_user_data; +}; + +enum gsi_xfer_flag { + GSI_XFER_FLAG_CHAIN = 0x1, + GSI_XFER_FLAG_EOB = 0x100, + GSI_XFER_FLAG_EOT = 0x200, + GSI_XFER_FLAG_BEI = 0x400 +}; + +enum gsi_xfer_elem_type { + GSI_XFER_ELEM_DATA, + GSI_XFER_ELEM_IMME_CMD, +}; + +/** + * gsi_xfer_elem - Metadata about a single transfer + * + * @addr: physical address of buffer + * @len: size of buffer for GSI_XFER_ELEM_DATA: + * for outbound transfers this is the number of bytes to + * transfer. + * for inbound transfers, this is the maximum number of + * bytes the host expects from device in this transfer + * + * immediate command opcode for GSI_XFER_ELEM_IMME_CMD + * @flags: transfer flags, OR of all the applicable flags + * + * GSI_XFER_FLAG_BEI: Block event interrupt + * 1: Event generated by this ring element must not assert + * an interrupt to the host + * 0: Event generated by this ring element must assert an + * interrupt to the host + * + * GSI_XFER_FLAG_EOT: Interrupt on end of transfer + * 1: If an EOT condition is encountered when processing + * this ring element, an event is generated by the device + * with its completion code set to EOT. + * 0: If an EOT condition is encountered for this ring + * element, a completion event is not be generated by the + * device, unless IEOB is 1 + * + * GSI_XFER_FLAG_EOB: Interrupt on end of block + * 1: Device notifies host after processing this ring element + * by sending a completion event + * 0: Completion event is not required after processing this + * ring element + * + * GSI_XFER_FLAG_CHAIN: Chain bit that identifies the ring + * elements in a TD + * + * @type: transfer type + * + * GSI_XFER_ELEM_DATA: for all data transfers + * GSI_XFER_ELEM_IMME_CMD: for IPA immediate commands + * + * @xfer_user_data: cookie used in xfer_cb + * + */ +struct gsi_xfer_elem { + uint64_t addr; + uint16_t len; + uint16_t flags; + enum gsi_xfer_elem_type type; + void *xfer_user_data; +}; + +/** + * gsi_gpi_channel_scratch - GPI protocol SW config area of + * channel scratch + * + * @max_outstanding_tre: Used for the prefetch management sequence by the + * sequencer. Defines the maximum number of allowed + * outstanding TREs in IPA/GSI (in Bytes). RE engine + * prefetch will be limited by this configuration. It + * is suggested to configure this value to IPA_IF + * channel TLV queue size times element size. To disable + * the feature in doorbell mode (DB Mode=1). Maximum + * outstanding TREs should be set to 64KB + * (or any value larger or equal to ring length . RLEN) + * @outstanding_threshold: Used for the prefetch management sequence by the + * sequencer. Defines the threshold (in Bytes) as to when + * to update the channel doorbell. Should be smaller than + * Maximum outstanding TREs. value. It is suggested to + * configure this value to 2 * element size. + */ +struct __packed gsi_gpi_channel_scratch { + uint64_t resvd1; + uint32_t resvd2:16; + uint32_t max_outstanding_tre:16; + uint32_t resvd3:16; + uint32_t outstanding_threshold:16; +}; + +/** + * gsi_mhi_channel_scratch - MHI protocol SW config area of + * channel scratch + * + * @mhi_host_wp_addr: Valid only when UL/DL Sync En is asserted. Defines + * address in host from which channel write pointer + * should be read in polling mode + * @assert_bit40: 1: bit #41 in address should be asserted upon + * IPA_IF.ProcessDescriptor routine (for MHI over PCIe + * transfers) + * 0: bit #41 in address should be deasserted upon + * IPA_IF.ProcessDescriptor routine (for non-MHI over + * PCIe transfers) + * @polling_configuration: Uplink channels: Defines timer to poll on MHI + * context. Range: 1 to 31 milliseconds. + * Downlink channel: Defines transfer ring buffer + * availability threshold to poll on MHI context in + * multiple of 8. Range: 0 to 31, meaning 0 to 258 ring + * elements. E.g., value of 2 indicates 16 ring elements. + * Valid only when Burst Mode Enabled is set to 1 + * @burst_mode_enabled: 0: Burst mode is disabled for this channel + * 1: Burst mode is enabled for this channel + * @polling_mode: 0: the channel is not in polling mode, meaning the + * host should ring DBs. + * 1: the channel is in polling mode, meaning the host + * @oob_mod_threshold: Defines OOB moderation threshold. Units are in 8 + * ring elements. + * should not ring DBs until notified of DB mode/OOB mode + * @max_outstanding_tre: Used for the prefetch management sequence by the + * sequencer. Defines the maximum number of allowed + * outstanding TREs in IPA/GSI (in Bytes). RE engine + * prefetch will be limited by this configuration. It + * is suggested to configure this value to IPA_IF + * channel TLV queue size times element size. + * To disable the feature in doorbell mode (DB Mode=1). + * Maximum outstanding TREs should be set to 64KB + * (or any value larger or equal to ring length . RLEN) + * @outstanding_threshold: Used for the prefetch management sequence by the + * sequencer. Defines the threshold (in Bytes) as to when + * to update the channel doorbell. Should be smaller than + * Maximum outstanding TREs. value. It is suggested to + * configure this value to min(TLV_FIFO_SIZE/2,8) * + * element size. + */ +struct __packed gsi_mhi_channel_scratch { + uint64_t mhi_host_wp_addr; + uint32_t rsvd1:1; + uint32_t assert_bit40:1; + uint32_t polling_configuration:5; + uint32_t burst_mode_enabled:1; + uint32_t polling_mode:1; + uint32_t oob_mod_threshold:5; + uint32_t resvd2:2; + uint32_t max_outstanding_tre:16; + uint32_t resvd3:16; + uint32_t outstanding_threshold:16; +}; + +/** + * gsi_xdci_channel_scratch - xDCI protocol SW config area of + * channel scratch + * + * @const_buffer_size: TRB buffer size in KB (similar to IPA aggregationi + * configuration). Must be aligned to Max USB Packet Size + * @xferrscidx: Transfer Resource Index (XferRscIdx). 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 + * @last_trb_addr: Address (LSB - based on alignment restrictions) of + * last TRB in queue. Used to identify rollover case + * @depcmd_low_addr: Used to generate "Update Transfer" command + * @max_outstanding_tre: Used for the prefetch management sequence by the + * sequencer. Defines the maximum number of allowed + * outstanding TREs in IPA/GSI (in Bytes). RE engine + * prefetch will be limited by this configuration. It + * is suggested to configure this value to IPA_IF + * channel TLV queue size times element size. + * To disable the feature in doorbell mode (DB Mode=1) + * Maximum outstanding TREs should be set to 64KB + * (or any value larger or equal to ring length . RLEN) + * @depcmd_hi_addr: Used to generate "Update Transfer" command + * @outstanding_threshold: Used for the prefetch management sequence by the + * sequencer. Defines the threshold (in Bytes) as to when + * to update the channel doorbell. Should be smaller than + * Maximum outstanding TREs. value. It is suggested to + * configure this value to 2 * element size. for MBIM the + * suggested configuration is the element size. + */ +struct __packed gsi_xdci_channel_scratch { + uint32_t last_trb_addr:16; + uint32_t resvd1:4; + uint32_t xferrscidx:7; + uint32_t const_buffer_size:5; + uint32_t depcmd_low_addr; + uint32_t depcmd_hi_addr:8; + uint32_t resvd2:8; + uint32_t max_outstanding_tre:16; + uint32_t resvd3:16; + uint32_t outstanding_threshold:16; +}; + +/** + * gsi_channel_scratch - channel scratch SW config area + * + */ +union __packed gsi_channel_scratch { + struct __packed gsi_gpi_channel_scratch gpi; + struct __packed gsi_mhi_channel_scratch mhi; + struct __packed gsi_xdci_channel_scratch xdci; + struct __packed { + uint32_t word1; + uint32_t word2; + uint32_t word3; + uint32_t word4; + } data; +}; + +/** + * gsi_mhi_evt_scratch - MHI protocol SW config area of + * event scratch + */ +struct __packed gsi_mhi_evt_scratch { + uint32_t resvd1; + uint32_t resvd2; +}; + +/** + * gsi_xdci_evt_scratch - xDCI protocol SW config area of + * event scratch + * + */ +struct __packed gsi_xdci_evt_scratch { + uint32_t gevntcount_low_addr; + uint32_t gevntcount_hi_addr:8; + uint32_t resvd1:24; +}; + +/** + * gsi_evt_scratch - event scratch SW config area + * + */ +union __packed gsi_evt_scratch { + struct __packed gsi_mhi_evt_scratch mhi; + struct __packed gsi_xdci_evt_scratch xdci; + struct __packed { + uint32_t word1; + uint32_t word2; + } data; +}; + +/** + * gsi_device_scratch - EE scratch config parameters + * + * @mhi_base_chan_idx_valid: is mhi_base_chan_idx valid? + * @mhi_base_chan_idx: base index of IPA MHI channel indexes. + * IPA MHI channel index = GSI channel ID + + * MHI base channel index + * @max_usb_pkt_size_valid: is max_usb_pkt_size valid? + * @max_usb_pkt_size: max USB packet size in bytes (valid values are + * 512 and 1024) + */ +struct gsi_device_scratch { + bool mhi_base_chan_idx_valid; + uint8_t mhi_base_chan_idx; + bool max_usb_pkt_size_valid; + uint16_t max_usb_pkt_size; +}; + +/** + * gsi_chan_info - information about channel occupancy + * + * @wp: channel write pointer (physical address) + * @rp: channel read pointer (physical address) + * @evt_valid: is evt* info valid? + * @evt_wp: event ring write pointer (physical address) + * @evt_rp: event ring read pointer (physical address) + */ +struct gsi_chan_info { + uint64_t wp; + uint64_t rp; + bool evt_valid; + uint64_t evt_wp; + uint64_t evt_rp; +}; + +#ifdef CONFIG_GSI +/** + * gsi_register_device - Peripheral should call this function to + * register itself with GSI before invoking any other APIs + * + * @props: Peripheral properties + * @dev_hdl: Handle populated by GSI, opaque to client + * + * @Return -GSI_STATUS_AGAIN if request should be re-tried later + * other error codes for failure + */ +int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl); + +/** + * gsi_complete_clk_grant - Peripheral should call this function to + * grant the clock resource requested by GSI previously that could not + * be granted synchronously. GSI will release the clock resource using + * the rel_clk_cb when appropriate + * + * @dev_hdl: Client handle previously obtained from + * gsi_register_device + * + * @Return gsi_status + */ +int gsi_complete_clk_grant(unsigned long dev_hdl); + +/** + * gsi_write_device_scratch - Peripheral should call this function to + * write to the EE scratch area + * + * @dev_hdl: Client handle previously obtained from + * gsi_register_device + * @val: Value to write + * + * @Return gsi_status + */ +int gsi_write_device_scratch(unsigned long dev_hdl, + struct gsi_device_scratch *val); + +/** + * gsi_deregister_device - Peripheral should call this function to + * de-register itself with GSI + * + * @dev_hdl: Client handle previously obtained from + * gsi_register_device + * @force: When set to true, cleanup is performed even if there + * are in use resources like channels, event rings, etc. + * this would be used after GSI reset to recover from some + * fatal error + * When set to false, there must not exist any allocated + * channels and event rings. + * + * @Return gsi_status + */ +int gsi_deregister_device(unsigned long dev_hdl, bool force); + +/** + * gsi_alloc_evt_ring - Peripheral should call this function to + * allocate an event ring + * + * @props: Event ring properties + * @dev_hdl: Client handle previously obtained from + * gsi_register_device + * @evt_ring_hdl: Handle populated by GSI, opaque to client + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl, + unsigned long *evt_ring_hdl); + +/** + * gsi_write_evt_ring_scratch - Peripheral should call this function to + * write to the scratch area of the event ring context + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @val: Value to write + * + * @Return gsi_status + */ +int gsi_write_evt_ring_scratch(unsigned long evt_ring_hdl, + union __packed gsi_evt_scratch val); + +/** + * gsi_dealloc_evt_ring - Peripheral should call this function to + * de-allocate an event ring. There should not exist any active + * channels using this event ring + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_dealloc_evt_ring(unsigned long evt_ring_hdl); + +/** + * gsi_query_evt_ring_db_addr - Peripheral should call this function to + * query the physical addresses of the event ring doorbell registers + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @db_addr_wp_lsb: Physical address of doorbell register where the 32 + * LSBs of the doorbell value should be written + * @db_addr_wp_msb: Physical address of doorbell register where the 32 + * MSBs of the doorbell value should be written + * + * @Return gsi_status + */ +int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl, + uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb); + +/** + * gsi_ring_evt_ring_db - Peripheral should call this function for + * ringing the event ring doorbell with given value + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @value: The value to be used for ringing the doorbell + * + * @Return gsi_status + */ +int gsi_ring_evt_ring_db(unsigned long evt_ring_hdl, uint64_t value); + +/** + * gsi_reset_evt_ring - Peripheral should call this function to + * reset an event ring to recover from error state + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_reset_evt_ring(unsigned long evt_ring_hdl); + +/** + * gsi_get_evt_ring_cfg - This function returns the current config + * of the specified event ring + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @props: where to copy properties to + * @scr: where to copy scratch info to + * + * @Return gsi_status + */ +int gsi_get_evt_ring_cfg(unsigned long evt_ring_hdl, + struct gsi_evt_ring_props *props, union gsi_evt_scratch *scr); + +/** + * gsi_set_evt_ring_cfg - This function applies the supplied config + * to the specified event ring. + * + * exclusive property of the event ring cannot be changed after + * gsi_alloc_evt_ring + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @props: the properties to apply + * @scr: the scratch info to apply + * + * @Return gsi_status + */ +int gsi_set_evt_ring_cfg(unsigned long evt_ring_hdl, + struct gsi_evt_ring_props *props, union gsi_evt_scratch *scr); + +/** + * gsi_alloc_channel - Peripheral should call this function to + * allocate a channel + * + * @props: Channel properties + * @dev_hdl: Client handle previously obtained from + * gsi_register_device + * @chan_hdl: Handle populated by GSI, opaque to client + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_alloc_channel(struct gsi_chan_props *props, unsigned long dev_hdl, + unsigned long *chan_hdl); + +/** + * gsi_write_channel_scratch - Peripheral should call this function to + * write to the scratch area of the channel context + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @val: Value to write + * + * @Return gsi_status + */ +int gsi_write_channel_scratch(unsigned long chan_hdl, + union __packed gsi_channel_scratch val); + +/** + * gsi_start_channel - Peripheral should call this function to + * start a channel i.e put into running state + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_start_channel(unsigned long chan_hdl); + +/** + * gsi_stop_channel - Peripheral should call this function to + * stop a channel. Stop will happen on a packet boundary + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * This function can sleep + * + * @Return -GSI_STATUS_AGAIN if client should call stop/stop_db again + * other error codes for failure + */ +int gsi_stop_channel(unsigned long chan_hdl); + +/** + * gsi_reset_channel - Peripheral should call this function to + * reset a channel to recover from error state + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_reset_channel(unsigned long chan_hdl); + +/** + * gsi_dealloc_channel - Peripheral should call this function to + * de-allocate a channel + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * This function can sleep + * + * @Return gsi_status + */ +int gsi_dealloc_channel(unsigned long chan_hdl); + +/** + * gsi_stop_db_channel - Peripheral should call this function to + * stop a channel when all transfer elements till the doorbell + * have been processed + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * This function can sleep + * + * @Return -GSI_STATUS_AGAIN if client should call stop/stop_db again + * other error codes for failure + */ +int gsi_stop_db_channel(unsigned long chan_hdl); + +/** + * gsi_query_channel_db_addr - Peripheral should call this function to + * query the physical addresses of the channel doorbell registers + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @db_addr_wp_lsb: Physical address of doorbell register where the 32 + * LSBs of the doorbell value should be written + * @db_addr_wp_msb: Physical address of doorbell register where the 32 + * MSBs of the doorbell value should be written + * + * @Return gsi_status + */ +int gsi_query_channel_db_addr(unsigned long chan_hdl, + uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb); + +/** + * gsi_query_channel_info - Peripheral can call this function to query the + * channel and associated event ring (if any) status. + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @info: Where to read the values into + * + * @Return gsi_status + */ +int gsi_query_channel_info(unsigned long chan_hdl, + struct gsi_chan_info *info); + +/** + * gsi_is_channel_empty - Peripheral can call this function to query if + * the channel is empty. This is only applicable to GPI. "Empty" means + * GSI has consumed all descriptors for a TO_GSI channel and SW has + * processed all completed descriptors for a FROM_GSI channel. + * + * @chan_hdl: Client handle previously obtained from gsi_alloc_channel + * @is_empty: set by GSI based on channel emptiness + * + * @Return gsi_status + */ +int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty); + +/** + * gsi_get_channel_cfg - This function returns the current config + * of the specified channel + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @props: where to copy properties to + * @scr: where to copy scratch info to + * + * @Return gsi_status + */ +int gsi_get_channel_cfg(unsigned long chan_hdl, struct gsi_chan_props *props, + union gsi_channel_scratch *scr); + +/** + * gsi_set_channel_cfg - This function applies the supplied config + * to the specified channel + * + * ch_id and evt_ring_hdl of the channel cannot be changed after + * gsi_alloc_channel + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @props: the properties to apply + * @scr: the scratch info to apply + * + * @Return gsi_status + */ +int gsi_set_channel_cfg(unsigned long chan_hdl, struct gsi_chan_props *props, + union gsi_channel_scratch *scr); + +/** + * gsi_poll_channel - Peripheral should call this function to query for + * completed transfer descriptors. + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @notify: Information about the completed transfer if any + * + * @Return gsi_status (GSI_STATUS_POLL_EMPTY is returned if no transfers + * completed) + */ +int gsi_poll_channel(unsigned long chan_hdl, + struct gsi_chan_xfer_notify *notify); + +/** + * gsi_config_channel_mode - Peripheral should call this function + * to configure the channel mode. + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @mode: Mode to move the channel into + * + * @Return gsi_status + */ +int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode); + +/** + * gsi_queue_xfer - Peripheral should call this function + * to queue transfers on the given channel + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * @num_xfers: Number of transfer in the array @ xfer + * @xfer: Array of num_xfers transfer descriptors + * @ring_db: If true, tell HW about these queued xfers + * If false, do not notify HW at this time + * + * @Return gsi_status + */ +int gsi_queue_xfer(unsigned long chan_hdl, uint16_t num_xfers, + struct gsi_xfer_elem *xfer, bool ring_db); + +/** + * gsi_start_xfer - Peripheral should call this function to + * inform HW about queued xfers + * + * @chan_hdl: Client handle previously obtained from + * gsi_alloc_channel + * + * @Return gsi_status + */ +int gsi_start_xfer(unsigned long chan_hdl); + +/** + * gsi_configure_regs - Peripheral should call this function + * to configure the GSI registers before/after the FW is + * loaded but before it is enabled. + * + * @gsi_base_addr: Base address of GSI register space + * @gsi_size: Mapping size of the GSI register space + * @per_base_addr: Base address of the peripheral using GSI + * + * @Return gsi_status + */ +int gsi_configure_regs(phys_addr_t gsi_base_addr, u32 gsi_size, + phys_addr_t per_base_addr); + +/** + * gsi_enable_fw - Peripheral should call this function + * to enable the GSI FW after the FW has been loaded to the SRAM. + * + * @gsi_base_addr: Base address of GSI register space + * @gsi_size: Mapping size of the GSI register space + + * @Return gsi_status + */ +int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size); + +/** + * gsi_get_inst_ram_offset_and_size - Peripheral should call this function + * to get instruction RAM base address offset and size. Peripheral typically + * uses this info to load GSI FW into the IRAM. + * + * @base_offset:[OUT] - IRAM base offset address + * @size: [OUT] - IRAM size + + * @Return none + */ +void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset, + unsigned long *size); + +/** + * gsi_halt_channel_ee - Peripheral should call this function + * to stop other EE's channel. This is usually used in SSR clean + * + * @chan_idx: Virtual channel index + * @ee: EE + * @code: [out] response code for operation + + * @Return gsi_status + */ +int gsi_halt_channel_ee(unsigned int chan_idx, unsigned int ee, int *code); + +/* + * Here is a typical sequence of calls + * + * gsi_register_device + * + * gsi_write_device_scratch (if the protocol needs this) + * + * gsi_alloc_evt_ring (for as many event rings as needed) + * gsi_write_evt_ring_scratch + * + * gsi_alloc_channel (for as many channels as needed; channels can have + * no event ring, an exclusive event ring or a shared event ring) + * gsi_write_channel_scratch + * gsi_start_channel + * gsi_queue_xfer/gsi_start_xfer + * gsi_config_channel_mode/gsi_poll_channel (if clients wants to poll on + * xfer completions) + * gsi_stop_db_channel/gsi_stop_channel + * + * gsi_dealloc_channel + * + * gsi_dealloc_evt_ring + * + * gsi_deregister_device + * + */ +#else +static inline int gsi_register_device(struct gsi_per_props *props, + unsigned long *dev_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_complete_clk_grant(unsigned long dev_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_write_device_scratch(unsigned long dev_hdl, + struct gsi_device_scratch *val) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_deregister_device(unsigned long dev_hdl, bool force) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, + unsigned long dev_hdl, + unsigned long *evt_ring_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_write_evt_ring_scratch(unsigned long evt_ring_hdl, + union __packed gsi_evt_scratch val) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_dealloc_evt_ring(unsigned long evt_ring_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl, + uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_ring_evt_ring_db(unsigned long evt_ring_hdl, + uint64_t value) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_reset_evt_ring(unsigned long evt_ring_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_alloc_channel(struct gsi_chan_props *props, + unsigned long dev_hdl, + unsigned long *chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_write_channel_scratch(unsigned long chan_hdl, + union __packed gsi_channel_scratch val) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_start_channel(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_stop_channel(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_reset_channel(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_dealloc_channel(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_stop_db_channel(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_query_channel_db_addr(unsigned long chan_hdl, + uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_query_channel_info(unsigned long chan_hdl, + struct gsi_chan_info *info) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_poll_channel(unsigned long chan_hdl, + struct gsi_chan_xfer_notify *notify) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_config_channel_mode(unsigned long chan_hdl, + enum gsi_chan_mode mode) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_queue_xfer(unsigned long chan_hdl, uint16_t num_xfers, + struct gsi_xfer_elem *xfer, bool ring_db) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_start_xfer(unsigned long chan_hdl) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_get_channel_cfg(unsigned long chan_hdl, + struct gsi_chan_props *props, + union gsi_channel_scratch *scr) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_set_channel_cfg(unsigned long chan_hdl, + struct gsi_chan_props *props, + union gsi_channel_scratch *scr) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_get_evt_ring_cfg(unsigned long evt_ring_hdl, + struct gsi_evt_ring_props *props, union gsi_evt_scratch *scr) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_set_evt_ring_cfg(unsigned long evt_ring_hdl, + struct gsi_evt_ring_props *props, union gsi_evt_scratch *scr) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_configure_regs(phys_addr_t gsi_base_addr, u32 gsi_size, + phys_addr_t per_base_addr) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + +static inline void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset, + unsigned long *size) +{ +} + +static inline int gsi_halt_channel_ee(unsigned int chan_idx, unsigned int ee, + int *code) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} +#endif +#endif diff --git a/include/linux/msm_iommu_domains.h b/include/linux/msm_iommu_domains.h new file mode 100644 index 000000000000..0cb44ee67797 --- /dev/null +++ b/include/linux/msm_iommu_domains.h @@ -0,0 +1,310 @@ +/* Copyright (c) 2011-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 _LINUX_MSM_IOMMU_DOMAINS_H +#define _LINUX_MSM_IOMMU_DOMAINS_H + +#include <linux/errno.h> +#include <linux/mutex.h> +#include <linux/rbtree.h> +#include <linux/msm_ion.h> + +#define MSM_IOMMU_DOMAIN_SECURE 0x1 + +struct mem_pool { + struct mutex pool_mutex; + unsigned long *bitmap; + unsigned long nr_pages; + phys_addr_t paddr; + unsigned long size; + unsigned long free; + unsigned int id; +}; + +enum { + VIDEO_DOMAIN, + CAMERA_DOMAIN, + DISPLAY_READ_DOMAIN, + DISPLAY_WRITE_DOMAIN, + ROTATOR_SRC_DOMAIN, + ROTATOR_DST_DOMAIN, + MAX_DOMAINS +}; + +enum { + VIDEO_FIRMWARE_POOL, + VIDEO_MAIN_POOL, + GEN_POOL, +}; + +struct msm_iommu_domain_name { + char *name; + int domain; +}; + +struct msm_iommu_domain { + /* iommu domain to map in */ + struct iommu_domain *domain; + /* total number of allocations from this domain */ + atomic_t allocation_cnt; + /* number of iova pools */ + int npools; + /* + * array of gen_pools for allocating iovas. + * behavior is undefined if these overlap + */ + struct mem_pool *iova_pools; +}; + +struct iommu_domains_pdata { + struct msm_iommu_domain *domains; + int ndomains; + struct msm_iommu_domain_name *domain_names; + int nnames; + unsigned int domain_alloc_flags; +}; + + +struct msm_iova_partition { + unsigned long start; + unsigned long size; +}; + +struct msm_iova_layout { + struct msm_iova_partition *partitions; + int npartitions; + const char *client_name; + unsigned int domain_flags; + unsigned int is_secure; +}; + +#if defined(CONFIG_MSM_IOMMU) +/** + * ion_map_iommu - map the given handle into an iommu + * + * @client - client who allocated the handle + * @handle - handle to map + * @domain_num - domain number to map to + * @partition_num - partition number to allocate iova from + * @align - alignment for the iova + * @iova_length - length of iova to map. If the iova length is + * greater than the handle length, the remaining + * address space will be mapped to a dummy buffer. + * @iova - pointer to store the iova address + * @buffer_size - pointer to store the size of the buffer + * @flags - flags for options to map + * @iommu_flags - flags specific to the iommu. + * + * Maps the handle into the iova space specified via domain number. Iova + * will be allocated from the partition specified via partition_num. + * Returns 0 on success, negative value on error. + */ +int ion_map_iommu(struct ion_client *client, struct ion_handle *handle, + int domain_num, int partition_num, unsigned long align, + unsigned long iova_length, ion_phys_addr_t *iova, + unsigned long *buffer_size, + unsigned long flags, unsigned long iommu_flags); + +/** + * ion_unmap_iommu - unmap the handle from an iommu + * + * @client - client who allocated the handle + * @handle - handle to unmap + * @domain_num - domain to unmap from + * @partition_num - partition to unmap from + * + * Decrement the reference count on the iommu mapping. If the count is + * 0, the mapping will be removed from the iommu. + */ +void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle, + int domain_num, int partition_num); + +extern void msm_iommu_set_client_name(struct iommu_domain *domain, + char const *name); +extern struct iommu_domain *msm_get_iommu_domain(int domain_num); +extern int msm_find_domain_no(const struct iommu_domain *domain); +extern struct iommu_domain *msm_iommu_domain_find(const char *name); +extern int msm_iommu_domain_no_find(const char *name); + + +extern int msm_allocate_iova_address(unsigned int iommu_domain, + unsigned int partition_no, + unsigned long size, + unsigned long align, + unsigned long *iova); + +extern void msm_free_iova_address(unsigned long iova, + unsigned int iommu_domain, + unsigned int partition_no, + unsigned long size); + +extern int msm_use_iommu(void); + +extern int msm_iommu_map_extra(struct iommu_domain *domain, + unsigned long start_iova, + phys_addr_t phys_addr, + unsigned long size, + unsigned long page_size, + int cached); + +extern void msm_iommu_unmap_extra(struct iommu_domain *domain, + unsigned long start_iova, + unsigned long size, + unsigned long page_size); + +extern int msm_iommu_map_contig_buffer(phys_addr_t phys, + unsigned int domain_no, + unsigned int partition_no, + unsigned long size, + unsigned long align, + unsigned long cached, + dma_addr_t *iova_val); + + +extern void msm_iommu_unmap_contig_buffer(dma_addr_t iova, + unsigned int domain_no, + unsigned int partition_no, + unsigned long size); + +extern int msm_register_domain(struct msm_iova_layout *layout); +extern int msm_unregister_domain(struct iommu_domain *domain); + +int msm_map_dma_buf(struct dma_buf *dma_buf, struct sg_table *table, + int domain_num, int partition_num, unsigned long align, + unsigned long iova_length, ion_phys_addr_t *iova, + unsigned long *buffer_size, + unsigned long flags, unsigned long iommu_flags); + +void msm_unmap_dma_buf(struct sg_table *table, int domain_num, + int partition_num); +#else +static inline int ion_map_iommu(struct ion_client *client, + struct ion_handle *handle, int domain_num, + int partition_num, unsigned long align, + unsigned long iova_length, ion_phys_addr_t *iova, + unsigned long *buffer_size, + unsigned long flags, + unsigned long iommu_flags) +{ + return -ENODEV; +} + +static inline void ion_unmap_iommu(struct ion_client *client, + struct ion_handle *handle, int domain_num, + int partition_num) +{ +} + +static inline void msm_iommu_set_client_name(struct iommu_domain *domain, + char const *name) +{ +} + +static inline struct iommu_domain + *msm_get_iommu_domain(int subsys_id) { return NULL; } + + +static inline int msm_find_domain_no(const struct iommu_domain *domain) +{ + return -EINVAL; +} + +static inline int msm_allocate_iova_address(unsigned int iommu_domain, + unsigned int partition_no, + unsigned long size, + unsigned long align, + unsigned long *iova) { return -ENOMEM; } + +static inline void msm_free_iova_address(unsigned long iova, + unsigned int iommu_domain, + unsigned int partition_no, + unsigned long size) { } + +static inline int msm_use_iommu(void) +{ + return 0; +} + +static inline int msm_iommu_map_extra(struct iommu_domain *domain, + unsigned long start_iova, + phys_addr_t phys_addr, + unsigned long size, + unsigned long page_size, + int cached) +{ + return -ENODEV; +} + +static inline void msm_iommu_unmap_extra(struct iommu_domain *domain, + unsigned long start_iova, + unsigned long size, + unsigned long page_size) +{ +} + +static inline int msm_iommu_map_contig_buffer(phys_addr_t phys, + unsigned int domain_no, + unsigned int partition_no, + unsigned long size, + unsigned long align, + unsigned long cached, + dma_addr_t *iova_val) +{ + *iova_val = phys; + return 0; +} + +static inline void msm_iommu_unmap_contig_buffer(dma_addr_t iova, + unsigned int domain_no, + unsigned int partition_no, + unsigned long size) +{ +} + +static inline int msm_register_domain(struct msm_iova_layout *layout) +{ + return -ENODEV; +} + +static inline int msm_unregister_domain(struct iommu_domain *domain) +{ + return -ENODEV; +} + +static inline struct iommu_domain *msm_iommu_domain_find(const char *name) +{ + return NULL; +} + +static inline int msm_iommu_domain_no_find(const char *name) +{ + return -ENODEV; +} + +static inline int msm_map_dma_buf(struct dma_buf *dma_buf, + struct sg_table *table, + int domain_num, int partition_num, unsigned long align, + unsigned long iova_length, ion_phys_addr_t *iova, + unsigned long *buffer_size, + unsigned long flags, unsigned long iommu_flags) +{ + return -ENODEV; +} + +static inline void msm_unmap_dma_buf(struct sg_table *table, int domain_num, + int partition_num) +{ +} + +#endif + +#endif diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h new file mode 100644 index 000000000000..04afdf587421 --- /dev/null +++ b/include/linux/msm_ion.h @@ -0,0 +1,6 @@ +#ifndef __LINUX_MSM_ION_H__ +#define __LINUX_MSM_ION_H__ + +#include "../../drivers/staging/android/ion/msm/msm_ion.h" + +#endif /* __LINUX_MSM_ION_H__ */ diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h new file mode 100644 index 000000000000..5991485cdea4 --- /dev/null +++ b/include/linux/msm_kgsl.h @@ -0,0 +1,34 @@ +#ifndef _MSM_KGSL_H +#define _MSM_KGSL_H + +#include <uapi/linux/msm_kgsl.h> + +#ifdef CONFIG_QCOM_KGSL +/* Limits mitigations APIs */ +void *kgsl_pwr_limits_add(enum kgsl_deviceid id); +void kgsl_pwr_limits_del(void *limit); +int kgsl_pwr_limits_set_freq(void *limit, unsigned int freq); +void kgsl_pwr_limits_set_default(void *limit); +unsigned int kgsl_pwr_limits_get_freq(enum kgsl_deviceid id); +#else +static inline void *kgsl_pwr_limits_add(enum kgsl_deviceid id) +{ + return NULL; +} + +static inline void kgsl_pwr_limits_del(void *limit) { } + +static inline int kgsl_pwr_limits_set_freq(void *limit, unsigned int freq) +{ + return -EINVAL; +} + +static inline void kgsl_pwr_limits_set_default(void *limit) { } + +static inline unsigned int kgsl_pwr_limits_get_freq(enum kgsl_deviceid id) +{ + return 0; +} +#endif + +#endif /* _MSM_KGSL_H */ diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h new file mode 100644 index 000000000000..22e64f4272b9 --- /dev/null +++ b/include/linux/msm_mdp.h @@ -0,0 +1,20 @@ +/* include/linux/msm_mdp.h + * + * Copyright (C) 2007 Google Incorporated + * Copyright (c) 2012-2014,2016 The Linux Foundation. All rights reserved. + * + * 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 _MSM_MDP_H_ +#define _MSM_MDP_H_ + +#include <uapi/linux/msm_mdp.h> + +#endif /*_MSM_MDP_H_*/ diff --git a/include/linux/msm_mhi.h b/include/linux/msm_mhi.h new file mode 100644 index 000000000000..1704cb93e6a3 --- /dev/null +++ b/include/linux/msm_mhi.h @@ -0,0 +1,421 @@ +/* Copyright (c) 2014-2017, 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 MSM_MHI_H +#define MSM_MHI_H +#include <linux/types.h> +#include <linux/device.h> +#include <linux/scatterlist.h> + +#define MHI_DMA_MASK 0xFFFFFFFFFFULL +#define MHI_MAX_MTU 0xFFFF + +struct mhi_client_config; +struct mhi_device_ctxt; + +enum MHI_CLIENT_CHANNEL { + MHI_CLIENT_LOOPBACK_OUT = 0, + MHI_CLIENT_LOOPBACK_IN = 1, + MHI_CLIENT_SAHARA_OUT = 2, + MHI_CLIENT_SAHARA_IN = 3, + MHI_CLIENT_DIAG_OUT = 4, + MHI_CLIENT_DIAG_IN = 5, + MHI_CLIENT_SSR_OUT = 6, + MHI_CLIENT_SSR_IN = 7, + MHI_CLIENT_QDSS_OUT = 8, + MHI_CLIENT_QDSS_IN = 9, + MHI_CLIENT_EFS_OUT = 10, + MHI_CLIENT_EFS_IN = 11, + MHI_CLIENT_MBIM_OUT = 12, + MHI_CLIENT_MBIM_IN = 13, + MHI_CLIENT_QMI_OUT = 14, + MHI_CLIENT_QMI_IN = 15, + MHI_CLIENT_IP_CTRL_0_OUT = 16, + MHI_CLIENT_IP_CTRL_0_IN = 17, + MHI_CLIENT_IP_CTRL_1_OUT = 18, + MHI_CLIENT_IP_CTRL_1_IN = 19, + MHI_CLIENT_DCI_OUT = 20, + MHI_CLIENT_DCI_IN = 21, + MHI_CLIENT_TF_OUT = 22, + MHI_CLIENT_TF_IN = 23, + MHI_CLIENT_BL_OUT = 24, + MHI_CLIENT_BL_IN = 25, + MHI_CLIENT_DUN_OUT = 32, + MHI_CLIENT_DUN_IN = 33, + MHI_CLIENT_IPC_ROUTER_OUT = 34, + MHI_CLIENT_IPC_ROUTER_IN = 35, + MHI_CLIENT_IP_SW_1_OUT = 36, + MHI_CLIENT_IP_SW_1_IN = 37, + MHI_CLIENT_IP_SW_2_OUT = 38, + MHI_CLIENT_IP_SW_2_IN = 39, + MHI_CLIENT_IP_SW_3_OUT = 40, + MHI_CLIENT_IP_SW_3_IN = 41, + MHI_CLIENT_CSVT_OUT = 42, + MHI_CLIENT_CSVT_IN = 43, + MHI_CLIENT_SMCT_OUT = 44, + MHI_CLIENT_SMCT_IN = 45, + MHI_CLIENT_IP_SW_4_OUT = 46, + MHI_CLIENT_IP_SW_4_IN = 47, + MHI_CLIENT_RESERVED_1_LOWER = 48, + MHI_CLIENT_RESERVED_1_UPPER = 99, + MHI_CLIENT_IP_HW_0_OUT = 100, + MHI_CLIENT_IP_HW_0_IN = 101, + MHI_CLIENT_IP_HW_ADPL_IN = 102, + MHI_CLIENT_RESERVED_2_LOWER = 103, + MHI_CLIENT_RESERVED_2_UPPER = 127, + MHI_MAX_CHANNELS = 103 +}; + +enum MHI_CB_REASON { + MHI_CB_XFER, + MHI_CB_MHI_DISABLED, + MHI_CB_MHI_ENABLED, + MHI_CB_MHI_SHUTDOWN, + MHI_CB_SYS_ERROR, + MHI_CB_RDDM, + MHI_CB_MHI_PROBED, +}; + +enum MHI_FLAGS { + MHI_EOB = 0x100, + MHI_EOT = 0x200, + MHI_CHAIN = 0x1, + MHI_FLAGS_reserved = 0x80000000, +}; + +struct mhi_result { + void *user_data; + void *buf_addr; + size_t bytes_xferd; + int transaction_status; + enum MHI_FLAGS flags; +}; + +struct mhi_cb_info { + struct mhi_result *result; + enum MHI_CB_REASON cb_reason; + u32 chan; +}; + +struct mhi_client_info_t { + enum MHI_CLIENT_CHANNEL chan; + const struct device *dev; + const char *node_name; + void (*mhi_client_cb)(struct mhi_cb_info *); + bool pre_allocate; + size_t max_payload; + void *user_data; +}; + +struct mhi_client_handle { + u32 dev_id; + u32 domain; + u32 bus; + u32 slot; + bool enabled; + struct mhi_client_config *client_config; +}; + +struct __packed bhi_vec_entry { + u64 phys_addr; + u64 size; +}; + +/** + * struct mhi_device - IO resources for MHI + * @dev: device node points to of_node + * @pdev: pci device node + * @resource: bar memory space and IRQ resources + * @support_rddm: this device support ramdump collection + * @rddm_size: size of ramdump buffer in bytes to allocate + * @pm_runtime_get: fp for bus masters rpm pm_runtime_get + * @pm_runtime_noidle: fp for bus masters rpm pm_runtime_noidle + * @status_cb: fp for MHI status change notifications + * @mhi_dev_ctxt: private data for host + */ +struct mhi_device { + struct device *dev; + struct pci_dev *pci_dev; + struct resource resources[2]; + bool support_rddm; + size_t rddm_size; + int (*pm_runtime_get)(struct pci_dev *pci_dev); + void (*pm_runtime_put_noidle)(struct pci_dev *pci_dev); + void (*status_cb)(enum MHI_CB_REASON, void *priv); + struct mhi_device_ctxt *mhi_dev_ctxt; +}; + +enum mhi_dev_ctrl { + MHI_DEV_CTRL_INIT, + MHI_DEV_CTRL_DE_INIT, + MHI_DEV_CTRL_SUSPEND, + MHI_DEV_CTRL_RESUME, + MHI_DEV_CTRL_POWER_OFF, + MHI_DEV_CTRL_POWER_ON, + MHI_DEV_CTRL_TRIGGER_RDDM, + MHI_DEV_CTRL_RDDM, + MHI_DEV_CTRL_RDDM_KERNEL_PANIC, + MHI_DEV_CTRL_NOTIFY_LINK_ERROR, + MHI_DEV_CTRL_MAXCMD, +}; + +enum mhi_rddm_segment { + MHI_RDDM_FW_SEGMENT, + MHI_RDDM_RD_SEGMENT, +}; + +#if defined(CONFIG_MSM_MHI) +/** + * mhi_is_device_ready - Check if MHI is ready to register clients + * + * @dev: device node that points to DT node + * @node_name: device tree node that links MHI node + * + * @Return true if ready + */ +bool mhi_is_device_ready(const struct device * const dev, + const char *node_name); + +/** + * mhi_resgister_device - register hardware resources with MHI + * + * @mhi_device: resources to be used + * @node_name: DT node name + * @userdata: cb data for client + * @Return 0 on success + */ +int mhi_register_device(struct mhi_device *mhi_device, const char *node_name, + void *user_data); + +/** + * mhi_register_channel - Client must call this function to obtain a handle for + * any MHI operations + * + * @client_handle: Handle populated by MHI, opaque to client + * @client_info: Channel\device information provided by client to + * which the handle maps to. + * + * @Return errno + */ +int mhi_register_channel(struct mhi_client_handle **client_handle, + struct mhi_client_info_t *client_info); + +/** + * mhi_pm_control_device - power management control api + * @mhi_device: registered device structure + * @ctrl: specific command + * @Return 0 on success + */ +int mhi_pm_control_device(struct mhi_device *mhi_device, + enum mhi_dev_ctrl ctrl); + +/** + * mhi_xfer_rddm - transfer rddm segment to bus master + * @mhi_device: registered device structure + * @seg: scatterlist pointing to segments + * @Return: # of segments, 0 if no segment available + */ +int mhi_xfer_rddm(struct mhi_device *mhi_device, enum mhi_rddm_segment seg, + struct scatterlist **sg_list); + +/** + * mhi_deregister_channel - de-register callbacks from MHI + * + * @client_handle: Handle populated by MHI, opaque to client + * + * @Return errno + */ +int mhi_deregister_channel(struct mhi_client_handle *client_handle); + +/** + * mhi_open_channel - Client must call this function to open a channel + * + * @client_handle: Handle populated by MHI, opaque to client + * + * Not thread safe, caller must ensure concurrency protection. + * + * @Return errno + */ +int mhi_open_channel(struct mhi_client_handle *client_handle); + +/** + * mhi_queue_xfer - Client called function to add a buffer to MHI channel + * + * @client_handle Pointer to client handle previously obtained from + * mhi_open_channel + * @buf Pointer to client buffer + * @buf_len Length of the client buffer + * @chain Specify whether to set the chain bit on this buffer + * @eob Specify whether this buffer should trigger EOB interrupt + * + * NOTE: + * Not thread safe, caller must ensure concurrency protection. + * User buffer must be physically contiguous. + * + * @Return errno + */ +int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf, + size_t buf_len, enum MHI_FLAGS mhi_flags); + +/** + * mhi_close_channel - Client can request channel to be closed and handle freed + * + * @client_handle Pointer to client handle previously obtained from + * mhi_open_channel + * Not thread safe, caller must ensure concurrency protection. + * + * @client_handle Pointer to handle to be released + */ +void mhi_close_channel(struct mhi_client_handle *client_handle); + +/** + * mhi_get_free_desc - Get the number of free descriptors on channel. + * client_handle Pointer to client handle previously obtained from + * mhi_open_channel. + * + * This API returns a snapshot of available descriptors on the given + * channel + * + * @Return non negative on success + */ +int mhi_get_free_desc(struct mhi_client_handle *client_handle); + +/* + * mhi_poll_inbound - Poll a buffer from MHI channel + * @client_handle Pointer to client handle previously obtained from + * mhi_open_channel. + * @result Result structure to be populated with buffer info + * if available; + * + * Client may asynchronously poll on an inbound channel for descriptors + * which have been populated. This API is used by client to receive data + * from device after a callback notification has been received. + * + * Not thread safe, caller must ensure concurrency protection. + * + * @Return non negative on success + */ +int mhi_poll_inbound(struct mhi_client_handle *client_handle, + struct mhi_result *result); + +/** + * mhi_get_max_desc - Get the maximum number of descriptors + * supported on the channel. + * @client_handle Pointer to client handle previously obtained from + * mhi_open_channel. + * @Return non negative on success + */ +int mhi_get_max_desc(struct mhi_client_handle *client_handle); + +/* following APIs meant to be used by rmnet interface only */ +int mhi_set_lpm(struct mhi_client_handle *client_handle, bool enable_lpm); +int mhi_get_epid(struct mhi_client_handle *mhi_handle); +struct mhi_result *mhi_poll(struct mhi_client_handle *client_handle); +void mhi_mask_irq(struct mhi_client_handle *client_handle); +void mhi_unmask_irq(struct mhi_client_handle *client_handle); + +#else +static inline bool mhi_is_device_ready(const struct device * const dev, + const char *node_name) +{ + return false; +}; + +static inline int mhi_register_device(struct mhi_device *mhi_device, + const char *node_name, void *user_data) +{ + return -EINVAL; +}; + +static inline int mhi_register_channel(struct mhi_client_handle **client_handle, + struct mhi_client_info_t *client_info) +{ + return -EINVAL; +}; + +static inline int mhi_pm_control_device(struct mhi_device *mhi_device, + enum mhi_dev_ctrl ctrl) +{ + return -EINVAL; +}; + +static inline int mhi_xfer_rddm(struct mhi_device *mhi_device, + enum mhi_rddm_segment seg, + struct scatterlist **sg_list) +{ + return -EINVAL; +}; + +static inline int mhi_deregister_channel(struct mhi_client_handle + *client_handle) +{ + return -EINVAL; +}; + +static inline int mhi_open_channel(struct mhi_client_handle *client_handle) +{ + return -EINVAL; +}; + +static inline int mhi_queue_xfer(struct mhi_client_handle *client_handle, + void *buf, size_t buf_len, + enum MHI_FLAGS mhi_flags) +{ + return -EINVAL; +}; + +static inline void mhi_close_channel(struct mhi_client_handle *client_handle) +{ +}; + +static inline int mhi_get_free_desc(struct mhi_client_handle *client_handle) +{ + return -EINVAL; +}; + +static inline int mhi_poll_inbound(struct mhi_client_handle *client_handle, + struct mhi_result *result) +{ + return -EINVAL; +}; + +static inline int mhi_get_max_desc(struct mhi_client_handle *client_handle) +{ + return -EINVAL; +}; + +static inline int mhi_set_lpm(struct mhi_client_handle *client_handle, + bool enable_lpm) +{ + return -EINVAL; +}; + +static inline int mhi_get_epid(struct mhi_client_handle *mhi_handle) +{ + return -EINVAL; +}; + +static inline struct mhi_result *mhi_poll(struct mhi_client_handle + *client_handle) +{ + return NULL; +}; + +static inline void mhi_mask_irq(struct mhi_client_handle *client_handle) +{ +}; + +static inline void mhi_unmask_irq(struct mhi_client_handle *client_handle) +{ +}; + +#endif +#endif diff --git a/include/linux/msm_pcie.h b/include/linux/msm_pcie.h new file mode 100644 index 000000000000..c9c467ff7428 --- /dev/null +++ b/include/linux/msm_pcie.h @@ -0,0 +1,217 @@ +/* Copyright (c) 2014-2016, 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 __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_NO_CFG_RESTORE = 0x1, + MSM_PCIE_CONFIG_LINKDOWN = 0x2, + MSM_PCIE_CONFIG_NO_RECOVERY = 0x4, +}; + +enum msm_pcie_pm_opt { + MSM_PCIE_SUSPEND, + MSM_PCIE_RESUME, + MSM_PCIE_DISABLE_PC, + MSM_PCIE_ENABLE_PC, +}; + +enum msm_pcie_event { + MSM_PCIE_EVENT_INVALID = 0, + MSM_PCIE_EVENT_LINKDOWN = 0x1, + MSM_PCIE_EVENT_LINKUP = 0x2, + MSM_PCIE_EVENT_WAKEUP = 0x4, +}; + +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 { + 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; +}; + +#ifdef CONFIG_PCI_MSM +/** + * 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_recover_config - recover config space. + * @dev: pci device structure + * + * This function recovers the config space of both RC and Endpoint. + * + * Return: 0 on success, negative value on error + */ +int msm_pcie_recover_config(struct pci_dev *dev); + +/** + * 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_recover_config - recover config space. + * @dev: pci device structure + * + * This function recovers the config space of both RC and Endpoint. + * + * Return: 0 on success, negative value on error + */ +int msm_pcie_recover_config(struct pci_dev *dev); + +/** + * msm_pcie_shadow_control - control the shadowing of PCIe config space. + * @dev: pci device structure + * @enable: shadowing should be enabled or disabled + * + * This function gives PCIe endpoint device drivers the control to enable + * or disable the shadowing of PCIe config space. + * + * Return: 0 on success, negative value on error + */ +int msm_pcie_shadow_control(struct pci_dev *dev, bool enable); + +/* + * 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_configure_sid - calculates the SID for a PCIe endpoint. + * @dev: device structure + * @sid: the calculated SID + * @domain: the domain number of the Root Complex + * + * This function calculates the SID for a PCIe endpoint device. + * + * Return: 0 on success, negative value on error + */ +int msm_pcie_configure_sid(struct device *dev, u32 *sid, + int *domain); +#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_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_recover_config(struct pci_dev *dev) +{ + return -ENODEV; +} + +static inline int msm_pcie_enumerate(u32 rc_idx) +{ + return -ENODEV; +} + +static inline int msm_pcie_shadow_control(struct pci_dev *dev, bool enable) +{ + 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_configure_sid(struct device *dev, u32 *sid, + int *domain) +{ + return -ENODEV; +} +#endif /* CONFIG_PCI_MSM */ + +#endif /* __MSM_PCIE_H */ diff --git a/include/linux/msm_remote_spinlock.h b/include/linux/msm_remote_spinlock.h new file mode 100644 index 000000000000..dc8e5912eb4d --- /dev/null +++ b/include/linux/msm_remote_spinlock.h @@ -0,0 +1,80 @@ +/* Copyright (c) 2009, 2011, 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. + * + */ + +/* + * Part of this this code is based on the standard ARM spinlock + * implementation (asm/spinlock.h) found in the 2.6.29 kernel. + */ + +#ifndef __ASM__ARCH_QC_REMOTE_SPINLOCK_H +#define __ASM__ARCH_QC_REMOTE_SPINLOCK_H + +#include <linux/io.h> +#include <linux/types.h> + +#define REMOTE_SPINLOCK_NUM_PID 128 +#define REMOTE_SPINLOCK_TID_START REMOTE_SPINLOCK_NUM_PID + +/* Remote spinlock definitions. */ + +typedef struct { + volatile uint32_t lock; +} raw_remote_spinlock_t; + +typedef raw_remote_spinlock_t *_remote_spinlock_t; + +#define remote_spinlock_id_t const char * + +#if defined(CONFIG_REMOTE_SPINLOCK_MSM) +int _remote_spin_lock_init(remote_spinlock_id_t, _remote_spinlock_t *lock); +void _remote_spin_release_all(uint32_t pid); +void _remote_spin_lock(_remote_spinlock_t *lock); +void _remote_spin_unlock(_remote_spinlock_t *lock); +int _remote_spin_trylock(_remote_spinlock_t *lock); +int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid); +int _remote_spin_owner(_remote_spinlock_t *lock); +void _remote_spin_lock_rlock_id(_remote_spinlock_t *lock, uint32_t tid); +void _remote_spin_unlock_rlock(_remote_spinlock_t *lock); +int _remote_spin_get_hw_spinlocks_element(_remote_spinlock_t *lock); +#else +static inline +int _remote_spin_lock_init(remote_spinlock_id_t id, _remote_spinlock_t *lock) +{ + return -EINVAL; +} +static inline void _remote_spin_release_all(uint32_t pid) {} +static inline void _remote_spin_lock(_remote_spinlock_t *lock) {} +static inline void _remote_spin_unlock(_remote_spinlock_t *lock) {} +static inline int _remote_spin_trylock(_remote_spinlock_t *lock) +{ + return -ENODEV; +} +static inline int _remote_spin_release(_remote_spinlock_t *lock, uint32_t pid) +{ + return -ENODEV; +} +static inline int _remote_spin_owner(_remote_spinlock_t *lock) +{ + return -ENODEV; +} +static inline void _remote_spin_lock_rlock_id(_remote_spinlock_t *lock, + uint32_t tid) {} +static inline void _remote_spin_unlock_rlock(_remote_spinlock_t *lock) {} +static inline int _remote_spin_get_hw_spinlocks_element( + _remote_spinlock_t *lock) +{ + return -ENODEV; +} +#endif +#endif /* __ASM__ARCH_QC_REMOTE_SPINLOCK_H */ diff --git a/include/linux/msm_rtb.h b/include/linux/msm_rtb.h new file mode 100644 index 000000000000..228094294b31 --- /dev/null +++ b/include/linux/msm_rtb.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012-2014, 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 __MSM_RTB_H__ +#define __MSM_RTB_H__ + +/* + * These numbers are used from the kernel command line and sysfs + * to control filtering. Remove items from here with extreme caution. + */ +enum logk_event_type { + LOGK_NONE = 0, + LOGK_READL = 1, + LOGK_WRITEL = 2, + LOGK_LOGBUF = 3, + LOGK_HOTPLUG = 4, + LOGK_CTXID = 5, + LOGK_TIMESTAMP = 6, + LOGK_L2CPREAD = 7, + LOGK_L2CPWRITE = 8, + LOGK_IRQ = 9, +}; + +#define LOGTYPE_NOPC 0x80 + +struct msm_rtb_platform_data { + unsigned int size; +}; + +#if defined(CONFIG_QCOM_RTB) +/* + * returns 1 if data was logged, 0 otherwise + */ +int uncached_logk_pc(enum logk_event_type log_type, void *caller, + void *data); + +/* + * returns 1 if data was logged, 0 otherwise + */ +int uncached_logk(enum logk_event_type log_type, void *data); + +#define ETB_WAYPOINT do { \ + BRANCH_TO_NEXT_ISTR; \ + nop(); \ + BRANCH_TO_NEXT_ISTR; \ + nop(); \ + } while (0) + +#define BRANCH_TO_NEXT_ISTR asm volatile("b .+4\n" : : : "memory") +/* + * both the mb and the isb are needed to ensure enough waypoints for + * etb tracing + */ +#define LOG_BARRIER do { \ + mb(); \ + isb();\ + } while (0) +#else + +static inline int uncached_logk_pc(enum logk_event_type log_type, + void *caller, + void *data) { return 0; } + +static inline int uncached_logk(enum logk_event_type log_type, + void *data) { return 0; } + +#define ETB_WAYPOINT +#define BRANCH_TO_NEXT_ISTR +/* + * Due to a GCC bug, we need to have a nop here in order to prevent an extra + * read from being generated after the write. + */ +#define LOG_BARRIER nop() +#endif +#endif diff --git a/include/linux/msm_smd_pkt.h b/include/linux/msm_smd_pkt.h new file mode 100644 index 000000000000..c79933d27d4a --- /dev/null +++ b/include/linux/msm_smd_pkt.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2010,2017 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 __LINUX_MSM_SMD_PKT_H +#define __LINUX_MSM_SMD_PKT_H + +#include <linux/ioctl.h> + +#define SMD_PKT_IOCTL_MAGIC (0xC2) + +#define SMD_PKT_IOCTL_BLOCKING_WRITE \ + _IOR(SMD_PKT_IOCTL_MAGIC, 0, unsigned int) + +#endif /* __LINUX_MSM_SMD_PKT_H */ diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h new file mode 100644 index 000000000000..1098a0c9afaa --- /dev/null +++ b/include/linux/msm_thermal.h @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2012-2016,2018, 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 __MSM_THERMAL_H +#define __MSM_THERMAL_H + +#include <linux/thermal.h> + +#define MAX_THRESHOLD 2 +#define TSENS_NAME_MAX 20 +#define MONITOR_ALL_TSENS -1 +#define HOTPLUG_DEVICE "hotplug" +#define CPU0_DEVICE "cpu0" +#define CPU1_DEVICE "cpu1" +#define CPU2_DEVICE "cpu2" +#define CPU3_DEVICE "cpu3" +#define CPU4_DEVICE "cpu4" +#define CPU5_DEVICE "cpu5" +#define CPU6_DEVICE "cpu6" +#define CPU7_DEVICE "cpu7" +#define CPUFREQ_MAX_NO_MITIGATION UINT_MAX +#define CPUFREQ_MIN_NO_MITIGATION 0 +#define HOTPLUG_NO_MITIGATION(_mask) cpumask_clear(_mask) + +#define IS_HI_THRESHOLD_SET(_val) (_val & 1) +#define IS_LOW_THRESHOLD_SET(_val) (_val & 2) + +struct msm_thermal_data { + struct platform_device *pdev; + uint32_t sensor_id; + uint32_t poll_ms; + int32_t limit_temp_degC; + int32_t temp_hysteresis_degC; + uint32_t bootup_freq_step; + uint32_t bootup_freq_control_mask; + int32_t core_limit_temp_degC; + int32_t core_temp_hysteresis_degC; + int32_t hotplug_temp_degC; + int32_t hotplug_temp_hysteresis_degC; + uint32_t core_control_mask; + uint32_t freq_mitig_temp_degc; + uint32_t freq_mitig_temp_hysteresis_degc; + uint32_t freq_mitig_control_mask; + uint32_t freq_limit; + int32_t vdd_rstr_temp_degC; + int32_t vdd_rstr_temp_hyst_degC; + int32_t vdd_rstr_sensor_id; + int32_t vdd_mx_min; + int32_t vdd_cx_min; + int32_t psm_temp_degC; + int32_t psm_temp_hyst_degC; + int32_t ocr_temp_degC; + int32_t ocr_temp_hyst_degC; + uint32_t ocr_sensor_id; + int32_t phase_rpm_resource_type; + int32_t phase_rpm_resource_id; + int32_t gfx_phase_warm_temp_degC; + int32_t gfx_phase_warm_temp_hyst_degC; + int32_t gfx_phase_hot_temp_degC; + int32_t gfx_phase_hot_temp_hyst_degC; + int32_t gfx_sensor; + int32_t gfx_phase_request_key; + int32_t cx_phase_hot_temp_degC; + int32_t cx_phase_hot_temp_hyst_degC; + int32_t cx_phase_request_key; + int32_t vdd_mx_temp_degC; + int32_t vdd_mx_temp_hyst_degC; + int32_t vdd_mx_sensor_id; + int32_t therm_reset_temp_degC; +}; + +enum sensor_id_type { + THERM_ZONE_ID, + THERM_TSENS_ID, + THERM_ID_MAX_NR, +}; + +struct threshold_info; +struct therm_threshold { + int32_t sensor_id; + enum sensor_id_type id_type; + struct sensor_threshold threshold[MAX_THRESHOLD]; + int32_t trip_triggered; + void (*notify)(struct therm_threshold *); + struct threshold_info *parent; + int32_t cur_state; +}; + +struct threshold_info { + uint32_t thresh_ct; + bool thresh_triggered; + struct list_head list_ptr; + struct therm_threshold *thresh_list; +}; + +enum device_req_type { + DEVICE_REQ_NONE = -1, + HOTPLUG_MITIGATION_REQ, + CPUFREQ_MITIGATION_REQ, + DEVICE_REQ_MAX, +}; + +/** + * For frequency mitigation request, if client is interested + * only in one, either max_freq or min_freq, update default + * value for other one also for mitigation request. + * Default value for request structure variables: + * max_freq = UINT_MAX; + * min_freq = 0; + * offline_mask = CPU_MASK_NONE; + */ +struct cpufreq_request { + uint32_t max_freq; + uint32_t min_freq; +}; + +union device_request { + struct cpufreq_request freq; + cpumask_t offline_mask; +}; + +struct device_clnt_data; +struct device_manager_data { + char device_name[TSENS_NAME_MAX]; + union device_request active_req; + struct list_head client_list; + struct list_head dev_ptr; + struct mutex clnt_lock; + int (*request_validate)(struct device_clnt_data *, + union device_request *, + enum device_req_type); + int (*update)(struct device_manager_data *); + void *data; +}; + +struct device_clnt_data { + struct device_manager_data *dev_mgr; + bool req_active; + union device_request request; + struct list_head clnt_ptr; + void (*callback)(struct device_clnt_data *, + union device_request *req, void *); + void *usr_data; +}; + +#ifdef CONFIG_THERMAL_MONITOR +extern int msm_thermal_ioctl_init(void); +extern void msm_thermal_ioctl_cleanup(void); +extern int msm_thermal_init(struct msm_thermal_data *pdata); +extern int msm_thermal_device_init(void); +extern int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, + bool is_max); +extern int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, + bool is_max); +extern int msm_thermal_get_freq_plan_size(uint32_t cluster, + unsigned int *table_len); +extern int msm_thermal_get_cluster_freq_plan(uint32_t cluster, + unsigned int *table_ptr); +extern int msm_thermal_get_cluster_voltage_plan(uint32_t cluster, + uint32_t *table_ptr); +/** + * sensor_mgr_init_threshold - Initialize thresholds data structure for + * sensor(s) with high and low thresholds and + * threshold callback. + * + * @thresh_inp: Client threshold data structure. + * @sensor_id: Sensor h/w ID to be monitored. Use MONITOR_ALL_TSENS + * to monitor all temperature sensors. + * + * @high_temp: Trigger threshold value for sensor_id or all sensors. + * @low_temp: Clear threshold value for sensor_id or all sensors. + * @callback: Callback pointer for threshold notification. + * + * Returns which threshold is set on success, negative error number + * on failure. MACRO IS_HI_THRESHOLD_SET/IS_LOW_THRESHOLD_SET can be used + * to decipher which threshold being set. + */ +extern int sensor_mgr_init_threshold(struct threshold_info *thresh_inp, + int sensor_id, int32_t high_temp, + int32_t low_temp, + void (*callback)(struct therm_threshold *)); +/** + * sensor_mgr_convert_id_and_set_threshold - It accepts sensor h/w ID, converts + * it to sensor zone id and sets + * thermal threshold for those + * sensors listed in threshold info. + * + * @thresh_inp: Client threshold data structure. + * + * Returns zero on success, negative error number on failure. + */ +extern int sensor_mgr_convert_id_and_set_threshold( + struct threshold_info *thresh_inp); +/** + * sensor_mgr_set_threshold- It sets thermal threshold trips for a sensor. + * + * @zone_id: Thermal zone ID for the sensor. + * @threshold: threshold info for the sensor. + * + * Returns zero on success, negative error number on failure. + */ +extern int sensor_mgr_set_threshold(uint32_t zone_id, + struct sensor_threshold *threshold); +/** + * sensor_mgr_remove_threshold- It cancels threshold notification and + * removes threshold from sensor manager + * threshold list. + * + * @thresh_inp: The threshold info which needs to be removed. + */ +extern void sensor_mgr_remove_threshold(struct threshold_info *thresh_inp); +/** + * devmgr_register_mitigation_client - Register for a device and + * gets a handle for mitigation. + * @dev: Client device structure. + * @device_name: Mitgation device name which the client is interested + * to mitigate. + * @callback: Optional callback pointer for device change notification, + * otherwise pass NULL. + * + * Returns client handle structure for that device on success, or NULL + * with IS_ERR() condition containing error number. + */ +extern struct device_clnt_data *devmgr_register_mitigation_client( + struct device *dev, + const char *device_name, + void (*callback)(struct device_clnt_data *, + union device_request *, void *)); +/** + * devmgr_client_request_mitigation - Set a valid mitigation for + * registered device. + * @clnt: Client handle for device. + * @type: Type of device request populated above. + * @req: Valid mitigation request. + * + * Returns zero on successful mitigation update, or negative error number. + */ +extern int devmgr_client_request_mitigation(struct device_clnt_data *clnt, + enum device_req_type type, + union device_request *req); +/** + * devmgr_unregister_mitigation_client - Unregister mitigation device + * @dev: Client device structure. + * @clnt: Client handle for device. + */ +extern void devmgr_unregister_mitigation_client( + struct device *dev, + struct device_clnt_data *clnt); +#ifdef CONFIG_QCOM_THERMAL_LIMITS_DCVS +extern int msm_lmh_dcvsh_sw_notify(int cpu); +#else +static inline int msm_lmh_dcvsh_sw_notify(int cpu) +{ + return -ENODEV; +} +#endif + +#else +static inline int msm_thermal_init(struct msm_thermal_data *pdata) +{ + return -ENOSYS; +} +static inline int msm_thermal_device_init(void) +{ + return -ENOSYS; +} +static inline int msm_thermal_set_frequency(uint32_t cpu, uint32_t freq, + bool is_max) +{ + return -ENOSYS; +} +static inline int msm_thermal_set_cluster_freq(uint32_t cluster, uint32_t freq, + bool is_max) +{ + return -ENOSYS; +} +static inline int msm_thermal_get_freq_plan_size(uint32_t cluster, + unsigned int *table_len) +{ + return -ENOSYS; +} +static inline int msm_thermal_get_cluster_freq_plan(uint32_t cluster, + unsigned int *table_ptr) +{ + return -ENOSYS; +} +static inline int msm_thermal_get_cluster_voltage_plan(uint32_t cluster, + uint32_t *table_ptr) +{ + return -ENOSYS; +} +static inline int sensor_mgr_init_threshold(struct threshold_info *thresh_inp, + int sensor_id, int32_t high_temp, + int32_t low_temp, + void (*callback)(struct therm_threshold *)) +{ + return -ENOSYS; +} +static inline int sensor_mgr_convert_id_and_set_threshold( + struct threshold_info *thresh_inp) +{ + return -ENOSYS; +} +static inline int sensor_mgr_set_threshold(uint32_t zone_id, + struct sensor_threshold *threshold) +{ + return -ENOSYS; +} +static inline void sensor_mgr_remove_threshold( + struct threshold_info *thresh_inp) +{ +} +static inline struct device_clnt_data *devmgr_register_mitigation_client( + struct device *dev, + const char *device_name, + void (*callback)(struct device_clnt_data *, + union device_request *, void *)) +{ + return NULL; +} +static inline int devmgr_client_request_mitigation( + struct device_clnt_data *clnt, + enum device_req_type type, + union device_request *req) +{ + return -ENOSYS; +} +static inline void devmgr_unregister_mitigation_client( + struct device *dev, + struct device_clnt_data *clnt) +{ +} +static inline int msm_lmh_dcvsh_sw_notify(int cpu) +{ + return -ENODEV; +} +#endif + +#endif /*__MSM_THERMAL_H*/ diff --git a/include/linux/msm_tsens.h b/include/linux/msm_tsens.h new file mode 100644 index 000000000000..62e59dbe8385 --- /dev/null +++ b/include/linux/msm_tsens.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2011-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. + */ +/* + * Qualcomm TSENS Header file + * + */ + +#ifndef __MSM_TSENS_H +#define __MSM_TSENS_H + +#define TSENS_MAX_SENSORS 11 +#define TSENS_MTC_ZONE_LOG_SIZE 6 +#define TSENS_NUM_MTC_ZONES_SUPPORT 3 +#define TSENS_ZONEMASK_PARAMS 3 +#define TSENS_ZONELOG_PARAMS 1 +#define TSENS_MTC_ZONE_HISTORY_SIZE 3 + +struct tsens_device { + uint32_t sensor_num; +}; + +#if defined(CONFIG_THERMAL_TSENS8974) +/** + * tsens_is_ready() - Clients can use this API to check if the TSENS device + * is ready and clients can start requesting temperature reads. + * @return: Returns true if device is ready else returns -EPROBE_DEFER + * for clients to check back after a time duration. + */ +int tsens_is_ready(void); +/** + * tsens_tm_init_driver() - Early initialization for clients to read + * TSENS temperature. + */ +int __init tsens_tm_init_driver(void); +/** + * tsens_get_hw_id_mapping() - Mapping software or sensor ID with the physical + * TSENS sensor. On certain cases where there are more number of + * controllers the sensor ID is used to map the clients software ID + * with the physical HW sensors used by the driver. + * @sensors_sw_id: Client ID. + * @sensor_hw_num: Sensor client ID passed by the driver. This ID is used + * by the driver to map it to the physical HW sensor + * number. + * @return: If the device is not present returns -EPROBE_DEFER + * for clients to check back after a time duration. + * 0 on success else error code on error. + */ +int tsens_get_hw_id_mapping(int sensor_sw_id, int *sensor_hw_num); +/** + * tsens_get_max_sensor_num() - Get the total number of active TSENS sensors. + * The total number received by the client is across multiple + * TSENS controllers if present. + * @tsens_num_sensors: Total number of sensor result to be stored. + */ +int tsens_get_max_sensor_num(uint32_t *tsens_num_sensors); +/** + * tsens_set_mtc_zone_sw_mask() - Mask the MTC threshold level of a zone. + * SW can force the MTC to stop issuing throttling commands that + * correspond to each MTC threshold level by writing the + * corresponding bit in register at any time. + * @zone: Zone ID. + * @th1_enable : Value corresponding to the threshold level. + * @th2_enable : Value corresponding to the threshold level. + */ +int tsens_set_mtc_zone_sw_mask(unsigned int zone , unsigned int th1_enable, + unsigned int th2_enable); +/** + * tsens_get_mtc_zone_log() - Get the log of last 6 commands sent to pulse + * swallower of a zone. + * zone: Zone ID + * @zone_log: Log commands result to be stored. + */ +int tsens_get_mtc_zone_log(unsigned int zone , void *zone_log); +/** + * tsens_mtc_reset_history_counter() - Reset history of throttling commands + * sent to pulse swallower. Tsens controller issues clock + * throttling commands to Pulse swallower to perform HW + * based clock throttling. Reset the history counter of a zone. + * @zone: Zone ID. + */ +int tsens_mtc_reset_history_counter(unsigned int zone); +/** + * tsens_get_mtc_zone_history() - Get the history of throttling commands sent + * to pulse swallower. Tsens controller issues clock throttling + * commands to Pulse swallower to perform HW based clock + * throttling. + * @zone: Zone ID + * @zone_hist: Commands history result to be stored. + */ +int tsens_get_mtc_zone_history(unsigned int zone , void *zone_hist); +/** + * tsens_get_temp() - Obtain the TSENS temperature for the respective sensor. + * + * @dev: Sensor number for which client wants the TSENS temperature + * reading. The ID passed by the sensor could be the sensor ID + * which the driver translates to internally to read the + * respective physical HW sensor from the controller. + * @temp: temperature result to be stored. + * @return: If the device is not present returns -EPROBE_DEFER + * for clients to check back after a time duration. + * 0 on success else error code on error. + */ +int tsens_get_temp(struct tsens_device *dev, int *temp); +#else +static inline int tsens_is_ready(void) +{ return -ENXIO; } +static inline int __init tsens_tm_init_driver(void) +{ return -ENXIO; } +static inline int tsens_get_hw_id_mapping( + int sensor_sw_id, int *sensor_hw_num) +{ return -ENXIO; } +static inline int tsens_get_max_sensor_num(uint32_t *tsens_num_sensors) +{ return -ENXIO; } +static inline int tsens_set_mtc_zone_sw_mask(unsigned int zone , + unsigned int th1_enable , + unsigned int th2_enable) +{ return -ENXIO; } +static inline int tsens_get_mtc_zone_log(unsigned int zone , void *zone_log) +{ return -ENXIO; } +static inline int tsens_mtc_reset_history_counter(unsigned int zone) +{ return -ENXIO; } +static inline int tsens_get_temp(struct tsens_device *dev, + int *temp) +{ return -ENXIO; } +static inline int tsens_get_mtc_zone_history(unsigned int zone, void *zone_hist) +{ return -ENXIO; } +#endif + +#endif /*MSM_TSENS_H */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d999e503ba8a..ef891fd26353 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2594,6 +2594,7 @@ extern int netdev_flow_limit_table_len; */ struct softnet_data { struct list_head poll_list; + struct napi_struct *current_napi; struct sk_buff_head process_queue; /* stats */ @@ -2601,6 +2602,8 @@ struct softnet_data { unsigned int time_squeeze; unsigned int cpu_collision; unsigned int received_rps; + unsigned int gro_coalesced; + #ifdef CONFIG_RPS struct softnet_data *rps_ipi_list; #endif @@ -3088,6 +3091,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi); gro_result_t napi_gro_frags(struct napi_struct *napi); struct packet_offload *gro_find_receive_by_type(__be16 type); struct packet_offload *gro_find_complete_by_type(__be16 type); +extern struct napi_struct *get_current_napi_context(void); static inline void napi_free_frags(struct napi_struct *napi) { diff --git a/include/linux/nfcinfo.h b/include/linux/nfcinfo.h new file mode 100644 index 000000000000..595544f92a37 --- /dev/null +++ b/include/linux/nfcinfo.h @@ -0,0 +1,6 @@ +#ifndef _NFCINFO_H +#define _NFCINFO_H + +#include <uapi/linux/nfc/nfcinfo.h> + +#endif diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 74385351935d..dbda77dc510c 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -41,13 +41,22 @@ static inline void hardlockup_detector_disable(void) {} #ifdef arch_trigger_all_cpu_backtrace static inline bool trigger_all_cpu_backtrace(void) { + #if defined(CONFIG_ARM64) + arch_trigger_all_cpu_backtrace(); + #else arch_trigger_all_cpu_backtrace(true); + #endif return true; } static inline bool trigger_allbutself_cpu_backtrace(void) { + #if defined(CONFIG_ARM64) + arch_trigger_all_cpu_backtrace(); + #else arch_trigger_all_cpu_backtrace(false); + #endif + return true; } diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 507daad0bc8d..a6dfa03a4676 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -36,6 +36,8 @@ extern struct device_node *of_find_matching_node_by_address( const struct of_device_id *matches, u64 base_address); extern void __iomem *of_iomap(struct device_node *device, int index); +extern void __iomem *of_iomap_by_name(struct device_node *device, + const char *name); /* Extract an address from a device, returns the region size and * the address space flags too. The PCI version uses a BAR number @@ -43,6 +45,8 @@ extern void __iomem *of_iomap(struct device_node *device, int index); */ extern const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags); +extern const __be32 *of_get_address_by_name(struct device_node *dev, + const char *name, u64 *size, unsigned int *flags); extern int pci_register_io_range(phys_addr_t addr, resource_size_t size); extern unsigned long pci_address_to_pio(phys_addr_t addr); diff --git a/include/linux/of_batterydata.h b/include/linux/of_batterydata.h new file mode 100644 index 000000000000..5505371488d0 --- /dev/null +++ b/include/linux/of_batterydata.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2013-2014, 2016 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. + */ + +#include <linux/of.h> +#include <linux/batterydata-lib.h> + +#ifdef CONFIG_OF_BATTERYDATA +/** + * of_batterydata_read_data() - Populate battery data from the device tree + * @container_node: pointer to the battery-data container device node + * containing the profile nodes. + * @batt_data: pointer to an allocated bms_battery_data structure that the + * loaded profile will be written to. + * @batt_id_uv: ADC voltage of the battery id line used to differentiate + * between different battery profiles. If there are multiple + * battery data in the device tree, the one with the closest + * battery id resistance will be automatically loaded. + * + * This routine loads the closest match battery data from device tree based on + * the battery id reading. Then, it will try to load all the relevant data from + * the device tree battery data profile. + * + * If any of the lookup table pointers are NULL, this routine will skip trying + * to read them. + */ +int of_batterydata_read_data(struct device_node *container_node, + struct bms_battery_data *batt_data, + int batt_id_uv); +/** + * of_batterydata_get_best_profile() - Find matching battery data device node + * @batterydata_container_node: pointer to the battery-data container device + * node containing the profile nodes. + * @batt_id_kohm: Battery ID in KOhms for which we want to find the profile. + * @batt_type: Battery type which we want to force load the profile. + * + * This routine returns a device_node pointer to the closest match battery data + * from device tree based on the battery id reading. + */ +struct device_node *of_batterydata_get_best_profile( + struct device_node *batterydata_container_node, + int batt_id_kohm, const char *batt_type); +#else +static inline int of_batterydata_read_data(struct device_node *container_node, + struct bms_battery_data *batt_data, + int batt_id_uv) +{ + return -ENXIO; +} +static inline struct device_node *of_batterydata_get_best_profile( + struct device_node *batterydata_container_node, + int batt_id_kohm, const char *batt_type) +{ + return -ENXIO; +} +#endif /* CONFIG_OF_QPNP */ diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h index ad2f67054372..33b4aac7adcb 100644 --- a/include/linux/of_reserved_mem.h +++ b/include/linux/of_reserved_mem.h @@ -13,6 +13,7 @@ struct reserved_mem { phys_addr_t base; phys_addr_t size; void *priv; + int fixup; }; struct reserved_mem_ops { diff --git a/include/linux/of_slimbus.h b/include/linux/of_slimbus.h new file mode 100644 index 000000000000..f686cdc5fa1c --- /dev/null +++ b/include/linux/of_slimbus.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2012, 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. + */ + +#include <linux/slimbus/slimbus.h> +#include <linux/of_irq.h> + +#ifdef CONFIG_OF_SLIMBUS +/* + * of_slim_register_devices() - Register devices in the SLIMbus Device Tree + * @ctrl: slim_controller which devices should be registered to. + * + * This routine scans the SLIMbus Device Tree, allocating resources and + * creating slim_devices according to the SLIMbus Device Tree + * hierarchy. Details of this hierarchy can be found in + * Documentation/devicetree/bindings/slimbus. This routine is normally + * called from the probe routine of the driver registering as a + * slim_controller. + */ +extern int of_register_slim_devices(struct slim_controller *ctrl); +#else +static int of_register_slim_devices(struct slim_controller *ctrl) +{ + return 0; +} +#endif /* CONFIG_OF_SLIMBUS */ diff --git a/include/linux/oom.h b/include/linux/oom.h index 03e6257321f0..0ba4a4c9dd47 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -113,6 +113,9 @@ static inline bool task_will_free_mem(struct task_struct *task) !(task->signal->flags & SIGNAL_GROUP_COREDUMP); } +extern void dump_tasks(struct mem_cgroup *memcg, + const nodemask_t *nodemask); + /* sysctls */ extern int sysctl_oom_dump_tasks; extern int sysctl_oom_kill_allocating_task; diff --git a/include/linux/overflow.h b/include/linux/overflow.h new file mode 100644 index 000000000000..8712ff70995f --- /dev/null +++ b/include/linux/overflow.h @@ -0,0 +1,278 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +#ifndef __LINUX_OVERFLOW_H +#define __LINUX_OVERFLOW_H + +#include <linux/compiler.h> + +/* + * In the fallback code below, we need to compute the minimum and + * maximum values representable in a given type. These macros may also + * be useful elsewhere, so we provide them outside the + * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block. + * + * It would seem more obvious to do something like + * + * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0) + * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0) + * + * Unfortunately, the middle expressions, strictly speaking, have + * undefined behaviour, and at least some versions of gcc warn about + * the type_max expression (but not if -fsanitize=undefined is in + * effect; in that case, the warning is deferred to runtime...). + * + * The slightly excessive casting in type_min is to make sure the + * macros also produce sensible values for the exotic type _Bool. [The + * overflow checkers only almost work for _Bool, but that's + * a-feature-not-a-bug, since people shouldn't be doing arithmetic on + * _Bools. Besides, the gcc builtins don't allow _Bool* as third + * argument.] + * + * Idea stolen from + * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html - + * credit to Christian Biere. + */ +#define is_signed_type(type) (((type)(-1)) < (type)1) +#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) +#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) +#define type_min(T) ((T)((T)-type_max(T)-(T)1)) + + +#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW +/* + * For simplicity and code hygiene, the fallback code below insists on + * a, b and *d having the same type (similar to the min() and max() + * macros), whereas gcc's type-generic overflow checkers accept + * different types. Hence we don't just make check_add_overflow an + * alias for __builtin_add_overflow, but add type checks similar to + * below. + */ +#define check_add_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + __builtin_add_overflow(__a, __b, __d); \ +}) + +#define check_sub_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + __builtin_sub_overflow(__a, __b, __d); \ +}) + +#define check_mul_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + __builtin_mul_overflow(__a, __b, __d); \ +}) + +#else + + +/* Checking for unsigned overflow is relatively easy without causing UB. */ +#define __unsigned_add_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a + __b; \ + *__d < __a; \ +}) +#define __unsigned_sub_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a - __b; \ + __a < __b; \ +}) +/* + * If one of a or b is a compile-time constant, this avoids a division. + */ +#define __unsigned_mul_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = __a * __b; \ + __builtin_constant_p(__b) ? \ + __b > 0 && __a > type_max(typeof(__a)) / __b : \ + __a > 0 && __b > type_max(typeof(__b)) / __a; \ +}) + +/* + * For signed types, detecting overflow is much harder, especially if + * we want to avoid UB. But the interface of these macros is such that + * we must provide a result in *d, and in fact we must produce the + * result promised by gcc's builtins, which is simply the possibly + * wrapped-around value. Fortunately, we can just formally do the + * operations in the widest relevant unsigned type (u64) and then + * truncate the result - gcc is smart enough to generate the same code + * with and without the (u64) casts. + */ + +/* + * Adding two signed integers can overflow only if they have the same + * sign, and overflow has happened iff the result has the opposite + * sign. + */ +#define __signed_add_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a + (u64)__b; \ + (((~(__a ^ __b)) & (*__d ^ __a)) \ + & type_min(typeof(__a))) != 0; \ +}) + +/* + * Subtraction is similar, except that overflow can now happen only + * when the signs are opposite. In this case, overflow has happened if + * the result has the opposite sign of a. + */ +#define __signed_sub_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a - (u64)__b; \ + ((((__a ^ __b)) & (*__d ^ __a)) \ + & type_min(typeof(__a))) != 0; \ +}) + +/* + * Signed multiplication is rather hard. gcc always follows C99, so + * division is truncated towards 0. This means that we can write the + * overflow check like this: + * + * (a > 0 && (b > MAX/a || b < MIN/a)) || + * (a < -1 && (b > MIN/a || b < MAX/a) || + * (a == -1 && b == MIN) + * + * The redundant casts of -1 are to silence an annoying -Wtype-limits + * (included in -Wextra) warning: When the type is u8 or u16, the + * __b_c_e in check_mul_overflow obviously selects + * __unsigned_mul_overflow, but unfortunately gcc still parses this + * code and warns about the limited range of __b. + */ + +#define __signed_mul_overflow(a, b, d) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + typeof(d) __d = (d); \ + typeof(a) __tmax = type_max(typeof(a)); \ + typeof(a) __tmin = type_min(typeof(a)); \ + (void) (&__a == &__b); \ + (void) (&__a == __d); \ + *__d = (u64)__a * (u64)__b; \ + (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \ + (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \ + (__b == (typeof(__b))-1 && __a == __tmin); \ +}) + + +#define check_add_overflow(a, b, d) \ + __builtin_choose_expr(is_signed_type(typeof(a)), \ + __signed_add_overflow(a, b, d), \ + __unsigned_add_overflow(a, b, d)) + +#define check_sub_overflow(a, b, d) \ + __builtin_choose_expr(is_signed_type(typeof(a)), \ + __signed_sub_overflow(a, b, d), \ + __unsigned_sub_overflow(a, b, d)) + +#define check_mul_overflow(a, b, d) \ + __builtin_choose_expr(is_signed_type(typeof(a)), \ + __signed_mul_overflow(a, b, d), \ + __unsigned_mul_overflow(a, b, d)) + + +#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ + +/** + * array_size() - Calculate size of 2-dimensional array. + * + * @a: dimension one + * @b: dimension two + * + * Calculates size of 2-dimensional array: @a * @b. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +static inline __must_check size_t array_size(size_t a, size_t b) +{ + size_t bytes; + + if (check_mul_overflow(a, b, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * array3_size() - Calculate size of 3-dimensional array. + * + * @a: dimension one + * @b: dimension two + * @c: dimension three + * + * Calculates size of 3-dimensional array: @a * @b * @c. + * + * Returns: number of bytes needed to represent the array or SIZE_MAX on + * overflow. + */ +static inline __must_check size_t array3_size(size_t a, size_t b, size_t c) +{ + size_t bytes; + + if (check_mul_overflow(a, b, &bytes)) + return SIZE_MAX; + if (check_mul_overflow(bytes, c, &bytes)) + return SIZE_MAX; + + return bytes; +} + +static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c) +{ + size_t bytes; + + if (check_mul_overflow(n, size, &bytes)) + return SIZE_MAX; + if (check_add_overflow(bytes, c, &bytes)) + return SIZE_MAX; + + return bytes; +} + +/** + * struct_size() - Calculate size of structure with trailing array. + * @p: Pointer to the structure. + * @member: Name of the array member. + * @n: Number of elements in the array. + * + * Calculates size of memory needed for structure @p followed by an + * array of @n @member elements. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size(p, member, n) \ + __ab_c_size(n, \ + sizeof(*(p)->member) + __must_be_array((p)->member),\ + sizeof(*(p))) + +#endif /* __LINUX_OVERFLOW_H */ diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index bb53c7b86315..985fb2c63cb7 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -108,6 +108,9 @@ enum pageflags { PG_young, PG_idle, #endif +#ifdef CONFIG_ZCACHE + PG_was_active, +#endif __NR_PAGEFLAGS, /* Filesystems */ @@ -129,53 +132,108 @@ enum pageflags { /* SLOB */ PG_slob_free = PG_private, + + /* non-lru isolated movable page */ + PG_isolated = PG_reclaim, }; #ifndef __GENERATING_BOUNDS_H +struct page; /* forward declaration */ + +static inline struct page *compound_head(struct page *page) +{ + unsigned long head = READ_ONCE(page->compound_head); + + if (unlikely(head & 1)) + return (struct page *) (head - 1); + return page; +} + +static inline int PageTail(struct page *page) +{ + return READ_ONCE(page->compound_head) & 1; +} + +static inline int PageCompound(struct page *page) +{ + return test_bit(PG_head, &page->flags) || PageTail(page); +} + +/* + * Page flags policies wrt compound pages + * + * PF_ANY: + * the page flag is relevant for small, head and tail pages. + * + * PF_HEAD: + * for compound page all operations related to the page flag applied to + * head page. + * + * PF_NO_TAIL: + * modifications of the page flag must be done on small or head pages, + * checks can be done on tail pages too. + * + * PF_NO_COMPOUND: + * the page flag is not relevant for compound pages. + */ +#define PF_ANY(page, enforce) page +#define PF_HEAD(page, enforce) compound_head(page) +#define PF_NO_TAIL(page, enforce) ({ \ + VM_BUG_ON_PGFLAGS(enforce && PageTail(page), page); \ + compound_head(page);}) +#define PF_NO_COMPOUND(page, enforce) ({ \ + VM_BUG_ON_PGFLAGS(enforce && PageCompound(page), page); \ + page;}) + /* * Macros to create function definitions for page flags */ -#define TESTPAGEFLAG(uname, lname) \ -static inline int Page##uname(const struct page *page) \ - { return test_bit(PG_##lname, &page->flags); } +#define TESTPAGEFLAG(uname, lname, policy) \ +static inline int Page##uname(struct page *page) \ + { return test_bit(PG_##lname, &policy(page, 0)->flags); } -#define SETPAGEFLAG(uname, lname) \ +#define SETPAGEFLAG(uname, lname, policy) \ static inline void SetPage##uname(struct page *page) \ - { set_bit(PG_##lname, &page->flags); } + { set_bit(PG_##lname, &policy(page, 1)->flags); } -#define CLEARPAGEFLAG(uname, lname) \ +#define CLEARPAGEFLAG(uname, lname, policy) \ static inline void ClearPage##uname(struct page *page) \ - { clear_bit(PG_##lname, &page->flags); } + { clear_bit(PG_##lname, &policy(page, 1)->flags); } -#define __SETPAGEFLAG(uname, lname) \ +#define __SETPAGEFLAG(uname, lname, policy) \ static inline void __SetPage##uname(struct page *page) \ - { __set_bit(PG_##lname, &page->flags); } + { __set_bit(PG_##lname, &policy(page, 1)->flags); } -#define __CLEARPAGEFLAG(uname, lname) \ +#define __CLEARPAGEFLAG(uname, lname, policy) \ static inline void __ClearPage##uname(struct page *page) \ - { __clear_bit(PG_##lname, &page->flags); } + { __clear_bit(PG_##lname, &policy(page, 1)->flags); } -#define TESTSETFLAG(uname, lname) \ +#define TESTSETFLAG(uname, lname, policy) \ static inline int TestSetPage##uname(struct page *page) \ - { return test_and_set_bit(PG_##lname, &page->flags); } + { return test_and_set_bit(PG_##lname, &policy(page, 1)->flags); } -#define TESTCLEARFLAG(uname, lname) \ +#define TESTCLEARFLAG(uname, lname, policy) \ static inline int TestClearPage##uname(struct page *page) \ - { return test_and_clear_bit(PG_##lname, &page->flags); } + { return test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); } -#define __TESTCLEARFLAG(uname, lname) \ +#define __TESTCLEARFLAG(uname, lname, policy) \ static inline int __TestClearPage##uname(struct page *page) \ - { return __test_and_clear_bit(PG_##lname, &page->flags); } + { return __test_and_clear_bit(PG_##lname, &policy(page, 1)->flags); } -#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \ - SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname) +#define PAGEFLAG(uname, lname, policy) \ + TESTPAGEFLAG(uname, lname, policy) \ + SETPAGEFLAG(uname, lname, policy) \ + CLEARPAGEFLAG(uname, lname, policy) -#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \ - __SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname) +#define __PAGEFLAG(uname, lname, policy) \ + TESTPAGEFLAG(uname, lname, policy) \ + __SETPAGEFLAG(uname, lname, policy) \ + __CLEARPAGEFLAG(uname, lname, policy) -#define TESTSCFLAG(uname, lname) \ - TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) +#define TESTSCFLAG(uname, lname, policy) \ + TESTSETFLAG(uname, lname, policy) \ + TESTCLEARFLAG(uname, lname, policy) #define TESTPAGEFLAG_FALSE(uname) \ static inline int Page##uname(const struct page *page) { return 0; } @@ -204,47 +262,53 @@ static inline int __TestClearPage##uname(struct page *page) { return 0; } #define TESTSCFLAG_FALSE(uname) \ TESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname) -struct page; /* forward declaration */ - -TESTPAGEFLAG(Locked, locked) -PAGEFLAG(Error, error) TESTCLEARFLAG(Error, error) -PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) - __SETPAGEFLAG(Referenced, referenced) -PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty) -PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru) -PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active) - TESTCLEARFLAG(Active, active) -__PAGEFLAG(Slab, slab) -PAGEFLAG(Checked, checked) /* Used by some filesystems */ -PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned) /* Xen */ -PAGEFLAG(SavePinned, savepinned); /* Xen */ -PAGEFLAG(Foreign, foreign); /* Xen */ -PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved) -PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked) - __SETPAGEFLAG(SwapBacked, swapbacked) - -__PAGEFLAG(SlobFree, slob_free) +__PAGEFLAG(Locked, locked, PF_NO_TAIL) +PAGEFLAG(Error, error, PF_ANY) TESTCLEARFLAG(Error, error, PF_ANY) +PAGEFLAG(Referenced, referenced, PF_ANY) TESTCLEARFLAG(Referenced, referenced, PF_ANY) + __SETPAGEFLAG(Referenced, referenced, PF_ANY) +PAGEFLAG(Dirty, dirty, PF_ANY) TESTSCFLAG(Dirty, dirty, PF_ANY) + __CLEARPAGEFLAG(Dirty, dirty, PF_ANY) +PAGEFLAG(LRU, lru, PF_ANY) __CLEARPAGEFLAG(LRU, lru, PF_ANY) +PAGEFLAG(Active, active, PF_ANY) __CLEARPAGEFLAG(Active, active, PF_ANY) + TESTCLEARFLAG(Active, active, PF_ANY) +__PAGEFLAG(Slab, slab, PF_ANY) +PAGEFLAG(Checked, checked, PF_ANY) /* Used by some filesystems */ +PAGEFLAG(Pinned, pinned, PF_ANY) TESTSCFLAG(Pinned, pinned, PF_ANY) /* Xen */ +PAGEFLAG(SavePinned, savepinned, PF_ANY); /* Xen */ +PAGEFLAG(Foreign, foreign, PF_ANY); /* Xen */ +PAGEFLAG(Reserved, reserved, PF_ANY) __CLEARPAGEFLAG(Reserved, reserved, PF_ANY) +PAGEFLAG(SwapBacked, swapbacked, PF_ANY) + __CLEARPAGEFLAG(SwapBacked, swapbacked, PF_ANY) + __SETPAGEFLAG(SwapBacked, swapbacked, PF_ANY) + +__PAGEFLAG(SlobFree, slob_free, PF_ANY) +#ifdef CONFIG_ZCACHE +PAGEFLAG(WasActive, was_active, PF_ANY) +#else +PAGEFLAG_FALSE(WasActive) +#endif /* * Private page markings that may be used by the filesystem that owns the page * for its own purposes. * - PG_private and PG_private_2 cause releasepage() and co to be invoked */ -PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private) - __CLEARPAGEFLAG(Private, private) -PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2) -PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1) +PAGEFLAG(Private, private, PF_ANY) __SETPAGEFLAG(Private, private, PF_ANY) + __CLEARPAGEFLAG(Private, private, PF_ANY) +PAGEFLAG(Private2, private_2, PF_ANY) TESTSCFLAG(Private2, private_2, PF_ANY) +PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY) + TESTCLEARFLAG(OwnerPriv1, owner_priv_1, PF_ANY) /* * Only test-and-set exist for PG_writeback. The unconditional operators are * risky: they bypass page accounting. */ -TESTPAGEFLAG(Writeback, writeback) TESTSCFLAG(Writeback, writeback) -PAGEFLAG(MappedToDisk, mappedtodisk) +TESTPAGEFLAG(Writeback, writeback, PF_ANY) TESTSCFLAG(Writeback, writeback, PF_ANY) +PAGEFLAG(MappedToDisk, mappedtodisk, PF_ANY) /* PG_readahead is only used for reads; PG_reclaim is only for writes */ -PAGEFLAG(Reclaim, reclaim) TESTCLEARFLAG(Reclaim, reclaim) -PAGEFLAG(Readahead, reclaim) TESTCLEARFLAG(Readahead, reclaim) +PAGEFLAG(Reclaim, reclaim, PF_ANY) TESTCLEARFLAG(Reclaim, reclaim, PF_ANY) +PAGEFLAG(Readahead, reclaim, PF_ANY) TESTCLEARFLAG(Readahead, reclaim, PF_ANY) #ifdef CONFIG_HIGHMEM /* @@ -257,31 +321,32 @@ PAGEFLAG_FALSE(HighMem) #endif #ifdef CONFIG_SWAP -PAGEFLAG(SwapCache, swapcache) +PAGEFLAG(SwapCache, swapcache, PF_ANY) #else PAGEFLAG_FALSE(SwapCache) #endif -PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) - TESTCLEARFLAG(Unevictable, unevictable) +PAGEFLAG(Unevictable, unevictable, PF_ANY) + __CLEARPAGEFLAG(Unevictable, unevictable, PF_ANY) + TESTCLEARFLAG(Unevictable, unevictable, PF_ANY) #ifdef CONFIG_MMU -PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked) - TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked) +PAGEFLAG(Mlocked, mlocked, PF_ANY) __CLEARPAGEFLAG(Mlocked, mlocked, PF_ANY) + TESTSCFLAG(Mlocked, mlocked, PF_ANY) __TESTCLEARFLAG(Mlocked, mlocked, PF_ANY) #else PAGEFLAG_FALSE(Mlocked) __CLEARPAGEFLAG_NOOP(Mlocked) TESTSCFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked) #endif #ifdef CONFIG_ARCH_USES_PG_UNCACHED -PAGEFLAG(Uncached, uncached) +PAGEFLAG(Uncached, uncached, PF_ANY) #else PAGEFLAG_FALSE(Uncached) #endif #ifdef CONFIG_MEMORY_FAILURE -PAGEFLAG(HWPoison, hwpoison) -TESTSCFLAG(HWPoison, hwpoison) +PAGEFLAG(HWPoison, hwpoison, PF_ANY) +TESTSCFLAG(HWPoison, hwpoison, PF_ANY) #define __PG_HWPOISON (1UL << PG_hwpoison) #else PAGEFLAG_FALSE(HWPoison) @@ -289,10 +354,10 @@ PAGEFLAG_FALSE(HWPoison) #endif #if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT) -TESTPAGEFLAG(Young, young) -SETPAGEFLAG(Young, young) -TESTCLEARFLAG(Young, young) -PAGEFLAG(Idle, idle) +TESTPAGEFLAG(Young, young, PF_ANY) +SETPAGEFLAG(Young, young, PF_ANY) +TESTCLEARFLAG(Young, young, PF_ANY) +PAGEFLAG(Idle, idle, PF_ANY) #endif /* @@ -301,25 +366,38 @@ PAGEFLAG(Idle, idle) * with the PAGE_MAPPING_ANON bit set to distinguish it. See rmap.h. * * On an anonymous page in a VM_MERGEABLE area, if CONFIG_KSM is enabled, - * the PAGE_MAPPING_KSM bit may be set along with the PAGE_MAPPING_ANON bit; - * and then page->mapping points, not to an anon_vma, but to a private + * the PAGE_MAPPING_MOVABLE bit may be set along with the PAGE_MAPPING_ANON + * bit; and then page->mapping points, not to an anon_vma, but to a private * structure which KSM associates with that merged page. See ksm.h. * - * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is currently never used. + * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is used for non-lru movable + * page and then page->mapping points a struct address_space. * * Please note that, confusingly, "page_mapping" refers to the inode * address_space which maps the page from disk; whereas "page_mapped" * refers to user virtual address space into which the page is mapped. */ -#define PAGE_MAPPING_ANON 1 -#define PAGE_MAPPING_KSM 2 -#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM) +#define PAGE_MAPPING_ANON 0x1 +#define PAGE_MAPPING_MOVABLE 0x2 +#define PAGE_MAPPING_KSM (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE) +#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE) + +static __always_inline int PageMappingFlags(struct page *page) +{ + return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0; +} static inline int PageAnon(struct page *page) { return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0; } +static __always_inline int __PageMovable(struct page *page) +{ + return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) == + PAGE_MAPPING_MOVABLE; +} + #ifdef CONFIG_KSM /* * A KSM page is one of those write-protected "shared pages" or "merged pages" @@ -330,7 +408,7 @@ static inline int PageAnon(struct page *page) static inline int PageKsm(struct page *page) { return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) == - (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); + PAGE_MAPPING_KSM; } #else TESTPAGEFLAG_FALSE(Ksm) @@ -373,7 +451,7 @@ static inline void SetPageUptodate(struct page *page) set_bit(PG_uptodate, &(page)->flags); } -CLEARPAGEFLAG(Uptodate, uptodate) +CLEARPAGEFLAG(Uptodate, uptodate, PF_ANY) int test_clear_page_writeback(struct page *page); int __test_set_page_writeback(struct page *page, bool keep_write); @@ -393,12 +471,7 @@ static inline void set_page_writeback_keepwrite(struct page *page) test_set_page_writeback_keepwrite(page); } -__PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head) - -static inline int PageTail(struct page *page) -{ - return READ_ONCE(page->compound_head) & 1; -} +__PAGEFLAG(Head, head, PF_ANY) CLEARPAGEFLAG(Head, head, PF_ANY) static inline void set_compound_head(struct page *page, struct page *head) { @@ -410,20 +483,6 @@ static inline void clear_compound_head(struct page *page) WRITE_ONCE(page->compound_head, 0); } -static inline struct page *compound_head(struct page *page) -{ - unsigned long head = READ_ONCE(page->compound_head); - - if (unlikely(head & 1)) - return (struct page *) (head - 1); - return page; -} - -static inline int PageCompound(struct page *page) -{ - return PageHead(page) || PageTail(page); - -} #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline void ClearPageCompound(struct page *page) { @@ -549,6 +608,8 @@ static inline void __ClearPageBalloon(struct page *page) atomic_set(&page->_mapcount, -1); } +__PAGEFLAG(Isolated, isolated, PF_ANY); + /* * If network-based swap is enabled, sl*b must keep track of whether pages * were allocated from pfmemalloc reserves. @@ -626,6 +687,10 @@ static inline int page_has_private(struct page *page) return !!(page->flags & PAGE_FLAGS_PRIVATE); } +#undef PF_ANY +#undef PF_HEAD +#undef PF_NO_TAIL +#undef PF_NO_COMPOUND #endif /* !__GENERATING_BOUNDS_H */ #endif /* PAGE_FLAGS_H */ diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index 17f118a82854..03f2a3e7d76d 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -3,6 +3,7 @@ #include <linux/types.h> #include <linux/stacktrace.h> +#include <linux/stackdepot.h> struct pglist_data; struct page_ext_operations { @@ -44,8 +45,8 @@ struct page_ext { #ifdef CONFIG_PAGE_OWNER unsigned int order; gfp_t gfp_mask; - unsigned int nr_entries; - unsigned long trace_entries[8]; + int last_migrate_reason; + depot_stack_handle_t handle; #endif }; diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index cacaabea8a09..30583ab0ffb1 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -1,38 +1,52 @@ #ifndef __LINUX_PAGE_OWNER_H #define __LINUX_PAGE_OWNER_H +#include <linux/jump_label.h> + #ifdef CONFIG_PAGE_OWNER -extern bool page_owner_inited; +extern struct static_key_false page_owner_inited; extern struct page_ext_operations page_owner_ops; extern void __reset_page_owner(struct page *page, unsigned int order); extern void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask); -extern gfp_t __get_page_owner_gfp(struct page *page); +extern void __split_page_owner(struct page *page, unsigned int order); +extern void __copy_page_owner(struct page *oldpage, struct page *newpage); +extern void __set_page_owner_migrate_reason(struct page *page, int reason); +extern void __dump_page_owner(struct page *page); static inline void reset_page_owner(struct page *page, unsigned int order) { - if (likely(!page_owner_inited)) - return; - - __reset_page_owner(page, order); + if (static_branch_unlikely(&page_owner_inited)) + __reset_page_owner(page, order); } static inline void set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) { - if (likely(!page_owner_inited)) - return; - - __set_page_owner(page, order, gfp_mask); + if (static_branch_unlikely(&page_owner_inited)) + __set_page_owner(page, order, gfp_mask); } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, unsigned int order) { - if (likely(!page_owner_inited)) - return 0; - - return __get_page_owner_gfp(page); + if (static_branch_unlikely(&page_owner_inited)) + __split_page_owner(page, order); +} +static inline void copy_page_owner(struct page *oldpage, struct page *newpage) +{ + if (static_branch_unlikely(&page_owner_inited)) + __copy_page_owner(oldpage, newpage); +} +static inline void set_page_owner_migrate_reason(struct page *page, int reason) +{ + if (static_branch_unlikely(&page_owner_inited)) + __set_page_owner_migrate_reason(page, reason); +} +static inline void dump_page_owner(struct page *page) +{ + if (static_branch_unlikely(&page_owner_inited)) + __dump_page_owner(page); } #else static inline void reset_page_owner(struct page *page, unsigned int order) @@ -42,10 +56,18 @@ static inline void set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) { } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, + unsigned int order) +{ +} +static inline void copy_page_owner(struct page *oldpage, struct page *newpage) +{ +} +static inline void set_page_owner_migrate_reason(struct page *page, int reason) +{ +} +static inline void dump_page_owner(struct page *page) { - return 0; } - #endif /* CONFIG_PAGE_OWNER */ #endif /* __LINUX_PAGE_OWNER_H */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 771774e13f10..d2f4a732b3e8 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -359,8 +359,16 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); -unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, - int tag, unsigned int nr_pages, struct page **pages); +unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, + pgoff_t end, int tag, unsigned int nr_pages, + struct page **pages); +static inline unsigned find_get_pages_tag(struct address_space *mapping, + pgoff_t *index, int tag, unsigned int nr_pages, + struct page **pages) +{ + return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag, + nr_pages, pages); +} struct page *grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index, unsigned flags); @@ -433,18 +441,9 @@ extern int __lock_page_or_retry(struct page *page, struct mm_struct *mm, unsigned int flags); extern void unlock_page(struct page *page); -static inline void __set_page_locked(struct page *page) -{ - __set_bit(PG_locked, &page->flags); -} - -static inline void __clear_page_locked(struct page *page) -{ - __clear_bit(PG_locked, &page->flags); -} - static inline int trylock_page(struct page *page) { + page = compound_head(page); return (likely(!test_and_set_bit_lock(PG_locked, &page->flags))); } @@ -497,9 +496,9 @@ extern int wait_on_page_bit_killable_timeout(struct page *page, static inline int wait_on_page_locked_killable(struct page *page) { - if (PageLocked(page)) - return wait_on_page_bit_killable(page, PG_locked); - return 0; + if (!PageLocked(page)) + return 0; + return wait_on_page_bit_killable(compound_head(page), PG_locked); } extern wait_queue_head_t *page_waitqueue(struct page *page); @@ -518,7 +517,7 @@ static inline void wake_up_page(struct page *page, int bit) static inline void wait_on_page_locked(struct page *page) { if (PageLocked(page)) - wait_on_page_bit(page, PG_locked); + wait_on_page_bit(compound_head(page), PG_locked); } /* @@ -664,17 +663,17 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask); /* * Like add_to_page_cache_locked, but used to add newly allocated pages: - * the page is new, so we can just run __set_page_locked() against it. + * the page is new, so we can just run __SetPageLocked() against it. */ static inline int add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) { int error; - __set_page_locked(page); + __SetPageLocked(page); error = add_to_page_cache_locked(page, mapping, offset, gfp_mask); if (unlikely(error)) - __clear_page_locked(page); + __ClearPageLocked(page); return error; } diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index b45d391b4540..cead4419f933 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -29,9 +29,17 @@ unsigned pagevec_lookup_entries(struct pagevec *pvec, void pagevec_remove_exceptionals(struct pagevec *pvec); unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, pgoff_t start, unsigned nr_pages); -unsigned pagevec_lookup_tag(struct pagevec *pvec, - struct address_space *mapping, pgoff_t *index, int tag, - unsigned nr_pages); +unsigned pagevec_lookup_range_tag(struct pagevec *pvec, + struct address_space *mapping, pgoff_t *index, pgoff_t end, + int tag); +unsigned pagevec_lookup_range_nr_tag(struct pagevec *pvec, + struct address_space *mapping, pgoff_t *index, pgoff_t end, + int tag, unsigned max_pages); +static inline unsigned pagevec_lookup_tag(struct pagevec *pvec, + struct address_space *mapping, pgoff_t *index, int tag) +{ + return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag); +} static inline void pagevec_init(struct pagevec *pvec, int cold) { diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 0e55e4016f49..5bc4836af286 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -77,6 +77,12 @@ struct pmu_hw_events { struct arm_pmu *percpu_pmu; }; +enum armpmu_pmu_states { + ARM_PMU_STATE_OFF, + ARM_PMU_STATE_RUNNING, + ARM_PMU_STATE_GOING_DOWN, +}; + struct arm_pmu { struct pmu pmu; cpumask_t active_irqs; @@ -101,9 +107,12 @@ struct arm_pmu { void (*free_irq)(struct arm_pmu *); int (*map_event)(struct perf_event *event); int num_events; + int pmu_state; + int percpu_irq; atomic_t active_events; struct mutex reserve_mutex; u64 max_period; + bool secure_access; /* 32-bit ARM only */ struct platform_device *plat_device; struct pmu_hw_events __percpu *hw_events; struct notifier_block hotplug_nb; @@ -112,7 +121,10 @@ struct arm_pmu { #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) -int armpmu_register(struct arm_pmu *armpmu, int type); +extern const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX]; +extern const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX]; u64 armpmu_event_update(struct perf_event *event); @@ -150,6 +162,18 @@ int arm_pmu_device_probe(struct platform_device *pdev, const struct of_device_id *of_table, const struct pmu_probe_info *probe_table); +void armv8_pmu_init(struct arm_pmu *cpu_pmu); +int armv8pmu_enable_intens(int idx); +int armv8pmu_disable_intens(int idx); +int armv8pmu_enable_counter(int idx); +int armv8pmu_disable_counter(int idx); +u32 armv8pmu_getreset_flags(void); +void armv8pmu_pmcr_write(u32 val); +void armv8pmu_write_evtype(int idx, u32 val); +int armv8pmu_probe_num_events(struct arm_pmu *arm_pmu); + +int kryo_pmu_init(struct arm_pmu *cpu_pmu); + #endif /* CONFIG_ARM_PMU */ #endif /* __ARM_PMU_H__ */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 1e398e6ec786..efce166a9f17 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -231,10 +231,12 @@ struct pmu { int capabilities; int * __percpu pmu_disable_count; - struct perf_cpu_context * __percpu pmu_cpu_context; + struct perf_cpu_context __percpu *pmu_cpu_context; atomic_t exclusive_cnt; /* < 0: cpu; > 0: tsk */ int task_ctx_nr; int hrtimer_interval_ms; + u32 events_across_hotplug:1, + reserved:31; /* * Fully disable/enable this PMU, can be used to protect from the PMI @@ -379,7 +381,7 @@ struct pmu { /* * Set up pmu-private data structures for an AUX area */ - void *(*setup_aux) (int cpu, void **pages, + void *(*setup_aux) (struct perf_event *event, void **pages, int nr_pages, bool overwrite); /* optional */ @@ -392,6 +394,14 @@ struct pmu { * Filter events for PMU-specific reasons. */ int (*filter_match) (struct perf_event *event); /* optional */ + + /* + * Initial, PMU driver specific configuration. + */ + int (*get_drv_configs) (struct perf_event *event, + void __user *arg); /* optional */ + void (*free_drv_configs) (struct perf_event *event); + /* optional */ }; /** @@ -467,6 +477,12 @@ struct perf_event { int nr_siblings; int group_flags; struct perf_event *group_leader; + + /* + * Protect the pmu, attributes and context of a group leader. + * Note: does not protect the pointer to the group_leader. + */ + struct mutex group_leader_mutex; struct pmu *pmu; enum perf_event_active_state state; @@ -559,6 +575,7 @@ struct perf_event { struct irq_work pending; atomic_t event_limit; + struct list_head drv_configs; void (*destroy)(struct perf_event *); struct rcu_head rcu_head; @@ -754,6 +771,7 @@ extern u64 perf_event_read_local(struct perf_event *event); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); +extern struct dentry *perf_create_debug_dir(void); struct perf_sample_data { /* diff --git a/include/linux/pfk.h b/include/linux/pfk.h new file mode 100644 index 000000000000..82ee74199752 --- /dev/null +++ b/include/linux/pfk.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2015-2017, 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 PFK_H_ +#define PFK_H_ + +#include <linux/bio.h> + +struct ice_crypto_setting; + +#ifdef CONFIG_PFK + +int pfk_load_key_start(const struct bio *bio, + struct ice_crypto_setting *ice_setting, bool *is_pfe, bool); +int pfk_load_key_end(const struct bio *bio, bool *is_pfe); +int pfk_remove_key(const unsigned char *key, size_t key_size); +bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2); +void pfk_clear_on_reset(void); + +#else +static inline int pfk_load_key_start(const struct bio *bio, + struct ice_crypto_setting *ice_setting, bool *is_pfe, bool async) +{ + return -ENODEV; +} + +static inline int pfk_load_key_end(const struct bio *bio, bool *is_pfe) +{ + return -ENODEV; +} + +static inline int pfk_remove_key(const unsigned char *key, size_t key_size) +{ + return -ENODEV; +} + +static inline bool pfk_allow_merge_bio(const struct bio *bio1, + const struct bio *bio2) +{ + return true; +} + +static inline void pfk_clear_on_reset(void) +{} + +#endif /* CONFIG_PFK */ + +#endif /* PFK_H */ diff --git a/include/linux/pft.h b/include/linux/pft.h new file mode 100644 index 000000000000..818383c73476 --- /dev/null +++ b/include/linux/pft.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2016, 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 PFT_H_ +#define PFT_H_ + +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/bio.h> + +#ifdef CONFIG_PFT + +/* dm-req-crypt API */ +int pft_get_key_index(struct bio *bio, u32 *key_index, + bool *is_encrypted, bool *is_inplace); + +/* block layer API */ +bool pft_allow_merge_bio(struct bio *bio1, struct bio *bio2); + +/* --- security hooks , called from selinux --- */ +int pft_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode); + +int pft_inode_post_create(struct inode *dir, struct dentry *dentry, + umode_t mode); + +int pft_file_open(struct file *filp, const struct cred *cred); + +int pft_file_permission(struct file *file, int mask); + +int pft_file_close(struct file *filp); + +int pft_inode_unlink(struct inode *dir, struct dentry *dentry); + +int pft_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, + dev_t dev); + +int pft_inode_rename(struct inode *inode, struct dentry *dentry, + struct inode *new_inode, struct dentry *new_dentry); + +int pft_inode_set_xattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); + + +#else +static inline int pft_get_key_index(struct bio *bio, u32 *key_index, + bool *is_encrypted, bool *is_inplace) +{ return -ENODEV; } + +static inline bool pft_allow_merge_bio(const struct bio *bio1, + const struct bio *bio2) +{ return true; } + +static inline int pft_file_permission(struct file *file, int mask) +{ return 0; } + +static inline int pft_inode_create( + struct inode *dir, struct dentry *dentry, umode_t mode) +{ return 0; } + +static inline int pft_inode_post_create( + struct inode *dir, struct dentry *dentry, umode_t mode) +{ return 0; } + +static inline int pft_file_open(struct file *filp, const struct cred *cred) +{ return 0; } + +static inline int pft_file_close(struct file *filp) +{ return 0; } + +static inline int pft_inode_unlink(struct inode *dir, struct dentry *dentry) +{ return 0; } + +static inline int pft_inode_mknod(struct inode *dir, struct dentry *dentry, + umode_t mode, dev_t dev) +{ return 0; } + +static inline int pft_inode_rename(struct inode *inode, struct dentry *dentry, + struct inode *new_inode, struct dentry *new_dentry) +{ return 0; } + +static inline int pft_inode_set_xattr(struct dentry *dentry, const char *name, + const void *value, size_t size, + int flags) +{ return 0; } + +#endif /* CONFIG_PFT */ + +#endif /* PFT_H */ diff --git a/include/linux/phy.h b/include/linux/phy.h index dbfd5ce9350f..c175610c8fdb 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -18,6 +18,7 @@ #include <linux/spinlock.h> #include <linux/ethtool.h> +#include <linux/mdio.h> #include <linux/mii.h> #include <linux/module.h> #include <linux/timer.h> @@ -357,6 +358,8 @@ struct phy_c45_device_ids { * handling, as well as handling shifts in PHY hardware state */ struct phy_device { + struct mdio_device mdio; + /* Information about the PHY type */ /* And management functions */ struct phy_driver *drv; diff --git a/include/linux/phy/phy-qcom-ufs.h b/include/linux/phy/phy-qcom-ufs.h index 9d18e9f948e9..25e7a5f183ec 100644 --- a/include/linux/phy/phy-qcom-ufs.h +++ b/include/linux/phy/phy-qcom-ufs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, 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 @@ -51,9 +51,13 @@ int ufs_qcom_phy_enable_iface_clk(struct phy *phy); void ufs_qcom_phy_disable_iface_clk(struct phy *phy); int ufs_qcom_phy_start_serdes(struct phy *phy); int ufs_qcom_phy_set_tx_lane_enable(struct phy *phy, u32 tx_lanes); +int ufs_qcom_phy_ctrl_rx_linecfg(struct phy *generic_phy, bool ctrl); int ufs_qcom_phy_calibrate_phy(struct phy *phy, bool is_rate_B); int ufs_qcom_phy_is_pcs_ready(struct phy *phy); void ufs_qcom_phy_save_controller_version(struct phy *phy, u8 major, u16 minor, u16 step); +const char *ufs_qcom_phy_name(struct phy *phy); +int ufs_qcom_phy_configure_lpm(struct phy *generic_phy, bool enable); +void ufs_qcom_phy_dbg_register_dump(struct phy *generic_phy); #endif /* PHY_QCOM_UFS_H_ */ diff --git a/include/linux/platform_data/msm_serial_hs.h b/include/linux/platform_data/msm_serial_hs.h new file mode 100644 index 000000000000..bc1f3e091d86 --- /dev/null +++ b/include/linux/platform_data/msm_serial_hs.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Google, Inc. + * Copyright (C) 2010-2014, The Linux Foundation. All rights reserved. + * Author: Nick Pelly <npelly@google.com> + * + * 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 __ASM_ARCH_MSM_SERIAL_HS_H +#define __ASM_ARCH_MSM_SERIAL_HS_H + +#include <linux/serial_core.h> + +/** + * struct msm_serial_hs_platform_data - platform device data + * for msm hsuart device + * @wakeup_irq : IRQ line to be configured as Wakeup source. + * @inject_rx_on_wakeup : Set 1 if specific character to be inserted on wakeup + * @rx_to_inject : Character to be inserted on wakeup + * @gpio_config : Configure gpios that are used for uart communication + * @userid : User-defined number to be used to enumerate device as tty<userid> + * @uart_tx_gpio: GPIO number for UART Tx Line. + * @uart_rx_gpio: GPIO number for UART Rx Line. + * @uart_cts_gpio: GPIO number for UART CTS Line. + * @uart_rfr_gpio: GPIO number for UART RFR Line. + * @bam_tx_ep_pipe_index : BAM TX Endpoint Pipe Index for HSUART + * @bam_tx_ep_pipe_index : BAM RX Endpoint Pipe Index for HSUART + * @no_suspend_delay : Flag used to make system go to suspend + * immediately or not + * @obs: Flag to enable out of band sleep feature support + */ +struct msm_serial_hs_platform_data { + int wakeup_irq; /* wakeup irq */ + bool inject_rx_on_wakeup; + u8 rx_to_inject; + int (*gpio_config)(int); + int userid; + + int uart_tx_gpio; + int uart_rx_gpio; + int uart_cts_gpio; + int uart_rfr_gpio; + unsigned bam_tx_ep_pipe_index; + unsigned bam_rx_ep_pipe_index; + bool no_suspend_delay; + bool obs; +}; + +/* return true when tx is empty */ +unsigned int msm_hs_tx_empty(struct uart_port *uport); +int msm_hs_request_clock_off(struct uart_port *uport); +int msm_hs_request_clock_on(struct uart_port *uport); +struct uart_port *msm_hs_get_uart_port(int port_index); +void msm_hs_set_mctrl(struct uart_port *uport, + unsigned int mctrl); +#endif diff --git a/include/linux/platform_data/qcom_crypto_device.h b/include/linux/platform_data/qcom_crypto_device.h new file mode 100644 index 000000000000..37cf3c8d7f93 --- /dev/null +++ b/include/linux/platform_data/qcom_crypto_device.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2011, 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 __QCOM_CRYPTO_DEVICE__H +#define __QCOM_CRYPTO_DEVICE__H + +struct msm_ce_hw_support { + uint32_t ce_shared; + uint32_t shared_ce_resource; + uint32_t hw_key_support; + uint32_t sha_hmac; + void *bus_scale_table; +}; + +#endif /* __QCOM_CRYPTO_DEVICE__H */ diff --git a/include/linux/platform_data/qcom_ssm.h b/include/linux/platform_data/qcom_ssm.h new file mode 100644 index 000000000000..5588bc752c8c --- /dev/null +++ b/include/linux/platform_data/qcom_ssm.h @@ -0,0 +1,21 @@ +/* Copyright (c) 2013-2014, 2016 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 __QCOM_SSM_H_ +#define __QCOM_SSM_H_ + +struct ssm_platform_data { + bool need_key_exchg; + const char *channel_name; +}; + +#endif /* __QCOM_SSM_H_ */ diff --git a/include/linux/platform_data/qcom_wcnss_device.h b/include/linux/platform_data/qcom_wcnss_device.h new file mode 100644 index 000000000000..be9a09a7dcd0 --- /dev/null +++ b/include/linux/platform_data/qcom_wcnss_device.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2011, 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 __QCOM_WCNSS_DEVICE__H +#define __QCOM_WCNSS_DEVICE__H + +struct qcom_wcnss_opts { + bool has_48mhz_xo; +}; + +#endif /* __QCOM_WCNSS_DEVICE__H */ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index dc777be5f2e1..6abd019c76f8 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -51,6 +51,7 @@ extern void arch_setup_pdev_archdata(struct platform_device *); extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); extern int platform_get_irq(struct platform_device *, unsigned int); +extern int platform_irq_count(struct platform_device *); extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); diff --git a/include/linux/plist.h b/include/linux/plist.h index 97883604a3c5..0ea3e1bc7ccc 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h @@ -266,6 +266,9 @@ static inline int plist_node_empty(const struct plist_node *node) #define plist_next(pos) \ list_next_entry(pos, node_list) +#define plist_next_entry(pos, type, member) \ + container_of(plist_next(pos), type, member) + /** * plist_prev - get the prev entry in list * @pos: the type * to cursor diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 9a2e50337af9..cccaf4a29e9f 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -34,6 +34,8 @@ bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp); int dev_pm_opp_get_opp_count(struct device *dev); unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev); +unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev); +unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev); struct dev_pm_opp *dev_pm_opp_get_suspend_opp(struct device *dev); struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, @@ -55,6 +57,14 @@ int dev_pm_opp_enable(struct device *dev, unsigned long freq); int dev_pm_opp_disable(struct device *dev, unsigned long freq); struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev); +int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, + unsigned int count); +void dev_pm_opp_put_supported_hw(struct device *dev); +int dev_pm_opp_set_prop_name(struct device *dev, const char *name); +void dev_pm_opp_put_prop_name(struct device *dev); +int dev_pm_opp_set_regulator(struct device *dev, const char *name); +void dev_pm_opp_put_regulator(struct device *dev); +int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); #else static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) { @@ -81,6 +91,16 @@ static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) return 0; } +static inline unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) +{ + return 0; +} + +static inline unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev) +{ + return 0; +} + static inline struct dev_pm_opp *dev_pm_opp_get_suspend_opp(struct device *dev) { return NULL; @@ -129,6 +149,35 @@ static inline struct srcu_notifier_head *dev_pm_opp_get_notifier( { return ERR_PTR(-EINVAL); } + +static inline int dev_pm_opp_set_supported_hw(struct device *dev, + const u32 *versions, + unsigned int count) +{ + return -EINVAL; +} + +static inline void dev_pm_opp_put_supported_hw(struct device *dev) {} + +static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) +{ + return -EINVAL; +} + +static inline void dev_pm_opp_put_prop_name(struct device *dev) {} + +static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name) +{ + return -EINVAL; +} + +static inline void dev_pm_opp_put_regulator(struct device *dev) {} + +static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) +{ + return -EINVAL; +} + #endif /* CONFIG_PM_OPP */ #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 0f65d36c2a75..ff49ab3516b1 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -9,6 +9,8 @@ #include <linux/miscdevice.h> #include <linux/device.h> #include <linux/workqueue.h> +#include <linux/cpumask.h> +#include <linux/interrupt.h> enum { PM_QOS_RESERVED = 0, @@ -42,7 +44,22 @@ enum pm_qos_flags_status { #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) #define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1) +enum pm_qos_req_type { + PM_QOS_REQ_ALL_CORES = 0, + PM_QOS_REQ_AFFINE_CORES, +#ifdef CONFIG_SMP + PM_QOS_REQ_AFFINE_IRQ, +#endif +}; + struct pm_qos_request { + enum pm_qos_req_type type; + struct cpumask cpus_affine; +#ifdef CONFIG_SMP + uint32_t irq; + /* Internal structure members */ + struct irq_affinity_notify irq_notify; +#endif struct plist_node node; int pm_qos_class; struct delayed_work work; /* for pm_qos_update_request_timeout */ @@ -62,7 +79,7 @@ enum dev_pm_qos_req_type { struct dev_pm_qos_request { enum dev_pm_qos_req_type type; union { - struct plist_node pnode; + struct pm_qos_request lat; struct pm_qos_flags_request flr; } data; struct device *dev; @@ -83,6 +100,7 @@ enum pm_qos_type { struct pm_qos_constraints { struct plist_head list; s32 target_value; /* Do not change to 64 bit */ + s32 target_per_cpu[NR_CPUS]; s32 default_value; s32 no_constraint_value; enum pm_qos_type type; @@ -115,8 +133,9 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req) return req->dev != NULL; } -int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, - enum pm_qos_req_action action, int value); +int pm_qos_update_target(struct pm_qos_constraints *c, + struct pm_qos_request *req, + enum pm_qos_req_action action, int value); bool pm_qos_update_flags(struct pm_qos_flags *pqf, struct pm_qos_flags_request *req, enum pm_qos_req_action action, s32 val); @@ -129,6 +148,8 @@ void pm_qos_update_request_timeout(struct pm_qos_request *req, void pm_qos_remove_request(struct pm_qos_request *req); int pm_qos_request(int pm_qos_class); +int pm_qos_request_for_cpu(int pm_qos_class, int cpu); +int pm_qos_request_for_cpumask(int pm_qos_class, struct cpumask *mask); int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); int pm_qos_request_active(struct pm_qos_request *req); @@ -166,7 +187,7 @@ void dev_pm_qos_hide_latency_tolerance(struct device *dev); static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev) { - return dev->power.qos->resume_latency_req->data.pnode.prio; + return dev->power.qos->resume_latency_req->data.lat.node.prio; } static inline s32 dev_pm_qos_requested_flags(struct device *dev) diff --git a/include/linux/pmic-voter.h b/include/linux/pmic-voter.h new file mode 100644 index 000000000000..f202bf704055 --- /dev/null +++ b/include/linux/pmic-voter.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2015-2016 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 __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); +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 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 */ diff --git a/include/linux/poison.h b/include/linux/poison.h index 317e16de09e5..199ffec4bdf3 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -30,7 +30,11 @@ #define TIMER_ENTRY_STATIC ((void *) 0x74737461) /********** mm/debug-pagealloc.c **********/ +#ifdef CONFIG_PAGE_POISONING_ZERO +#define PAGE_POISON 0x00 +#else #define PAGE_POISON 0xaa +#endif /********** mm/slab.c **********/ /* diff --git a/include/linux/power/qcom/apm.h b/include/linux/power/qcom/apm.h new file mode 100644 index 000000000000..8ac88630257a --- /dev/null +++ b/include/linux/power/qcom/apm.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 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 __LINUX_POWER_QCOM_APM_H__ +#define __LINUX_POWER_QCOM_APM_H__ + +#include <linux/device.h> +#include <linux/err.h> + +/** + * enum msm_apm_supply - supported power rails to supply memory arrays + * %MSM_APM_SUPPLY_APCC: to enable selection of VDD_APCC rail as supply + * %MSM_APM_SUPPLY_MX: to enable selection of VDD_MX rail as supply + */ +enum msm_apm_supply { + MSM_APM_SUPPLY_APCC, + MSM_APM_SUPPLY_MX, +}; + +/* Handle used to identify an APM controller device */ +struct msm_apm_ctrl_dev; + +#ifdef CONFIG_MSM_APM +struct msm_apm_ctrl_dev *msm_apm_ctrl_dev_get(struct device *dev); +int msm_apm_set_supply(struct msm_apm_ctrl_dev *ctrl_dev, + enum msm_apm_supply supply); +int msm_apm_get_supply(struct msm_apm_ctrl_dev *ctrl_dev); + +#else +static inline struct msm_apm_ctrl_dev *msm_apm_ctrl_dev_get(struct device *dev) +{ return ERR_PTR(-EPERM); } +static inline int msm_apm_set_supply(struct msm_apm_ctrl_dev *ctrl_dev, + enum msm_apm_supply supply) +{ return -EPERM; } +static inline int msm_apm_get_supply(struct msm_apm_ctrl_dev *ctrl_dev) +{ return -EPERM; } +#endif +#endif diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 1c075892c6fd..2ebd54c98e61 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -46,6 +46,7 @@ enum { POWER_SUPPLY_CHARGE_TYPE_NONE, POWER_SUPPLY_CHARGE_TYPE_TRICKLE, POWER_SUPPLY_CHARGE_TYPE_FAST, + POWER_SUPPLY_CHARGE_TYPE_TAPER, }; enum { @@ -58,6 +59,9 @@ enum { POWER_SUPPLY_HEALTH_COLD, POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE, POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE, + POWER_SUPPLY_HEALTH_WARM, + POWER_SUPPLY_HEALTH_COOL, + POWER_SUPPLY_HEALTH_HOT, }; enum { @@ -85,6 +89,37 @@ enum { POWER_SUPPLY_SCOPE_DEVICE, }; +enum { + POWER_SUPPLY_DP_DM_UNKNOWN = 0, + POWER_SUPPLY_DP_DM_PREPARE = 1, + POWER_SUPPLY_DP_DM_UNPREPARE = 2, + POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3 = 3, + POWER_SUPPLY_DP_DM_DP_PULSE = 4, + POWER_SUPPLY_DP_DM_DM_PULSE = 5, + POWER_SUPPLY_DP_DM_DP0P6_DMF = 6, + POWER_SUPPLY_DP_DM_DP0P6_DM3P3 = 7, + POWER_SUPPLY_DP_DM_DPF_DMF = 8, + POWER_SUPPLY_DP_DM_DPR_DMR = 9, + POWER_SUPPLY_DP_DM_HVDCP3_SUPPORTED = 10, + POWER_SUPPLY_DP_DM_ICL_DOWN = 11, + POWER_SUPPLY_DP_DM_ICL_UP = 12, + POWER_SUPPLY_DP_DM_FORCE_5V = 13, + POWER_SUPPLY_DP_DM_FORCE_9V = 14, + POWER_SUPPLY_DP_DM_FORCE_12V = 15, +}; + +enum { + POWER_SUPPLY_PL_NONE, + POWER_SUPPLY_PL_USBIN_USBIN, + POWER_SUPPLY_PL_USBIN_USBIN_EXT, + POWER_SUPPLY_PL_USBMID_USBMID, +}; + +enum { + POWER_SUPPLY_PL_STACKED_BATFET, + POWER_SUPPLY_PL_NON_STACKED_BATFET, +}; + enum power_supply_property { /* Properties of type `int' */ POWER_SUPPLY_PROP_STATUS = 0, @@ -114,6 +149,8 @@ enum power_supply_property { POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_EMPTY, POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CHARGE_NOW_RAW, + POWER_SUPPLY_PROP_CHARGE_NOW_ERROR, POWER_SUPPLY_PROP_CHARGE_AVG, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, @@ -133,6 +170,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */ POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_CAPACITY_RAW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TEMP_MAX, POWER_SUPPLY_PROP_TEMP_MIN, @@ -152,13 +190,98 @@ enum power_supply_property { /* Local extensions */ POWER_SUPPLY_PROP_USB_HC, POWER_SUPPLY_PROP_USB_OTG, - POWER_SUPPLY_PROP_CHARGE_ENABLED, + POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, + POWER_SUPPLY_PROP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED, + POWER_SUPPLY_PROP_STEP_CHARGING_STEP, + POWER_SUPPLY_PROP_PIN_ENABLED, + POWER_SUPPLY_PROP_INPUT_SUSPEND, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_REGULATION, + POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, + POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM, + POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, + POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, + POWER_SUPPLY_PROP_VCHG_LOOP_DBC_BYPASS, + POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW, + POWER_SUPPLY_PROP_HI_POWER, + POWER_SUPPLY_PROP_LOW_POWER, + POWER_SUPPLY_PROP_COOL_TEMP, + POWER_SUPPLY_PROP_WARM_TEMP, + POWER_SUPPLY_PROP_COLD_TEMP, + POWER_SUPPLY_PROP_HOT_TEMP, + POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL, + POWER_SUPPLY_PROP_RESISTANCE, + POWER_SUPPLY_PROP_RESISTANCE_CAPACITIVE, + POWER_SUPPLY_PROP_RESISTANCE_ID, /* in Ohms */ + POWER_SUPPLY_PROP_RESISTANCE_NOW, + POWER_SUPPLY_PROP_FLASH_CURRENT_MAX, + POWER_SUPPLY_PROP_UPDATE_NOW, + POWER_SUPPLY_PROP_ESR_COUNT, + POWER_SUPPLY_PROP_BUCK_FREQ, + POWER_SUPPLY_PROP_BOOST_CURRENT, + POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE, + POWER_SUPPLY_PROP_CHARGE_DONE, + POWER_SUPPLY_PROP_FLASH_ACTIVE, + POWER_SUPPLY_PROP_FLASH_TRIGGER, + POWER_SUPPLY_PROP_FORCE_TLIM, + POWER_SUPPLY_PROP_DP_DM, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED, + POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_QNOVO_ENABLE, + POWER_SUPPLY_PROP_CURRENT_QNOVO, + POWER_SUPPLY_PROP_VOLTAGE_QNOVO, + POWER_SUPPLY_PROP_RERUN_AICL, + POWER_SUPPLY_PROP_CYCLE_COUNT_ID, + POWER_SUPPLY_PROP_SAFETY_TIMER_EXPIRED, + POWER_SUPPLY_PROP_RESTRICTED_CHARGING, + POWER_SUPPLY_PROP_CURRENT_CAPABILITY, + POWER_SUPPLY_PROP_TYPEC_MODE, + POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, /* 0: N/C, 1: CC1, 2: CC2 */ + POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, + POWER_SUPPLY_PROP_PD_ALLOWED, + POWER_SUPPLY_PROP_PD_ACTIVE, + POWER_SUPPLY_PROP_PD_IN_HARD_RESET, + POWER_SUPPLY_PROP_PD_CURRENT_MAX, + POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, + POWER_SUPPLY_PROP_CHARGER_TEMP, + POWER_SUPPLY_PROP_CHARGER_TEMP_MAX, + POWER_SUPPLY_PROP_PARALLEL_DISABLE, + POWER_SUPPLY_PROP_PE_START, + POWER_SUPPLY_PROP_SET_SHIP_MODE, + POWER_SUPPLY_PROP_SOC_REPORTING_READY, + POWER_SUPPLY_PROP_DEBUG_BATTERY, + POWER_SUPPLY_PROP_FCC_DELTA, + POWER_SUPPLY_PROP_ICL_REDUCTION, + POWER_SUPPLY_PROP_PARALLEL_MODE, + POWER_SUPPLY_PROP_DIE_HEALTH, + POWER_SUPPLY_PROP_CONNECTOR_HEALTH, + POWER_SUPPLY_PROP_CTM_CURRENT_MAX, + POWER_SUPPLY_PROP_HW_CURRENT_MAX, + POWER_SUPPLY_PROP_REAL_TYPE, + POWER_SUPPLY_PROP_PR_SWAP, + POWER_SUPPLY_PROP_CC_STEP, + POWER_SUPPLY_PROP_CC_STEP_SEL, + POWER_SUPPLY_PROP_SW_JEITA_ENABLED, + POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, + POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, + POWER_SUPPLY_PROP_SDP_CURRENT_MAX, + POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE, + POWER_SUPPLY_PROP_IGNORE_FALSE_NEGATIVE_ISENSE, + POWER_SUPPLY_PROP_BATTERY_INFO, + POWER_SUPPLY_PROP_BATTERY_INFO_ID, + POWER_SUPPLY_PROP_ENABLE_JEITA_DETECTION, + POWER_SUPPLY_PROP_ALLOW_HVDCP3, + POWER_SUPPLY_PROP_MAX_PULSE_ALLOWED, + POWER_SUPPLY_PROP_PARALLEL_BATFET_MODE, + POWER_SUPPLY_PROP_PARALLEL_FCC_MAX, + POWER_SUPPLY_PROP_MIN_ICL, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_SERIAL_NUMBER, + POWER_SUPPLY_PROP_BATTERY_TYPE, }; enum power_supply_type { @@ -170,12 +293,55 @@ enum power_supply_type { POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */ + POWER_SUPPLY_TYPE_USB_HVDCP, /* High Voltage DCP */ + POWER_SUPPLY_TYPE_USB_HVDCP_3, /* Efficient High Voltage DCP */ + POWER_SUPPLY_TYPE_USB_PD, /* Power Delivery */ + POWER_SUPPLY_TYPE_WIRELESS, /* Accessory Charger Adapters */ + POWER_SUPPLY_TYPE_USB_FLOAT, /* Floating charger */ + POWER_SUPPLY_TYPE_BMS, /* Battery Monitor System */ + POWER_SUPPLY_TYPE_PARALLEL, /* Parallel Path */ + POWER_SUPPLY_TYPE_MAIN, /* Main Path */ + POWER_SUPPLY_TYPE_WIPOWER, /* Wipower */ + POWER_SUPPLY_TYPE_TYPEC, /* Type-C */ + POWER_SUPPLY_TYPE_UFP, /* Type-C UFP */ + POWER_SUPPLY_TYPE_DFP, /* TYpe-C DFP */ +}; + +/* Indicates USB Type-C CC connection status */ +enum power_supply_typec_mode { + POWER_SUPPLY_TYPEC_NONE, + + /* Acting as source */ + POWER_SUPPLY_TYPEC_SINK, /* Rd only */ + POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE, /* Rd/Ra */ + POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY, /* Rd/Rd */ + POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER, /* Ra/Ra */ + POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY, /* Ra only */ + + /* Acting as sink */ + POWER_SUPPLY_TYPEC_SOURCE_DEFAULT, /* Rp default */ + POWER_SUPPLY_TYPEC_SOURCE_MEDIUM, /* Rp 1.5A */ + POWER_SUPPLY_TYPEC_SOURCE_HIGH, /* Rp 3A */ + POWER_SUPPLY_TYPEC_NON_COMPLIANT, +}; + +enum power_supply_typec_power_role { + POWER_SUPPLY_TYPEC_PR_NONE, /* CC lines in high-Z */ + POWER_SUPPLY_TYPEC_PR_DUAL, + POWER_SUPPLY_TYPEC_PR_SINK, + POWER_SUPPLY_TYPEC_PR_SOURCE, }; enum power_supply_notifier_events { PSY_EVENT_PROP_CHANGED, }; +enum vmbms_power_usecase { + VMBMS_IGNORE_ALL_BIT = 1, + VMBMS_VOICE_CALL_BIT = (1 << 4), + VMBMS_STATIC_DISPLAY_BIT = (1 << 5), +}; + union power_supply_propval { int intval; const char *strval; @@ -369,6 +535,9 @@ static inline bool power_supply_is_amp_property(enum power_supply_property psp) case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_CURRENT_AVG: case POWER_SUPPLY_PROP_CURRENT_BOOT: + case POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW: + case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: + case POWER_SUPPLY_PROP_FLASH_CURRENT_MAX: return 1; default: break; diff --git a/include/linux/psci.h b/include/linux/psci.h index f78438214a59..4a24c1d0ff6d 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h @@ -24,6 +24,9 @@ bool psci_tos_resident_on(int cpu); bool psci_power_state_loses_context(u32 state); bool psci_power_state_is_valid(u32 state); +int psci_cpu_init_idle(unsigned int cpu); +int psci_cpu_suspend_enter(unsigned long index); + enum psci_conduit { PSCI_CONDUIT_NONE, PSCI_CONDUIT_SMC, @@ -36,6 +39,7 @@ enum smccc_version { }; struct psci_operations { + u32 (*get_version)(void); int (*cpu_suspend)(u32 state, unsigned long entry_point); int (*cpu_off)(u32 state); int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); diff --git a/include/linux/qcn_sdio_al.h b/include/linux/qcn_sdio_al.h new file mode 100644 index 000000000000..bee020b0ccb4 --- /dev/null +++ b/include/linux/qcn_sdio_al.h @@ -0,0 +1,296 @@ +/* Copyright (c) 2019 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 _QCN_SDIO_AL_ +#define _QCN_SDIO_AL_ + + +/** + * ------------------------------------ + * ------- SDIO AL Interface ---------- + * ------------------------------------ + * + * This file contains the proposed SDIO AL (Abstraction Layer) interface. + * Terminologies: + * SDIO AL : SDIO host function-1 driver + * SDIO AL client: Clients of SDIO host function-1 driver. + * WLAN, QMI, DIAG etc. are possible clients. + * Remote SDIO client: SDIO client on device side which implements ADMA + * functionality as function-1 + */ + +enum sdio_al_dma_direction { + SDIO_AL_TX, + SDIO_AL_RX, +}; + +/** + * struct sdio_al_client_handle - unique handler to identify + * each SDIO AL (Abstraction Layer) client + * + * @id: unique id for each client + * @block_size: block size + * @func: pointer to sdio_func data structure, some clients may need this. + * @client_priv: This is client priv that can used by client driver. + */ +struct sdio_al_client_handle { + int id; + struct sdio_al_client_data *client_data; + unsigned int block_size; + struct sdio_func *func; + void *client_priv; +}; + +/** + * struct sdio_al_xfer_result - Completed buffer information + * + * @buf_addr: Address of data buffer + * + * @xfer_len: Transfer data length in bytes + * + * @xfer_status: status of transfer, 0 if successful, + * negative in case of error + */ +struct sdio_al_xfer_result { + void *buf_addr; + size_t xfer_len; + int xfer_status; +}; + +enum sdio_al_lpm_event { + LPM_ENTER, /* SDIO client will be put to LPM mode soon */ + LPM_EXIT, /* SDIO client has exited LPM mode */ +}; + +/** + * sdio_al_client_data - client data of sdio_al + * + * @name: client name, could be one of the following: + * "SDIO_AL_CLIENT_WLAN", + * "SDIO_AL_CLIENT_QMI", + * "SDIO_AL_CLIENT_DIAG", + * "SDIO_AL_CLIENT_TTY" + * + * @probe: This probe function is called by SDIO AL driver when it is ready for + * SDIO traffic. SDIO AL client must wait for this callback before + * initiating any transfer over SDIO transport layer. + * + * @remove: This remove function is called by SDIO AL driver when it isn't ready + * for SDIO traffic. SDIO AL client must stop issuing any transfers + * after getting this callback, ongoing transfers would be errored out + * by SDIO AL. + * + * @lpm_notify_cb: callback to notify SDIO AL clients about Low Power modes. + * + */ +struct sdio_al_client_data { + const char *name; + + int id; + + int mode; + + int (*probe)(struct sdio_al_client_handle *); + + int (*remove)(struct sdio_al_client_handle *); + + void (*lpm_notify_cb)(struct sdio_al_client_handle *, + enum sdio_al_lpm_event event); +}; + +/** + * sdio_al_channel_handle - channel handle of sdio_al + * + * @id: Channel id unique at the AL layer + * + * @client_data: Client to which this channel belongs + * + */ +struct sdio_al_channel_handle { + unsigned int channel_id; + + struct sdio_al_channel_data *channel_data; + void *priv; +}; + +/** + * sdio_al_channel_data - channel data of sdio_al + * + * @name: channel name, could be one of the following: + * "SDIO_AL_WLAN_CH0", + * "SDIO_AL_WLAN_CH1", + * "SDIO_AL_QMI_CH0", + * "SDIO_AL_DIAG_CH0", + * "SDIO_AL_TTY_CH0" + * + * @client_data: The client driver by which this channel is being claimed + * + * @ul_xfer_cb: UL/TX data transfer callback. + * SDIO AL client can queue request using sdio_al_queue_transfer() + * asynchronous API, once request is transported over SDIO + * transport, SDIO AL calls "ul_xfer_cb" to notify the transfer + complete. + * + * @dl_xfer_cb: DL/RX data transfer callback + * Once SDIO AL receives requested data from remote SDIO client + * then SDIO AL invokes "dl_xfer_cb" callback to notify the SDIO + * AL client. + * + * @dl_data_avail_cb: callback to notify SDIO AL client that it can read + * specified bytes of data from remote SDIO client, SDIO AL client + * is then expected call sdio_al_queue_transfer() to read the data. + * This is optional and if client doesn't provide this callback + * then SDIO AL would allocate the buffer and SDIO AL + * client would have to memcpy the buffer in dl_xfer_cb(). + * + */ +struct sdio_al_channel_data { + const char *name; + + struct sdio_al_client_data *client_data; + + void (*ul_xfer_cb)(struct sdio_al_channel_handle *, + struct sdio_al_xfer_result *, void *ctxt); + + void (*dl_xfer_cb)(struct sdio_al_channel_handle *, + struct sdio_al_xfer_result *, void *ctxt); + + void (*dl_data_avail_cb)(struct sdio_al_channel_handle *, + unsigned int len); + + void (*dl_meta_data_cb)(struct sdio_al_channel_handle *, + unsigned int data); +}; + +/** + * sdio_al_is_ready - API Check to know whether the al driver is ready + * This API can be used to deffer the probe incase of early execution. + * + * @return zero on success and negative value on error. + * + */ +int sdio_al_is_ready(void); + +/** + * sdio_al_register_client - register as client of sdio AL (function-1 driver) + * SDIO AL driver would allocate the unique instance of + * "struct sdio_al_client_handle" and returns to client. + * + * @client_data: pointer to SDIO AL client data (struct sdio_al_client_data) + * + * @return valid sdio_al_client_handler ptr on success, negative value on error. + * + */ +struct sdio_al_client_handle *sdio_al_register_client( + struct sdio_al_client_data *client_data); + +/** + * sdio_al_deregister_client - deregisters client from SDIO AL + * (function-1 driver) + * + * @handle: sdio_al client handler + * + */ +void sdio_al_deregister_client(struct sdio_al_client_handle *handle); + +/** + * sdio_al_register_channel - register a channel for a client of SDIO AL + * SDIO AL driver would allocate a unique instance of the "struct + * sdio_al_channel_handle" and returns to the client. + * + * @client_handle: The client to which the channel shall belong + * + * @channel_data: The channel data which contains the details of the channel + * + * @return valid channel handle in success error on success, error pointer on + * failure + */ +struct sdio_al_channel_handle *sdio_al_register_channel( + struct sdio_al_client_handle *client_handle, + struct sdio_al_channel_data *client_data); + +/** + * sdio_al_deregister_channel - deregister a channel for a client of SDIO AL + * + * @ch_handle: The channel handle which needs to deregistered + * + * @return none + */ +void sdio_al_deregister_channel(struct sdio_al_channel_handle *ch_handle); + + +/** + * sdio_al_queue_transfer_async - Queue asynchronous data transfer request + * All transfers are asynchronous transfers, SDIO AL will call + * ul_xfer_cb or dl_xfer_cb callback to nofity completion to SDIO AL client. + * + * @ch_handle: sdio_al channel handle + * + * @dir: Data direction (DMA_TO_DEVICE for TX, DMA_FROM_DEVICE for RX) + * + * @buf: Data buffer + * + * @len: Size in bytes + * + * @priority: set any non-zero value for higher priority, 0 for normal priority + * All SDIO AL clients except WLAN client is expected to use normal + * priority. + * + * @return 0 on success, non-zero in case of error + */ +int sdio_al_queue_transfer_async(struct sdio_al_channel_handle *handle, + enum sdio_al_dma_direction dir, + void *buf, size_t len, int priority, void *ctxt); + +/** + * sdio_al_queue_transfer - Queue synchronous data transfer request + * In constrast to asynchronous transfer API sdio_al_queue_transfer(), this + * API will completely the request synchronously. If there is no outstanding + * request at SDIO AL Layer, request will be immediately initiated on SDIO bus. + * + * @ch_handle: sdio_al channel handle + * + * @dir: Data direction (DMA_TO_DEVICE for TX, DMA_FROM_DEVICE for RX) + * + * @buf: Data buffer + * + * @len: Size in bytes + * + * @priority: set any non-zero value for higher priority, 0 for normal priority + * All SDIO AL clients except WLAN client is expected to use normal + * priority. + * + * @return 0 on success, non-zero in case of error + */ +int sdio_al_queue_transfer(struct sdio_al_channel_handle *ch_handle, + enum sdio_al_dma_direction dir, + void *buf, size_t len, int priority); + + +/** + * sdio_al_meta_transfer - Queue synchronous data transfer request + * In constrast to asynchronous transfer API sdio_al_queue_transfer(), this + * API will completely the request synchronously. If there is no outstanding + * request at SDIO AL Layer, request will be immediately initiated on SDIO bus. + * + * @ch_handle: sdio_al channel handle + * + * @data: Meta data to be transferred + * + * @return 0 on success, non-zero in case of error + */ +int sdio_al_meta_transfer(struct sdio_al_channel_handle *ch_handle, + unsigned int data, unsigned int trans); + +extern void qcn_sdio_client_probe_complete(int id); +int qcn_sdio_card_state(bool enable); +#endif /* _QCN_SDIO_AL_ */ diff --git a/include/linux/qcom/diag_dload.h b/include/linux/qcom/diag_dload.h new file mode 100644 index 000000000000..83c7f2d45f2d --- /dev/null +++ b/include/linux/qcom/diag_dload.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2012, 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 __LINUX_DIAG_DLOAD_H__ +#define __LINUX_DIAG_DLOAD_H__ + + +#define PID_MAGIC_ID 0x71432909 +#define SERIAL_NUM_MAGIC_ID 0x61945374 +#define SERIAL_NUMBER_LENGTH 128 + +struct magic_num_struct { + uint32_t pid; + uint32_t serial_num; +}; + +struct dload_struct { + uint32_t pid; + char serial_number[SERIAL_NUMBER_LENGTH]; + struct magic_num_struct magic_struct; +}; + +#endif diff --git a/include/linux/qcom_iommu.h b/include/linux/qcom_iommu.h new file mode 100644 index 000000000000..4062b40d205b --- /dev/null +++ b/include/linux/qcom_iommu.h @@ -0,0 +1,429 @@ +/* Copyright (c) 2010-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 MSM_IOMMU_H +#define MSM_IOMMU_H + +#include <linux/interrupt.h> +#include <linux/clk.h> +#include <linux/list.h> +#include <linux/regulator/consumer.h> +#include <linux/platform_device.h> +#include <linux/idr.h> +#include <soc/qcom/socinfo.h> + +extern pgprot_t pgprot_kernel; +extern struct bus_type msm_iommu_sec_bus_type; +extern struct bus_type *msm_iommu_non_sec_bus_type; +extern struct iommu_access_ops iommu_access_ops_v0; +extern struct iommu_access_ops iommu_access_ops_v1; + +/* Domain attributes */ +#define MSM_IOMMU_DOMAIN_PT_CACHEABLE 0x1 +#define MSM_IOMMU_DOMAIN_PT_SECURE 0x2 + +/* Mask for the cache policy attribute */ +#define MSM_IOMMU_CP_MASK 0x03 + +/* Maximum number of Machine IDs that we are allowing to be mapped to the same + * context bank. The number of MIDs mapped to the same CB does not affect + * performance, but there is a practical limit on how many distinct MIDs may + * be present. These mappings are typically determined at design time and are + * not expected to change at run time. + */ +#define MAX_NUM_MIDS 32 + +/* Maximum number of SMT entries allowed by the system */ +#define MAX_NUM_SMR 128 + +#define MAX_NUM_BFB_REGS 32 + +/** + * struct msm_iommu_dev - a single IOMMU hardware instance + * name Human-readable name given to this IOMMU HW instance + * ncb Number of context banks present on this IOMMU HW instance + */ +struct msm_iommu_dev { + const char *name; + int ncb; + int ttbr_split; +}; + +/** + * struct msm_iommu_ctx_dev - an IOMMU context bank instance + * name Human-readable name given to this context bank + * num Index of this context bank within the hardware + * mids List of Machine IDs that are to be mapped into this context + * bank, terminated by -1. The MID is a set of signals on the + * AXI bus that identifies the function associated with a specific + * memory request. (See ARM spec). + */ +struct msm_iommu_ctx_dev { + const char *name; + int num; + int mids[MAX_NUM_MIDS]; +}; + +/** + * struct msm_iommu_bfb_settings - a set of IOMMU BFB tuning parameters + * regs An array of register offsets to configure + * data Values to write to corresponding registers + * length Number of valid entries in the offset/val arrays + */ +struct msm_iommu_bfb_settings { + unsigned int regs[MAX_NUM_BFB_REGS]; + unsigned int data[MAX_NUM_BFB_REGS]; + int length; +}; + +/** + * struct msm_iommu_drvdata - A single IOMMU hardware instance + * @base: IOMMU config port base address (VA) + * @glb_base: IOMMU config port base address for global register space (VA) + * @phys_base: IOMMU physical base address. + * @ncb The number of contexts on this IOMMU + * @irq: Interrupt number + * @clk: The bus clock for this IOMMU hardware instance + * @pclk: The clock for the IOMMU bus interconnect + * @aclk: Alternate core clock for this IOMMU core, if any + * @aiclk: Alternate interface clock for this IOMMU core, if any + * @name: Human-readable name of this IOMMU device + * @gdsc: Regulator needed to power this HW block (v2 only) + * @bfb_settings: Optional BFB performance tuning parameters + * @dev: Struct device this hardware instance is tied to + * @list: List head to link all iommus together + * @clk_reg_virt: Optional clock register virtual address. + * @halt_enabled: Set to 1 if IOMMU halt is supported in the IOMMU, 0 otherwise. + * @ctx_attach_count: Count of how many context are attached. + * @bus_client : Bus client needed to vote for bus bandwidth. + * @needs_rem_spinlock : 1 if remote spinlock is needed, 0 otherwise + * @powered_on: Powered status of the IOMMU. 0 means powered off. + * + * A msm_iommu_drvdata holds the global driver data about a single piece + * of an IOMMU hardware instance. + */ +struct msm_iommu_drvdata { + void __iomem *base; + phys_addr_t phys_base; + void __iomem *glb_base; + void __iomem *cb_base; + void __iomem *smmu_local_base; + void __iomem *vbif_base; + int ncb; + int ttbr_split; + struct clk *clk; + struct clk *pclk; + struct clk *aclk; + struct clk *aiclk; + const char *name; + struct regulator *gdsc; + struct regulator *alt_gdsc; + struct msm_iommu_bfb_settings *bfb_settings; + int sec_id; + struct device *dev; + struct list_head list; + void __iomem *clk_reg_virt; + int halt_enabled; + unsigned int ctx_attach_count; + unsigned int bus_client; + int needs_rem_spinlock; + int powered_on; + unsigned int model; + struct idr asid_idr; +}; + +/** + * struct iommu_access_ops - Callbacks for accessing IOMMU + * @iommu_power_on: Turn on power to unit + * @iommu_power_off: Turn off power to unit + * @iommu_bus_vote: Vote for bus bandwidth + * @iommu_clk_on: Turn on clks to unit + * @iommu_clk_off: Turn off clks to unit + * @iommu_lock_initialize: Initialize the remote lock + * @iommu_lock_acquire: Acquire any locks needed + * @iommu_lock_release: Release locks needed + */ +struct iommu_access_ops { + int (*iommu_power_on)(struct msm_iommu_drvdata *); + void (*iommu_power_off)(struct msm_iommu_drvdata *); + int (*iommu_bus_vote)(struct msm_iommu_drvdata *drvdata, + unsigned int vote); + int (*iommu_clk_on)(struct msm_iommu_drvdata *); + void (*iommu_clk_off)(struct msm_iommu_drvdata *); + void * (*iommu_lock_initialize)(void); + void (*iommu_lock_acquire)(unsigned int need_extra_lock); + void (*iommu_lock_release)(unsigned int need_extra_lock); +}; + +void msm_iommu_add_drv(struct msm_iommu_drvdata *drv); +void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv); +void program_iommu_bfb_settings(void __iomem *base, + const struct msm_iommu_bfb_settings *bfb_settings); +void iommu_halt(const struct msm_iommu_drvdata *iommu_drvdata); +void iommu_resume(const struct msm_iommu_drvdata *iommu_drvdata); + +/** + * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance + * @num: Hardware context number of this context + * @pdev: Platform device associated wit this HW instance + * @attached_elm: List element for domains to track which devices are + * attached to them + * @attached_domain Domain currently attached to this context (if any) + * @name Human-readable name of this context device + * @sids List of Stream IDs mapped to this context + * @nsid Number of Stream IDs mapped to this context + * @secure_context true if this is a secure context programmed by + the secure environment, false otherwise + * @asid ASID used with this context. + * @attach_count Number of time this context has been attached. + * @report_error_on_fault - true if error is returned back to master + * @dynamic true if any dynamic domain is ever attached to this CB + * + * A msm_iommu_ctx_drvdata holds the driver data for a single context bank + * within each IOMMU hardware instance + */ +struct msm_iommu_ctx_drvdata { + int num; + struct platform_device *pdev; + struct list_head attached_elm; + struct iommu_domain *attached_domain; + const char *name; + u32 sids[MAX_NUM_SMR]; + unsigned int nsid; + unsigned int secure_context; + int asid; + int attach_count; + u32 sid_mask[MAX_NUM_SMR]; + unsigned int n_sid_mask; + bool report_error_on_fault; + unsigned int prefetch_depth; + bool dynamic; +}; + +enum dump_reg { + DUMP_REG_FIRST, + DUMP_REG_FAR0 = DUMP_REG_FIRST, + DUMP_REG_FAR1, + DUMP_REG_PAR0, + DUMP_REG_PAR1, + DUMP_REG_FSR, + DUMP_REG_FSYNR0, + DUMP_REG_FSYNR1, + DUMP_REG_TTBR0_0, + DUMP_REG_TTBR0_1, + DUMP_REG_TTBR1_0, + DUMP_REG_TTBR1_1, + DUMP_REG_SCTLR, + DUMP_REG_ACTLR, + DUMP_REG_PRRR, + DUMP_REG_MAIR0 = DUMP_REG_PRRR, + DUMP_REG_NMRR, + DUMP_REG_MAIR1 = DUMP_REG_NMRR, + DUMP_REG_CBAR_N, + DUMP_REG_CBFRSYNRA_N, + MAX_DUMP_REGS, +}; + +enum dump_reg_type { + DRT_CTX_REG, + DRT_GLOBAL_REG, + DRT_GLOBAL_REG_N, +}; + +enum model_id { + QSMMUv1 = 1, + QSMMUv2, + MMU_500 = 500, + MAX_MODEL, +}; + +struct dump_regs_tbl_entry { + /* + * To keep things context-bank-agnostic, we only store the + * register offset in `reg_offset' + */ + unsigned int reg_offset; + const char *name; + int must_be_present; + enum dump_reg_type dump_reg_type; +}; +extern struct dump_regs_tbl_entry dump_regs_tbl[MAX_DUMP_REGS]; + +#define COMBINE_DUMP_REG(upper, lower) (((u64) upper << 32) | lower) + +struct msm_iommu_context_reg { + uint32_t val; + bool valid; +}; + +void print_ctx_regs(struct msm_iommu_context_reg regs[]); + +/* + * Interrupt handler for the IOMMU context fault interrupt. Hooking the + * interrupt is not supported in the API yet, but this will print an error + * message and dump useful IOMMU registers. + */ +irqreturn_t msm_iommu_global_fault_handler(int irq, void *dev_id); +irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id); +irqreturn_t msm_iommu_fault_handler_v2(int irq, void *dev_id); +irqreturn_t msm_iommu_secure_fault_handler_v2(int irq, void *dev_id); + +enum { + PROC_APPS, + PROC_GPU, + PROC_MAX +}; + +/* Expose structure to allow kgsl iommu driver to use the same structure to + * communicate to GPU the addresses of the flag and turn variables. + */ +struct remote_iommu_petersons_spinlock { + uint32_t flag[PROC_MAX]; + uint32_t turn; +}; + +#ifdef CONFIG_MSM_IOMMU +void *msm_iommu_lock_initialize(void); +void msm_iommu_mutex_lock(void); +void msm_iommu_mutex_unlock(void); +void msm_set_iommu_access_ops(struct iommu_access_ops *ops); +struct iommu_access_ops *msm_get_iommu_access_ops(void); +#else +static inline void *msm_iommu_lock_initialize(void) +{ + return NULL; +} +static inline void msm_iommu_mutex_lock(void) { } +static inline void msm_iommu_mutex_unlock(void) { } +static inline void msm_set_iommu_access_ops(struct iommu_access_ops *ops) +{ + +} +static inline struct iommu_access_ops *msm_get_iommu_access_ops(void) +{ + return NULL; +} +#endif + +#ifdef CONFIG_MSM_IOMMU_SYNC +void msm_iommu_remote_p0_spin_lock(unsigned int need_lock); +void msm_iommu_remote_p0_spin_unlock(unsigned int need_lock); + +#define msm_iommu_remote_lock_init() _msm_iommu_remote_spin_lock_init() +#define msm_iommu_remote_spin_lock(need_lock) \ + msm_iommu_remote_p0_spin_lock(need_lock) +#define msm_iommu_remote_spin_unlock(need_lock) \ + msm_iommu_remote_p0_spin_unlock(need_lock) +#else +#define msm_iommu_remote_lock_init() +#define msm_iommu_remote_spin_lock(need_lock) +#define msm_iommu_remote_spin_unlock(need_lock) +#endif + +#ifdef CONFIG_MSM_IOMMU +/* + * Look up an IOMMU context device by its context name. NULL if none found. + * Useful for testing and drivers that do not yet fully have IOMMU stuff in + * their platform devices. + */ +struct device *msm_iommu_get_ctx(const char *ctx_name); +struct bus_type *msm_iommu_get_bus(struct device *dev); +int msm_iommu_bus_register(void); +void msm_access_control(void); +#else +static inline struct device *msm_iommu_get_ctx(const char *ctx_name) +{ + return NULL; +} + +static inline struct bus_type *msm_iommu_get_bus(struct device *dev) +{ + return &platform_bus_type; +} + +static inline void msm_access_control(void) +{ +} +#endif + +/* + * Function to program the global registers of an IOMMU securely. + * This should only be called on IOMMUs for which kernel programming + * of global registers is not possible + */ +void msm_iommu_sec_set_access_ops(struct iommu_access_ops *access_ops); +int msm_iommu_sec_program_iommu(struct msm_iommu_drvdata *drvdata, + struct msm_iommu_ctx_drvdata *ctx_drvdata); +int is_vfe_secure(void); + +#ifdef CONFIG_MSM_IOMMU_V0 +static inline int msm_soc_version_supports_iommu_v0(void) +{ + static int soc_supports_v0 = -1; +#ifdef CONFIG_OF + struct device_node *node; +#endif + + if (soc_supports_v0 != -1) + return soc_supports_v0; + +#ifdef CONFIG_OF + node = of_find_compatible_node(NULL, NULL, "qcom,msm-smmu-v0"); + if (node) { + soc_supports_v0 = 1; + of_node_put(node); + return 1; + } +#endif + if (cpu_is_msm8960() && + SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 2) { + soc_supports_v0 = 0; + return 0; + } + + if (cpu_is_msm8x60() && + (SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 2 || + SOCINFO_VERSION_MINOR(socinfo_get_version()) < 1)) { + soc_supports_v0 = 0; + return 0; + } + + soc_supports_v0 = 1; + return 1; +} +#else +static inline int msm_soc_version_supports_iommu_v0(void) +{ + return 0; +} +#endif + +int msm_iommu_get_scm_call_avail(void); +void msm_iommu_check_scm_call_avail(void); + +u32 msm_iommu_get_mair0(void); +u32 msm_iommu_get_mair1(void); +u32 msm_iommu_get_prrr(void); +u32 msm_iommu_get_nmrr(void); + +/* events for notifiers passed to msm_iommu_register_notify */ +#define TLB_SYNC_TIMEOUT 1 + +#ifdef CONFIG_MSM_IOMMU_V1 +void msm_iommu_register_notify(struct notifier_block *nb); +#else +static inline void msm_iommu_register_notify(struct notifier_block *nb) +{ +} +#endif + +#endif diff --git a/include/linux/qcom_tspp.h b/include/linux/qcom_tspp.h new file mode 100644 index 000000000000..1b34c389d7f0 --- /dev/null +++ b/include/linux/qcom_tspp.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2012-2017, 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 _MSM_TSPP_H_ +#define _MSM_TSPP_H_ + +struct tspp_data_descriptor { + void *virt_base; /* logical address of the actual data */ + phys_addr_t phys_base; /* physical address of the actual data */ + u32 size; /* size of buffer in bytes */ + int id; /* unique identifier */ + void *user; /* user-defined data */ +}; + +enum tspp_key_parity { + TSPP_KEY_PARITY_EVEN, + TSPP_KEY_PARITY_ODD +}; + +struct tspp_key { + enum tspp_key_parity parity; + int lsb; + int msb; +}; + +enum tspp_source { + TSPP_SOURCE_TSIF0, + TSPP_SOURCE_TSIF1, + TSPP_SOURCE_MEM, + TSPP_SOURCE_NONE = -1 +}; + +enum tspp_mode { + TSPP_MODE_DISABLED, + TSPP_MODE_PES, + TSPP_MODE_RAW, + TSPP_MODE_RAW_NO_SUFFIX +}; + +enum tspp_tsif_mode { + TSPP_TSIF_MODE_LOOPBACK, /* loopback mode */ + TSPP_TSIF_MODE_1, /* without sync */ + TSPP_TSIF_MODE_2 /* with sync signal */ +}; + +struct tspp_filter { + int pid; + int mask; + enum tspp_mode mode; + unsigned int priority; /* 0 - 15 */ + int decrypt; + enum tspp_source source; +}; + +struct tspp_select_source { + enum tspp_source source; + enum tspp_tsif_mode mode; + int clk_inverse; + int data_inverse; + int sync_inverse; + int enable_inverse; +}; + +enum tsif_tts_source { + TSIF_TTS_TCR = 0, /* Time stamps from TCR counter */ + TSIF_TTS_LPASS_TIMER /* Time stamps from AV/Qtimer Timer */ +}; + +typedef void (tspp_notifier)(int channel_id, void *user); +typedef void* (tspp_allocator)(int channel_id, u32 size, + phys_addr_t *phys_base, void *user); +typedef void (tspp_memfree)(int channel_id, u32 size, + void *virt_base, phys_addr_t phys_base, void *user); + +/* Kernel API functions */ +int tspp_open_stream(u32 dev, u32 channel_id, + struct tspp_select_source *source); +int tspp_close_stream(u32 dev, u32 channel_id); +int tspp_open_channel(u32 dev, u32 channel_id); +int tspp_close_channel(u32 dev, u32 channel_id); +int tspp_get_ref_clk_counter(u32 dev, + enum tspp_source source, u32 *tcr_counter); +int tspp_add_filter(u32 dev, u32 channel_id, struct tspp_filter *filter); +int tspp_remove_filter(u32 dev, u32 channel_id, struct tspp_filter *filter); +int tspp_set_key(u32 dev, u32 channel_id, struct tspp_key *key); +int tspp_register_notification(u32 dev, u32 channel_id, tspp_notifier *notify, + void *data, u32 timer_ms); +int tspp_unregister_notification(u32 dev, u32 channel_id); +const struct tspp_data_descriptor *tspp_get_buffer(u32 dev, u32 channel_id); +int tspp_release_buffer(u32 dev, u32 channel_id, u32 descriptor_id); +int tspp_allocate_buffers(u32 dev, u32 channel_id, u32 count, + u32 size, u32 int_freq, tspp_allocator *alloc, + tspp_memfree *memfree, void *user); + +int tspp_get_tts_source(u32 dev, int *tts_source); +int tspp_get_lpass_time_counter(u32 dev, enum tspp_source source, + u64 *lpass_time_counter); + +#endif /* _MSM_TSPP_H_ */ diff --git a/include/linux/qcomwlan_secif.h b/include/linux/qcomwlan_secif.h new file mode 100644 index 000000000000..6334e3dc7b6b --- /dev/null +++ b/include/linux/qcomwlan_secif.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2011-2013, 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 __QCOM_WLAN_SECIF_H__ +#define __QCOM_WLAN_SECIF_H__ + +#include <crypto/hash.h> + +#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ + +/* + * Prototypes for WLAN Security Interface Functions + */ + +extern struct crypto_ahash * +wcnss_wlan_crypto_alloc_ahash(const char *alg_name, u32 type, u32 mask); + +extern int wcnss_wlan_crypto_ahash_digest(struct ahash_request *req); +extern void wcnss_wlan_crypto_free_ahash(struct crypto_ahash *tfm); +extern int wcnss_wlan_crypto_ahash_setkey(struct crypto_ahash *tfm, + const u8 *key, unsigned int keylen); +extern struct crypto_ablkcipher * +wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_ablkcipher_request_free(struct ablkcipher_request *req); +extern void wcnss_wlan_crypto_free_cipher(struct crypto_cipher *tfm); +extern void wcnss_wlan_crypto_free_ablkcipher(struct crypto_ablkcipher *tfm); +extern struct crypto_cipher * +wcnss_wlan_crypto_alloc_cipher(const char *alg_name, u32 type, u32 mask); +extern void wcnss_wlan_cmac_calc_mic(struct crypto_cipher *tfm, u8 *m, + u16 length, u8 *mac); + +#endif /* __QCOM_WLAN_SECIF_H__ */ diff --git a/include/linux/qcrypto.h b/include/linux/qcrypto.h new file mode 100644 index 000000000000..b2295ced6f1a --- /dev/null +++ b/include/linux/qcrypto.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2014-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 _DRIVERS_CRYPTO_MSM_QCRYPTO_H_ +#define _DRIVERS_CRYPTO_MSM_QCRYPTO_H_ + +#include <linux/crypto.h> +#include <crypto/hash.h> + +#define QCRYPTO_CTX_KEY_MASK 0x000000ff +#define QCRYPTO_CTX_USE_HW_KEY 0x00000001 +#define QCRYPTO_CTX_USE_PIPE_KEY 0x00000002 + +#define QCRYPTO_CTX_XTS_MASK 0x0000ff00 +#define QCRYPTO_CTX_XTS_DU_SIZE_512B 0x00000100 +#define QCRYPTO_CTX_XTS_DU_SIZE_1KB 0x00000200 + + +int qcrypto_cipher_set_device(struct ablkcipher_request *req, unsigned int dev); +int qcrypto_ahash_set_device(struct ahash_request *req, unsigned int dev); +/*int qcrypto_aead_set_device(struct aead_request *req, unsigned int dev);*/ + +int qcrypto_cipher_set_flag(struct ablkcipher_request *req, unsigned int flags); +int qcrypto_ahash_set_flag(struct ahash_request *req, unsigned int flags); +/*int qcrypto_aead_set_flag(struct aead_request *req, unsigned int flags);*/ + +int qcrypto_cipher_clear_flag(struct ablkcipher_request *req, + unsigned int flags); +int qcrypto_ahash_clear_flag(struct ahash_request *req, unsigned int flags); +/*int qcrypto_aead_clear_flag(struct aead_request *req, unsigned int flags);*/ + +struct crypto_engine_entry { + u32 hw_instance; + u32 ce_device; + int shared; +}; + +int qcrypto_get_num_engines(void); +void qcrypto_get_engine_list(size_t num_engines, + struct crypto_engine_entry *arr); +int qcrypto_cipher_set_device_hw(struct ablkcipher_request *req, + unsigned int fde_pfe, + unsigned int hw_inst); + + +struct qcrypto_func_set { + int (*cipher_set)(struct ablkcipher_request *req, + unsigned int fde_pfe, + unsigned hw_inst); + int (*cipher_flag)(struct ablkcipher_request *req, unsigned int flags); + int (*get_num_engines)(void); + void (*get_engine_list)(size_t num_engines, + struct crypto_engine_entry *arr); +}; + +#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTO_H */ diff --git a/include/linux/qdsp6v2/apr.h b/include/linux/qdsp6v2/apr.h new file mode 100644 index 000000000000..d80320e74661 --- /dev/null +++ b/include/linux/qdsp6v2/apr.h @@ -0,0 +1,215 @@ +/* Copyright (c) 2010-2017, 2019, 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 __APR_H_ +#define __APR_H_ + +#include <linux/mutex.h> +#include <soc/qcom/subsystem_notif.h> + +enum apr_subsys_state { + APR_SUBSYS_DOWN, + APR_SUBSYS_UP, + APR_SUBSYS_LOADED, +}; + +struct apr_q6 { + void *pil; + atomic_t q6_state; + atomic_t modem_state; + struct mutex lock; +}; + +struct apr_hdr { + uint16_t hdr_field; + uint16_t pkt_size; + uint8_t src_svc; + uint8_t src_domain; + uint16_t src_port; + uint8_t dest_svc; + uint8_t dest_domain; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; +}; + +#define APR_HDR_LEN(hdr_len) ((hdr_len)/4) +#define APR_PKT_SIZE(hdr_len, payload_len) ((hdr_len) + (payload_len)) +#define APR_HDR_FIELD(msg_type, hdr_len, ver)\ + (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF)) + +#define APR_HDR_SIZE sizeof(struct apr_hdr) + +/* Version */ +#define APR_PKT_VER 0x0 + +/* Command and Response Types */ +#define APR_MSG_TYPE_EVENT 0x0 +#define APR_MSG_TYPE_CMD_RSP 0x1 +#define APR_MSG_TYPE_SEQ_CMD 0x2 +#define APR_MSG_TYPE_NSEQ_CMD 0x3 +#define APR_MSG_TYPE_MAX 0x04 + +/* APR Basic Response Message */ +#define APR_BASIC_RSP_RESULT 0x000110E8 +#define APR_RSP_ACCEPTED 0x000100BE + +/* Domain IDs */ +#define APR_DOMAIN_SIM 0x1 +#define APR_DOMAIN_PC 0x2 +#define APR_DOMAIN_MODEM 0x3 +#define APR_DOMAIN_ADSP 0x4 +#define APR_DOMAIN_APPS 0x5 +#define APR_DOMAIN_SDSP 0x8 +#define APR_DOMAIN_MAX 0x9 + + +/* ADSP service IDs */ +#define APR_SVC_TEST_CLIENT 0x2 +#define APR_SVC_ADSP_CORE 0x3 +#define APR_SVC_AFE 0x4 +#define APR_SVC_VSM 0x5 +#define APR_SVC_VPM 0x6 +#define APR_SVC_ASM 0x7 +#define APR_SVC_ADM 0x8 +#define APR_SVC_ADSP_MVM 0x09 +#define APR_SVC_ADSP_CVS 0x0A +#define APR_SVC_ADSP_CVP 0x0B +#define APR_SVC_USM 0x0C +#define APR_SVC_LSM 0x0D +#define APR_SVC_VIDC 0x16 +#define APR_SVC_MAX 0x17 + +/* Modem Service IDs */ +#define APR_SVC_MVS 0x3 +#define APR_SVC_MVM 0x4 +#define APR_SVC_CVS 0x5 +#define APR_SVC_CVP 0x6 +#define APR_SVC_SRD 0x7 + +/* Sensor DSP Micro Audio Service IDs */ +#define APR_SVC_MAS 0x3 + +/* APR Port IDs */ +#define APR_MAX_PORTS 0x80 + +#define APR_NAME_MAX 0x40 + +#define RESET_EVENTS 0x000130D7 + +#define LPASS_RESTART_EVENT 0x1000 +#define LPASS_RESTART_READY 0x1001 + +struct apr_client_data { + uint16_t reset_event; + uint16_t reset_proc; + uint16_t payload_size; + uint16_t hdr_len; + uint16_t msg_type; + uint16_t src; + uint16_t dest_svc; + uint16_t src_port; + uint16_t dest_port; + uint32_t token; + uint32_t opcode; + void *payload; +}; + +typedef int32_t (*apr_fn)(struct apr_client_data *data, void *priv); + +struct apr_svc { + uint16_t id; + uint16_t dest_id; + uint16_t client_id; + uint16_t dest_domain; + uint8_t rvd; + uint8_t port_cnt; + uint8_t svc_cnt; + uint8_t need_reset; + apr_fn port_fn[APR_MAX_PORTS]; + void *port_priv[APR_MAX_PORTS]; + apr_fn fn; + void *priv; + struct mutex m_lock; + spinlock_t w_lock; + uint8_t pkt_owner; +#ifdef CONFIG_MSM_QDSP6_APRV2_VM + uint16_t vm_dest_svc; + uint32_t vm_handle; +#endif +}; + +struct apr_client { + uint8_t id; + uint8_t svc_cnt; + uint8_t rvd; + struct mutex m_lock; + struct apr_svc_ch_dev *handle; + struct apr_svc svc[APR_SVC_MAX]; +}; + +struct apr_rx_intents { + int num_of_intents; + uint32_t size; +}; + +struct apr_pkt_cfg { + uint8_t pkt_owner; + struct apr_rx_intents intents; +}; + +int apr_load_adsp_image(void); +struct apr_client *apr_get_client(int dest_id, int client_id); +int apr_wait_for_device_up(int dest_id); +int apr_get_svc(const char *svc_name, int dest_id, int *client_id, + int *svc_idx, int *svc_id); +void apr_cb_func(void *buf, int len, void *priv); +struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn, + uint32_t src_port, void *priv); +inline int apr_fill_hdr(void *handle, uint32_t *buf, uint16_t src_port, + uint16_t msg_type, uint16_t dest_port, + uint32_t token, uint32_t opcode, uint16_t len); + +int apr_send_pkt(void *handle, uint32_t *buf); +int apr_deregister(void *handle); +void subsys_notif_register(char *client_name, int domain, + struct notifier_block *nb); +int apr_get_dest_id(char *dest); +uint16_t apr_get_data_src(struct apr_hdr *hdr); +void change_q6_state(int state); +void q6audio_dsp_not_responding(void); +void apr_reset(void *handle); +enum apr_subsys_state apr_get_subsys_state(void); +enum apr_subsys_state apr_get_modem_state(void); +void apr_set_modem_state(enum apr_subsys_state state); +enum apr_subsys_state apr_get_q6_state(void); +int apr_set_q6_state(enum apr_subsys_state state); +void apr_set_subsys_state(void); +const char *apr_get_lpass_subsys_name(void); +uint16_t apr_get_reset_domain(uint16_t proc); +#ifdef CONFIG_MSM_QDSP6_APRV2_VM +static inline int apr_start_rx_rt(void *handle) +{ + return 0; +} + +static inline int apr_end_rx_rt(void *handle) +{ + return 0; +} +#else +int apr_start_rx_rt(void *handle); +int apr_end_rx_rt(void *handle); +#endif +int apr_dummy_init(void); +void apr_dummy_exit(void); +#endif diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h new file mode 100644 index 000000000000..6100fe0b229c --- /dev/null +++ b/include/linux/qdsp6v2/apr_tal.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2010-2011, 2016-2017, 2019 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 __APR_TAL_H_ +#define __APR_TAL_H_ + +#include <linux/kernel.h> +#include <linux/kthread.h> +#include <linux/uaccess.h> + +/* APR Client IDs */ +#define APR_CLIENT_AUDIO 0x0 +#define APR_CLIENT_VOICE 0x1 +#define APR_CLIENT_MAX 0x2 + +#define APR_DL_SMD 0 +#define APR_DL_MAX 1 + +#define APR_DEST_MODEM 0 +#define APR_DEST_QDSP6 1 +#define APR_DEST_DSPS 3 +#define APR_DEST_MAX 4 + +#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \ + defined(CONFIG_MSM_QDSP6_APRV3_GLINK) +#define APR_MAX_BUF 512 +#else +#define APR_MAX_BUF 8092 +#endif + +#define APR_DEFAULT_NUM_OF_INTENTS 20 + +#define APR_OPEN_TIMEOUT_MS 5000 + +enum { + /* If client sets the pkt_owner to APR_PKT_OWNER_DRIVER, APR + * driver will allocate a buffer, where the user packet is + * copied into, for each and every single Tx transmission. + * The buffer is thereafter passed to underlying link layer + * and freed upon the notification received from the link layer + * that the packet has been consumed. + */ + APR_PKT_OWNER_DRIVER, + /* If client sets the pkt_owner to APR_PKT_OWNER_CLIENT, APR + * will pass the user packet memory address directly to underlying + * link layer. In this case it is the client's responsibility to + * make sure the packet is intact until being notified that the + * packet has been consumed. + */ + APR_PKT_OWNER_CLIENT, +}; + +struct apr_pkt_priv { + /* This property is only applicable for APR over Glink. + * It is ignored in APR over SMD cases. + */ + uint8_t pkt_owner; +}; + +typedef void (*apr_svc_cb_fn)(void *buf, int len, void *priv); +struct apr_svc_ch_dev *apr_tal_open(uint32_t svc, uint32_t dest, + uint32_t dl, apr_svc_cb_fn func, void *priv); +int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, + struct apr_pkt_priv *pkt_priv, int len); +int apr_tal_close(struct apr_svc_ch_dev *apr_ch); +int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch, + int num_of_intents, uint32_t size); + + +#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \ + defined(CONFIG_MSM_QDSP6_APRV3_GLINK) +int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch); +int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch); + +struct apr_svc_ch_dev { + void *handle; + spinlock_t w_lock; + spinlock_t r_lock; + struct mutex m_lock; + apr_svc_cb_fn func; + wait_queue_head_t wait; + void *priv; + unsigned channel_state; + bool if_remote_intent_ready; +}; +#else +static inline int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch) +{ return 0; } +static inline int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch) { return 0; } + +struct apr_svc_ch_dev { + struct smd_channel *ch; + spinlock_t lock; + spinlock_t w_lock; + struct mutex m_lock; + apr_svc_cb_fn func; + char data[APR_MAX_BUF]; + wait_queue_head_t wait; + void *priv; + uint32_t smd_state; + wait_queue_head_t dest; + uint32_t dest_state; +}; +#endif + +#endif diff --git a/include/linux/qdsp6v2/apr_us.h b/include/linux/qdsp6v2/apr_us.h new file mode 100644 index 000000000000..9a6804a4d634 --- /dev/null +++ b/include/linux/qdsp6v2/apr_us.h @@ -0,0 +1,193 @@ +/* Copyright (c) 2011-2014, 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 __APR_US_H__ +#define __APR_US_H__ + +#include <linux/qdsp6v2/apr.h> + +/* ======================================================================= */ +/* Session Level commands */ + +#define USM_SESSION_CMD_RUN 0x00012306 +struct usm_stream_cmd_run { + struct apr_hdr hdr; + u32 flags; + u32 msw_ts; + u32 lsw_ts; +} __packed; + +/* Stream level commands */ +#define USM_STREAM_CMD_OPEN_READ 0x00012309 +struct usm_stream_cmd_open_read { + struct apr_hdr hdr; + u32 uMode; + u32 src_endpoint; + u32 pre_proc_top; + u32 format; +} __packed; + +#define USM_STREAM_CMD_OPEN_WRITE 0x00011271 +struct usm_stream_cmd_open_write { + struct apr_hdr hdr; + u32 format; +} __packed; + + +#define USM_STREAM_CMD_CLOSE 0x0001230A + +#define USM_STREAM_CMD_SET_PARAM 0x00012731 +struct usm_stream_cmd_set_param { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 module_id; + u32 param_id; +} __packed; + +#define USM_STREAM_CMD_GET_PARAM 0x00012732 +struct usm_stream_cmd_get_param { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 module_id; + u32 param_id; +} __packed; + +/* Encoder configuration definitions */ +#define USM_STREAM_CMD_SET_ENC_PARAM 0x0001230B +/* Decoder configuration definitions */ +#define USM_DATA_CMD_MEDIA_FORMAT_UPDATE 0x00011272 + +/* Encoder/decoder configuration block */ +#define USM_PARAM_ID_ENCDEC_ENC_CFG_BLK 0x0001230D + +/* Max number of static located ports (bytes) */ +#define USM_MAX_PORT_NUMBER 8 + +/* Max number of static located transparent data (bytes) */ +#define USM_MAX_CFG_DATA_SIZE 100 + +/* Parameter structures used in USM_STREAM_CMD_SET_ENCDEC_PARAM command */ +/* common declarations */ +struct usm_cfg_common { + u16 ch_cfg; + u16 bits_per_sample; + u32 sample_rate; + u32 dev_id; + u8 data_map[USM_MAX_PORT_NUMBER]; +} __packed; + +struct us_encdec_cfg { + u32 format_id; + struct usm_cfg_common cfg_common; + u16 params_size; + u8 *params; +} __packed; + +/* Start/stop US signal detection */ +#define USM_SESSION_CMD_SIGNAL_DETECT_MODE 0x00012719 + +struct usm_session_cmd_detect_info { + struct apr_hdr hdr; + u32 detect_mode; + u32 skip_interval; + u32 algorithm_cfg_size; +} __packed; + +/* US signal detection result */ +#define USM_SESSION_EVENT_SIGNAL_DETECT_RESULT 0x00012720 + +/* ======================================================================= */ +/* Session Level commands */ +#define USM_CMD_SHARED_MEM_MAP_REGION 0x00012728 +struct usm_cmd_memory_map_region { + struct apr_hdr hdr; + u16 mempool_id; + u16 num_regions; + u32 flags; + u32 shm_addr_lsw; + u32 shm_addr_msw; + u32 mem_size_bytes; +} __packed; + +#define USM_CMDRSP_SHARED_MEM_MAP_REGION 0x00012729 +struct usm_cmdrsp_memory_map_region { + u32 mem_map_handle; +} __packed; + +#define USM_CMD_SHARED_MEM_UNMAP_REGION 0x0001272A +struct usm_cmd_memory_unmap_region { + struct apr_hdr hdr; + u32 mem_map_handle; +} __packed; + +#define USM_DATA_CMD_READ 0x00012724 +struct usm_stream_cmd_read { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 seq_id; + u32 counter; +} __packed; + +#define USM_DATA_EVENT_READ_DONE 0x00012725 + +#define USM_DATA_CMD_WRITE 0x00012726 +struct usm_stream_cmd_write { + struct apr_hdr hdr; + u32 buf_addr_lsw; + u32 buf_addr_msw; + u32 mem_map_handle; + u32 buf_size; + u32 seq_id; + u32 res0; + u32 res1; + u32 res2; +} __packed; + +#define USM_DATA_EVENT_WRITE_DONE 0x00012727 + +struct usm_stream_media_format_update { + struct apr_hdr hdr; + u32 format_id; + /* <cfg_size> = sizeof(usm_cfg_common)+|transp_data| */ + u32 cfg_size; + struct usm_cfg_common cfg_common; + /* Transparent configuration data for specific encoder */ + u8 transp_data[USM_MAX_CFG_DATA_SIZE]; +} __packed; + +struct usm_encode_cfg_blk { + u32 frames_per_buf; + u32 format_id; + /* <cfg_size> = sizeof(usm_cfg_common)+|transp_data| */ + u32 cfg_size; + struct usm_cfg_common cfg_common; + /* Transparent configuration data for specific encoder */ + u8 transp_data[USM_MAX_CFG_DATA_SIZE]; +} __packed; + +struct usm_stream_cmd_encdec_cfg_blk { + struct apr_hdr hdr; + u32 param_id; + u32 param_size; + struct usm_encode_cfg_blk enc_blk; +} __packed; + +#endif /* __APR_US_H__ */ diff --git a/include/linux/qdsp6v2/aprv2_vm.h b/include/linux/qdsp6v2/aprv2_vm.h new file mode 100644 index 000000000000..d16ea12d62b5 --- /dev/null +++ b/include/linux/qdsp6v2/aprv2_vm.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2016-2017 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 __APRV2_VM_H__ +#define __APRV2_VM_H__ + +#define APRV2_VM_MAX_DNS_SIZE (31) + /* Includes NULL character. */ +#define APRV2_VM_PKT_SERVICE_ID_MASK (0x00FF) + /* Bitmask of the service ID field. */ + +/* Packet Structure Definition */ +struct aprv2_vm_packet_t { + uint32_t header; + uint16_t src_addr; + uint16_t src_port; + uint16_t dst_addr; + uint16_t dst_port; + uint32_t token; + uint32_t opcode; +}; + +/** + * In order to send command/event via MM HAB, the following buffer + * format shall be followed, where the buffer is provided to the + * HAB send API. + * |-----cmd_id or evt_id -----| <- 32 bit, e.g. APRV2_VM_CMDID_REGISTER + * |-----cmd payload ----------| e.g. aprv2_vm_cmd_register_t + * | ... | + * + * In order to receive a command response or event ack, the following + * buffer format shall be followed, where the buffer is provided to + * the HAB receive API. + * |-----cmd response ---------| e.g. aprv2_vm_cmd_register_rsp_t + * | ... | + */ + +/* Registers a service with the backend APR driver. */ +#define APRV2_VM_CMDID_REGISTER (0x00000001) + +struct aprv2_vm_cmd_register_t { + uint32_t name_size; + /**< The service name string size in bytes. */ + char name[APRV2_VM_MAX_DNS_SIZE]; + /**< + * The service name string to register. + * + * A NULL name means the service does not have a name. + */ + uint16_t addr; + /**< + * The address to register. + * + * A zero value means to auto-generate a free dynamic address. + * A non-zero value means to directly use the statically assigned address. + */ +}; + +struct aprv2_vm_cmd_register_rsp_t { + int32_t status; + /**< The status of registration. */ + uint32_t handle; + /**< The registered service handle. */ + uint16_t addr; + /**< The actual registered address. */ +}; + +#define APRV2_VM_CMDID_DEREGISTER (0x00000002) + +struct aprv2_vm_cmd_deregister_t { + uint32_t handle; + /**< The registered service handle. */ +}; + +struct aprv2_vm_cmd_deregister_rsp_t { + int32_t status; + /**< The status of de-registration. */ +}; + +#define APRV2_VM_CMDID_ASYNC_SEND (0x00000003) + +struct aprv2_vm_cmd_async_send_t { + uint32_t handle; + /**< The registered service handle. */ + struct aprv2_vm_packet_t pkt_header; + /**< The packet header. */ + /* The apr packet payload follows */ +}; + +struct aprv2_vm_cmd_async_send_rsp_t { + int32_t status; + /**< The status of send. */ +}; + +#define APRV2_VM_EVT_RX_PKT_AVAILABLE (0x00000004) + +struct aprv2_vm_evt_rx_pkt_available_t { + struct aprv2_vm_packet_t pkt_header; + /**< The packet header. */ + /* The apr packet payload follows */ +}; + +struct aprv2_vm_ack_rx_pkt_available_t { + int32_t status; +}; + +#endif /* __APRV2_VM_H__ */ diff --git a/include/linux/qdsp6v2/audio-anc-dev-mgr.h b/include/linux/qdsp6v2/audio-anc-dev-mgr.h new file mode 100644 index 000000000000..b0ece2dbb239 --- /dev/null +++ b/include/linux/qdsp6v2/audio-anc-dev-mgr.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2018, 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 _AUDIO_ANC_DEV_MGR_H_ +#define _AUDIO_ANC_DEV_MGR_H_ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/mfd/wcd9xxx/core.h> +#include <linux/bitops.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/of_device.h> +#include <linux/clk/msm-clk.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/apr_audio-v2.h> +#include <sound/q6afe-v2.h> +#include <sound/msm-dai-q6-v2.h> +#include <linux/msm_audio_anc.h> + +int msm_anc_dev_init(void); +int msm_anc_dev_deinit(void); + +int msm_anc_dev_start(void); +int msm_anc_dev_stop(void); + +int msm_anc_dev_set_info(void *info_p, int32_t anc_cmd); + +int msm_anc_dev_get_info(void *info_p, int32_t anc_cmd); + +int msm_anc_dev_create(struct platform_device *pdev); + +int msm_anc_dev_destroy(struct platform_device *pdev); + +#endif diff --git a/include/linux/qdsp6v2/audio_notifier.h b/include/linux/qdsp6v2/audio_notifier.h new file mode 100644 index 000000000000..0d7f84613107 --- /dev/null +++ b/include/linux/qdsp6v2/audio_notifier.h @@ -0,0 +1,105 @@ +/* Copyright (c) 2016, 2018, 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 __AUDIO_NOTIFIER_H_ +#define __AUDIO_NOTIFIER_H_ + +/* State of the notifier domain */ +enum { + AUDIO_NOTIFIER_SERVICE_DOWN, + AUDIO_NOTIFIER_SERVICE_UP +}; + +/* Service order determines connection priority + * Highest number connected first + */ +enum { + AUDIO_NOTIFIER_SSR_SERVICE, + AUDIO_NOTIFIER_PDR_SERVICE, + AUDIO_NOTIFIER_MAX_SERVICES +}; + +enum { + AUDIO_NOTIFIER_ADSP_DOMAIN, + AUDIO_NOTIFIER_MODEM_DOMAIN, + AUDIO_NOTIFIER_MAX_DOMAINS +}; + +/* Structure populated in void *data of nb function + * callback used for audio_notifier_register + */ +struct audio_notifier_cb_data { + int service; + int domain; +}; + +#ifdef CONFIG_MSM_QDSP6_NOTIFIER + +/* + * Use audio_notifier_register to register any audio + * clients who need to be notified of a remote process. + * This API will determine and register the client with + * the best available subsystem (SSR or PDR) for that + * domain (Adsp or Modem). When an event is sent from that + * domain the notifier block callback function will be called. + * + * client_name - A unique user name defined by the client. + * If the same name is used for multiple calls each will + * be tracked & called back separately and a single call + * to deregister will delete them all. + * domain - Domain the client wants to get events from. + * AUDIO_NOTIFIER_ADSP_DOMAIN + * AUDIO_NOTIFIER_MODEM_DOMAIN + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified of an even on that domain. + * + * nb_func(struct notifier_block *this, unsigned long opcode, void *data) + * this - pointer to own nb + * opcode - event from registered domain + * AUDIO_NOTIFIER_SERVICE_DOWN + * AUDIO_NOTIFIER_SERVICE_UP + * *data - pointer to struct audio_notifier_cb_data + * + * Returns: Success: 0 + * Error: -# + */ +int audio_notifier_register(char *client_name, int domain, + struct notifier_block *nb); + +/* + * Use audio_notifier_deregister to deregister the clients from + * all domains registered using audio_notifier_register that + * match the client name. + * + * client_name - Unique user name used in audio_notifier_register. + * Returns: Success: 0 + * Error: -# + */ +int audio_notifier_deregister(char *client_name); + +#else + +static inline int audio_notifier_register(char *client_name, int domain, + struct notifier_block *nb) +{ + return 0; +} + +static inline int audio_notifier_deregister(char *client_name) +{ + return 0; +} + +#endif /* CONFIG_MSM_QDSP6_PDR */ + +#endif diff --git a/include/linux/qdsp6v2/audio_pdr.h b/include/linux/qdsp6v2/audio_pdr.h new file mode 100644 index 000000000000..b8eb1be3ee64 --- /dev/null +++ b/include/linux/qdsp6v2/audio_pdr.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2016, 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 __AUDIO_PDR_H_ +#define __AUDIO_PDR_H_ + +enum { + AUDIO_PDR_DOMAIN_ADSP, + AUDIO_PDR_DOMAIN_MAX +}; + +enum { + AUDIO_PDR_FRAMEWORK_DOWN, + AUDIO_PDR_FRAMEWORK_UP +}; + +#ifdef CONFIG_MSM_QDSP6_PDR + +/* + * Use audio_pdr_register to register with the PDR subsystem this + * should be done before module late init otherwise notification + * of the AUDIO_PDR_FRAMEWORK_UP cannot be guaranteed. + * + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified once the PDR framework has been initialized. + * Callback will receive either the AUDIO_PDR_FRAMEWORK_DOWN + * or AUDIO_PDR_FRAMEWORK_UP ioctl depending on the state of + * the PDR framework. + * + * Returns: Success: 0 + * Failure: Error code + */ +int audio_pdr_register(struct notifier_block *nb); + +/* + * Use audio_pdr_service_register to register with a PDR service + * Function should be called after nb callback registered with + * audio_pdr_register has been called back with the + * AUDIO_PDR_FRAMEWORK_UP ioctl. + * + * domain_id - Domain to use, example: AUDIO_PDR_ADSP + * *nb - Pointer to a notifier block. Provide a callback function + * that will be notified of the state of the domain + * requested. The ioctls received by the callback are + * defined in service-notifier.h. + * + * Returns: Success: Client handle + * Failure: Pointer error code + */ +void *audio_pdr_service_register(int domain_id, + struct notifier_block *nb, int *curr_state); + + /* + * Use audio_pdr_service_deregister to deregister with a PDR + * service that was registered using the audio_pdr_service_register + * API. + * + * *service_handle - Service handle returned by audio_pdr_service_register + * *nb - Pointer to the notifier block. Used in the call to + * audio_pdr_service_register. + * + * Returns: Success: Client handle + * Failure: Error code + */ +int audio_pdr_service_deregister(void *service_handle, + struct notifier_block *nb); + +#else + +static inline int audio_pdr_register(struct notifier_block *nb) +{ + return -ENODEV; +} + + +static inline void *audio_pdr_service_register(int domain_id, + struct notifier_block *nb, + int *curr_state) +{ + return NULL; +} + +static inline int audio_pdr_service_deregister(void *service_handle, + struct notifier_block *nb) +{ + return 0; +} + +#endif /* CONFIG_MSM_QDSP6_PDR */ + +#endif diff --git a/include/linux/qdsp6v2/audio_ssr.h b/include/linux/qdsp6v2/audio_ssr.h new file mode 100644 index 000000000000..a807021ba7ca --- /dev/null +++ b/include/linux/qdsp6v2/audio_ssr.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2016, 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 __AUDIO_SSR_H_ +#define __AUDIO_SSR_H_ + +enum { + AUDIO_SSR_DOMAIN_ADSP, + AUDIO_SSR_DOMAIN_MODEM, + AUDIO_SSR_DOMAIN_MAX +}; + +#ifdef CONFIG_MSM_QDSP6_SSR + +/* + * Use audio_ssr_register to register with the SSR subsystem + * + * domain_id - Service to use, example: AUDIO_SSR_DOMAIN_ADSP + * *nb - Pointer to a notifier block. Provide a callback function + * to be notified of an event for that service. The ioctls + * used by the callback are defined in subsystem_notif.h. + * + * Returns: Success: Client handle + * Failure: Pointer error code + */ +void *audio_ssr_register(int domain_id, struct notifier_block *nb); + +/* + * Use audio_ssr_deregister to register with the SSR subsystem + * + * handle - Handle received from audio_ssr_register + * *nb - Pointer to a notifier block. Callback function + * Used from audio_ssr_register. + * + * Returns: Success: 0 + * Failure: Error code + */ +int audio_ssr_deregister(void *handle, struct notifier_block *nb); + + +/* + * Use audio_ssr_send_nmi to force a RAM dump on ADSP + * down event. + * + * *ssr_cb_data - *data received from notifier callback + */ +void audio_ssr_send_nmi(void *ssr_cb_data); + +#else + +static inline void *audio_ssr_register(int domain_id, + struct notifier_block *nb) +{ + return NULL; +} + +static inline int audio_ssr_deregister(void *handle, struct notifier_block *nb) +{ + return 0; +} + +static inline void audio_ssr_send_nmi(void *ssr_cb_data) +{ +} + +#endif /* CONFIG_MSM_QDSP6_SSR */ + +#endif diff --git a/include/linux/qdsp6v2/dsp_debug.h b/include/linux/qdsp6v2/dsp_debug.h new file mode 100644 index 000000000000..bc1cd9ec8743 --- /dev/null +++ b/include/linux/qdsp6v2/dsp_debug.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2010, 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 __DSP_DEBUG_H_ +#define __DSP_DEBUG_H_ + +typedef int (*dsp_state_cb)(int state); +int dsp_debug_register(dsp_state_cb ptr); + +#define DSP_STATE_CRASHED 0x0 +#define DSP_STATE_CRASH_DUMP_DONE 0x1 + +#endif diff --git a/include/linux/qdsp6v2/rtac.h b/include/linux/qdsp6v2/rtac.h new file mode 100644 index 000000000000..5bd0923fd72b --- /dev/null +++ b/include/linux/qdsp6v2/rtac.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2011, 2013-2015, 2017, 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 __RTAC_H__ +#define __RTAC_H__ + +#include <sound/apr_audio-v2.h> + +/* Voice Modes */ +#define RTAC_CVP 0 +#define RTAC_CVS 1 +#define RTAC_VOICE_MODES 2 + +#define RTAC_MAX_ACTIVE_DEVICES 6 +#define RTAC_MAX_ACTIVE_POPP 8 + +#define DEFAULT_APP_TYPE 0x00011130 + +enum { + ADM_RTAC_CAL, + ASM_RTAC_CAL, + VOICE_RTAC_CAL, + AFE_RTAC_CAL, + MAX_RTAC_BLOCKS +}; + +struct rtac_cal_mem_map_data { + uint32_t map_size; + uint32_t map_handle; + struct ion_client *ion_client; + struct ion_handle *ion_handle; +}; + +struct rtac_cal_data { + size_t size; + void *kvaddr; + phys_addr_t paddr; +}; + +struct rtac_cal_block_data { + struct rtac_cal_mem_map_data map_data; + struct rtac_cal_data cal_data; +}; + +struct rtac_popp_data { + uint32_t popp; + uint32_t popp_topology; + uint32_t app_type; +}; + +struct rtac_adm_data { + uint32_t topology_id; + uint32_t afe_topology; + uint32_t afe_port; + uint32_t copp; + uint32_t num_of_popp; + uint32_t app_type; + uint32_t acdb_dev_id; + struct rtac_popp_data popp[RTAC_MAX_ACTIVE_POPP]; +}; + +struct rtac_adm { + uint32_t num_of_dev; + struct rtac_adm_data device[RTAC_MAX_ACTIVE_DEVICES]; +}; + +void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id, + u32 app_type, u32 acdb_dev_id); +void rtac_remove_adm_device(u32 port_id, u32 copp_id); +void rtac_remove_popp_from_adm_devices(u32 popp_id); +void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port, + u32 tx_afe_port, u32 rx_acdb_id, u32 tx_acdb_id, u32 session_id); +void rtac_remove_voice(u32 cvs_handle); +void rtac_set_adm_handle(void *handle); +bool rtac_make_adm_callback(uint32_t *payload, u32 payload_size); +void rtac_copy_adm_payload_to_user(void *payload, u32 payload_size); +void rtac_set_asm_handle(u32 session_id, void *handle); +bool rtac_make_asm_callback(u32 session_id, uint32_t *payload, + u32 payload_size); +void rtac_copy_asm_payload_to_user(void *payload, u32 payload_size); +void rtac_set_voice_handle(u32 mode, void *handle); +bool rtac_make_voice_callback(u32 mode, uint32_t *payload, u32 payload_size); +void rtac_copy_voice_payload_to_user(void *payload, u32 payload_size); +int rtac_clear_mapping(uint32_t cal_type); +bool rtac_make_afe_callback(uint32_t *payload, u32 payload_size); +void rtac_set_afe_handle(void *handle); +void get_rtac_adm_data(struct rtac_adm *adm_data); +void rtac_update_afe_topology(u32 port_id); +#endif diff --git a/include/linux/qdsp6v2/sdsp_anc.h b/include/linux/qdsp6v2/sdsp_anc.h new file mode 100644 index 000000000000..5c1b7055c1d5 --- /dev/null +++ b/include/linux/qdsp6v2/sdsp_anc.h @@ -0,0 +1,271 @@ +/* Copyright (c) 2018, 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 __SDSP_ANC_H__ +#define __SDSP_ANC_H__ + +#include <sound/q6afe-v2.h> +#include <sound/apr_audio-v2.h> + +#define AUD_MSVC_MODULE_AUDIO_DEV_RESOURCE_SHARE 0x0001028A +#define AUD_MSVC_PARAM_ID_PORT_SHARE_RESOURCE_CONFIG 0x00010297 +#define AUD_MSVC_API_VERSION_SHARE_RESOURCE_CONFIG 0x1 +#define AUD_MSVC_MODULE_AUDIO_DEV_ANC_REFS 0x00010254 +#define AUD_MSVC_PARAM_ID_DEV_ANC_REFS_CONFIG 0x00010286 +#define AUD_MSVC_API_VERSION_DEV_ANC_REFS_CONFIG 0x1 +#define AUD_MSVC_MODULE_AUDIO_DEV_ANC_ALGO 0x00010234 + +struct aud_msvc_port_param_data_v2 { + /* ID of the module to be configured. + * Supported values: Valid module ID + */ + u32 module_id; + + /* ID of the parameter corresponding to the supported parameters + * for the module ID. + * Supported values: Valid parameter ID + */ + u32 param_id; + + /* Actual size of the data for the + * module_id/param_id pair. The size is a + * multiple of four bytes. + * Supported values: > 0 + */ + u16 param_size; + + /* This field must be set to zero. + */ + u16 reserved; +} __packed; + + +/* Payload of the #AFE_PORT_CMD_SET_PARAM_V2 command's + * configuration/calibration settings for the AFE port. + */ +struct aud_msvc_port_cmd_set_param_v2 { + /* Port interface and direction (Rx or Tx) to start. + */ + u16 port_id; + + /* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + u16 payload_size; + + /* LSW of 64 bit Payload address. + * Address should be 32-byte, + * 4kbyte aligned and must be contiguous memory. + */ + u32 payload_address_lsw; + + /* MSW of 64 bit Payload address. + * In case of 32-bit shared memory address, + * this field must be set to zero. + * In case of 36-bit shared memory address, + * bit-4 to bit-31 must be set to zero. + * Address should be 32-byte, 4kbyte aligned + * and must be contiguous memory. + */ + u32 payload_address_msw; + + /* Memory map handle returned by + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. + * Supported Values: + * - NULL -- Message. The parameter data is in-band. + * - Non-NULL -- The parameter data is Out-band.Pointer to + * the physical address + * in shared memory of the payload data. + * An optional field is available if parameter + * data is in-band: + * aud_msvc_param_data_v2 param_data[...]. + * For detailed payload content, see the + * aud_msvc_port_param_data_v2 structure. + */ + u32 mem_map_handle; + +} __packed; + +/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, + * which queries for one post/preprocessing parameter of a + * stream. + */ +struct aud_msvc_port_cmd_get_param_v2 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + + /* Maximum data size of the parameter ID/module ID combination. + * This is a multiple of four bytes + * Supported values: > 0 + */ + u16 payload_size; + + /* LSW of 64 bit Payload address. Address should be 32-byte, + * 4kbyte aligned and must be contig memory. + */ + u32 payload_address_lsw; + + /* MSW of 64 bit Payload address. In case of 32-bit shared + * memory address, this field must be set to zero. In case of 36-bit + * shared memory address, bit-4 to bit-31 must be set to zero. + * Address should be 32-byte, 4kbyte aligned and must be contiguous + * memory. + */ + u32 payload_address_msw; + + /* Memory map handle returned by + * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. + * Supported Values: - NULL -- Message. The parameter data is + * in-band. - Non-NULL -- The parameter data is Out-band.Pointer to + * - the physical address in shared memory of the payload data. + * For detailed payload content, see the aud_msvc_port_param_data_v2 + * structure + */ + u32 mem_map_handle; + + /* ID of the module to be queried. + * Supported values: Valid module ID + */ + u32 module_id; + + /* ID of the parameter to be queried. + * Supported values: Valid parameter ID + */ + u32 param_id; + +} __packed; + +struct aud_audioif_config_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + union afe_port_config port; +} __packed; + +struct aud_msvc_param_id_dev_share_resource_cfg { + u32 minor_version; + u16 rddma_idx; + u16 wrdma_idx; + u32 lpm_start_addr; + u32 lpm_length; +} __packed; + +struct aud_msvc_param_id_dev_anc_refs_cfg { + u32 minor_version; + u16 port_id; + u16 num_channel; + u32 sample_rate; + u32 bit_width; +} __packed; + +struct anc_share_resource_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + struct aud_msvc_param_id_dev_share_resource_cfg resource; +} __packed; + +struct anc_config_ref_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + struct aud_msvc_param_id_dev_anc_refs_cfg refs; +} __packed; + +#define AUD_MSVC_PARAM_ID_PORT_ANC_ALGO_MODULE_ID 0x0001023A + +struct aud_msvc_param_id_dev_anc_algo_module_id { + uint32_t minor_version; + uint32_t module_id; +} __packed; + +struct anc_set_algo_module_id_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + struct aud_msvc_param_id_dev_anc_algo_module_id set_algo_module_id; +} __packed; + + +#define AUD_MSVC_PARAM_ID_PORT_ANC_MIC_SPKR_LAYOUT_INFO 0x0001029C + +#define AUD_MSVC_API_VERSION_DEV_ANC_MIC_SPKR_LAYOUT_INFO 0x1 + +#define AUD_MSVC_ANC_MAX_NUM_OF_MICS 16 +#define AUD_MSVC_ANC_MAX_NUM_OF_SPKRS 16 + +struct aud_msvc_param_id_dev_anc_mic_spkr_layout_info { + uint32_t minor_version; + uint16_t mic_layout_array[AUD_MSVC_ANC_MAX_NUM_OF_MICS]; + uint16_t spkr_layout_array[AUD_MSVC_ANC_MAX_NUM_OF_SPKRS]; + uint16_t num_anc_mic; + uint16_t num_anc_spkr; + uint16_t num_add_mic_signal; + uint16_t num_add_spkr_signal; +} __packed; + +struct anc_set_mic_spkr_layout_info_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + struct aud_msvc_param_id_dev_anc_mic_spkr_layout_info + set_mic_spkr_layout; +} __packed; + +struct anc_set_algo_module_cali_data_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_set_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + /* + * calibration data payload followed + */ +} __packed; + +struct anc_get_algo_module_cali_data_command { + struct apr_hdr hdr; + struct aud_msvc_port_cmd_get_param_v2 param; + struct aud_msvc_port_param_data_v2 pdata; + /* + * calibration data payload followed + */ +} __packed; + +struct anc_get_algo_module_cali_data_resp { + uint32_t status; + struct aud_msvc_port_param_data_v2 pdata; + uint32_t payload[128]; +} __packed; + +int anc_if_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port); + +int anc_if_tdm_port_stop(u16 port_id); + +int anc_if_share_resource(u16 port_id, u16 rddma_idx, u16 wrdma_idx, + u32 lpm_start_addr, u32 lpm_length); + +int anc_if_config_ref(u16 port_id, u32 sample_rate, u32 bit_width, + u16 num_channel); + +int anc_if_set_algo_module_id(u16 port_id, u32 module_id); + +int anc_if_set_anc_mic_spkr_layout(u16 port_id, +struct aud_msvc_param_id_dev_anc_mic_spkr_layout_info *set_mic_spkr_layout_p); + +int anc_if_set_algo_module_cali_data(u16 port_id, void *data_p); + +int anc_if_get_algo_module_cali_data(u16 port_id, void *data_p); + +int anc_if_shared_mem_map(void); + +int anc_if_shared_mem_unmap(void); + +#endif /* __SDSP_ANC_H__ */ diff --git a/include/linux/qdsp6v2/usf.h b/include/linux/qdsp6v2/usf.h new file mode 100644 index 000000000000..544b624c2cda --- /dev/null +++ b/include/linux/qdsp6v2/usf.h @@ -0,0 +1,298 @@ +/* Copyright (c) 2011-2014, 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 __USF_H__ +#define __USF_H__ + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define USF_IOCTL_MAGIC 'U' + +#define US_SET_TX_INFO _IOW(USF_IOCTL_MAGIC, 0, \ + struct us_tx_info_type) +#define US_START_TX _IO(USF_IOCTL_MAGIC, 1) +#define US_GET_TX_UPDATE _IOWR(USF_IOCTL_MAGIC, 2, \ + struct us_tx_update_info_type) +#define US_SET_RX_INFO _IOW(USF_IOCTL_MAGIC, 3, \ + struct us_rx_info_type) +#define US_SET_RX_UPDATE _IOWR(USF_IOCTL_MAGIC, 4, \ + struct us_rx_update_info_type) +#define US_START_RX _IO(USF_IOCTL_MAGIC, 5) + +#define US_STOP_TX _IO(USF_IOCTL_MAGIC, 6) +#define US_STOP_RX _IO(USF_IOCTL_MAGIC, 7) + +#define US_SET_DETECTION _IOWR(USF_IOCTL_MAGIC, 8, \ + struct us_detect_info_type) + +#define US_GET_VERSION _IOWR(USF_IOCTL_MAGIC, 9, \ + struct us_version_info_type) + +#define US_SET_TX_STREAM_PARAM _IOW(USF_IOCTL_MAGIC, 10, \ + struct us_stream_param_type) +#define US_GET_TX_STREAM_PARAM _IOWR(USF_IOCTL_MAGIC, 11, \ + struct us_stream_param_type) +#define US_SET_RX_STREAM_PARAM _IOW(USF_IOCTL_MAGIC, 12, \ + struct us_stream_param_type) +#define US_GET_RX_STREAM_PARAM _IOWR(USF_IOCTL_MAGIC, 13, \ + struct us_stream_param_type) + +/* Special timeout values */ +#define USF_NO_WAIT_TIMEOUT 0x00000000 +/* Infinitive */ +#define USF_INFINITIVE_TIMEOUT 0xffffffff +/* Default value, used by the driver */ +#define USF_DEFAULT_TIMEOUT 0xfffffffe + +/* US detection place (HW|FW) */ +enum us_detect_place_enum { +/* US is detected in HW */ + US_DETECT_HW, +/* US is detected in FW */ + US_DETECT_FW +}; + +/* US detection mode */ +enum us_detect_mode_enum { +/* US detection is disabled */ + US_DETECT_DISABLED_MODE, +/* US detection is enabled in continue mode */ + US_DETECT_CONTINUE_MODE, +/* US detection is enabled in one shot mode */ + US_DETECT_SHOT_MODE +}; + +/* Encoder (TX), decoder (RX) supported US data formats */ +#define USF_POINT_EPOS_FORMAT 0 +#define USF_RAW_FORMAT 1 + +/* Indexes of event types, produced by the calculators */ +#define USF_TSC_EVENT_IND 0 +#define USF_TSC_PTR_EVENT_IND 1 +#define USF_MOUSE_EVENT_IND 2 +#define USF_KEYBOARD_EVENT_IND 3 +#define USF_TSC_EXT_EVENT_IND 4 +#define USF_MAX_EVENT_IND 5 + +/* Types of events, produced by the calculators */ +#define USF_NO_EVENT 0 +#define USF_TSC_EVENT (1 << USF_TSC_EVENT_IND) +#define USF_TSC_PTR_EVENT (1 << USF_TSC_PTR_EVENT_IND) +#define USF_MOUSE_EVENT (1 << USF_MOUSE_EVENT_IND) +#define USF_KEYBOARD_EVENT (1 << USF_KEYBOARD_EVENT_IND) +#define USF_TSC_EXT_EVENT (1 << USF_TSC_EXT_EVENT_IND) +#define USF_ALL_EVENTS (USF_TSC_EVENT |\ + USF_TSC_PTR_EVENT |\ + USF_MOUSE_EVENT |\ + USF_KEYBOARD_EVENT |\ + USF_TSC_EXT_EVENT) + +/* min, max array dimension */ +#define MIN_MAX_DIM 2 + +/* coordinates (x,y,z) array dimension */ +#define COORDINATES_DIM 3 + +/* tilts (x,y) array dimension */ +#define TILTS_DIM 2 + +/* Max size of the client name */ +#define USF_MAX_CLIENT_NAME_SIZE 20 + +/* Max number of the ports (mics/speakers) */ +#define USF_MAX_PORT_NUM 8 + +/* Info structure common for TX and RX */ +struct us_xx_info_type { +/* Input: general info */ +/* Name of the client - event calculator */ + const char __user *client_name; +/* Selected device identification, accepted in the kernel's CAD */ + uint32_t dev_id; +/* 0 - point_epos type; (e.g. 1 - gr_mmrd) */ + uint32_t stream_format; +/* Required sample rate in Hz */ + uint32_t sample_rate; +/* Size of a buffer (bytes) for US data transfer between the module and USF */ + uint32_t buf_size; +/* Number of the buffers for the US data transfer */ + uint16_t buf_num; +/* Number of the microphones (TX) or speakers(RX) */ + uint16_t port_cnt; +/* Microphones(TX) or speakers(RX) indexes in their enumeration */ + uint8_t port_id[USF_MAX_PORT_NUM]; +/* Bits per sample 16 or 32 */ + uint16_t bits_per_sample; +/* Input: Transparent info for encoder in the LPASS */ +/* Parameters data size in bytes */ + uint16_t params_data_size; +/* Pointer to the parameters */ + uint8_t __user *params_data; +/* Max size of buffer for get and set parameter */ + uint32_t max_get_set_param_buf_size; +}; + +struct us_input_info_type { + /* Touch screen dimensions: min & max;for input module */ + int tsc_x_dim[MIN_MAX_DIM]; + int tsc_y_dim[MIN_MAX_DIM]; + int tsc_z_dim[MIN_MAX_DIM]; + /* Touch screen tilt dimensions: min & max;for input module */ + int tsc_x_tilt[MIN_MAX_DIM]; + int tsc_y_tilt[MIN_MAX_DIM]; + /* Touch screen pressure limits: min & max; for input module */ + int tsc_pressure[MIN_MAX_DIM]; + /* The requested buttons bitmap */ + uint16_t req_buttons_bitmap; + /* Bitmap of types of events (USF_X_EVENT), produced by calculator */ + uint16_t event_types; + /* Bitmap of types of events from devs, conflicting with USF */ + uint16_t conflicting_event_types; +}; + +struct us_tx_info_type { + /* Common info */ + struct us_xx_info_type us_xx_info; + /* Info specific for TX*/ + struct us_input_info_type input_info; +}; + +struct us_rx_info_type { + /* Common info */ + struct us_xx_info_type us_xx_info; + /* Info specific for RX*/ +}; + +struct point_event_type { +/* Pen coordinates (x, y, z) in units, defined by <coordinates_type> */ + int coordinates[COORDINATES_DIM]; + /* {x;y} in transparent units */ + int inclinations[TILTS_DIM]; +/* [0-1023] (10bits); 0 - pen up */ + uint32_t pressure; +/* Bitmap for button state. 1 - down, 0 - up */ + uint16_t buttons_state_bitmap; +}; + +/* Mouse buttons, supported by USF */ +#define USF_BUTTON_LEFT_MASK 1 +#define USF_BUTTON_MIDDLE_MASK 2 +#define USF_BUTTON_RIGHT_MASK 4 +struct mouse_event_type { +/* The mouse relative movement (dX, dY, dZ) */ + int rels[COORDINATES_DIM]; +/* Bitmap of mouse buttons states: 1 - down, 0 - up; */ + uint16_t buttons_states; +}; + +struct key_event_type { +/* Calculated MS key- see input.h. */ + uint32_t key; +/* Keyboard's key state: 1 - down, 0 - up; */ + uint8_t key_state; +}; + +struct usf_event_type { +/* Event sequence number */ + uint32_t seq_num; +/* Event generation system time */ + uint32_t timestamp; +/* Destination input event type index (e.g. touch screen, mouse, key) */ + uint16_t event_type_ind; + union { + struct point_event_type point_event; + struct mouse_event_type mouse_event; + struct key_event_type key_event; + } event_data; +}; + +struct us_tx_update_info_type { +/* Input general: */ +/* Number of calculated events */ + uint16_t event_counter; +/* Calculated events or NULL */ + struct usf_event_type __user *event; +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +/* Time (sec) to wait for data or special values: */ +/* USF_NO_WAIT_TIMEOUT, USF_INFINITIVE_TIMEOUT, USF_DEFAULT_TIMEOUT */ + uint32_t timeout; +/* Events (from conflicting devs) to be disabled/enabled */ + uint16_t event_filters; + +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* Pointer to the parameters */ + uint8_t __user *params_data; +/* Output parameters: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +}; + +struct us_rx_update_info_type { +/* Input general: */ +/* Pointer (write index) to the end of ready US data region */ +/* in the shared memory */ + uint32_t ready_region; +/* Input transparent data: */ +/* Parameters size */ + uint16_t params_data_size; +/* pPointer to the parameters */ + uint8_t __user *params_data; +/* Output parameters: */ +/* Pointer (read index) to the end of available region */ +/* in the shared US data memory */ + uint32_t free_region; +}; + +struct us_detect_info_type { +/* US detection place (HW|FW) */ +/* NA in the Active and OFF states */ + enum us_detect_place_enum us_detector; +/* US detection mode */ + enum us_detect_mode_enum us_detect_mode; +/* US data dropped during this time (msec) */ + uint32_t skip_time; +/* Transparent data size */ + uint16_t params_data_size; +/* Pointer to the transparent data */ + uint8_t __user *params_data; +/* Time (sec) to wait for US presence event */ + uint32_t detect_timeout; +/* Out parameter: US presence */ + bool is_us; +}; + +struct us_version_info_type { +/* Size of memory for the version string */ + uint16_t buf_size; +/* Pointer to the memory for the version string */ + char __user *pbuf; +}; + +struct us_stream_param_type { +/* Id of module */ + uint32_t module_id; +/* Id of parameter */ + uint32_t param_id; +/* Size of memory of the parameter buffer */ + uint32_t buf_size; +/* Pointer to the memory of the parameter buffer */ + uint8_t __user *pbuf; +}; + +#endif /* __USF_H__ */ diff --git a/include/linux/qmi_encdec.h b/include/linux/qmi_encdec.h new file mode 100644 index 000000000000..66c3d84485ed --- /dev/null +++ b/include/linux/qmi_encdec.h @@ -0,0 +1,184 @@ +/* Copyright (c) 2012-2014, 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 _QMI_ENCDEC_H_ +#define _QMI_ENCDEC_H_ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/socket.h> +#include <linux/gfp.h> + +#define QMI_REQUEST_CONTROL_FLAG 0x00 +#define QMI_RESPONSE_CONTROL_FLAG 0x02 +#define QMI_INDICATION_CONTROL_FLAG 0x04 +#define QMI_HEADER_SIZE 7 + +/** + * elem_type - Enum to identify the data type of elements in a data + * structure. + */ +enum elem_type { + QMI_OPT_FLAG = 1, + QMI_DATA_LEN, + QMI_UNSIGNED_1_BYTE, + QMI_UNSIGNED_2_BYTE, + QMI_UNSIGNED_4_BYTE, + QMI_UNSIGNED_8_BYTE, + QMI_SIGNED_2_BYTE_ENUM, + QMI_SIGNED_4_BYTE_ENUM, + QMI_STRUCT, + QMI_STRING, + QMI_EOTI, +}; + +/** + * array_type - Enum to identify if an element in a data structure is + * an array. If so, then is it a static length array or a + * variable length array. + */ +enum array_type { + NO_ARRAY = 0, + STATIC_ARRAY = 1, + VAR_LEN_ARRAY = 2, +}; + +/** + * elem_info - Data structure to specify information about an element + * in a data structure. An array of this data structure + * can be used to specify info about a complex data + * structure to be encoded/decoded. + * + * @data_type: Data type of this element. + * @elem_len: Array length of this element, if an array. + * @elem_size: Size of a single instance of this data type. + * @is_array: Array type of this element. + * @tlv_type: QMI message specific type to identify which element + * is present in an incoming message. + * @offset: To identify the address of the first instance of this + * element in the data structure. + * @ei_array: Array to provide information about the nested structure + * within a data structure to be encoded/decoded. + */ +struct elem_info { + enum elem_type data_type; + uint32_t elem_len; + uint32_t elem_size; + enum array_type is_array; + uint8_t tlv_type; + uint32_t offset; + struct elem_info *ei_array; +}; + +/** + * @msg_desc - Describe about the main/outer structure to be + * encoded/decoded. + * + * @max_msg_len: Maximum possible length of the QMI message. + * @ei_array: Array to provide information about a data structure. + */ +struct msg_desc { + uint16_t msg_id; + int max_msg_len; + struct elem_info *ei_array; +}; + +struct qmi_header { + unsigned char cntl_flag; + uint16_t txn_id; + uint16_t msg_id; + uint16_t msg_len; +} __attribute__((__packed__)); + +static inline void encode_qmi_header(unsigned char *buf, + unsigned char cntl_flag, uint16_t txn_id, + uint16_t msg_id, uint16_t msg_len) +{ + struct qmi_header *hdr = (struct qmi_header *)buf; + + hdr->cntl_flag = cntl_flag; + hdr->txn_id = txn_id; + hdr->msg_id = msg_id; + hdr->msg_len = msg_len; +} + +static inline void decode_qmi_header(unsigned char *buf, + unsigned char *cntl_flag, uint16_t *txn_id, + uint16_t *msg_id, uint16_t *msg_len) +{ + struct qmi_header *hdr = (struct qmi_header *)buf; + + *cntl_flag = hdr->cntl_flag; + *txn_id = hdr->txn_id; + *msg_id = hdr->msg_id; + *msg_len = hdr->msg_len; +} + +#ifdef CONFIG_QMI_ENCDEC +/** + * qmi_kernel_encode() - Encode to QMI message wire format + * @desc: Pointer to structure descriptor. + * @out_buf: Buffer to hold the encoded QMI message. + * @out_buf_len: Length of the out buffer. + * @in_c_struct: C Structure to be encoded. + * + * @return: size of encoded message on success, < 0 on error. + */ +int qmi_kernel_encode(struct msg_desc *desc, + void *out_buf, uint32_t out_buf_len, + void *in_c_struct); + +/** + * qmi_kernel_decode() - Decode to C Structure format + * @desc: Pointer to structure descriptor. + * @out_c_struct: Buffer to hold the decoded C structure. + * @in_buf: Buffer containg the QMI message to be decoded. + * @in_buf_len: Length of the incoming QMI message. + * + * @return: 0 on success, < 0 on error. + */ +int qmi_kernel_decode(struct msg_desc *desc, void *out_c_struct, + void *in_buf, uint32_t in_buf_len); + +/** + * qmi_verify_max_msg_len() - Verify the maximum length of a QMI message + * @desc: Pointer to structure descriptor. + * + * @return: true if the maximum message length embedded in structure + * descriptor matches the calculated value, else false. + */ +bool qmi_verify_max_msg_len(struct msg_desc *desc); + +#else +static inline int qmi_kernel_encode(struct msg_desc *desc, + void *out_buf, uint32_t out_buf_len, + void *in_c_struct) +{ + return -EOPNOTSUPP; +} + +static inline int qmi_kernel_decode(struct msg_desc *desc, + void *out_c_struct, + void *in_buf, uint32_t in_buf_len) +{ + return -EOPNOTSUPP; +} + +static inline bool qmi_verify_max_msg_len(struct msg_desc *desc) +{ + return false; +} +#endif + +#endif diff --git a/include/linux/qpnp-misc.h b/include/linux/qpnp-misc.h new file mode 100644 index 000000000000..7d95bf24a425 --- /dev/null +++ b/include/linux/qpnp-misc.h @@ -0,0 +1,56 @@ +/* Copyright (c) 2013-2014, 2017, 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 __QPNP_MISC_H +#define __QPNP_MISC_H + +#include <linux/errno.h> + +#ifdef CONFIG_QPNP_MISC +/** + * qpnp_misc_irqs_available - check if IRQs are available + * + * @consumer_dev: device struct + * + * This function returns true if the MISC interrupts are available + * based on a check in the MISC peripheral revision registers. + * + * Any consumer of this function needs to reference a MISC device phandle + * using the "qcom,misc-ref" property in their device tree node. + */ + +int qpnp_misc_irqs_available(struct device *consumer_dev); + +/** + * qpnp_misc_read_reg - read register from misc device + * + * @node: device node pointer + * @address: address offset in misc peripheral to be read + * @val: data read from register + * + * This function returns zero if reading the MISC register succeeds. + * + */ + +int qpnp_misc_read_reg(struct device_node *node, u16 addr, u8 *val); +#else +static inline int qpnp_misc_irqs_available(struct device *consumer_dev) +{ + return 0; +} +static inline int qpnp_misc_read_reg(struct device_node *node, u16 addr, + u8 *val) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/qpnp/pin.h b/include/linux/qpnp/pin.h new file mode 100644 index 000000000000..7fb57aa7a778 --- /dev/null +++ b/include/linux/qpnp/pin.h @@ -0,0 +1,226 @@ +/* Copyright (c) 2012, 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. + */ + +/* Mode select */ +#define QPNP_PIN_MODE_DIG_IN 0 +#define QPNP_PIN_MODE_DIG_OUT 1 +#define QPNP_PIN_MODE_DIG_IN_OUT 2 +#define QPNP_PIN_MODE_ANA_PASS_THRU 3 +#define QPNP_PIN_MODE_BIDIR 3 +#define QPNP_PIN_MODE_AIN 4 +#define QPNP_PIN_MODE_AOUT 5 +#define QPNP_PIN_MODE_SINK 6 + +/* Invert source select (GPIO, MPP) */ +#define QPNP_PIN_INVERT_DISABLE 0 +#define QPNP_PIN_INVERT_ENABLE 1 + +/* Output type (GPIO) */ +#define QPNP_PIN_OUT_BUF_CMOS 0 +#define QPNP_PIN_OUT_BUF_OPEN_DRAIN_NMOS 1 +#define QPNP_PIN_OUT_BUF_OPEN_DRAIN_PMOS 2 +#define QPNP_PIN_OUT_BUF_NO_DRIVE 3 + +/* Voltage select (GPIO, MPP) */ +#define QPNP_PIN_VIN0 0 +#define QPNP_PIN_VIN1 1 +#define QPNP_PIN_VIN2 2 +#define QPNP_PIN_VIN3 3 +#define QPNP_PIN_VIN4 4 +#define QPNP_PIN_VIN5 5 +#define QPNP_PIN_VIN6 6 +#define QPNP_PIN_VIN7 7 + +/* Pull Up Values (GPIO) */ +#define QPNP_PIN_GPIO_PULL_UP_30 0 +#define QPNP_PIN_GPIO_PULL_UP_1P5 1 +#define QPNP_PIN_GPIO_PULL_UP_31P5 2 +#define QPNP_PIN_GPIO_PULL_UP_1P5_30 3 +#define QPNP_PIN_GPIO_PULL_DN 4 +#define QPNP_PIN_GPIO_PULL_NO 5 + +/* Pull Up Values (MPP) */ +#define QPNP_PIN_MPP_PULL_UP_0P6KOHM 0 +#define QPNP_PIN_MPP_PULL_UP_OPEN 1 +#define QPNP_PIN_MPP_PULL_UP_10KOHM 2 +#define QPNP_PIN_MPP_PULL_UP_30KOHM 3 + +/* Out Strength (GPIO) */ +#define QPNP_PIN_OUT_STRENGTH_LOW 1 +#define QPNP_PIN_OUT_STRENGTH_MED 2 +#define QPNP_PIN_OUT_STRENGTH_HIGH 3 + +/* Digital-in CTL (GPIO/MPP) */ +#define QPNP_PIN_DIG_IN_CTL_DTEST1 1 +#define QPNP_PIN_DIG_IN_CTL_DTEST2 2 +#define QPNP_PIN_DIG_IN_CTL_DTEST3 3 +#define QPNP_PIN_DIG_IN_CTL_DTEST4 4 + +/* Source Select (GPIO) / Enable Select (MPP) */ +#define QPNP_PIN_SEL_FUNC_CONSTANT 0 +#define QPNP_PIN_SEL_FUNC_PAIRED 1 +#define QPNP_PIN_SEL_FUNC_1 2 +#define QPNP_PIN_SEL_FUNC_2 3 +#define QPNP_PIN_SEL_DTEST1 4 +#define QPNP_PIN_SEL_DTEST2 5 +#define QPNP_PIN_SEL_DTEST3 6 +#define QPNP_PIN_SEL_DTEST4 7 + +/* Source Select for GPIO_LV/GPIO_MV only */ +#define QPNP_PIN_LV_MV_SEL_FUNC_CONSTANT 0 +#define QPNP_PIN_LV_MV_SEL_FUNC_PAIRED 1 +#define QPNP_PIN_LV_MV_SEL_FUNC_1 2 +#define QPNP_PIN_LV_MV_SEL_FUNC_2 3 +#define QPNP_PIN_LV_MV_SEL_FUNC_3 4 +#define QPNP_PIN_LV_MV_SEL_FUNC_4 5 +#define QPNP_PIN_LV_MV_SEL_DTEST1 6 +#define QPNP_PIN_LV_MV_SEL_DTEST2 7 +#define QPNP_PIN_LV_MV_SEL_DTEST3 8 +#define QPNP_PIN_LV_MV_SEL_DTEST4 9 + +/* Master enable (GPIO, MPP) */ +#define QPNP_PIN_MASTER_DISABLE 0 +#define QPNP_PIN_MASTER_ENABLE 1 + +/* Analog Output (MPP) */ +#define QPNP_PIN_AOUT_1V25 0 +#define QPNP_PIN_AOUT_0V625 1 +#define QPNP_PIN_AOUT_0V3125 2 +#define QPNP_PIN_AOUT_MPP 3 +#define QPNP_PIN_AOUT_ABUS1 4 +#define QPNP_PIN_AOUT_ABUS2 5 +#define QPNP_PIN_AOUT_ABUS3 6 +#define QPNP_PIN_AOUT_ABUS4 7 + +/* Analog Input (MPP) */ +#define QPNP_PIN_AIN_AMUX_CH5 0 +#define QPNP_PIN_AIN_AMUX_CH6 1 +#define QPNP_PIN_AIN_AMUX_CH7 2 +#define QPNP_PIN_AIN_AMUX_CH8 3 +#define QPNP_PIN_AIN_AMUX_ABUS1 4 +#define QPNP_PIN_AIN_AMUX_ABUS2 5 +#define QPNP_PIN_AIN_AMUX_ABUS3 6 +#define QPNP_PIN_AIN_AMUX_ABUS4 7 + +/* Current Sink (MPP) */ +#define QPNP_PIN_CS_OUT_5MA 0 +#define QPNP_PIN_CS_OUT_10MA 1 +#define QPNP_PIN_CS_OUT_15MA 2 +#define QPNP_PIN_CS_OUT_20MA 3 +#define QPNP_PIN_CS_OUT_25MA 4 +#define QPNP_PIN_CS_OUT_30MA 5 +#define QPNP_PIN_CS_OUT_35MA 6 +#define QPNP_PIN_CS_OUT_40MA 7 + +/* ANALOG PASS SEL (GPIO LV/MV) */ +#define QPNP_PIN_APASS_SEL_ATEST1 0 +#define QPNP_PIN_APASS_SEL_ATEST2 1 +#define QPNP_PIN_APASS_SEL_ATEST3 2 +#define QPNP_PIN_APASS_SEL_ATEST4 3 + +/** + * struct qpnp_pin_cfg - structure to specify pin configurtion values + * @mode: indicates whether the pin should be input, output, or + * both for gpios. mpp pins also support bidirectional, + * analog in, analog out and current sink. This value + * should be of type QPNP_PIN_MODE_*. + * @output_type: indicates pin should be configured as CMOS or open + * drain. Should be of the type QPNP_PIN_OUT_BUF_*. This + * setting applies for gpios only. + * @invert: Invert the signal of the line - + * QPNP_PIN_INVERT_DISABLE or QPNP_PIN_INVERT_ENABLE. + * @pull: This parameter should be programmed to different values + * depending on whether it's GPIO or MPP. + * For GPIO, it indicates whether a pull up or pull down + * should be applied. If a pullup is required the + * current strength needs to be specified. + * Current values of 30uA, 1.5uA, 31.5uA, 1.5uA with 30uA + * boost are supported. This value should be one of + * the QPNP_PIN_GPIO_PULL_*. Note that the hardware ignores + * this configuration if the GPIO is not set to input or + * output open-drain mode. + * For MPP, it indicates whether a pullup should be + * applied for bidirectitional mode only. The hardware + * ignores the configuration when operating in other modes. + * This value should be one of the QPNP_PIN_MPP_PULL_*. + * @vin_sel: specifies the voltage level when the output is set to 1. + * For an input gpio specifies the voltage level at which + * the input is interpreted as a logical 1. + * @out_strength: the amount of current supplied for an output gpio, + * should be of the type QPNP_PIN_STRENGTH_*. + * @src_sel: select alternate function for the pin. Certain pins + * can be paired (shorted) with each other. Some pins + * can act as alternate functions. In the context of + * gpio, this acts as a source select. For mpps, + * this is an enable select. + * This parameter should be of type QPNP_PIN_SEL_*. + * @master_en: QPNP_PIN_MASTER_ENABLE = Enable features within the + * pin block based on configurations. + * QPNP_PIN_MASTER_DISABLE = Completely disable the pin + * block and let the pin float with high impedance + * regardless of other settings. + * @aout_ref: Set the analog output reference. This parameter should + * be of type QPNP_PIN_AOUT_*. This parameter only applies + * to mpp pins. + * @ain_route: Set the source for analog input. This parameter + * should be of type QPNP_PIN_AIN_*. This parameter only + * applies to mpp pins. + * @cs_out: Set the the amount of current to sync in mA. This + * parameter should be of type QPNP_PIN_CS_OUT_*. This + * parameter only applies to mpp pins. + * @apass_sel: Set the ATEST line to which the signal is to be + * routed to. The parameter should be of type + * QPNP_PIN_APASS_SEL_*. This + * parameter only applies to GPIO LV/MV pins. + * @dtest_sel: Select the DTEST line to which the signal needs + * is routed to. The parameter should be of type + * QPNP_PIN_DIG_IN_CTL_*. The parameter applies + * to both gpio and mpp pins. + */ +struct qpnp_pin_cfg { + int mode; + int output_type; + int invert; + int pull; + int vin_sel; + int out_strength; + int src_sel; + int master_en; + int aout_ref; + int ain_route; + int cs_out; + int apass_sel; + int dtest_sel; +}; + +/** + * qpnp_pin_config - Apply pin configuration for Linux gpio + * @gpio: Linux gpio number to configure. + * @param: parameters to configure. + * + * This routine takes a Linux gpio number that corresponds with a + * PMIC pin and applies the configuration specified in 'param'. + * This gpio number can be ascertained by of_get_gpio_flags() or + * the qpnp_pin_map_gpio() API. + */ +int qpnp_pin_config(int gpio, struct qpnp_pin_cfg *param); + +/** + * qpnp_pin_map - Obtain Linux GPIO number from device spec + * @name: Name assigned by the 'label' binding for the primary node. + * @pmic_pin: PMIC pin number to lookup. + * + * This routine is used in legacy configurations that do not support + * Device Tree. If you are using Device Tree, you should not use this. + * For such cases, use of_get_gpio() or friends instead. + */ +int qpnp_pin_map(const char *name, uint32_t pmic_pin); diff --git a/include/linux/qpnp/pwm.h b/include/linux/qpnp/pwm.h new file mode 100644 index 000000000000..782b7849da4a --- /dev/null +++ b/include/linux/qpnp/pwm.h @@ -0,0 +1,227 @@ +/* Copyright (c) 2012-2016, 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 __QPNP_PWM_H__ +#define __QPNP_PWM_H__ + +#include <linux/pwm.h> + +/* usec: 19.2M, n=6, m=0, pre=2 */ +#define PM_PWM_PERIOD_MIN 7 +/* 1K, n=9, m=7, pre=6 */ +#define PM_PWM_PERIOD_MAX (384 * USEC_PER_SEC) +#define PM_PWM_LUT_RAMP_STEP_TIME_MAX 499 +#define PM_PWM_MAX_PAUSE_CNT 8191 +/* + * Formula from HSID, + * pause_time (hi/lo) = (pause_code - 1)*(duty_ms) + */ +#define PM_PWM_LUT_PAUSE_MAX \ + ((PM_PWM_MAX_PAUSE_CNT - 1) * PM_PWM_LUT_RAMP_STEP_TIME_MAX) /* ms */ + +/* Flags for Look Up Table */ +#define PM_PWM_LUT_LOOP 0x01 +#define PM_PWM_LUT_RAMP_UP 0x02 +#define PM_PWM_LUT_REVERSE 0x04 +#define PM_PWM_LUT_PAUSE_HI_EN 0x08 +#define PM_PWM_LUT_PAUSE_LO_EN 0x10 + +#define PM_PWM_LUT_NO_TABLE 0x20 +#define PM_PWM_LUT_USE_RAW_VALUE 0x40 + +/* + * PWM frequency/period control + * + * PWM Frequency = ClockFrequency / (N * T) + * or + * PWM Period = Clock Period * (N * T) + * where + * N = 2^9 or 2^6 for 9-bit or 6-bit PWM size + * T = Pre-divide * 2^m, m = 0..7 (exponent) + */ + +/* + * enum pm_pwm_size - PWM bit mode selection + * %PM_PWM_SIZE_6BIT - Select 6 bit mode; 64 levels + * %PM_PWM_SIZE_9BIT - Select 9 bit mode; 512 levels + */ +enum pm_pwm_size { + PM_PWM_SIZE_6BIT = 6, + PM_PWM_SIZE_9BIT = 9, +}; + +/* + * enum pm_pwm_clk - PWM clock selection + * %PM_PWM_CLK_1KHZ - 1KHz clock + * %PM_PWM_CLK_32KHZ - 32KHz clock + * %PM_PWM_CLK_19P2MHZ - 19.2MHz clock + * Note: Here 1KHz = 1024Hz + */ +enum pm_pwm_clk { + PM_PWM_CLK_1KHZ, + PM_PWM_CLK_32KHZ, + PM_PWM_CLK_19P2MHZ, +}; + +/* PWM pre-divider selection */ +enum pm_pwm_pre_div { + PM_PWM_PDIV_2, + PM_PWM_PDIV_3, + PM_PWM_PDIV_5, + PM_PWM_PDIV_6, +}; + +/* + * struct pwm_period_config - PWM period configuration + * @pwm_size: enum pm_pwm_size + * @clk: enum pm_pwm_clk + * @pre_div: enum pm_pwm_pre_div + * @pre_div_exp: exponent of 2 as part of pre-divider: 0..7 + */ +struct pwm_period_config { + enum pm_pwm_size pwm_size; + enum pm_pwm_clk clk; + enum pm_pwm_pre_div pre_div; + int pre_div_exp; +}; + +/* + * struct pwm_duty_cycles - PWM duty cycle info + * duty_pcts - pointer to an array of duty percentage for a pwm period + * num_duty_pcts - total entries in duty_pcts array + * duty_ms - duty cycle time in ms + * start_idx - index in the LUT + */ +struct pwm_duty_cycles { + int *duty_pcts; + int num_duty_pcts; + int duty_ms; + int start_idx; +}; + +/* + * enum pm_pwm_mode - PWM mode selection + * %PM_PWM_MODE_PWM - Select PWM mode + * %PM_PWM_MODE_LPG - Select LPG mode + */ +enum pm_pwm_mode { + PM_PWM_MODE_PWM, + PM_PWM_MODE_LPG, +}; + +/* + * lut_params: Lookup table (LUT) parameters + * @start_idx: start index in lookup table from 0 to MAX-1 + * @idx_len: number of index + * @pause_lo: pause time in millisecond at low index + * @pause_hi: pause time in millisecond at high index + * @ramp_step_ms: time before loading next LUT pattern in millisecond + * @flags: control flags + */ +struct lut_params { + int start_idx; + int idx_len; + int lut_pause_hi; + int lut_pause_lo; + int ramp_step_ms; + int flags; +}; + +#if IS_ENABLED(CONFIG_PWM_QPNP) +int pwm_config_period(struct pwm_device *pwm, + struct pwm_period_config *pwm_p); + +int pwm_config_pwm_value(struct pwm_device *pwm, int pwm_value); + + +int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode); + + +int pwm_lut_config(struct pwm_device *pwm, int period_us, + int duty_pct[], struct lut_params lut_params); + +/* + * support microsecond level configuration + */ +int pwm_config_us(struct pwm_device *pwm, + int duty_us, int period_us); + +/* + * synchronized enable of multiple pwm instances + */ +int pwm_enable_synchronized(struct pwm_device **pwms, size_t num); + +#else +static inline int pwm_config_period(struct pwm_device *pwm, + struct pwm_period_config *pwm_p) +{ + return -EINVAL; +} + +static inline int pwm_config_pwm_value(struct pwm_device *pwm, int pwm_value) +{ + return -EINVAL; +} + +static inline int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode) +{ + return -EINVAL; +} + +static inline int pwm_lut_config(struct pwm_device *pwm, int period_us, + int duty_pct[], struct lut_params lut_params) +{ + return -EINVAL; +} + +static inline int pwm_config_us(struct pwm_device *pwm, + int duty_us, int period_us) +{ + return -EINVAL; +} + +static inline int pwm_enable_synchronized(struct pwm_device **pwms, size_t num) +{ + return -EINVAL; +} +#endif + +/* Standard APIs supported */ +/* + * pwm_request - request a PWM device + * @pwm_id: PWM id or channel + * @label: the label to identify the user + */ + +/* + * pwm_free - free a PWM device + * @pwm: the PWM device + */ + +/* + * pwm_config - change a PWM device configuration + * @pwm: the PWM device + * @period_ns: period in nanosecond + * @duty_ns: duty cycle in nanosecond + */ + +/* + * pwm_enable - start a PWM output toggling + * @pwm: the PWM device + */ + +/* + * pwm_disable - stop a PWM output toggling + * @pwm: the PWM device + */ + +#endif /* __QPNP_PWM_H__ */ diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h new file mode 100644 index 000000000000..af25f0c01369 --- /dev/null +++ b/include/linux/qpnp/qpnp-adc.h @@ -0,0 +1,2290 @@ +/* + * Copyright (c) 2012-2016, 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. + */ +/* + * Qualcomm PMIC QPNP ADC driver header file + * + */ + +#ifndef __QPNP_ADC_H +#define __QPNP_ADC_H + +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/qpnp/qpnp-revid.h> +#include <linux/regulator/consumer.h> +/** + * enum qpnp_vadc_channels - QPNP AMUX arbiter channels + */ +enum qpnp_vadc_channels { + USBIN = 0, + DCIN, + VCHG_SNS, + SPARE1_03, + USB_ID_MV, + VCOIN, + VBAT_SNS, + VSYS, + DIE_TEMP, + REF_625MV, + REF_125V, + CHG_TEMP, + SPARE1, + SPARE2, + GND_REF, + VDD_VADC, + P_MUX1_1_1, + P_MUX2_1_1, + P_MUX3_1_1, + P_MUX4_1_1, + P_MUX5_1_1, + P_MUX6_1_1, + P_MUX7_1_1, + P_MUX8_1_1, + P_MUX9_1_1, + P_MUX10_1_1, + P_MUX11_1_1, + P_MUX12_1_1, + P_MUX13_1_1, + P_MUX14_1_1, + P_MUX15_1_1, + P_MUX16_1_1, + P_MUX1_1_3, + P_MUX2_1_3, + P_MUX3_1_3, + P_MUX4_1_3, + P_MUX5_1_3, + P_MUX6_1_3, + P_MUX7_1_3, + P_MUX8_1_3, + P_MUX9_1_3, + P_MUX10_1_3, + P_MUX11_1_3, + P_MUX12_1_3, + P_MUX13_1_3, + P_MUX14_1_3, + P_MUX15_1_3, + P_MUX16_1_3, + LR_MUX1_BATT_THERM, + LR_MUX2_BAT_ID, + LR_MUX3_XO_THERM, + LR_MUX4_AMUX_THM1, + LR_MUX5_AMUX_THM2, + LR_MUX6_AMUX_THM3, + LR_MUX7_HW_ID, + LR_MUX8_AMUX_THM4, + LR_MUX9_AMUX_THM5, + LR_MUX10_USB_ID_LV, + AMUX_PU1, + AMUX_PU2, + LR_MUX3_BUF_XO_THERM_BUF, + LR_MUX1_PU1_BAT_THERM = 112, + LR_MUX2_PU1_BAT_ID = 113, + LR_MUX3_PU1_XO_THERM = 114, + LR_MUX4_PU1_AMUX_THM1 = 115, + LR_MUX5_PU1_AMUX_THM2 = 116, + LR_MUX6_PU1_AMUX_THM3 = 117, + LR_MUX7_PU1_AMUX_HW_ID = 118, + LR_MUX8_PU1_AMUX_THM4 = 119, + LR_MUX9_PU1_AMUX_THM5 = 120, + LR_MUX10_PU1_AMUX_USB_ID_LV = 121, + LR_MUX3_BUF_PU1_XO_THERM_BUF = 124, + LR_MUX1_PU2_BAT_THERM = 176, + LR_MUX2_PU2_BAT_ID = 177, + LR_MUX3_PU2_XO_THERM = 178, + LR_MUX4_PU2_AMUX_THM1 = 179, + LR_MUX5_PU2_AMUX_THM2 = 180, + LR_MUX6_PU2_AMUX_THM3 = 181, + LR_MUX7_PU2_AMUX_HW_ID = 182, + LR_MUX8_PU2_AMUX_THM4 = 183, + LR_MUX9_PU2_AMUX_THM5 = 184, + LR_MUX10_PU2_AMUX_USB_ID_LV = 185, + LR_MUX3_BUF_PU2_XO_THERM_BUF = 188, + LR_MUX1_PU1_PU2_BAT_THERM = 240, + LR_MUX2_PU1_PU2_BAT_ID = 241, + LR_MUX3_PU1_PU2_XO_THERM = 242, + LR_MUX4_PU1_PU2_AMUX_THM1 = 243, + LR_MUX5_PU1_PU2_AMUX_THM2 = 244, + LR_MUX6_PU1_PU2_AMUX_THM3 = 245, + LR_MUX7_PU1_PU2_AMUX_HW_ID = 246, + LR_MUX8_PU1_PU2_AMUX_THM4 = 247, + LR_MUX9_PU1_PU2_AMUX_THM5 = 248, + LR_MUX10_PU1_PU2_AMUX_USB_ID_LV = 249, + LR_MUX3_BUF_PU1_PU2_XO_THERM_BUF = 252, + ALL_OFF = 255, + ADC_MAX_NUM = 0xffff, + + /* Channel listing for refreshed VADC in hex format */ + VADC_VREF_GND = 0, + VADC_CALIB_VREF_1P25 = 1, + VADC_CALIB_VREF = 2, + VADC_CALIB_VREF_1_DIV_3 = 0x82, + VADC_VPH_PWR = 0x83, + VADC_VBAT_SNS = 0x84, + VADC_VCOIN = 0x85, + VADC_DIE_TEMP = 6, + VADC_CHG_TEMP = 7, + VADC_USB_IN = 8, + VADC_IREG_FB = 9, + /* External input connection */ + VADC_BAT_THERM = 0xa, + VADC_BAT_ID = 0xb, + VADC_XO_THERM = 0xc, + VADC_AMUX_THM1 = 0xd, + VADC_AMUX_THM2 = 0xe, + VADC_AMUX_THM3 = 0xf, + VADC_AMUX_THM4 = 0x10, + VADC_AMUX_THM5 = 0x11, + VADC_AMUX1_GPIO = 0x12, + VADC_AMUX2_GPIO = 0x13, + VADC_AMUX3_GPIO = 0x14, + VADC_AMUX4_GPIO = 0x15, + VADC_AMUX5_GPIO = 0x16, + VADC_AMUX6_GPIO = 0x17, + VADC_AMUX7_GPIO = 0x18, + VADC_AMUX8_GPIO = 0x19, + VADC_ATEST1 = 0x1a, + VADC_ATEST2 = 0x1b, + VADC_ATEST3 = 0x1c, + VADC_ATEST4 = 0x1d, + VADC_OFF = 0xff, + /* PU1 is 30K pull up */ + VADC_BAT_THERM_PU1 = 0x2a, + VADC_BAT_ID_PU1 = 0x2b, + VADC_XO_THERM_PU1 = 0x2c, + VADC_AMUX_THM1_PU1 = 0x2d, + VADC_AMUX_THM2_PU1 = 0x2e, + VADC_AMUX_THM3_PU1 = 0x2f, + VADC_AMUX_THM4_PU1 = 0x30, + VADC_AMUX_THM5_PU1 = 0x31, + VADC_AMUX1_GPIO_PU1 = 0x32, + VADC_AMUX2_GPIO_PU1 = 0x33, + VADC_AMUX3_GPIO_PU1 = 0x34, + VADC_AMUX4_GPIO_PU1 = 0x35, + VADC_AMUX5_GPIO_PU1 = 0x36, + VADC_AMUX6_GPIO_PU1 = 0x37, + VADC_AMUX7_GPIO_PU1 = 0x38, + VADC_AMUX8_GPIO_PU1 = 0x39, + /* PU2 is 100K pull up */ + VADC_BAT_THERM_PU2 = 0x4a, + VADC_BAT_ID_PU2 = 0x4b, + VADC_XO_THERM_PU2 = 0x4c, + VADC_AMUX_THM1_PU2 = 0x4d, + VADC_AMUX_THM2_PU2 = 0x4e, + VADC_AMUX_THM3_PU2 = 0x4f, + VADC_AMUX_THM4_PU2 = 0x50, + VADC_AMUX_THM5_PU2 = 0x51, + VADC_AMUX1_GPIO_PU2 = 0x52, + VADC_AMUX2_GPIO_PU2 = 0x53, + VADC_AMUX3_GPIO_PU2 = 0x54, + VADC_AMUX4_GPIO_PU2 = 0x55, + VADC_AMUX5_GPIO_PU2 = 0x56, + VADC_AMUX6_GPIO_PU2 = 0x57, + VADC_AMUX7_GPIO_PU2 = 0x58, + VADC_AMUX8_GPIO_PU2 = 0x59, + /* PU3 is 400K pull up */ + VADC_BAT_THERM_PU3 = 0x6a, + VADC_BAT_ID_PU3 = 0x6b, + VADC_XO_THERM_PU3 = 0x6c, + VADC_AMUX_THM1_PU3 = 0x6d, + VADC_AMUX_THM2_PU3 = 0x6e, + VADC_AMUX_THM3_PU3 = 0x6f, + VADC_AMUX_THM4_PU3 = 0x70, + VADC_AMUX_THM5_PU3 = 0x71, + VADC_AMUX1_GPIO_PU3 = 0x72, + VADC_AMUX2_GPIO_PU3 = 0x73, + VADC_AMUX3_GPIO_PU3 = 0x74, + VADC_AMUX4_GPIO_PU3 = 0x75, + VADC_AMUX5_GPIO_PU3 = 0x76, + VADC_AMUX6_GPIO_PU3 = 0x77, + VADC_AMUX7_GPIO_PU3 = 0x78, + VADC_AMUX8_GPIO_PU3 = 0x79, + /* External input connection with 1/3 div */ + VADC_AMUX1_GPIO_DIV_3 = 0x92, + VADC_AMUX2_GPIO_DIV_3 = 0x93, + VADC_AMUX3_GPIO_DIV_3 = 0x94, + VADC_AMUX4_GPIO_DIV_3 = 0x95, + VADC_AMUX5_GPIO_DIV_3 = 0x96, + VADC_AMUX6_GPIO_DIV_3 = 0x97, + VADC_AMUX7_GPIO_DIV_3 = 0x98, + VADC_AMUX8_GPIO_DIV_3 = 0x99, + VADC_ATEST1_DIV_3 = 0x9a, + VADC_ATEST2_DIV_3 = 0x9b, + VADC_ATEST3_DIV_3 = 0x9c, + VADC_ATEST4_DIV_3 = 0x9d, + VADC_REFRESH_MAX_NUM = 0xffff, +}; + +/** + * enum qpnp_iadc_channels - QPNP IADC channel list + */ +enum qpnp_iadc_channels { + INTERNAL_RSENSE = 0, + EXTERNAL_RSENSE, + ALT_LEAD_PAIR, + GAIN_CALIBRATION_17P857MV, + OFFSET_CALIBRATION_SHORT_CADC_LEADS, + OFFSET_CALIBRATION_CSP_CSN, + OFFSET_CALIBRATION_CSP2_CSN2, + IADC_MUX_NUM, +}; + +#define QPNP_ADC_625_UV 625000 +#define QPNP_ADC_HWMON_NAME_LENGTH 64 +#define QPNP_MAX_PROP_NAME_LEN 32 +#define QPNP_THERMALNODE_NAME_LENGTH 25 +#define QPNP_ADC_1P25_UV 1250000 + +/* Structure device for qpnp vadc */ +struct qpnp_vadc_chip; + +/* Structure device for qpnp iadc */ +struct qpnp_iadc_chip; + +/* Structure device for qpnp adc tm */ +struct qpnp_adc_tm_chip; + +/** + * enum qpnp_adc_clk_type - Clock rate supported. + * %CLK_TYPE1: 2P4MHZ + * %CLK_TYPE2: 4P8MHZ + * %CLK_TYPE3: 9P6MHZ + * %CLK_TYPE4: 19P2MHZ + * %CLK_NONE: Do not use this Clk type. + * + * The Clock rate is specific to each channel of the QPNP ADC arbiter. + */ +enum qpnp_adc_clk_type { + CLK_TYPE1 = 0, + CLK_TYPE2, + CLK_TYPE3, + CLK_TYPE4, + CLK_NONE, +}; + +/** + * enum qpnp_adc_decimation_type - Sampling rate supported. + * %DECIMATION_TYPE1: 512 + * %DECIMATION_TYPE2: 1K + * %DECIMATION_TYPE3: 2K + * %DECIMATION_TYPE4: 4k + * %DECIMATION_NONE: Do not use this Sampling type. + * + * The Sampling rate is specific to each channel of the QPNP ADC arbiter. + */ +enum qpnp_adc_decimation_type { + DECIMATION_TYPE1 = 0, + DECIMATION_TYPE2, + DECIMATION_TYPE3, + DECIMATION_TYPE4, + DECIMATION_NONE = 0xff, + + ADC_HC_DEC_RATIO_256 = 0, + ADC_HC_DEC_RATIO_512 = 1, + ADC_HC_DEC_RATIO_1024 = 2, + ADC_HC_DEC_RATIO_NONE = 0xff, +}; + +/** + * enum qpnp_adc_calib_type - QPNP ADC Calibration type. + * %ADC_CALIB_ABSOLUTE: Use 625mV and 1.25V reference channels. + * %ADC_CALIB_RATIOMETRIC: Use reference Voltage/GND. + * %ADC_CALIB_CONFIG_NONE: Do not use this calibration type. + * + * enum qpnp_adc_cal_sel - Selects the calibration type that is applied + * on the corresponding channel measurement after + * the ADC data is read. + * %ADC_HC_NO_CAL : To obtain raw, uncalibrated data on qpnp-vadc-hc type. + * %ADC_HC_RATIO_CAL : Applies ratiometric calibration. Note the calibration + * values stored in the CAL peripheral for VADC_VREF and + * VREF_1P25 already have GND_REF value removed. Used + * only with qpnp-vadc-hc type of VADC. + * %ADC_HC_ABS_CAL : Applies absolute calibration. Note the calibration + * values stored in the CAL peripheral for VADC_VREF and + * VREF_1P25 already have GND_REF value removed. Used + * only with qpnp-vadc-hc type of VADC. + * + * Use the input reference voltage depending on the calibration type + * to calcluate the offset and gain parameters. The calibration is + * specific to each channel of the QPNP ADC. + */ +enum qpnp_adc_calib_type { + CALIB_ABSOLUTE = 0, + CALIB_RATIOMETRIC, + CALIB_NONE, + + ADC_HC_NO_CAL = 0, + ADC_HC_RATIO_CAL = 1, + ADC_HC_ABS_CAL = 2, + ADC_HC_CAL_SEL_NONE, +}; + +/** + * enum qpnp_adc_channel_scaling_param - pre-scaling AMUX ratio. + * %CHAN_PATH_SCALING0: ratio of {1, 1} + * %CHAN_PATH_SCALING1: ratio of {1, 3} + * %CHAN_PATH_SCALING2: ratio of {1, 4} + * %CHAN_PATH_SCALING3: ratio of {1, 6} + * %CHAN_PATH_SCALING4: ratio of {1, 20} + * %CHAN_PATH_SCALING5: ratio of {1, 8} + * %CHAN_PATH_SCALING6: ratio of {10, 81} The actual ratio is (1/8.1). + * %CHAN_PATH_SCALING7: ratio of {1, 10} + * %CHAN_PATH_NONE: Do not use this pre-scaling ratio type. + * + * The pre-scaling is applied for signals to be within the voltage range + * of the ADC. + */ +enum qpnp_adc_channel_scaling_param { + PATH_SCALING0 = 0, + PATH_SCALING1, + PATH_SCALING2, + PATH_SCALING3, + PATH_SCALING4, + PATH_SCALING5, + PATH_SCALING6, + PATH_SCALING7, + PATH_SCALING_NONE, +}; + +/** + * enum qpnp_adc_scale_fn_type - Scaling function for pm8941 pre calibrated + * digital data relative to ADC reference. + * %SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV). + * %SCALE_BATT_THERM: Conversion to temperature(decidegC) based on btm + * parameters. + * %SCALE_THERM_100K_PULLUP: Returns temperature in degC. + * Uses a mapping table with 100K pullup. + * %SCALE_PMIC_THERM: Returns result in milli degree's Centigrade. + * %SCALE_XOTHERM: Returns XO thermistor voltage in degree's Centigrade. + * %SCALE_THERM_150K_PULLUP: Returns temperature in degC. + * Uses a mapping table with 150K pullup. + * %SCALE_QRD_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters. + * %SCALE_QRD_SKUAA_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters for SKUAA. + * %SCALE_SMB_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters for SMB. + * %SCALE_QRD_SKUG_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters for SKUG. + * %SCALE_QRD_SKUH_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters for SKUH + * %SCALE_QRD_SKUT1_BATT_THERM: Conversion to temperature(decidegC) based on + * btm parameters for SKUT1 + * %SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp + * %SCALE_NONE: Do not use this scaling type. + */ +enum qpnp_adc_scale_fn_type { + SCALE_DEFAULT = 0, + SCALE_BATT_THERM, + SCALE_THERM_100K_PULLUP, + SCALE_PMIC_THERM, + SCALE_XOTHERM, + SCALE_THERM_150K_PULLUP, + SCALE_QRD_BATT_THERM, + SCALE_QRD_SKUAA_BATT_THERM, + SCALE_SMB_BATT_THERM, + SCALE_QRD_SKUG_BATT_THERM, + SCALE_QRD_SKUH_BATT_THERM, + SCALE_NCP_03WF683_THERM, + SCALE_QRD_SKUT1_BATT_THERM, + SCALE_PMI_CHG_TEMP = 16, + SCALE_NONE, +}; + +/** + * enum qpnp_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 qpnp_adc_tm_rscale_fn_type { + SCALE_R_VBATT = 0, + SCALE_RBATT_THERM, + SCALE_R_USB_ID, + SCALE_RPMIC_THERM, + SCALE_R_SMB_BATT_THERM, + SCALE_R_ABSOLUTE, + SCALE_QRD_SKUH_RBATT_THERM, + SCALE_QRD_SKUT1_RBATT_THERM, + SCALE_RSCALE_NONE, +}; + +/** + * enum qpnp_vadc_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. The order below should match the one in the + * driver for qpnp_adc_scale_fn[]. + */ +enum qpnp_vadc_rscale_fn_type { + SCALE_RVADC_ABSOLUTE = 0, + SCALE_RVADC_SCALE_NONE, +}; + +/** + * enum qpnp_adc_fast_avg_ctl - Provides ability to obtain single result + * from the ADC that is an average of multiple measurement + * samples. Select number of samples for use in fast + * average mode (i.e. 2 ^ value). + * %ADC_FAST_AVG_SAMPLE_1: 0x0 = 1 + * %ADC_FAST_AVG_SAMPLE_2: 0x1 = 2 + * %ADC_FAST_AVG_SAMPLE_4: 0x2 = 4 + * %ADC_FAST_AVG_SAMPLE_8: 0x3 = 8 + * %ADC_FAST_AVG_SAMPLE_16: 0x4 = 16 + * %ADC_FAST_AVG_SAMPLE_32: 0x5 = 32 + * %ADC_FAST_AVG_SAMPLE_64: 0x6 = 64 + * %ADC_FAST_AVG_SAMPLE_128: 0x7 = 128 + * %ADC_FAST_AVG_SAMPLE_256: 0x8 = 256 + * %ADC_FAST_AVG_SAMPLE_512: 0x9 = 512 + */ +enum qpnp_adc_fast_avg_ctl { + ADC_FAST_AVG_SAMPLE_1 = 0, + ADC_FAST_AVG_SAMPLE_2, + ADC_FAST_AVG_SAMPLE_4, + ADC_FAST_AVG_SAMPLE_8, + ADC_FAST_AVG_SAMPLE_16, + ADC_FAST_AVG_SAMPLE_32, + ADC_FAST_AVG_SAMPLE_64, + ADC_FAST_AVG_SAMPLE_128, + ADC_FAST_AVG_SAMPLE_256, + ADC_FAST_AVG_SAMPLE_512, + ADC_FAST_AVG_SAMPLE_NONE, +}; + +/** + * enum qpnp_adc_hw_settle_time - Time between AMUX getting configured and + * the ADC starting conversion. Delay = 100us * value for + * value < 11 and 2ms * (value - 10) otherwise. + * %ADC_CHANNEL_HW_SETTLE_DELAY_0US: 0us + * %ADC_CHANNEL_HW_SETTLE_DELAY_100US: 100us + * %ADC_CHANNEL_HW_SETTLE_DELAY_200US: 200us + * %ADC_CHANNEL_HW_SETTLE_DELAY_300US: 300us + * %ADC_CHANNEL_HW_SETTLE_DELAY_400US: 400us + * %ADC_CHANNEL_HW_SETTLE_DELAY_500US: 500us + * %ADC_CHANNEL_HW_SETTLE_DELAY_600US: 600us + * %ADC_CHANNEL_HW_SETTLE_DELAY_700US: 700us + * %ADC_CHANNEL_HW_SETTLE_DELAY_800US: 800us + * %ADC_CHANNEL_HW_SETTLE_DELAY_900US: 900us + * %ADC_CHANNEL_HW_SETTLE_DELAY_1MS: 1ms + * %ADC_CHANNEL_HW_SETTLE_DELAY_2MS: 2ms + * %ADC_CHANNEL_HW_SETTLE_DELAY_4MS: 4ms + * %ADC_CHANNEL_HW_SETTLE_DELAY_6MS: 6ms + * %ADC_CHANNEL_HW_SETTLE_DELAY_8MS: 8ms + * %ADC_CHANNEL_HW_SETTLE_DELAY_10MS: 10ms + * %ADC_CHANNEL_HW_SETTLE_NONE + */ +enum qpnp_adc_hw_settle_time { + ADC_CHANNEL_HW_SETTLE_DELAY_0US = 0, + ADC_CHANNEL_HW_SETTLE_DELAY_100US, + ADC_CHANNEL_HW_SETTLE_DELAY_2000US, + ADC_CHANNEL_HW_SETTLE_DELAY_300US, + ADC_CHANNEL_HW_SETTLE_DELAY_400US, + ADC_CHANNEL_HW_SETTLE_DELAY_500US, + ADC_CHANNEL_HW_SETTLE_DELAY_600US, + ADC_CHANNEL_HW_SETTLE_DELAY_700US, + ADC_CHANNEL_HW_SETTLE_DELAY_800US, + ADC_CHANNEL_HW_SETTLE_DELAY_900US, + ADC_CHANNEL_HW_SETTLE_DELAY_1MS, + ADC_CHANNEL_HW_SETTLE_DELAY_2MS, + ADC_CHANNEL_HW_SETTLE_DELAY_4MS, + ADC_CHANNEL_HW_SETTLE_DELAY_6MS, + ADC_CHANNEL_HW_SETTLE_DELAY_8MS, + ADC_CHANNEL_HW_SETTLE_DELAY_10MS, + ADC_CHANNEL_HW_SETTLE_NONE, +}; + +/** + * enum qpnp_adc_dec_ratio_sel - Selects the decimation ratio of the ADC. + * Support values are 256, 512 and 1024. + */ +enum qpnp_vadc_dec_ratio_sel { + ADC_DEC_RATIO_256 = 0, + ADC_DEC_RATIO_512, + ADC_DEC_RATIO_1024, + ADC_DEC_RATIO_NONE, +}; + +/** + * enum qpnp_adc_cal_sel - Selects the calibration type that is applied + * on the corresponding channel measurement after + * the ADC data is read. + * %ADC_NO_CAL : To obtain raw, uncalibrated data. + * %ADC_RATIO_CAL : Applies ratiometric calibration. Note the calibration + * values stored in the CAL peripheral for VADC_VREF and + * VREF_1P25 already have GND_REF value removed. + * %ADC_ABS_CAL : Applies absolute calibration. Note the calibration + * values stored in the CAL peripheral for VADC_VREF and + * VREF_1P25 already have GND_REF value removed. + */ + +/** + * enum qpnp_adc_cal_val - Selects if the calibration values applied + * are the ones when collected on a timer interval + * or if an immediate calibration needs to be forced. + * %ADC_TIMER_CAL : Uses calibration value collected on the timer interval. + * %ADC_NEW_CAL : Forces an immediate calibration. Use only when necessary + * since it forces 3 calibration measurements in addition to + * the channel measurement. For most measurement, using + * calibration based on the timer interval is sufficient. + */ +enum qpnp_adc_cal_val { + ADC_TIMER_CAL = 0, + ADC_NEW_CAL, + ADC_CAL_VAL_NONE, +}; + +/** + * enum qpnp_vadc_mode_sel - Selects the basic mode of operation. + * - The normal mode is used for single measurement. + * - The Conversion sequencer is used to trigger an + * ADC read when a HW trigger is selected. + * - The measurement interval performs a single or + * continous measurement at a specified interval/delay. + * %ADC_OP_NORMAL_MODE : Normal mode used for single measurement. + * %ADC_OP_CONVERSION_SEQUENCER : Conversion sequencer used to trigger + * an ADC read on a HW supported trigger. + * Refer to enum qpnp_vadc_trigger for + * supported HW triggers. + * %ADC_OP_MEASUREMENT_INTERVAL : The measurement interval performs a + * single or continous measurement after a specified delay. + * For delay look at qpnp_adc_meas_timer. + */ +enum qpnp_vadc_mode_sel { + ADC_OP_NORMAL_MODE = 0, + ADC_OP_CONVERSION_SEQUENCER, + ADC_OP_MEASUREMENT_INTERVAL, + ADC_OP_MODE_NONE, +}; + +/** + * enum qpnp_vadc_trigger - Select the HW trigger to be used while + * measuring the ADC reading. + * %ADC_GSM_PA_ON : GSM power amplifier on. + * %ADC_TX_GTR_THRES : Transmit power greater than threshold. + * %ADC_CAMERA_FLASH_RAMP : Flash ramp up done. + * %ADC_DTEST : DTEST. + */ +enum qpnp_vadc_trigger { + ADC_GSM_PA_ON = 0, + ADC_TX_GTR_THRES, + ADC_CAMERA_FLASH_RAMP, + ADC_DTEST, + ADC_SEQ_NONE, +}; + +/** + * enum qpnp_vadc_conv_seq_timeout - Select delay (0 to 15ms) from + * conversion request to triggering conversion sequencer + * hold off time. + */ +enum qpnp_vadc_conv_seq_timeout { + ADC_CONV_SEQ_TIMEOUT_0MS = 0, + ADC_CONV_SEQ_TIMEOUT_1MS, + ADC_CONV_SEQ_TIMEOUT_2MS, + ADC_CONV_SEQ_TIMEOUT_3MS, + ADC_CONV_SEQ_TIMEOUT_4MS, + ADC_CONV_SEQ_TIMEOUT_5MS, + ADC_CONV_SEQ_TIMEOUT_6MS, + ADC_CONV_SEQ_TIMEOUT_7MS, + ADC_CONV_SEQ_TIMEOUT_8MS, + ADC_CONV_SEQ_TIMEOUT_9MS, + ADC_CONV_SEQ_TIMEOUT_10MS, + ADC_CONV_SEQ_TIMEOUT_11MS, + ADC_CONV_SEQ_TIMEOUT_12MS, + ADC_CONV_SEQ_TIMEOUT_13MS, + ADC_CONV_SEQ_TIMEOUT_14MS, + ADC_CONV_SEQ_TIMEOUT_15MS, + ADC_CONV_SEQ_TIMEOUT_NONE, +}; + +/** + * enum qpnp_adc_conv_seq_holdoff - Select delay from conversion + * trigger signal (i.e. adc_conv_seq_trig) transition + * to ADC enable. Delay = 25us * (value + 1). + */ +enum qpnp_adc_conv_seq_holdoff { + ADC_SEQ_HOLD_25US = 0, + ADC_SEQ_HOLD_50US, + ADC_SEQ_HOLD_75US, + ADC_SEQ_HOLD_100US, + ADC_SEQ_HOLD_125US, + ADC_SEQ_HOLD_150US, + ADC_SEQ_HOLD_175US, + ADC_SEQ_HOLD_200US, + ADC_SEQ_HOLD_225US, + ADC_SEQ_HOLD_250US, + ADC_SEQ_HOLD_275US, + ADC_SEQ_HOLD_300US, + ADC_SEQ_HOLD_325US, + ADC_SEQ_HOLD_350US, + ADC_SEQ_HOLD_375US, + ADC_SEQ_HOLD_400US, + ADC_SEQ_HOLD_NONE, +}; + +/** + * enum qpnp_adc_conv_seq_state - Conversion sequencer operating state + * %ADC_CONV_SEQ_IDLE : Sequencer is in idle. + * %ADC_CONV_TRIG_RISE : Waiting for rising edge trigger. + * %ADC_CONV_TRIG_HOLDOFF : Waiting for rising trigger hold off time. + * %ADC_CONV_MEAS_RISE : Measuring selected ADC signal. + * %ADC_CONV_TRIG_FALL : Waiting for falling trigger edge. + * %ADC_CONV_FALL_HOLDOFF : Waiting for falling trigger hold off time. + * %ADC_CONV_MEAS_FALL : Measuring selected ADC signal. + * %ADC_CONV_ERROR : Aberrant Hardware problem. + */ +enum qpnp_adc_conv_seq_state { + ADC_CONV_SEQ_IDLE = 0, + ADC_CONV_TRIG_RISE, + ADC_CONV_TRIG_HOLDOFF, + ADC_CONV_MEAS_RISE, + ADC_CONV_TRIG_FALL, + ADC_CONV_FALL_HOLDOFF, + ADC_CONV_MEAS_FALL, + ADC_CONV_ERROR, + ADC_CONV_NONE, +}; + +/** + * enum qpnp_adc_meas_timer_1 - Selects the measurement interval time. + * If value = 0, use 0ms else use 2^(value + 4)/ 32768). + * The timer period is used by the USB_ID. Do not set a polling rate + * greater than 1 second on PMIC 2.0. The max polling rate on the PMIC 2.0 + * appears to be limited to 1 second. + * %ADC_MEAS_INTERVAL_0MS : 0ms + * %ADC_MEAS_INTERVAL_1P0MS : 1ms + * %ADC_MEAS_INTERVAL_2P0MS : 2ms + * %ADC_MEAS_INTERVAL_3P9MS : 3.9ms + * %ADC_MEAS_INTERVAL_7P8MS : 7.8ms + * %ADC_MEAS_INTERVAL_15P6MS : 15.6ms + * %ADC_MEAS_INTERVAL_31P3MS : 31.3ms + * %ADC_MEAS_INTERVAL_62P5MS : 62.5ms + * %ADC_MEAS_INTERVAL_125MS : 125ms + * %ADC_MEAS_INTERVAL_250MS : 250ms + * %ADC_MEAS_INTERVAL_500MS : 500ms + * %ADC_MEAS_INTERVAL_1S : 1seconds + * %ADC_MEAS_INTERVAL_2S : 2seconds + * %ADC_MEAS_INTERVAL_4S : 4seconds + * %ADC_MEAS_INTERVAL_8S : 8seconds + * %ADC_MEAS_INTERVAL_16S: 16seconds + */ +enum qpnp_adc_meas_timer_1 { + ADC_MEAS1_INTERVAL_0MS = 0, + ADC_MEAS1_INTERVAL_1P0MS, + ADC_MEAS1_INTERVAL_2P0MS, + ADC_MEAS1_INTERVAL_3P9MS, + ADC_MEAS1_INTERVAL_7P8MS, + ADC_MEAS1_INTERVAL_15P6MS, + ADC_MEAS1_INTERVAL_31P3MS, + ADC_MEAS1_INTERVAL_62P5MS, + ADC_MEAS1_INTERVAL_125MS, + ADC_MEAS1_INTERVAL_250MS, + ADC_MEAS1_INTERVAL_500MS, + ADC_MEAS1_INTERVAL_1S, + ADC_MEAS1_INTERVAL_2S, + ADC_MEAS1_INTERVAL_4S, + ADC_MEAS1_INTERVAL_8S, + ADC_MEAS1_INTERVAL_16S, + ADC_MEAS1_INTERVAL_NONE, +}; + +/** + * enum qpnp_adc_meas_timer_2 - Selects the measurement interval time. + * If value = 0, use 0ms else use 2^(value + 4)/ 32768). + * The timer period is used by the batt_therm. Do not set a polling rate + * greater than 1 second on PMIC 2.0. The max polling rate on the PMIC 2.0 + * appears to be limited to 1 second. + * %ADC_MEAS_INTERVAL_0MS : 0ms + * %ADC_MEAS_INTERVAL_100MS : 100ms + * %ADC_MEAS_INTERVAL_200MS : 200ms + * %ADC_MEAS_INTERVAL_300MS : 300ms + * %ADC_MEAS_INTERVAL_400MS : 400ms + * %ADC_MEAS_INTERVAL_500MS : 500ms + * %ADC_MEAS_INTERVAL_600MS : 600ms + * %ADC_MEAS_INTERVAL_700MS : 700ms + * %ADC_MEAS_INTERVAL_800MS : 800ms + * %ADC_MEAS_INTERVAL_900MS : 900ms + * %ADC_MEAS_INTERVAL_1S: 1seconds + * %ADC_MEAS_INTERVAL_1P1S: 1.1seconds + * %ADC_MEAS_INTERVAL_1P2S: 1.2seconds + * %ADC_MEAS_INTERVAL_1P3S: 1.3seconds + * %ADC_MEAS_INTERVAL_1P4S: 1.4seconds + * %ADC_MEAS_INTERVAL_1P5S: 1.5seconds + */ +enum qpnp_adc_meas_timer_2 { + ADC_MEAS2_INTERVAL_0MS = 0, + ADC_MEAS2_INTERVAL_100MS, + ADC_MEAS2_INTERVAL_200MS, + ADC_MEAS2_INTERVAL_300MS, + ADC_MEAS2_INTERVAL_400MS, + ADC_MEAS2_INTERVAL_500MS, + ADC_MEAS2_INTERVAL_600MS, + ADC_MEAS2_INTERVAL_700MS, + ADC_MEAS2_INTERVAL_800MS, + ADC_MEAS2_INTERVAL_900MS, + ADC_MEAS2_INTERVAL_1S, + ADC_MEAS2_INTERVAL_1P1S, + ADC_MEAS2_INTERVAL_1P2S, + ADC_MEAS2_INTERVAL_1P3S, + ADC_MEAS2_INTERVAL_1P4S, + ADC_MEAS2_INTERVAL_1P5S, + ADC_MEAS2_INTERVAL_NONE, +}; + +/** + * enum qpnp_adc_meas_timer_3 - Selects the measurement interval time. + * If value = 0, use 0ms else use 2^(value + 4)/ 32768). + * Do not set a polling rate greater than 1 second on PMIC 2.0. + * The max polling rate on the PMIC 2.0 appears to be limited to 1 second. + * %ADC_MEAS_INTERVAL_0MS : 0ms + * %ADC_MEAS_INTERVAL_1S : 1seconds + * %ADC_MEAS_INTERVAL_2S : 2seconds + * %ADC_MEAS_INTERVAL_3S : 3seconds + * %ADC_MEAS_INTERVAL_4S : 4seconds + * %ADC_MEAS_INTERVAL_5S : 5seconds + * %ADC_MEAS_INTERVAL_6S: 6seconds + * %ADC_MEAS_INTERVAL_7S : 7seconds + * %ADC_MEAS_INTERVAL_8S : 8seconds + * %ADC_MEAS_INTERVAL_9S : 9seconds + * %ADC_MEAS_INTERVAL_10S : 10seconds + * %ADC_MEAS_INTERVAL_11S : 11seconds + * %ADC_MEAS_INTERVAL_12S : 12seconds + * %ADC_MEAS_INTERVAL_13S : 13seconds + * %ADC_MEAS_INTERVAL_14S : 14seconds + * %ADC_MEAS_INTERVAL_15S : 15seconds + */ +enum qpnp_adc_meas_timer_3 { + ADC_MEAS3_INTERVAL_0S = 0, + ADC_MEAS3_INTERVAL_1S, + ADC_MEAS3_INTERVAL_2S, + ADC_MEAS3_INTERVAL_3S, + ADC_MEAS3_INTERVAL_4S, + ADC_MEAS3_INTERVAL_5S, + ADC_MEAS3_INTERVAL_6S, + ADC_MEAS3_INTERVAL_7S, + ADC_MEAS3_INTERVAL_8S, + ADC_MEAS3_INTERVAL_9S, + ADC_MEAS3_INTERVAL_10S, + ADC_MEAS3_INTERVAL_11S, + ADC_MEAS3_INTERVAL_12S, + ADC_MEAS3_INTERVAL_13S, + ADC_MEAS3_INTERVAL_14S, + ADC_MEAS3_INTERVAL_15S, + ADC_MEAS3_INTERVAL_NONE, +}; + +/** + * enum qpnp_adc_meas_timer_select - Selects the timer for which + * the appropriate polling frequency is set. + * %ADC_MEAS_TIMER_SELECT1 - Select this timer for measurement polling interval + * for 1 second. + * %ADC_MEAS_TIMER_SELECT2 - Select this timer for 500ms measurement interval. + * %ADC_MEAS_TIMER_SELECT3 - Select this timer for 5 second interval. + */ +enum qpnp_adc_meas_timer_select { + ADC_MEAS_TIMER_SELECT1 = 0, + ADC_MEAS_TIMER_SELECT2, + ADC_MEAS_TIMER_SELECT3, + ADC_MEAS_TIMER_NUM, +}; + +/** + * enum qpnp_adc_meas_interval_op_ctl - Select operating mode. + * %ADC_MEAS_INTERVAL_OP_SINGLE : Conduct single measurement at specified time + * delay. + * %ADC_MEAS_INTERVAL_OP_CONTINUOUS : Make measurements at measurement interval + * times. + */ +enum qpnp_adc_meas_interval_op_ctl { + ADC_MEAS_INTERVAL_OP_SINGLE = 0, + ADC_MEAS_INTERVAL_OP_CONTINUOUS, + ADC_MEAS_INTERVAL_OP_NONE, +}; + +/** + * Channel selection registers for each of the configurable measurements + * Channels allotment is set at device config for a channel. + * The USB_ID, BATT_THERM, PMIC_THERM and VBAT channels are used by the + * kernel space USB, Battery and IADC drivers. + * The other 3 channels are configurable for use by userspace clients. + */ +enum qpnp_adc_tm_channel_select { + QPNP_ADC_TM_M0_ADC_CH_SEL_CTL = 0x48, + QPNP_ADC_TM_M1_ADC_CH_SEL_CTL = 0x68, + QPNP_ADC_TM_M2_ADC_CH_SEL_CTL = 0x70, + QPNP_ADC_TM_M3_ADC_CH_SEL_CTL = 0x78, + QPNP_ADC_TM_M4_ADC_CH_SEL_CTL = 0x80, + QPNP_ADC_TM_M5_ADC_CH_SEL_CTL = 0x88, + QPNP_ADC_TM_M6_ADC_CH_SEL_CTL = 0x90, + QPNP_ADC_TM_M7_ADC_CH_SEL_CTL = 0x98, + QPNP_ADC_TM_CH_SELECT_NONE +}; + +/** + * Channel index for the corresponding index to qpnp_adc_tm_channel_selec + */ +enum qpnp_adc_tm_channel_num { + QPNP_ADC_TM_CHAN0 = 0, + QPNP_ADC_TM_CHAN1, + QPNP_ADC_TM_CHAN2, + QPNP_ADC_TM_CHAN3, + QPNP_ADC_TM_CHAN4, + QPNP_ADC_TM_CHAN5, + QPNP_ADC_TM_CHAN6, + QPNP_ADC_TM_CHAN7, + QPNP_ADC_TM_CHAN_NONE +}; + +enum qpnp_comp_scheme_type { + COMP_ID_GF = 0, + COMP_ID_SMIC, + COMP_ID_TSMC, + COMP_ID_NUM, +}; + +/** + * struct qpnp_adc_tm_config - Represent ADC Thermal Monitor configuration. + * @channel: ADC channel for which thermal monitoring is requested. + * @adc_code: The pre-calibrated digital output of a given ADC releative to the + * ADC reference. + * @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 qpnp_adc_tm_config { + int channel; + int adc_code; + int high_thr_temp; + int low_thr_temp; + int64_t high_thr_voltage; + int64_t low_thr_voltage; +}; + +/** + * enum qpnp_adc_tm_trip_type - Type for setting high/low temperature/voltage. + * %ADC_TM_TRIP_HIGH_WARM: Setting high temperature. Note that high temperature + * corresponds to low voltage. Driver handles this case + * appropriately to set high/low thresholds for voltage. + * threshold. + * %ADC_TM_TRIP_LOW_COOL: Setting low temperature. + */ +enum qpnp_adc_tm_trip_type { + ADC_TM_TRIP_HIGH_WARM = 0, + ADC_TM_TRIP_LOW_COOL, + ADC_TM_TRIP_NUM, +}; + +#define ADC_TM_WRITABLE_TRIPS_MASK ((1 << ADC_TM_TRIP_NUM) - 1) + +/** + * enum qpnp_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 qpnp_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 qpnp_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 qpnp_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 qpnp_adc_tm_btm_param - Represent Battery temperature threshold + * monitoring configuration. + * @high_temp: High temperature threshold for which notification is requested. + * @low_temp: Low temperature threshold for which notification is requested. + * @high_thr_voltage: High voltage for which notification is requested. + * @low_thr_voltage: Low voltage for which notification is requested. + * @adc_tm_hc: Represents the refreshed BTM register design. + * @state_request: Enable/disable the corresponding high and low temperature + * thresholds. + * @timer_interval1: Select polling rate from qpnp_adc_meas_timer_1 type. + * @timer_interval2: Select polling rate from qpnp_adc_meas_timer_2 type. + * @timer_interval3: Select polling rate from qpnp_adc_meas_timer_3 type. + * @btmid_ctx: A context of void type. + * @threshold_notification: Notification callback once threshold are crossed. + * units to be used for High/Low temperature and voltage notification - + * This depends on the clients usage. Check the rscaling function + * for the appropriate channel nodes. + * @Batt therm clients temperature units is decidegreesCentigrate. + * @USB_ID inputs the voltage units in milli-volts. + * @PA_THERM inputs the units in degC. + * @PMIC_THERM inputs the units in millidegC. + */ +struct qpnp_adc_tm_btm_param { + int32_t high_temp; + int32_t low_temp; + int32_t high_thr; + int32_t low_thr; + int32_t gain_num; + int32_t gain_den; + bool adc_tm_hc; + enum qpnp_vadc_channels channel; + enum qpnp_state_request state_request; + enum qpnp_adc_meas_timer_1 timer_interval; + enum qpnp_adc_meas_timer_2 timer_interval2; + enum qpnp_adc_meas_timer_3 timer_interval3; + void *btm_ctx; + void (*threshold_notification)(enum qpnp_tm_state state, + void *ctx); +}; + +/** + * struct qpnp_vadc_linear_graph - Represent ADC characteristics. + * @dy: Numerator slope to calculate the gain. + * @dx: Denominator slope to calculate the gain. + * @adc_vref: A/D word of the voltage reference used for the channel. + * @adc_gnd: A/D word of the ground reference used for the channel. + * + * Each ADC device has different offset and gain parameters which are computed + * to calibrate the device. + */ +struct qpnp_vadc_linear_graph { + int64_t dy; + int64_t dx; + int64_t adc_vref; + int64_t adc_gnd; +}; + +/** + * struct qpnp_vadc_map_pt - Map the graph representation for ADC channel + * @x: Represent the ADC digitized code. + * @y: Represent the physical data which can be temperature, voltage, + * resistance. + */ +struct qpnp_vadc_map_pt { + int32_t x; + int32_t y; +}; + +/** + * struct qpnp_vadc_scaling_ratio - Represent scaling ratio for adc input. + * @num: Numerator scaling parameter. + * @den: Denominator scaling parameter. + */ +struct qpnp_vadc_scaling_ratio { + int32_t num; + int32_t den; +}; + +/** + * struct qpnp_adc_properties - Represent the ADC properties. + * @adc_reference: Reference voltage for QPNP ADC. + * @bitresolution: ADC bit resolution for QPNP ADC. + * @biploar: Polarity for QPNP ADC. + * @adc_hc: Represents using HC variant of the ADC controller. + */ +struct qpnp_adc_properties { + uint32_t adc_vdd_reference; + uint32_t bitresolution; + bool bipolar; + bool adc_hc; +}; + +/** + * struct qpnp_vadc_chan_properties - Represent channel properties of the ADC. + * @offset_gain_numerator: The inverse numerator of the gain applied to the + * input channel. + * @offset_gain_denominator: The inverse denominator of the gain applied to the + * input channel. + * @high_thr: High threshold voltage that is requested to be set. + * @low_thr: Low threshold voltage that is requested to be set. + * @timer_select: Choosen from one of the 3 timers to set the polling rate for + * the VADC_BTM channel. + * @meas_interval1: Polling rate to set for timer 1. + * @meas_interval2: Polling rate to set for timer 2. + * @tm_channel_select: BTM channel number for the 5 VADC_BTM channels. + * @state_request: User can select either enable or disable high/low or both + * activation levels based on the qpnp_state_request type. + * @adc_graph: ADC graph for the channel of struct type qpnp_adc_linear_graph. + */ +struct qpnp_vadc_chan_properties { + uint32_t offset_gain_numerator; + uint32_t offset_gain_denominator; + uint32_t high_thr; + uint32_t low_thr; + enum qpnp_adc_meas_timer_select timer_select; + enum qpnp_adc_meas_timer_1 meas_interval1; + enum qpnp_adc_meas_timer_2 meas_interval2; + enum qpnp_adc_tm_channel_select tm_channel_select; + enum qpnp_state_request state_request; + enum qpnp_adc_calib_type calib_type; + struct qpnp_vadc_linear_graph adc_graph[ADC_HC_CAL_SEL_NONE]; +}; + +/** + * struct qpnp_vadc_result - Represent the result of the QPNP ADC. + * @chan: The channel number of the requested conversion. + * @adc_code: The pre-calibrated digital output of a given ADC relative to the + * the ADC reference. + * @measurement: In units specific for a given ADC; most ADC uses reference + * voltage but some ADC uses reference current. This measurement + * here is a number relative to a reference of a given ADC. + * @physical: The data meaningful for each individual channel whether it is + * voltage, current, temperature, etc. + * All voltage units are represented in micro - volts. + * -Battery temperature units are represented as 0.1 DegC. + * -PA Therm temperature units are represented as DegC. + * -PMIC Die temperature units are represented as 0.001 DegC. + */ +struct qpnp_vadc_result { + uint32_t chan; + int32_t adc_code; + int64_t measurement; + int64_t physical; +}; + +/** + * struct qpnp_adc_amux - AMUX properties for individual channel + * @name: Channel string name. + * @channel_num: Channel in integer used from qpnp_adc_channels. + * @chan_path_prescaling: Channel scaling performed on the input signal. + * @adc_decimation: Sampling rate desired for the channel. + * adc_scale_fn: Scaling function to convert to the data meaningful for + * each individual channel whether it is voltage, current, + * temperature, etc and compensates the channel properties. + */ +struct qpnp_adc_amux { + char *name; + enum qpnp_vadc_channels channel_num; + enum qpnp_adc_channel_scaling_param chan_path_prescaling; + enum qpnp_adc_decimation_type adc_decimation; + enum qpnp_adc_scale_fn_type adc_scale_fn; + enum qpnp_adc_fast_avg_ctl fast_avg_setup; + enum qpnp_adc_hw_settle_time hw_settle_time; + enum qpnp_adc_calib_type calib_type; + enum qpnp_adc_cal_val cal_val; +}; + +/** + * struct qpnp_vadc_scaling_ratio + * + */ +static const struct qpnp_vadc_scaling_ratio qpnp_vadc_amux_scaling_ratio[] = { + {1, 1}, + {1, 3}, + {1, 4}, + {1, 6}, + {1, 20}, + {1, 8}, + {10, 81}, + {1, 10} +}; + +/** + * struct qpnp_vadc_scale_fn - Scaling function prototype + * @chan: Function pointer to one of the scaling functions + * which takes the adc properties, channel properties, + * and returns the physical result + */ +struct qpnp_vadc_scale_fn { + int32_t (*chan)(struct qpnp_vadc_chip *, int32_t, + const struct qpnp_adc_properties *, + const struct qpnp_vadc_chan_properties *, + struct qpnp_vadc_result *); +}; + +/** + * struct qpnp_adc_tm_reverse_scale_fn - Reverse scaling prototype + * @chan: Function pointer to one of the scaling functions + * which takes the adc properties, channel properties, + * and returns the physical result + */ +struct qpnp_adc_tm_reverse_scale_fn { + int32_t (*chan)(struct qpnp_vadc_chip *, + struct qpnp_adc_tm_btm_param *, + uint32_t *, uint32_t *); +}; + +/** + * struct qpnp_vadc_rscale_fn - Scaling function prototype + * @chan: Function pointer to one of the scaling functions + * which takes the adc properties, channel properties, + * and returns the physical result + */ +struct qpnp_vadc_rscale_fn { + int32_t (*chan)(struct qpnp_vadc_chip *, + const struct qpnp_vadc_chan_properties *, + struct qpnp_adc_tm_btm_param *, + uint32_t *, uint32_t *); +}; + +/** + * struct qpnp_iadc_calib - IADC channel calibration structure. + * @channel - Channel for which the historical offset and gain is + * calculated. Available channels are internal rsense, + * external rsense and alternate lead pairs. + * @offset_raw - raw Offset value for the channel. + * @gain_raw - raw Gain of the channel. + * @ideal_offset_uv - ideal offset value for the channel. + * @ideal_gain_nv - ideal gain for the channel. + * @offset_uv - converted value of offset in uV. + * @gain_uv - converted value of gain in uV. + */ +struct qpnp_iadc_calib { + enum qpnp_iadc_channels channel; + uint16_t offset_raw; + uint16_t gain_raw; + uint32_t ideal_offset_uv; + uint32_t ideal_gain_nv; + uint32_t offset_uv; + uint32_t gain_uv; +}; + +/** + * struct qpnp_iadc_result - IADC read result structure. + * @oresult_uv - Result of ADC in uV. + * @result_ua - Result of ADC in uA. + */ +struct qpnp_iadc_result { + int32_t result_uv; + int32_t result_ua; +}; + +/** + * struct qpnp_adc_drv - QPNP ADC device structure. + * @spmi - spmi device for ADC peripheral. + * @offset - base offset for the ADC peripheral. + * @adc_prop - ADC properties specific to the ADC peripheral. + * @amux_prop - AMUX properties representing the ADC peripheral. + * @adc_channels - ADC channel properties for the ADC peripheral. + * @adc_irq_eoc - End of Conversion IRQ. + * @adc_irq_fifo_not_empty - Conversion sequencer request written + * to FIFO when not empty. + * @adc_irq_conv_seq_timeout - Conversion sequencer trigger timeout. + * @adc_high_thr_irq - Output higher than high threshold set for measurement. + * @adc_low_thr_irq - Output lower than low threshold set for measurement. + * @adc_lock - ADC lock for access to the peripheral. + * @adc_rslt_completion - ADC result notification after interrupt + * is received. + * @calib - Internal rsens calibration values for gain and offset. + */ +struct qpnp_adc_drv { + struct platform_device *pdev; + struct regmap *regmap; + uint8_t slave; + uint16_t offset; + struct qpnp_adc_properties *adc_prop; + struct qpnp_adc_amux_properties *amux_prop; + struct qpnp_adc_amux *adc_channels; + int adc_irq_eoc; + int adc_irq_fifo_not_empty; + int adc_irq_conv_seq_timeout; + int adc_high_thr_irq; + int adc_low_thr_irq; + struct mutex adc_lock; + struct completion adc_rslt_completion; + struct qpnp_iadc_calib calib; + struct regulator *hkadc_ldo; + struct regulator *hkadc_ldo_ok; + bool adc_hc; +}; + +/** + * struct qpnp_adc_amux_properties - QPNP VADC amux channel property. + * @amux_channel - Refer to the qpnp_vadc_channel list. + * @decimation - Sampling rate supported for the channel. + * @mode_sel - The basic mode of operation. + * @hw_settle_time - The time between AMUX being configured and the + * start of conversion. + * @fast_avg_setup - Ability to provide single result from the ADC + * that is an average of multiple measurements. + * @trigger_channel - HW trigger channel for conversion sequencer. + * @calib_type - Used to store the calibration type for the channel + * absolute/ratiometric. + * @cal_val - Used to determine if fresh calibration value or timer + * updated calibration value is to be used. + * @chan_prop - Represent the channel properties of the ADC. + */ +struct qpnp_adc_amux_properties { + uint32_t amux_channel; + uint32_t decimation; + uint32_t mode_sel; + uint32_t hw_settle_time; + uint32_t fast_avg_setup; + enum qpnp_vadc_trigger trigger_channel; + enum qpnp_adc_calib_type calib_type; + enum qpnp_adc_cal_val cal_val; + struct qpnp_vadc_chan_properties chan_prop[0]; +}; + +/* SW index's for PMIC type and version used by QPNP VADC and IADC */ +#define QPNP_REV_ID_8941_3_1 1 +#define QPNP_REV_ID_8026_1_0 2 +#define QPNP_REV_ID_8026_2_0 3 +#define QPNP_REV_ID_8110_1_0 4 +#define QPNP_REV_ID_8026_2_1 5 +#define QPNP_REV_ID_8110_2_0 6 +#define QPNP_REV_ID_8026_2_2 7 +#define QPNP_REV_ID_8941_3_0 8 +#define QPNP_REV_ID_8941_2_0 9 +#define QPNP_REV_ID_8916_1_0 10 +#define QPNP_REV_ID_8916_1_1 11 +#define QPNP_REV_ID_8916_2_0 12 +#define QPNP_REV_ID_8909_1_0 13 +#define QPNP_REV_ID_8909_1_1 14 +#define QPNP_REV_ID_PM8950_1_0 16 + +/* Public API */ +#if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE) \ + || defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE_MODULE) +/** + * qpnp_vadc_read() - Performs ADC read on the channel. + * @dev: Structure device for qpnp vadc + * @channel: Input channel to perform the ADC read. + * @result: Structure pointer of type adc_chan_result + * in which the ADC read results are stored. + */ +int32_t qpnp_vadc_read(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel, + struct qpnp_vadc_result *result); + +/** + * qpnp_vadc_hc_read() - Performs ADC read on the channel. + * It uses the refreshed VADC design from qpnp-vadc-hc. + * @dev: Structure device for qpnp vadc + * @channel: Input channel to perform the ADC read. + * @result: Structure pointer of type adc_chan_result + * in which the ADC read results are stored. + */ +int32_t qpnp_vadc_hc_read(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel, + struct qpnp_vadc_result *result); + +/** + * qpnp_vadc_conv_seq_request() - Performs ADC read on the conversion + * sequencer channel. + * @dev: Structure device for qpnp vadc + * @channel: Input channel to perform the ADC read. + * @result: Structure pointer of type adc_chan_result + * in which the ADC read results are stored. + */ +int32_t qpnp_vadc_conv_seq_request(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_trigger trigger_channel, + enum qpnp_vadc_channels channel, + struct qpnp_vadc_result *result); + +/** + * qpnp_adc_get_devicetree_data() - Abstracts the ADC devicetree data. + * @spmi: spmi ADC device. + * @adc_qpnp: spmi device tree node structure + */ +int32_t qpnp_adc_get_devicetree_data(struct platform_device *pdev, + struct qpnp_adc_drv *adc_qpnp); + +/** + * qpnp_adc_scale_default() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the qpnp adc such as bit resolution, + * reference voltage. + * @chan_prop: Individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: Physical result to be stored. + */ +int32_t qpnp_adc_scale_default(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_pmic_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Performs the AMUX out as 2mV/K and returns + * the temperature in milli degC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the qpnp adc such as bit resolution, + * reference voltage. + * @chan_prop: Individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: Physical result to be stored. + */ +int32_t qpnp_adc_scale_pmic_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_pmi_chg_temp() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. The voltage measured by HKADC is related to + * the junction temperature according to + * Tj = -137.67 degC * (V_adc * 2) + 382.04 degC + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the qpnp adc such as bit resolution, + * reference voltage. + * @chan_prop: Individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: Physical result to be stored. + */ +int32_t qpnp_adc_scale_pmi_chg_temp(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_qrd_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_qrd_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_qrd_skuaa_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_qrd_skuaa_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_qrd_skug_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_qrd_skug_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_qrd_skuh_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_qrd_skuh_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_qrd_skut1_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_qrd_skut1_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_smb_batt_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature in decidegC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_smb_batt_therm(struct qpnp_vadc_chip *dev, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_batt_id() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_batt_id(struct qpnp_vadc_chip *dev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_tdkntcg_therm() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature of the xo therm in mili + degC. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_tdkntcg_therm(struct qpnp_vadc_chip *dev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_therm_pu1() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature of the therm in degC. + * It uses a mapping table computed for a 150K pull-up. + * Pull-up1 is an internal pull-up on the AMUX of 150K. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_therm_pu1(struct qpnp_vadc_chip *dev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_therm_pu2() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature of the therm in degC. + * It uses a mapping table computed for a 100K pull-up. + * Pull-up2 is an internal pull-up on the AMUX of 100K. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_therm_pu2(struct qpnp_vadc_chip *dev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_adc_scale_therm_ncp03() - Scales the pre-calibrated digital output + * of an ADC to the ADC reference and compensates for the + * gain and offset. Returns the temperature of the therm in degC. + * It uses a mapping table computed for a NCP03WF683. + * @dev: Structure device for qpnp vadc + * @adc_code: pre-calibrated digital output of the ADC. + * @adc_prop: adc properties of the pm8xxx adc such as bit resolution, + * reference voltage. + * @chan_prop: individual channel properties to compensate the i/p scaling, + * slope and offset. + * @chan_rslt: physical result to be stored. + */ +int32_t qpnp_adc_scale_therm_ncp03(struct qpnp_vadc_chip *dev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt); +/** + * qpnp_get_vadc() - Clients need to register with the vadc using the + * corresponding device instance it wants to read the channels + * from. Read the bindings document on how to pass the phandle + * for the corresponding vadc driver to register with. + * @dev: Clients device structure + * @name: Corresponding client's DT parser name. Read the DT bindings + * document on how to register with the vadc + * @struct qpnp_vadc_chip * - On success returns the vadc device structure + * pointer that needs to be used during an ADC request. + */ +struct qpnp_vadc_chip *qpnp_get_vadc(struct device *dev, const char *name); +/** + * qpnp_adc_tm_scaler() - Performs reverse calibration. + * @config: Thermal monitoring configuration. + * @adc_prop: adc properties of the qpnp adc such as bit resolution and + * reference voltage. + * @chan_prop: Individual channel properties to compensate the i/p scaling, + * slope and offset. + */ +static inline int32_t qpnp_adc_tm_scaler(struct qpnp_adc_tm_config *tm_config, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop) +{ return -ENXIO; } +/** + * qpnp_get_vadc_gain_and_offset() - Obtains the VADC gain and offset + * for absolute and ratiometric calibration. + * @dev: Structure device for qpnp vadc + * @param: The result in which the ADC offset and gain values are stored. + * @type: The calibration type whether client needs the absolute or + * ratiometric gain and offset values. + */ +int32_t qpnp_get_vadc_gain_and_offset(struct qpnp_vadc_chip *dev, + struct qpnp_vadc_linear_graph *param, + enum qpnp_adc_calib_type calib_type); +/** + * qpnp_adc_scale_millidegc_pmic_voltage_thr() - Performs reverse calibration + * on the low/high temperature threshold values passed by the + * client. The function coverts milldegC to voltage threshold + * and accounts for the corresponding channels scaling as (2mV/K). + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high temperature + * values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_btm_scaler() - Performs reverse calibration on the low/high + * temperature threshold values passed by the client. + * The function maps the temperature to voltage and applies + * ratiometric calibration on the voltage values. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high temperature + * values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); + +/** + * qpnp_adc_qrd_skuh_btm_scaler() - Performs reverse calibration on the low/high + * temperature threshold values passed by the client. + * The function maps the temperature to voltage and applies + * ratiometric calibration on the voltage values for SKUH board. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high temperature + * values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_qrd_skuh_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_qrd_skut1_btm_scaler() - Performs reverse calibration on the low/high + * temperature threshold values passed by the client. + * The function maps the temperature to voltage and applies + * ratiometric calibration on the voltage values for SKUT1 board. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high temperature + * values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_qrd_skut1_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_tm_scale_therm_voltage_pu2() - Performs reverse calibration + * and convert given temperature to voltage on supported + * thermistor channels using 100k pull-up. + * @dev: Structure device for qpnp vadc + * @adc_prop: adc properties of the qpnp adc such as bit resolution, + * reference voltage. + * @param: The input temperature values. + */ +int32_t qpnp_adc_tm_scale_therm_voltage_pu2(struct qpnp_vadc_chip *dev, + const struct qpnp_adc_properties *adc_properties, + struct qpnp_adc_tm_config *param); +/** + * qpnp_adc_tm_scale_therm_voltage_pu2() - Performs reverse calibration + * and converts the given ADC code to temperature for + * thermistor channels using 100k pull-up. + * @dev: Structure device for qpnp vadc + * @adc_prop: adc properties of the qpnp adc such as bit resolution, + * reference voltage. + * @reg: The input ADC code. + * @result: The physical measurement temperature on the thermistor. + */ +int32_t qpnp_adc_tm_scale_voltage_therm_pu2(struct qpnp_vadc_chip *dev, + const struct qpnp_adc_properties *adc_prop, + uint32_t reg, int64_t *result); +/** + * qpnp_adc_usb_scaler() - Performs reverse calibration on the low/high + * voltage threshold values passed by the client. + * The function applies ratiometric calibration on the + * voltage values. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high voltage + * threshold values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_usb_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_vbatt_rscaler() - Performs reverse calibration on the low/high + * voltage threshold values passed by the client. + * The function applies ratiometric calibration on the + * voltage values. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high voltage + * threshold values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_vbatt_rscaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_vadc_absolute_rthr() - Performs reverse calibration on the low/high + * voltage threshold values passed by the client. + * The function applies absolute calibration on the + * voltage values. + * @dev: Structure device for qpnp vadc + * @chan_prop: Individual channel properties to compensate the i/p scaling, + * slope and offset. + * @param: The input parameters that contain the low/high voltage + * threshold values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_vadc_absolute_rthr(struct qpnp_vadc_chip *dev, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_absolute_rthr() - Performs reverse calibration on the low/high + * voltage threshold values passed by the client. + * The function applies absolute calibration on the + * voltage values. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high voltage + * threshold values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_absolute_rthr(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_adc_smb_btm_rscaler() - Performs reverse calibration on the low/high + * temperature threshold values passed by the client. + * The function maps the temperature to voltage and applies + * ratiometric calibration on the voltage values. + * @dev: Structure device for qpnp vadc + * @param: The input parameters that contain the low/high temperature + * values. + * @low_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + * @high_threshold: The low threshold value that needs to be updated with + * the above calibrated voltage value. + */ +int32_t qpnp_adc_smb_btm_rscaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold); +/** + * qpnp_vadc_iadc_sync_request() - Performs Voltage ADC read and + * locks the peripheral. When performing simultaneous + * voltage and current request the VADC peripheral is + * prepared for conversion and the IADC sync conversion + * is done from the IADC peripheral. + * @dev: Structure device for qpnp vadc + * @channel: Input channel to perform the voltage ADC read. + */ +int32_t qpnp_vadc_iadc_sync_request(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel); +/** + * qpnp_vadc_iadc_sync_complete_request() - Reads the ADC result and + * unlocks the peripheral. + * @dev: Structure device for qpnp vadc + * @result: Structure pointer of type adc_chan_result + * in which the ADC read results are stored. + */ +int32_t qpnp_vadc_iadc_sync_complete_request(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel, struct qpnp_vadc_result *result); +/** + * qpnp_vadc_sns_comp_result() - Compensate vbatt readings based on temperature + * @dev: Structure device for qpnp vadc + * @result: Voltage in uV that needs compensation. + * @is_pon_ocv: Whether the reading is from a power on OCV or not + */ +int32_t qpnp_vbat_sns_comp_result(struct qpnp_vadc_chip *dev, + int64_t *result, bool is_pon_ocv); +/** + * qpnp_adc_get_revid_version() - Obtain the PMIC number and revision. + * @dev: Structure device node. + * returns internal mapped PMIC number and revision id. + */ +int qpnp_adc_get_revid_version(struct device *dev); +/** + * qpnp_vadc_channel_monitor() - Configures kernel clients a channel to + * monitor the corresponding ADC channel for threshold detection. + * Driver passes the high/low voltage threshold along + * with the notification callback once the set thresholds + * are crossed. + * @param: Structure pointer of qpnp_adc_tm_btm_param type. + * Clients pass the low/high temperature along with the threshold + * notification callback. + */ +int32_t qpnp_vadc_channel_monitor(struct qpnp_vadc_chip *chip, + struct qpnp_adc_tm_btm_param *param); +/** + * qpnp_vadc_end_channel_monitor() - Disables recurring measurement mode for + * VADC_USR and disables the bank. + * @param: device instance for the VADC + */ +int32_t qpnp_vadc_end_channel_monitor(struct qpnp_vadc_chip *chip); +/** + * qpnp_vadc_calib_vref() - Read calibration channel REF_125V/VDD_VADC + * @dev: Structure device for qpnp vadc + * @calib_type: absolute or ratiometric calib type. + * returns calibration channel adc code. + */ +int32_t qpnp_vadc_calib_vref(struct qpnp_vadc_chip *vadc, + enum qpnp_adc_calib_type calib_type, + int *calib_data); +/** + * qpnp_vadc_calib_gnd() - Read calibration channel REF_625MV/GND_REF + * @dev: Structure device for qpnp vadc + * @calib_type: absolute or ratiometric calib type. + * returns calibration channel adc code. + */ +int32_t qpnp_vadc_calib_gnd(struct qpnp_vadc_chip *vadc, + enum qpnp_adc_calib_type calib_type, + int *calib_data); + +/** + * qpnp_adc_enable_voltage() - Enable LDO for HKADC + * @dev: Structure device for qpnp vadc + * returns result of enabling the regulator interface. + */ +int32_t qpnp_adc_enable_voltage(struct qpnp_adc_drv *adc); + +/** + * qpnp_adc_disable_voltage() - Disable vote for HKADC LDO + * @dev: Structure device for qpnp vadc + */ +void qpnp_adc_disable_voltage(struct qpnp_adc_drv *adc); + +/** + * qpnp_adc_free_voltage_resource() - Puts HKADC LDO + * @dev: Structure device for qpnp vadc + */ +void qpnp_adc_free_voltage_resource(struct qpnp_adc_drv *adc); + +#else +static inline int32_t qpnp_vadc_read(struct qpnp_vadc_chip *dev, + uint32_t channel, + struct qpnp_vadc_result *result) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_hc_read(struct qpnp_vadc_chip *dev, + uint32_t channel, + struct qpnp_vadc_result *result) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_conv_seq_request(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_trigger trigger_channel, + enum qpnp_vadc_channels channel, + struct qpnp_vadc_result *result) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_default(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_pmic_therm(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_pmi_chg_temp(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_batt_therm(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_qrd_batt_therm( + struct qpnp_vadc_chip *vadc, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_qrd_skuaa_batt_therm( + struct qpnp_vadc_chip *vadc, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_qrd_skug_batt_therm( + struct qpnp_vadc_chip *vadc, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_qrd_skuh_batt_therm( + struct qpnp_vadc_chip *vdev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_qrd_skut1_batt_therm( + struct qpnp_vadc_chip *vdev, int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_smb_batt_therm(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_batt_id(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tdkntcg_therm(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_therm_pu1(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_therm_pu2(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_therm_ncp03(struct qpnp_vadc_chip *vadc, + int32_t adc_code, + const struct qpnp_adc_properties *adc_prop, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_vadc_result *chan_rslt) +{ return -ENXIO; } +static inline struct qpnp_vadc_chip *qpnp_get_vadc(struct device *dev, + const char *name) +{ return ERR_PTR(-ENXIO); } +static inline int32_t qpnp_get_vadc_gain_and_offset(struct qpnp_vadc_chip *dev, + struct qpnp_vadc_linear_graph *param, + enum qpnp_adc_calib_type calib_type) +{ return -ENXIO; } +static inline int32_t qpnp_adc_usb_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_vbatt_rscaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_absolute_rthr(struct qpnp_vadc_chip *dev, + const struct qpnp_vadc_chan_properties *chan_prop, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_absolute_rthr(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_qrd_skuh_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_qrd_skut1_btm_scaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_scale_millidegc_pmic_voltage_thr( + struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tm_scale_therm_voltage_pu2( + struct qpnp_vadc_chip *dev, + const struct qpnp_adc_properties *adc_properties, + struct qpnp_adc_tm_config *param) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tm_scale_voltage_therm_pu2( + struct qpnp_vadc_chip *dev, + const struct qpnp_adc_properties *adc_prop, + uint32_t reg, int64_t *result) +{ return -ENXIO; } +static inline int32_t qpnp_adc_smb_btm_rscaler(struct qpnp_vadc_chip *dev, + struct qpnp_adc_tm_btm_param *param, + uint32_t *low_threshold, uint32_t *high_threshold) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_iadc_sync_request(struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_iadc_sync_complete_request( + struct qpnp_vadc_chip *dev, + enum qpnp_vadc_channels channel, + struct qpnp_vadc_result *result) +{ return -ENXIO; } +static inline int32_t qpnp_vbat_sns_comp_result(struct qpnp_vadc_chip *dev, + int64_t *result) +{ return -ENXIO; } +static inline int qpnp_adc_get_revid_version(struct device *dev) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_channel_monitor(struct qpnp_vadc_chip *chip, + struct qpnp_adc_tm_btm_param *param) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_end_channel_monitor(struct qpnp_vadc_chip *chip) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_calib_vref(struct qpnp_vadc_chip *vadc, + enum qpnp_adc_calib_type calib_type, + int *calib_data) +{ return -ENXIO; } +static inline int32_t qpnp_vadc_calib_gnd(struct qpnp_vadc_chip *vadc, + enum qpnp_adc_calib_type calib_type, + int *calib_data) +{ return -ENXIO; } + +static inline int32_t qpnp_adc_enable_voltage(struct qpnp_adc_drv *adc) +{ return -ENXIO; } + +static inline void qpnp_adc_disable_voltage(struct qpnp_adc_drv *adc) +{ return; } + +static inline void qpnp_adc_free_voltage_resource(struct qpnp_adc_drv *adc) +{ return; } + +static inline int32_t qpnp_adc_get_devicetree_data( + struct platform_device *pdev, struct qpnp_adc_drv *adc_qpnp) +{ return -ENXIO; } + +#endif + +/* Public API */ +#if defined(CONFIG_SENSORS_QPNP_ADC_CURRENT) \ + || defined(CONFIG_SENSORS_QPNP_ADC_CURRENT_MODULE) +/** + * qpnp_iadc_read() - Performs ADC read on the current channel. + * @dev: Structure device for qpnp iadc + * @channel: Input channel to perform the ADC read. + * @result: Current across rsense in mA. + * @return: 0 on success. + */ +int32_t qpnp_iadc_read(struct qpnp_iadc_chip *dev, + enum qpnp_iadc_channels channel, + struct qpnp_iadc_result *result); +/** + * qpnp_iadc_get_rsense() - Reads the RDS resistance value from the + trim registers. + * @dev: Structure device for qpnp iadc + * @rsense: RDS resistance in nOhms. + * @return: 0 on success. + */ +int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *dev, int32_t *rsense); +/** + * qpnp_iadc_get_gain_and_offset() - Performs gain calibration + * over 17.8571mV and offset over selected + * channel. Channel can be internal rsense, + * external rsense and alternate lead pair. + * @dev: Structure device for qpnp iadc + * @result: result structure where the gain and offset is stored of + * type qpnp_iadc_calib. + * @return: 0 on success. + */ +int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *dev, + struct qpnp_iadc_calib *result); +/** + * qpnp_get_iadc() - Clients need to register with the iadc with the + * corresponding device instance it wants to read the channels. + * Read the bindings document on how to pass the phandle for + * the corresponding vadc driver to register with. + * @dev: Clients device structure + * @name: Corresponding client's DT parser name. Read the DT bindings + * document on how to register with the iadc + * @struct qpnp_iadc_chip * - On success returns the iadc device structure + * pointer used everytime client makes an ADC request. + */ +struct qpnp_iadc_chip *qpnp_get_iadc(struct device *dev, const char *name); +/** + * qpnp_iadc_vadc_sync_read() - Performs synchronous VADC and IADC read. + * The api is to be used only by the BMS to perform + * simultaneous VADC and IADC measurement for battery voltage + * and current. + * @dev: Structure device for qpnp iadc + * @i_channel: Input battery current channel to perform the IADC read. + * @i_result: Current across the rsense in mA. + * @v_channel: Input battery voltage channel to perform VADC read. + * @v_result: Voltage on the vbatt channel with units in mV. + * @return: 0 on success. + */ +int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *dev, + enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result, + enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result); +/** + * qpnp_iadc_calibrate_for_trim - Clients can use this API to re-calibrate + * IADC. The offset and gain values are programmed in the trim + * registers. The offset and the gain can be retrieved using + * qpnp_iadc_get_gain_and_offset + * @dev: Structure device for qpnp iadc + * @batfet_closed: batfet is opened or closed. The IADC chooses proper + * channel (internal/external) based on batfet status + * for calibration. + * RETURNS: 0 on success. + */ +int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *dev, + bool batfet_closed); +/** + * qpnp_iadc_comp_result() - Compensates the result of the current based on + * the gain and offset co-effients and rsense parameters. + * @dev: Structure device for qpnp iadc + * @result: Current value to perform the compensation. + * @return: 0 on success. + */ +int32_t qpnp_iadc_comp_result(struct qpnp_iadc_chip *dev, int64_t *result); +/** + * qpnp_iadc_skip_calibration() - Clients can use this API to ask the driver + * to skip iadc calibrations + * @dev: Structure device for qpnp iadc + * @result: 0 on success and -EPROBE_DEFER when probe for the device + * has not occured. + */ +int qpnp_iadc_skip_calibration(struct qpnp_iadc_chip *dev); +/** + * qpnp_iadc_resume_calibration() - Clients can use this API to ask the driver + * to resume iadc calibrations + * @dev: Structure device for qpnp iadc + * @result: 0 on success and -EPROBE_DEFER when probe for the device + * has not occured. + */ +int qpnp_iadc_resume_calibration(struct qpnp_iadc_chip *dev); +#else +static inline int32_t qpnp_iadc_read(struct qpnp_iadc_chip *iadc, + enum qpnp_iadc_channels channel, struct qpnp_iadc_result *result) +{ return -ENXIO; } +static inline int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *iadc, + int32_t *rsense) +{ return -ENXIO; } +static inline int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *iadc, + struct qpnp_iadc_calib *result) +{ return -ENXIO; } +static inline struct qpnp_iadc_chip *qpnp_get_iadc(struct device *dev, + const char *name) +{ return ERR_PTR(-ENXIO); } +static inline int32_t qpnp_iadc_vadc_sync_read(struct qpnp_iadc_chip *iadc, + enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result, + enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result) +{ return -ENXIO; } +static inline int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc, + bool batfet_closed) +{ return -ENXIO; } +static inline int32_t qpnp_iadc_comp_result(struct qpnp_iadc_chip *iadc, + int64_t *result) +{ return -ENXIO; } +static inline int qpnp_iadc_skip_calibration(struct qpnp_iadc_chip *iadc) +{ return -ENXIO; } +static inline int qpnp_iadc_resume_calibration(struct qpnp_iadc_chip *iadc) +{ return -ENXIO; } +#endif + +/* Public API */ +#if defined(CONFIG_THERMAL_QPNP_ADC_TM) \ + || defined(CONFIG_THERMAL_QPNP_ADC_TM_MODULE) +/** + * qpnp_adc_tm_usbid_configure() - Configures Channel 0 of VADC_BTM to + * monitor USB_ID channel using 100k internal pull-up. + * USB driver passes the high/low voltage threshold along + * with the notification callback once the set thresholds + * are crossed. + * @param: Structure pointer of qpnp_adc_tm_usbid_param type. + * Clients pass the low/high voltage along with the threshold + * notification callback. + */ +int32_t qpnp_adc_tm_usbid_configure(struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param); +/** + * qpnp_adc_tm_usbid_end() - Disables the monitoring of channel 0 thats + * assigned for monitoring USB_ID. Disables the low/high + * threshold activation for channel 0 as well. + * @param: none. + */ +int32_t qpnp_adc_tm_usbid_end(struct qpnp_adc_tm_chip *chip); +/** + * qpnp_adc_tm_channel_measure() - Configures kernel clients a channel to + * monitor the corresponding ADC channel for threshold detection. + * Driver passes the high/low voltage threshold along + * with the notification callback once the set thresholds + * are crossed. + * @param: Structure pointer of qpnp_adc_tm_btm_param type. + * Clients pass the low/high temperature along with the threshold + * notification callback. + */ +int32_t qpnp_adc_tm_channel_measure(struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param); +/** + * qpnp_adc_tm_disable_chan_meas() - Disables the monitoring of channel thats + * assigned for monitoring kernel clients. Disables the low/high + * threshold activation for the corresponding channel. + * @param: Structure pointer of qpnp_adc_tm_btm_param type. + * This is used to identify the channel for which the corresponding + * channels high/low threshold notification will be disabled. + */ +int32_t qpnp_adc_tm_disable_chan_meas(struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param); +/** + * qpnp_get_adc_tm() - Clients need to register with the adc_tm using the + * corresponding device instance it wants to read the channels + * from. Read the bindings document on how to pass the phandle + * for the corresponding adc_tm driver to register with. + * @name: Corresponding client's DT parser name. Read the DT bindings + * document on how to register with the vadc + * @struct qpnp_adc_tm_chip * - On success returns the vadc device structure + * pointer that needs to be used during an ADC TM request. + */ +struct qpnp_adc_tm_chip *qpnp_get_adc_tm(struct device *dev, const char *name); +#else +static inline int32_t qpnp_adc_tm_usbid_configure( + struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tm_usbid_end(struct qpnp_adc_tm_chip *chip) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tm_channel_measure( + struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param) +{ return -ENXIO; } +static inline int32_t qpnp_adc_tm_disable_chan_meas( + struct qpnp_adc_tm_chip *chip, + struct qpnp_adc_tm_btm_param *param) +{ return -ENXIO; } +static inline struct qpnp_adc_tm_chip *qpnp_get_adc_tm(struct device *dev, + const char *name) +{ return ERR_PTR(-ENXIO); } +#endif + +#endif diff --git a/include/linux/qpnp/qpnp-haptic.h b/include/linux/qpnp/qpnp-haptic.h new file mode 100644 index 000000000000..95e514a513e2 --- /dev/null +++ b/include/linux/qpnp/qpnp-haptic.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2015-2016, 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 __QPNP_HAPTIC_H +#define __QPNP_HAPTIC_H + +/* interface for the other module to play different sequences */ +#ifdef CONFIG_QPNP_HAPTIC +int qpnp_hap_play_byte(u8 data, bool on); +#else +static inline int qpnp_hap_play_byte(u8 data, bool on) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/qpnp/qpnp-pbs.h b/include/linux/qpnp/qpnp-pbs.h new file mode 100644 index 000000000000..39497ac4b552 --- /dev/null +++ b/include/linux/qpnp/qpnp-pbs.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2017, 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 _QPNP_PBS_H +#define _QPNP_PBS_H + +#ifdef CONFIG_QPNP_PBS +int qpnp_pbs_trigger_event(struct device_node *dev_node, u8 bitmap); +#else +static inline int qpnp_pbs_trigger_event(struct device_node *dev_node, + u8 bitmap) { + return -ENODEV; +} +#endif + +#endif diff --git a/include/linux/qpnp/qpnp-revid.h b/include/linux/qpnp/qpnp-revid.h new file mode 100644 index 000000000000..bbc4625a2d39 --- /dev/null +++ b/include/linux/qpnp/qpnp-revid.h @@ -0,0 +1,267 @@ +/* Copyright (c) 2013-2017, 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 __QPNP_REVID +#define __QPNP_REVID + +/* Common TYPE for all PMICs */ +#define PMIC_TYPE 0x51 + +/* PM8994 */ +#define PM8941_SUBTYPE 0x01 + +#define PM8941_V1P0_REV1 0x00 +#define PM8941_V1P0_REV2 0x00 +#define PM8941_V1P0_REV3 0x00 +#define PM8941_V1P0_REV4 0x01 + +#define PM8941_V2P0_REV1 0x00 +#define PM8941_V2P0_REV2 0x00 +#define PM8941_V2P0_REV3 0x00 +#define PM8941_V2P0_REV4 0x01 + +#define PM8941_V3P0_REV1 0x00 +#define PM8941_V3P0_REV2 0x00 +#define PM8941_V3P0_REV3 0x00 +#define PM8941_V3P0_REV4 0x03 + +#define PM8941_V3P1_REV1 0x00 +#define PM8941_V3P1_REV2 0x00 +#define PM8941_V3P1_REV3 0x01 +#define PM8941_V3P1_REV4 0x03 + +/* PM8841 */ +#define PM8841_SUBTYPE 0x02 + +/* PM8019 */ +#define PM8019_SUBTYPE 0x03 + +/* PM8226 */ +#define PM8226_SUBTYPE 0x04 + +#define PM8226_V2P2_REV1 0x00 +#define PM8226_V2P2_REV2 0x00 +#define PM8226_V2P2_REV3 0x02 +#define PM8226_V2P2_REV4 0x02 + +#define PM8226_V2P1_REV1 0x00 +#define PM8226_V2P1_REV2 0x00 +#define PM8226_V2P1_REV3 0x01 +#define PM8226_V2P1_REV4 0x02 + +#define PM8226_V2P0_REV1 0x00 +#define PM8226_V2P0_REV2 0x00 +#define PM8226_V2P0_REV3 0x00 +#define PM8226_V2P0_REV4 0x02 + +#define PM8226_V1P0_REV1 0x00 +#define PM8226_V1P0_REV2 0x00 +#define PM8226_V1P0_REV3 0x00 +#define PM8226_V1P0_REV4 0x00 + +/* PM8110 */ +#define PM8110_SUBTYPE 0x05 + +#define PM8110_V1P0_REV1 0x00 +#define PM8110_V1P0_REV2 0x00 +#define PM8110_V1P0_REV3 0x00 +#define PM8110_V1P0_REV4 0x01 + +#define PM8110_V1P1_REV1 0x00 +#define PM8110_V1P1_REV2 0x01 +#define PM8110_V1P1_REV3 0x00 +#define PM8110_V1P1_REV4 0x01 + +#define PM8110_V1P3_REV1 0x00 +#define PM8110_V1P3_REV2 0x03 +#define PM8110_V1P3_REV3 0x00 +#define PM8110_V1P3_REV4 0x01 + +#define PM8110_V2P0_REV1 0x00 +#define PM8110_V2P0_REV2 0x00 +#define PM8110_V2P0_REV3 0x00 +#define PM8110_V2P0_REV4 0x02 + +/* PMA8084 */ +#define PMA8084_SUBTYPE 0x06 + +/* PMI8962 */ +#define PMI8962_SUBTYPE 0x07 + +/* PMD9635 */ +#define PMD9635_SUBTYPE 0x08 +/* PM8994 */ +#define PM8994_SUBTYPE 0x09 + +/* PMI8994 */ +#define PMI8994_TYPE 0x51 +#define PMI8994_SUBTYPE 0x0A + +#define PMI8994_V1P0_REV1 0x00 +#define PMI8994_V1P0_REV2 0x00 +#define PMI8994_V1P0_REV3 0x00 +#define PMI8994_V1P0_REV4 0x01 + +#define PMI8994_V2P0_REV1 0x00 +#define PMI8994_V2P0_REV2 0x00 +#define PMI8994_V2P0_REV3 0x00 +#define PMI8994_V2P0_REV4 0x02 + +/* PM8916 */ +#define PM8916_SUBTYPE 0x0B + +#define PM8916_V1P0_REV1 0x00 +#define PM8916_V1P0_REV2 0x00 +#define PM8916_V1P0_REV3 0x00 +#define PM8916_V1P0_REV4 0x01 + +#define PM8916_V1P1_REV1 0x00 +#define PM8916_V1P1_REV2 0x00 +#define PM8916_V1P1_REV3 0x01 +#define PM8916_V1P1_REV4 0x01 + +#define PM8916_V2P0_REV1 0x00 +#define PM8916_V2P0_REV2 0x00 +#define PM8916_V2P0_REV3 0x00 +#define PM8916_V2P0_REV4 0x02 + +/* PM8004 */ +#define PM8004_SUBTYPE 0x0C + +/* PM8909 */ +#define PM8909_SUBTYPE 0x0D + +#define PM8909_V1P0_REV1 0x00 +#define PM8909_V1P0_REV2 0x00 +#define PM8909_V1P0_REV3 0x00 +#define PM8909_V1P0_REV4 0x01 + +#define PM8909_V1P1_REV1 0x00 +#define PM8909_V1P1_REV2 0x00 +#define PM8909_V1P1_REV3 0x01 +#define PM8909_V1P1_REV4 0x01 + +/* PM2433 */ +#define PM2433_SUBTYPE 0x0E + +/* PMD9655 */ +#define PMD9655_SUBTYPE 0x0F + +/* PM8950 */ +#define PM8950_SUBTYPE 0x10 +#define PM8950_V1P0_REV4 0x01 + +#define PM8950_V2P0_REV4 0x02 + +/* PMI8950 */ +#define PMI8950_SUBTYPE 0x11 + +/* PMK8001 */ +#define PMK8001_SUBTYPE 0x12 + +/* PMI8996 */ +#define PMI8996_SUBTYPE 0x13 + +/* PM8998 */ +#define PM8998_SUBTYPE 0x14 + +/* PMI8998 */ +#define PMI8998_SUBTYPE 0x15 + +/* PM660 */ +#define PM660L_SUBTYPE 0x1A +#define PM660_SUBTYPE 0x1B + +/* PMI8998 REV_ID */ +#define PMI8998_V1P0_REV1 0x00 +#define PMI8998_V1P0_REV2 0x00 +#define PMI8998_V1P0_REV3 0x00 +#define PMI8998_V1P0_REV4 0x01 + +#define PMI8998_V1P1_REV1 0x00 +#define PMI8998_V1P1_REV2 0x00 +#define PMI8998_V1P1_REV3 0x01 +#define PMI8998_V1P1_REV4 0x01 + +#define PMI8998_V2P0_REV1 0x00 +#define PMI8998_V2P0_REV2 0x00 +#define PMI8998_V2P0_REV3 0x00 +#define PMI8998_V2P0_REV4 0x02 + +/* PM660 REV_ID */ +#define PM660_V1P0_REV1 0x00 +#define PM660_V1P0_REV2 0x00 +#define PM660_V1P0_REV3 0x00 +#define PM660_V1P0_REV4 0x01 + +#define PM660_V1P1_REV1 0x00 +#define PM660_V1P1_REV2 0x00 +#define PM660_V1P1_REV3 0x01 +#define PM660_V1P1_REV4 0x01 + +/* PM660L REV_ID */ +#define PM660L_V1P1_REV1 0x00 +#define PM660L_V1P1_REV2 0x00 +#define PM660L_V1P1_REV3 0x01 +#define PM660L_V1P1_REV4 0x01 + +#define PM660L_V2P0_REV1 0x00 +#define PM660L_V2P0_REV2 0x00 +#define PM660L_V2P0_REV3 0x00 +#define PM660L_V2P0_REV4 0x02 + +/* PMI8998 FAB_ID */ +#define PMI8998_FAB_ID_SMIC 0x11 +#define PMI8998_FAB_ID_GF 0x30 + +/* PM660 FAB_ID */ +#define PM660_FAB_ID_GF 0x0 +#define PM660_FAB_ID_TSMC 0x2 +#define PM660_FAB_ID_MX 0x3 + +/* PM8005 */ +#define PM8005_SUBTYPE 0x18 + +/* PM8937 */ +#define PM8937_SUBTYPE 0x19 + +/* PMI8937 */ +#define PMI8937_SUBTYPE 0x37 + +/* SMB1381 */ +#define SMB1381_SUBTYPE 0x17 + +/* SMB1355 */ +#define SMB1355_SUBTYPE 0x1C + +struct pmic_revid_data { + u8 rev1; + u8 rev2; + u8 rev3; + u8 rev4; + u8 pmic_type; + u8 pmic_subtype; + const char *pmic_name; + int fab_id; + int tp_rev; +}; + +#ifdef CONFIG_QPNP_REVID +struct pmic_revid_data *get_revid_data(struct device_node *dev_node); +#else +static inline +struct pmic_revid_data *get_revid_data(struct device_node *dev_node) +{ + return NULL; +} +#endif +#endif diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 673dee29a9b9..f9f3a4541072 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -274,6 +274,10 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); +unsigned int +radix_tree_gang_lookup_index(struct radix_tree_root *root, void **results, + unsigned long *indices, unsigned long first_index, + unsigned int max_items); unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, unsigned long *indices, unsigned long first_index, unsigned int max_items); diff --git a/include/linux/rculist.h b/include/linux/rculist.h index a579240c64e9..c22ce750df4e 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -45,19 +45,17 @@ static inline void INIT_LIST_HEAD_RCU(struct list_head *list) * This is only for internal list manipulation where we know * the prev/next entries already! */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_add_rcu(struct list_head *new, struct list_head *prev, struct list_head *next) { + if (!__list_add_valid(new, prev, next)) + return; + new->next = next; new->prev = prev; rcu_assign_pointer(list_next_rcu(prev), new); next->prev = new; } -#else -void __list_add_rcu(struct list_head *new, - struct list_head *prev, struct list_head *next); -#endif /** * list_add_rcu - add a new entry to rcu-protected list diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 60d15a080d7c..9d3eda39bcd2 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -37,7 +37,7 @@ void rcu_cpu_stall_reset(void); /* * Note a virtualization-based context switch. This is simply a * wrapper around rcu_note_context_switch(), which allows TINY_RCU - * to save a few bytes. + * to save a few bytes. The caller must have disabled interrupts. */ static inline void rcu_virt_note_context_switch(int cpu) { diff --git a/include/linux/regmap.h b/include/linux/regmap.h index d68bb402120e..ab1a11cbfd25 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -29,6 +29,7 @@ struct regmap; struct regmap_range_cfg; struct regmap_field; struct snd_ac97; +struct swr_device; /* An enum of all the supported cache types */ enum regcache_type { @@ -387,7 +388,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); - +struct regmap *__regmap_init_swr(struct swr_device *dev, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); struct regmap *__devm_regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, @@ -420,6 +424,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); +struct regmap *__devm_regmap_init_swr(struct swr_device *dev, + const struct regmap_config *config, + struct lock_class_key *lock_key, + const char *lock_name); /* * Wrapper for regmap_init macros to include a unique lockdep key and name @@ -554,6 +562,18 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); /** + * regmap_init_swr(): Initialise register map + * + * @swr: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer to + * a struct regmap. + */ +#define regmap_init_swr(swr, config) \ + __regmap_lockdep_wrapper(__regmap_init_swr, #config, \ + swr, config) +/** * devm_regmap_init(): Initialise managed register map * * @dev: Device that will be interacted with @@ -668,6 +688,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config, \ ac97, config) +/** + * devm_regmap_init_swr(): Initialise managed register map + * + * @swr: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The regmap will be automatically freed by the + * device management code. + */ +#define devm_regmap_init_swr(swr, config) \ + __regmap_lockdep_wrapper(__devm_regmap_init_swr, #config, \ + swr, config) + void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index bf62713af290..a4f06dcfc85c 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -103,6 +103,7 @@ struct regmap; * Data passed is old voltage cast to (void *). * PRE_DISABLE Regulator is about to be disabled * ABORT_DISABLE Regulator disable failed for some reason + * ENABLE Regulator was enabled. * * NOTE: These events can be OR'ed together when passed into handler. */ @@ -119,6 +120,7 @@ struct regmap; #define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200 #define REGULATOR_EVENT_PRE_DISABLE 0x400 #define REGULATOR_EVENT_ABORT_DISABLE 0x800 +#define REGULATOR_EVENT_ENABLE 0x1000 /** * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event @@ -142,6 +144,10 @@ struct regulator; * using the bulk regulator APIs. * @consumer: The regulator consumer for the supply. This will be managed * by the bulk API. + * @min_uV: The minimum requested voltage for the regulator (in microvolts), + * or 0 to not set a voltage. + * @max_uV: The maximum requested voltage for the regulator (in microvolts), + * or 0 to use @min_uV. * * The regulator APIs provide a series of regulator_bulk_() API calls as * a convenience to consumers which require multiple supplies. This @@ -150,6 +156,8 @@ struct regulator; struct regulator_bulk_data { const char *supply; struct regulator *consumer; + int min_uV; + int max_uV; /* private: Internal use */ int ret; @@ -214,6 +222,8 @@ int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers); int __must_check regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers); +int regulator_bulk_set_voltage(int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_force_disable(int num_consumers, @@ -224,6 +234,7 @@ void regulator_bulk_free(int num_consumers, int regulator_can_change_voltage(struct regulator *regulator); int regulator_count_voltages(struct regulator *regulator); int regulator_list_voltage(struct regulator *regulator, unsigned selector); +int regulator_list_corner_voltage(struct regulator *regulator, int corner); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV); unsigned int regulator_get_linear_step(struct regulator *regulator); @@ -556,6 +567,11 @@ static inline int regulator_list_voltage(struct regulator *regulator, unsigned s return -EINVAL; } +static inline int regulator_list_corner_voltage(struct regulator *regulator, + int corner) +{ + return -EINVAL; +} #endif static inline int regulator_set_voltage_triplet(struct regulator *regulator, diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9c2903e58adb..9cee86d33f86 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -18,6 +18,7 @@ #include <linux/device.h> #include <linux/notifier.h> #include <linux/regulator/consumer.h> +#include <linux/regulator/proxy-consumer.h> struct regmap; struct regulator_dev; @@ -87,6 +88,10 @@ struct regulator_linear_range { * if the selector indicates a voltage that is unusable on this system; * or negative errno. Selectors range from zero to one less than * regulator_desc.n_voltages. Voltages may be reported in any order. + * @list_corner_voltage: Return the maximum voltage in microvolts that + * that can be physically configured for the regulator when operating at + * the specified voltage corner or a negative errno if the corner value + * can't be used on this system. * * @set_current_limit: Configure a limit for a current-limited regulator. * The driver should select the current closest to max_uA. @@ -133,6 +138,7 @@ struct regulator_ops { /* enumerate supported voltages */ int (*list_voltage) (struct regulator_dev *, unsigned selector); + int (*list_corner_voltage)(struct regulator_dev *, int corner); /* get/set regulator voltage */ int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV, @@ -370,6 +376,7 @@ struct regulator_dev { int exclusive; u32 use_count; u32 open_count; + u32 open_offset; u32 bypass_count; /* lists we belong to */ @@ -399,6 +406,8 @@ struct regulator_dev { /* time when this regulator was disabled last time */ unsigned long last_off_jiffy; + struct proxy_consumer *proxy_consumer; + struct regulator *debug_consumer; }; struct regulator_dev * diff --git a/include/linux/regulator/msm-ldo-regulator.h b/include/linux/regulator/msm-ldo-regulator.h new file mode 100644 index 000000000000..ad04e294cfe6 --- /dev/null +++ b/include/linux/regulator/msm-ldo-regulator.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015-2016, 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 __MSM_LDO_REGULATOR_H__ +#define __MSM_LDO_REGULATOR_H__ + +/** + * enum msm_ldo_supply_mode - supported operating modes by this regulator type. + * Use negative logic to ensure BHS mode is treated as the safe default by the + * the regulator framework. This is necessary since LDO mode can only be enabled + * when several constraints are satisfied. Consumers of this regulator are + * expected to request changes in operating modes through the use of + * regulator_allow_bypass() passing in the desired LDO supply mode. + * %BHS_MODE: to select BHS as operating mode + * %LDO_MODE: to select LDO as operating mode + */ +enum msm_ldo_supply_mode { + BHS_MODE = false, + LDO_MODE = true, +}; + +#endif /* __MSM_LDO_REGULATOR_H__ */ diff --git a/include/linux/regulator/onsemi-ncp6335d.h b/include/linux/regulator/onsemi-ncp6335d.h new file mode 100644 index 000000000000..399742f7e2ac --- /dev/null +++ b/include/linux/regulator/onsemi-ncp6335d.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2012-2014, 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 __NCP6335D_H__ +#define __NCP6335D_H__ + +enum { + NCP6335D_VSEL0, + NCP6335D_VSEL1, +}; + +struct ncp6335d_platform_data { + struct regulator_init_data *init_data; + int default_vsel; + int slew_rate_ns; + int discharge_enable; + bool sleep_enable; +}; + +#ifdef CONFIG_REGULATOR_ONSEMI_NCP6335D +int __init ncp6335d_regulator_init(void); +#else +static inline int __init ncp6335d_regulator_init(void) { return 0; } +#endif + +#endif diff --git a/include/linux/regulator/proxy-consumer.h b/include/linux/regulator/proxy-consumer.h new file mode 100644 index 000000000000..10ba5411a983 --- /dev/null +++ b/include/linux/regulator/proxy-consumer.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 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 _LINUX_REGULATOR_PROXY_CONSUMER_H_ +#define _LINUX_REGULATOR_PROXY_CONSUMER_H_ + +#include <linux/device.h> +#include <linux/of.h> + +struct proxy_consumer; + +#ifdef CONFIG_REGULATOR_PROXY_CONSUMER + +struct proxy_consumer *regulator_proxy_consumer_register(struct device *reg_dev, + struct device_node *reg_node); + +int regulator_proxy_consumer_unregister(struct proxy_consumer *consumer); + +#else + +static inline struct proxy_consumer *regulator_proxy_consumer_register( + struct device *reg_dev, struct device_node *reg_node) +{ return NULL; } + +static inline int regulator_proxy_consumer_unregister( + struct proxy_consumer *consumer) +{ return 0; } + +#endif + +#endif diff --git a/include/linux/regulator/qpnp-labibb-regulator.h b/include/linux/regulator/qpnp-labibb-regulator.h new file mode 100644 index 000000000000..33985afeb6e9 --- /dev/null +++ b/include/linux/regulator/qpnp-labibb-regulator.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2017 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 _QPNP_LABIBB_REGULATOR_H +#define _QPNP_LABIBB_REGULATOR_H + +enum labibb_notify_event { + LAB_VREG_OK = 1, + LAB_VREG_NOT_OK, +}; + +int qpnp_labibb_notifier_register(struct notifier_block *nb); +int qpnp_labibb_notifier_unregister(struct notifier_block *nb); + +#endif diff --git a/include/linux/regulator/qpnp-regulator.h b/include/linux/regulator/qpnp-regulator.h new file mode 100644 index 000000000000..36288c068ac3 --- /dev/null +++ b/include/linux/regulator/qpnp-regulator.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012-2013, 2017, 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 __REGULATOR_QPNP_REGULATOR_H__ +#define __REGULATOR_QPNP_REGULATOR_H__ + +#include <linux/regulator/machine.h> + +#define QPNP_REGULATOR_DRIVER_NAME "qcom,qpnp-regulator" + +/* Pin control enable input pins. */ +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_NONE 0x00 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN0 0x01 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN1 0x02 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN2 0x04 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_EN3 0x08 +#define QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT 0x10 + +/* Pin control high power mode input pins. */ +#define QPNP_REGULATOR_PIN_CTRL_HPM_NONE 0x00 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN0 0x01 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN1 0x02 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN2 0x04 +#define QPNP_REGULATOR_PIN_CTRL_HPM_EN3 0x08 +#define QPNP_REGULATOR_PIN_CTRL_HPM_SLEEP_B 0x10 +#define QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT 0x20 + +/* + * Used with enable parameters to specify that hardware default register values + * should be left unaltered. + */ +#define QPNP_REGULATOR_DISABLE 0 +#define QPNP_REGULATOR_ENABLE 1 +#define QPNP_REGULATOR_USE_HW_DEFAULT 2 + +/* Soft start strength of a voltage switch type regulator */ +enum qpnp_vs_soft_start_str { + QPNP_VS_SOFT_START_STR_0P05_UA, + QPNP_VS_SOFT_START_STR_0P25_UA, + QPNP_VS_SOFT_START_STR_0P55_UA, + QPNP_VS_SOFT_START_STR_0P75_UA, + QPNP_VS_SOFT_START_STR_HW_DEFAULT, +}; + +/* Current limit of a boost type regulator */ +enum qpnp_boost_current_limit { + QPNP_BOOST_CURRENT_LIMIT_300_MA, + QPNP_BOOST_CURRENT_LIMIT_600_MA, + QPNP_BOOST_CURRENT_LIMIT_900_MA, + QPNP_BOOST_CURRENT_LIMIT_1200_MA, + QPNP_BOOST_CURRENT_LIMIT_1500_MA, + QPNP_BOOST_CURRENT_LIMIT_1800_MA, + QPNP_BOOST_CURRENT_LIMIT_2100_MA, + QPNP_BOOST_CURRENT_LIMIT_2400_MA, + QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT, +}; + +/** + * struct qpnp_regulator_platform_data - qpnp-regulator initialization data + * @init_data: regulator constraints + * @pull_down_enable: 1 = Enable output pull down resistor when the + * regulator is disabled + * 0 = Disable pull down resistor + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * pull down state + * @pin_ctrl_enable: Bit mask specifying which hardware pins should be + * used to enable the regulator, if any + * Value should be an ORing of + * QPNP_REGULATOR_PIN_CTRL_ENABLE_* constants. If + * the bit specified by + * QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT is + * set, then pin control enable hardware registers + * will not be modified. + * @pin_ctrl_hpm: Bit mask specifying which hardware pins should be + * used to force the regulator into high power + * mode, if any + * Value should be an ORing of + * QPNP_REGULATOR_PIN_CTRL_HPM_* constants. If + * the bit specified by + * QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT is + * set, then pin control mode hardware registers + * will not be modified. + * @system_load: Load in uA present on regulator that is not captured + * by any consumer request + * @enable_time: Time in us to delay after enabling the regulator + * @ocp_enable: 1 = Allow over current protection (OCP) to be + * enabled for voltage switch type regulators so + * that they latch off automatically when over + * current is detected. OCP is enabled when in HPM + * or auto mode. + * 0 = Disable OCP + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * OCP state + * @ocp_irq: IRQ number of the voltage switch OCP IRQ. If + * specified the voltage switch will be toggled off + * and back on when OCP triggers in order to handle + * high in-rush current. + * @ocp_max_retries: Maximum number of times to try toggling a voltage + * switch off and back on as a result of + * consecutive over current events. + * @ocp_retry_delay_ms: Time to delay in milliseconds between each + * voltage switch toggle after an over current + * event takes place. + * @boost_current_limit: This parameter sets the current limit of boost type + * regulators. Its value should be one of + * QPNP_BOOST_CURRENT_LIMIT_*. If its value is + * QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT, then the + * boost current limit will be left at its default + * hardware value. + * @soft_start_enable: 1 = Enable soft start for LDO and voltage switch + * type regulators so that output voltage slowly + * ramps up when the regulator is enabled + * 0 = Disable soft start + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * soft start state + * @vs_soft_start_strength: This parameter sets the soft start strength for + * voltage switch type regulators. Its value + * should be one of QPNP_VS_SOFT_START_STR_*. If + * its value is QPNP_VS_SOFT_START_STR_HW_DEFAULT, + * then the soft start strength will be left at its + * default hardware value. + * @auto_mode_enable: 1 = Enable automatic hardware selection of regulator + * mode (HPM vs LPM). Auto mode is not available + * on boost type regulators + * 0 = Disable auto mode selection + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * auto mode state + * @bypass_mode_enable: 1 = Enable bypass mode for an LDO type regulator so + * that it acts like a switch and simply outputs + * its input voltage + * 0 = Do not enable bypass mode + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * bypass mode state + * @hpm_enable: 1 = Enable high power mode (HPM), also referred to + * as NPM. HPM consumes more ground current than + * LPM, but it can source significantly higher load + * current. HPM is not available on boost type + * regulators. For voltage switch type regulators, + * HPM implies that over current protection and + * soft start are active all the time. This + * configuration can be overwritten by changing the + * regulator's mode dynamically. + * 0 = Do not enable HPM + * QPNP_REGULATOR_USE_HW_DEFAULT = do not modify + * HPM state + * @base_addr: SMPI base address for the regulator peripheral + */ +struct qpnp_regulator_platform_data { + struct regulator_init_data init_data; + int pull_down_enable; + unsigned int pin_ctrl_enable; + unsigned int pin_ctrl_hpm; + int system_load; + int enable_time; + int ocp_enable; + int ocp_irq; + int ocp_max_retries; + int ocp_retry_delay_ms; + enum qpnp_boost_current_limit boost_current_limit; + int soft_start_enable; + enum qpnp_vs_soft_start_str vs_soft_start_strength; + int auto_mode_enable; + int bypass_mode_enable; + int hpm_enable; + u16 base_addr; +}; + +#ifdef CONFIG_REGULATOR_QPNP + +/** + * qpnp_regulator_init() - register spmi driver for qpnp-regulator + * + * This initialization function should be called in systems in which driver + * registration ordering must be controlled precisely. + */ +int __init qpnp_regulator_init(void); + +#else + +static inline int __init qpnp_regulator_init(void) +{ + return -ENODEV; +} + +#endif /* CONFIG_REGULATOR_QPNP */ + +#endif diff --git a/include/linux/regulator/rpm-smd-regulator.h b/include/linux/regulator/rpm-smd-regulator.h new file mode 100644 index 000000000000..c57995d3f5a2 --- /dev/null +++ b/include/linux/regulator/rpm-smd-regulator.h @@ -0,0 +1,132 @@ +/* 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 _LINUX_REGULATOR_RPM_SMD_H +#define _LINUX_REGULATOR_RPM_SMD_H + +#include <linux/device.h> + +struct rpm_regulator; + +/** + * enum rpm_regulator_voltage_corner - possible voltage corner values + * + * These should be used in regulator_set_voltage() and + * rpm_regulator_set_voltage() calls for corner type regulators as if they had + * units of uV. + * + * Note, the meaning of corner values is set by the RPM. It is possible that + * future platforms will utilize different corner values. The values specified + * in this enum correspond to MSM8974 for PMIC PM8841 SMPS 2 (VDD_Dig). + */ +enum rpm_regulator_voltage_corner { + RPM_REGULATOR_CORNER_NONE = 1, + RPM_REGULATOR_CORNER_RETENTION, + RPM_REGULATOR_CORNER_SVS_KRAIT, + RPM_REGULATOR_CORNER_SVS_SOC, + RPM_REGULATOR_CORNER_NORMAL, + RPM_REGULATOR_CORNER_TURBO, + RPM_REGULATOR_CORNER_SUPER_TURBO, +}; + +/** + * enum rpm_regulator_voltage_level - possible voltage level values + * + * These should be used in regulator_set_voltage() and + * rpm_regulator_set_voltage() calls for level type regulators as if they had + * units of uV. + * + * Note: the meaning of level values is set by the RPM. + */ +enum rpm_regulator_voltage_level { + RPM_REGULATOR_LEVEL_NONE = 0, + RPM_REGULATOR_LEVEL_RETENTION = 16, + RPM_REGULATOR_LEVEL_RETENTION_PLUS = 32, + RPM_REGULATOR_LEVEL_MIN_SVS = 48, + RPM_REGULATOR_LEVEL_LOW_SVS = 64, + RPM_REGULATOR_LEVEL_SVS = 128, + RPM_REGULATOR_LEVEL_SVS_PLUS = 192, + RPM_REGULATOR_LEVEL_NOM = 256, + RPM_REGULATOR_LEVEL_NOM_PLUS = 320, + RPM_REGULATOR_LEVEL_TURBO = 384, + RPM_REGULATOR_LEVEL_BINNING = 512, + RPM_REGULATOR_LEVEL_MAX = 65535, +}; + +/** + * enum rpm_regulator_mode - control mode for LDO or SMPS type regulators + * %RPM_REGULATOR_MODE_AUTO: For SMPS type regulators, use SMPS auto mode so + * that the hardware can automatically switch + * between PFM and PWM modes based on realtime + * load. + * LDO type regulators do not support this mode. + * %RPM_REGULATOR_MODE_IPEAK: For SMPS type regulators, use aggregated + * software current requests to determine + * usage of PFM or PWM mode. + * For LDO type regulators, use aggregated + * software current requests to determine + * usage of LPM or HPM mode. + * %RPM_REGULATOR_MODE_HPM: For SMPS type regulators, force the + * usage of PWM mode. + * For LDO type regulators, force the + * usage of HPM mode. + * + * These values should be used in calls to rpm_regulator_set_mode(). + */ +enum rpm_regulator_mode { + RPM_REGULATOR_MODE_AUTO, + RPM_REGULATOR_MODE_IPEAK, + RPM_REGULATOR_MODE_HPM, +}; + +#ifdef CONFIG_REGULATOR_RPM_SMD + +struct rpm_regulator *rpm_regulator_get(struct device *dev, const char *supply); + +void rpm_regulator_put(struct rpm_regulator *regulator); + +int rpm_regulator_enable(struct rpm_regulator *regulator); + +int rpm_regulator_disable(struct rpm_regulator *regulator); + +int rpm_regulator_set_voltage(struct rpm_regulator *regulator, int min_uV, + int max_uV); + +int rpm_regulator_set_mode(struct rpm_regulator *regulator, + enum rpm_regulator_mode mode); + +int __init rpm_smd_regulator_driver_init(void); + +#else + +static inline struct rpm_regulator *rpm_regulator_get(struct device *dev, + const char *supply) { return NULL; } + +static inline void rpm_regulator_put(struct rpm_regulator *regulator) { } + +static inline int rpm_regulator_enable(struct rpm_regulator *regulator) + { return 0; } + +static inline int rpm_regulator_disable(struct rpm_regulator *regulator) + { return 0; } + +static inline int rpm_regulator_set_voltage(struct rpm_regulator *regulator, + int min_uV, int max_uV) { return 0; } + +static inline int rpm_regulator_set_mode(struct rpm_regulator *regulator, + enum rpm_regulator_mode mode) { return 0; } + +static inline int __init rpm_smd_regulator_driver_init(void) { return 0; } + +#endif /* CONFIG_REGULATOR_RPM_SMD */ + +#endif diff --git a/include/linux/regulator/spm-regulator.h b/include/linux/regulator/spm-regulator.h new file mode 100644 index 000000000000..bd5da2e3352b --- /dev/null +++ b/include/linux/regulator/spm-regulator.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2013-2014, 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 _LINUX_REGULATOR_SPM_H +#define _LINUX_REGULATOR_SPM_H + +#include <linux/err.h> +#include <linux/init.h> + +#ifdef CONFIG_REGULATOR_SPM +int __init spm_regulator_init(void); +#else +static inline int __init spm_regulator_init(void) { return -ENODEV; } +#endif + +#endif diff --git a/include/linux/regulator/stub-regulator.h b/include/linux/regulator/stub-regulator.h new file mode 100644 index 000000000000..1155d82ba27b --- /dev/null +++ b/include/linux/regulator/stub-regulator.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2012, 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 __STUB_REGULATOR_H__ +#define __STUB_REGULATOR_H__ + +#include <linux/regulator/machine.h> + +#define STUB_REGULATOR_DRIVER_NAME "stub-regulator" + +/** + * struct stub_regulator_pdata - stub regulator device data + * @init_data: regulator constraints + * @hpm_min_load: minimum load in uA that will result in the regulator + * being set to high power mode + * @system_uA: current drawn from regulator not accounted for by any + * regulator framework consumer + */ +struct stub_regulator_pdata { + struct regulator_init_data init_data; + int hpm_min_load; + int system_uA; +}; + +#ifdef CONFIG_REGULATOR_STUB + +/** + * regulator_stub_init() - register platform driver for stub-regulator + * + * This initialization function should be called in systems in which driver + * registration ordering must be controlled precisely. + */ + +int __init regulator_stub_init(void); + +#else + +static inline int __init regulator_stub_init(void) +{ + return -ENODEV; +} + +#endif /* CONFIG_REGULATOR_STUB */ + +#endif diff --git a/include/linux/remote_spinlock.h b/include/linux/remote_spinlock.h new file mode 100644 index 000000000000..591c1b24df9c --- /dev/null +++ b/include/linux/remote_spinlock.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2008-2009, 2011, 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 __LINUX_REMOTE_SPINLOCK_H +#define __LINUX_REMOTE_SPINLOCK_H + +#include <linux/spinlock.h> +#include <linux/msm_remote_spinlock.h> + +/* Grabbing a local spin lock before going for a remote lock has several + * advantages: + * 1. Get calls to preempt enable/disable and IRQ save/restore for free. + * 2. For UP kernel, there is no overhead. + * 3. Reduces the possibility of executing the remote spin lock code. This is + * especially useful when the remote CPUs' mutual exclusion instructions + * don't work with the local CPUs' instructions. In such cases, one has to + * use software based mutex algorithms (e.g. Lamport's bakery algorithm) + * which could get expensive when the no. of contending CPUs is high. + * 4. In the case of software based mutex algorithm the exection time will be + * smaller since the no. of contending CPUs is reduced by having just one + * contender for all the local CPUs. + * 5. Get most of the spin lock debug features for free. + * 6. The code will continue to work "gracefully" even when the remote spin + * lock code is stubbed out for debug purposes or when there is no remote + * CPU in some board/machine types. + */ +typedef struct { + spinlock_t local; + _remote_spinlock_t remote; +} remote_spinlock_t; + +#define remote_spin_lock_init(lock, id) \ + ({ \ + spin_lock_init(&((lock)->local)); \ + _remote_spin_lock_init(id, &((lock)->remote)); \ + }) +#define remote_spin_lock(lock) \ + do { \ + spin_lock(&((lock)->local)); \ + _remote_spin_lock(&((lock)->remote)); \ + } while (0) +#define remote_spin_unlock(lock) \ + do { \ + _remote_spin_unlock(&((lock)->remote)); \ + spin_unlock(&((lock)->local)); \ + } while (0) +#define remote_spin_lock_irqsave(lock, flags) \ + do { \ + spin_lock_irqsave(&((lock)->local), flags); \ + _remote_spin_lock(&((lock)->remote)); \ + } while (0) +#define remote_spin_unlock_irqrestore(lock, flags) \ + do { \ + _remote_spin_unlock(&((lock)->remote)); \ + spin_unlock_irqrestore(&((lock)->local), flags); \ + } while (0) +#define remote_spin_trylock(lock) \ + ({ \ + spin_trylock(&((lock)->local)) \ + ? _remote_spin_trylock(&((lock)->remote)) \ + ? 1 \ + : ({ spin_unlock(&((lock)->local)); 0; }) \ + : 0; \ + }) +#define remote_spin_trylock_irqsave(lock, flags) \ + ({ \ + spin_trylock_irqsave(&((lock)->local), flags) \ + ? _remote_spin_trylock(&((lock)->remote)) \ + ? 1 \ + : ({ spin_unlock_irqrestore(&((lock)->local), flags); \ + 0; }) \ + : 0; \ + }) +#define remote_spin_lock_rlock_id(lock, tid) \ + _remote_spin_lock_rlock_id(&((lock)->remote), tid) + +#define remote_spin_unlock_rlock(lock) \ + _remote_spin_unlock_rlock(&((lock)->remote)) + +#define remote_spin_release(lock, pid) \ + _remote_spin_release(&((lock)->remote), pid) + +#define remote_spin_release_all(pid) \ + _remote_spin_release_all(pid) + +#define remote_spin_owner(lock) \ + _remote_spin_owner(&((lock)->remote)) + +#define remote_spin_get_hw_spinlocks_element(lock) \ + _remote_spin_get_hw_spinlocks_element(&((lock)->remote)) +#endif diff --git a/include/linux/rmap.h b/include/linux/rmap.h index ddda2ac3446e..e72b85737a99 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -10,6 +10,11 @@ #include <linux/rwsem.h> #include <linux/memcontrol.h> +extern int isolate_lru_page(struct page *page); +extern void putback_lru_page(struct page *page); +extern unsigned long reclaim_pages_from_list(struct list_head *page_list, + struct vm_area_struct *vma); + /* * The anon_vma heads a list of private "related" vmas, to scan if * an anonymous page pointing to this anon_vma needs to be unmapped: @@ -176,7 +181,8 @@ int page_referenced(struct page *, int is_locked, #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK) -int try_to_unmap(struct page *, enum ttu_flags flags); +int try_to_unmap(struct page *, enum ttu_flags flags, + struct vm_area_struct *vma); /* * Used by uprobes to replace a userspace page safely @@ -232,6 +238,7 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); */ struct rmap_walk_control { void *arg; + struct vm_area_struct *target_vma; int (*rmap_one)(struct page *page, struct vm_area_struct *vma, unsigned long addr, void *arg); int (*done)(struct page *page); @@ -255,7 +262,7 @@ static inline int page_referenced(struct page *page, int is_locked, return 0; } -#define try_to_unmap(page, refs) SWAP_FAIL +#define try_to_unmap(page, refs, vma) SWAP_FAIL static inline int page_mkclean(struct page *page) { diff --git a/include/linux/rndis_ipa.h b/include/linux/rndis_ipa.h new file mode 100644 index 000000000000..9dcb8c30901b --- /dev/null +++ b/include/linux/rndis_ipa.h @@ -0,0 +1,102 @@ +/* Copyright (c) 2013-2016, 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 _RNDIS_IPA_H_ +#define _RNDIS_IPA_H_ + +#include <linux/ipa.h> + +/* + * @priv: private data given upon ipa_connect + * @evt: event enum, should be IPA_WRITE_DONE + * @data: for tx path the data field is the sent socket buffer. + */ +typedef void (*ipa_callback)(void *priv, + enum ipa_dp_evt_type evt, + unsigned long data); + +/* + * struct ipa_usb_init_params - parameters for driver initialization API + * + * @device_ready_notify: callback supplied by USB core driver + * This callback shall be called by the Netdev once the device + * is ready to recieve data from tethered PC. + * @ipa_rx_notify: The network driver will set this callback (out parameter). + * this callback shall be supplied for ipa_connect upon pipe + * connection (USB->IPA), once IPA driver receive data packets + * from USB pipe destined for Apps this callback will be called. + * @ipa_tx_notify: The network driver will set this callback (out parameter). + * this callback shall be supplied for ipa_connect upon pipe + * connection (IPA->USB), once IPA driver send packets destined + * for USB, IPA BAM will notify for Tx-complete. + * @host_ethaddr: host Ethernet address in network order + * @device_ethaddr: device Ethernet address in network order + * @private: The network driver will set this pointer (out parameter). + * This pointer will hold the network device for later interaction + * with between USB driver and the network driver. + * @skip_ep_cfg: boolean field that determines if Apps-processor + * should or should not configure this end-point. + */ +struct ipa_usb_init_params { + void (*device_ready_notify)(void); + ipa_callback ipa_rx_notify; + ipa_callback ipa_tx_notify; + u8 host_ethaddr[ETH_ALEN]; + u8 device_ethaddr[ETH_ALEN]; + void *private; + bool skip_ep_cfg; +}; + +#ifdef CONFIG_RNDIS_IPA + +int rndis_ipa_init(struct ipa_usb_init_params *params); + +int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl, + u32 ipa_to_usb_hdl, + u32 max_xfer_size_bytes_to_dev, + u32 max_packet_number_to_dev, + u32 max_xfer_size_bytes_to_host, + void *private); + +int rndis_ipa_pipe_disconnect_notify(void *private); + +void rndis_ipa_cleanup(void *private); + +#else /* CONFIG_RNDIS_IPA*/ + +static inline int rndis_ipa_init(struct ipa_usb_init_params *params) +{ + return -ENOMEM; +} + +static inline int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl, + u32 ipa_to_usb_hdl, + u32 max_xfer_size_bytes_to_dev, + u32 max_packet_number_to_dev, + u32 max_xfer_size_bytes_to_host, + void *private) +{ + return -ENOMEM; +} + +static inline int rndis_ipa_pipe_disconnect_notify(void *private) +{ + return -ENOMEM; +} + +static inline void rndis_ipa_cleanup(void *private) +{ + +} +#endif /* CONFIG_RNDIS_IPA */ + +#endif /* _RNDIS_IPA_H_ */ diff --git a/include/linux/rq_stats.h b/include/linux/rq_stats.h new file mode 100644 index 000000000000..44cd8426de37 --- /dev/null +++ b/include/linux/rq_stats.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2011,2013-2014, 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. + * + */ + +struct rq_data { + unsigned int rq_avg; + unsigned long rq_poll_jiffies; + unsigned long def_timer_jiffies; + unsigned long rq_poll_last_jiffy; + unsigned long rq_poll_total_jiffies; + unsigned long def_timer_last_jiffy; + unsigned int hotplug_disabled; + int64_t def_start_time; + struct attribute_group *attr_group; + struct kobject *kobj; + struct work_struct def_timer_work; + int init; +}; + +extern spinlock_t rq_lock; +extern struct rq_data rq_info; +extern struct workqueue_struct *rq_wq; diff --git a/include/linux/sched.h b/include/linux/sched.h index 0af3977aeda2..5f59b7fc2a13 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -178,6 +178,28 @@ extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load); extern u64 nr_running_integral(unsigned int cpu); #endif +extern void sched_update_nr_prod(int cpu, long delta, bool inc); +extern void sched_get_nr_running_avg(int *avg, int *iowait_avg, int *big_avg, + unsigned int *max_nr, + unsigned int *big_max_nr); +extern u64 sched_get_cpu_last_busy_time(int cpu); + +#ifdef CONFIG_SMP +extern u32 sched_get_wake_up_idle(struct task_struct *p); +extern int sched_set_wake_up_idle(struct task_struct *p, int wake_up_idle); +#else +static inline u32 sched_get_wake_up_idle(struct task_struct *p) +{ + return 0; +} + +static inline int sched_set_wake_up_idle(struct task_struct *p, + int wake_up_idle) +{ + return 0; +} +#endif /* CONFIG_SMP */ + extern void calc_global_load(unsigned long ticks); #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) @@ -319,6 +341,8 @@ extern char ___assert_task_state[1 - 2*!!( /* Task command name length */ #define TASK_COMM_LEN 16 +extern const char *sched_window_reset_reasons[]; + enum task_event { PUT_PREV_TASK = 0, PICK_NEXT_TASK = 1, @@ -328,6 +352,12 @@ enum task_event { IRQ_UPDATE = 5, }; +/* Note: this need to be in sync with migrate_type_names array */ +enum migrate_types { + GROUP_TO_RQ, + RQ_TO_GROUP, +}; + #include <linux/spinlock.h> /* @@ -355,6 +385,41 @@ extern cpumask_var_t cpu_isolated_map; extern int runqueue_is_locked(int cpu); +#ifdef CONFIG_HOTPLUG_CPU +extern int sched_isolate_count(const cpumask_t *mask, bool include_offline); +extern int sched_isolate_cpu(int cpu); +extern int sched_unisolate_cpu(int cpu); +extern int sched_unisolate_cpu_unlocked(int cpu); +#else +static inline int sched_isolate_count(const cpumask_t *mask, + bool include_offline) +{ + cpumask_t count_mask; + + if (include_offline) + cpumask_andnot(&count_mask, mask, cpu_online_mask); + else + return 0; + + return cpumask_weight(&count_mask); +} + +static inline int sched_isolate_cpu(int cpu) +{ + return 0; +} + +static inline int sched_unisolate_cpu(int cpu) +{ + return 0; +} + +static inline int sched_unisolate_cpu_unlocked(int cpu) +{ + return 0; +} +#endif + #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) extern void nohz_balance_enter_idle(int cpu); extern void set_cpu_sd_state_idle(void); @@ -391,6 +456,7 @@ extern void scheduler_tick(void); extern void sched_show_task(struct task_struct *p); #ifdef CONFIG_LOCKUP_DETECTOR +extern void touch_softlockup_watchdog_sched(void); extern void touch_softlockup_watchdog(void); extern void touch_softlockup_watchdog_sync(void); extern void touch_all_softlockup_watchdogs(void); @@ -400,7 +466,13 @@ extern int proc_dowatchdog_thresh(struct ctl_table *table, int write, extern unsigned int softlockup_panic; extern unsigned int hardlockup_panic; void lockup_detector_init(void); +extern void watchdog_enable(unsigned int cpu); +extern void watchdog_disable(unsigned int cpu); +extern bool watchdog_configured(unsigned int cpu); #else +static inline void touch_softlockup_watchdog_sched(void) +{ +} static inline void touch_softlockup_watchdog(void) { } @@ -413,6 +485,20 @@ static inline void touch_all_softlockup_watchdogs(void) static inline void lockup_detector_init(void) { } +static inline void watchdog_enable(unsigned int cpu) +{ +} +static inline void watchdog_disable(unsigned int cpu) +{ +} +static inline bool watchdog_configured(unsigned int cpu) +{ + /* + * Predend the watchdog is always configured. + * We will be waiting for the watchdog to be enabled in core isolation + */ + return true; +} #endif #ifdef CONFIG_DETECT_HUNG_TASK @@ -1361,8 +1447,8 @@ struct sched_statistics { }; #endif -#ifdef CONFIG_SCHED_WALT #define RAVG_HIST_SIZE_MAX 5 +#define NUM_BUSY_BUCKETS 10 /* ravg represents frequency scaled cpu-demand of tasks */ struct ravg { @@ -1382,19 +1468,31 @@ struct ravg { * sysctl_sched_ravg_hist_size windows. 'demand' could drive frequency * demand for tasks. * - * 'curr_window' represents task's contribution to cpu busy time - * statistics (rq->curr_runnable_sum) in current window + * 'curr_window_cpu' represents task's contribution to cpu busy time on + * various CPUs in the current window + * + * 'prev_window_cpu' represents task's contribution to cpu busy time on + * various CPUs in the previous window * - * 'prev_window' represents task's contribution to cpu busy time - * statistics (rq->prev_runnable_sum) in previous window + * 'curr_window' represents the sum of all entries in curr_window_cpu + * + * 'prev_window' represents the sum of all entries in prev_window_cpu + * + * 'pred_demand' represents task's current predicted cpu busy time + * + * 'busy_buckets' groups historical busy time into different buckets + * used for prediction */ u64 mark_start; u32 sum, demand; u32 sum_history[RAVG_HIST_SIZE_MAX]; + u32 *curr_window_cpu, *prev_window_cpu; u32 curr_window, prev_window; + u64 curr_burst, avg_burst, avg_sleep_time; u16 active_windows; + u32 pred_demand; + u8 busy_buckets[NUM_BUSY_BUCKETS]; }; -#endif struct sched_entity { struct load_weight load; /* for load-balancing */ @@ -1433,6 +1531,8 @@ struct sched_rt_entity { unsigned long timeout; unsigned long watchdog_stamp; unsigned int time_slice; + unsigned short on_rq; + unsigned short on_list; /* Accesses for these must be guarded by rq->lock of the task's rq */ bool schedtune_enqueued; @@ -1568,16 +1668,21 @@ struct task_struct { const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; -#ifdef CONFIG_SCHED_WALT +#ifdef CONFIG_SCHED_HMP struct ravg ravg; /* * 'init_load_pct' represents the initial task load assigned to children * of this task */ u32 init_load_pct; + u64 last_wake_ts; + u64 last_switch_out_ts; + u64 last_cpu_selected_ts; + struct related_thread_group *grp; + struct list_head grp_list; + u64 cpu_cycles; u64 last_sleep_ts; #endif - #ifdef CONFIG_CGROUP_SCHED struct task_group *sched_task_group; #endif @@ -1819,6 +1924,9 @@ struct task_struct { struct held_lock held_locks[MAX_LOCK_DEPTH]; gfp_t lockdep_reclaim_gfp; #endif +#ifdef CONFIG_UBSAN + unsigned int in_ubsan; +#endif /* journalling filesystem info */ void *journal_info; @@ -2131,8 +2239,8 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) return tsk->tgid; } - static inline int pid_alive(const struct task_struct *p); +static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) @@ -2269,6 +2377,7 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, /* * Per process flags */ +#define PF_WAKE_UP_IDLE 0x00000002 /* try to wake up on an idle CPU */ #define PF_EXITING 0x00000004 /* getting shut down */ #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ @@ -2451,6 +2560,7 @@ extern void do_set_cpus_allowed(struct task_struct *p, extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask); +extern bool cpupri_check_rt(void); #else static inline void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) @@ -2463,8 +2573,103 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, return -EINVAL; return 0; } +static inline bool cpupri_check_rt(void) +{ + return false; +} #endif +struct sched_load { + unsigned long prev_load; + unsigned long new_task_load; + unsigned long predicted_load; +}; + +struct cpu_cycle_counter_cb { + u64 (*get_cpu_cycle_counter)(int cpu); +}; + +#define MAX_NUM_CGROUP_COLOC_ID 20 + +#ifdef CONFIG_SCHED_HMP +extern void free_task_load_ptrs(struct task_struct *p); +extern int sched_set_window(u64 window_start, unsigned int window_size); +extern unsigned long sched_get_busy(int cpu); +extern void sched_get_cpus_busy(struct sched_load *busy, + const struct cpumask *query_cpus); +extern void sched_set_io_is_busy(int val); +extern int sched_set_boost(int enable); +extern int sched_set_init_task_load(struct task_struct *p, int init_load_pct); +extern u32 sched_get_init_task_load(struct task_struct *p); +extern int sched_set_static_cpu_pwr_cost(int cpu, unsigned int cost); +extern unsigned int sched_get_static_cpu_pwr_cost(int cpu); +extern int sched_set_static_cluster_pwr_cost(int cpu, unsigned int cost); +extern unsigned int sched_get_static_cluster_pwr_cost(int cpu); +extern int sched_set_cluster_wake_idle(int cpu, unsigned int wake_idle); +extern unsigned int sched_get_cluster_wake_idle(int cpu); +extern int sched_update_freq_max_load(const cpumask_t *cpumask); +extern void sched_update_cpu_freq_min_max(const cpumask_t *cpus, + u32 fmin, u32 fmax); +extern void sched_set_cpu_cstate(int cpu, int cstate, + int wakeup_energy, int wakeup_latency); +extern void sched_set_cluster_dstate(const cpumask_t *cluster_cpus, int dstate, + int wakeup_energy, int wakeup_latency); +extern int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb); +extern u64 sched_ktime_clock(void); +extern int sched_set_group_id(struct task_struct *p, unsigned int group_id); +extern unsigned int sched_get_group_id(struct task_struct *p); + +#else /* CONFIG_SCHED_HMP */ +static inline void free_task_load_ptrs(struct task_struct *p) { } + +static inline u64 sched_ktime_clock(void) +{ + return 0; +} + +static inline int +register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb) +{ + return 0; +} + +static inline int sched_set_window(u64 window_start, unsigned int window_size) +{ + return -EINVAL; +} +static inline unsigned long sched_get_busy(int cpu) +{ + return 0; +} +static inline void sched_get_cpus_busy(struct sched_load *busy, + const struct cpumask *query_cpus) {}; + +static inline void sched_set_io_is_busy(int val) {}; + +static inline int sched_set_boost(int enable) +{ + return -EINVAL; +} + +static inline int sched_update_freq_max_load(const cpumask_t *cpumask) +{ + return 0; +} + +static inline void sched_update_cpu_freq_min_max(const cpumask_t *cpus, + u32 fmin, u32 fmax) { } + +static inline void +sched_set_cpu_cstate(int cpu, int cstate, int wakeup_energy, int wakeup_latency) +{ +} + +static inline void sched_set_cluster_dstate(const cpumask_t *cluster_cpus, + int dstate, int wakeup_energy, int wakeup_latency) +{ +} +#endif /* CONFIG_SCHED_HMP */ + #ifdef CONFIG_NO_HZ_COMMON void calc_load_enter_idle(void); void calc_load_exit_idle(void); @@ -2473,6 +2678,14 @@ static inline void calc_load_enter_idle(void) { } static inline void calc_load_exit_idle(void) { } #endif /* CONFIG_NO_HZ_COMMON */ +static inline void set_wake_up_idle(bool enabled) +{ + if (enabled) + current->flags |= PF_WAKE_UP_IDLE; + else + current->flags &= ~PF_WAKE_UP_IDLE; +} + /* * Do not use outside of architecture code which knows its limitations. * @@ -2490,8 +2703,8 @@ extern u64 local_clock(void); extern u64 running_clock(void); extern u64 sched_clock_cpu(int cpu); - extern void sched_clock_init(void); +extern int sched_clock_initialized(void); #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK static inline void sched_clock_tick(void) @@ -2538,7 +2751,7 @@ extern unsigned long long task_sched_runtime(struct task_struct *task); /* sched_exec is called by processes performing an exec */ -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) extern void sched_exec(void); #else #define sched_exec() {} @@ -2674,6 +2887,7 @@ extern void xtime_update(unsigned long ticks); extern int wake_up_state(struct task_struct *tsk, unsigned int state); extern int wake_up_process(struct task_struct *tsk); +extern int wake_up_process_no_notif(struct task_struct *tsk); extern void wake_up_new_task(struct task_struct *tsk); #ifdef CONFIG_SMP extern void kick_process(struct task_struct *tsk); @@ -2682,6 +2896,11 @@ extern void wake_up_new_task(struct task_struct *tsk); #endif extern int sched_fork(unsigned long clone_flags, struct task_struct *p); extern void sched_dead(struct task_struct *p); +#ifdef CONFIG_SCHED_HMP +extern void sched_exit(struct task_struct *p); +#else +static inline void sched_exit(struct task_struct *p) { } +#endif extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); @@ -2809,7 +3028,7 @@ static inline bool mmget_not_zero(struct mm_struct *mm) } /* mmput gets rid of the mappings and all user-space */ -extern void mmput(struct mm_struct *); +extern int mmput(struct mm_struct *); /* same as above but performs the slow path from the async kontext. Can * be called from the atomic context as well */ @@ -3234,6 +3453,15 @@ static inline void cond_resched_rcu(void) #endif } +static inline unsigned long get_preempt_disable_ip(struct task_struct *p) +{ +#ifdef CONFIG_DEBUG_PREEMPT + return p->preempt_disable_ip; +#else + return 0; +#endif +} + /* * Does a critical section need to be broken due to another * task waiting?: (technically does not depend on CONFIG_PREEMPT, @@ -3389,6 +3617,15 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) #endif /* CONFIG_SMP */ +extern struct atomic_notifier_head migration_notifier_head; +struct migration_notify_data { + int src_cpu; + int dest_cpu; + int load; +}; + +extern struct atomic_notifier_head load_alert_notifier_head; + extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); extern long sched_getaffinity(pid_t pid, struct cpumask *mask); @@ -3482,6 +3719,7 @@ static inline unsigned long rlimit_max(unsigned int limit) #define SCHED_CPUFREQ_RT (1U << 0) #define SCHED_CPUFREQ_DL (1U << 1) #define SCHED_CPUFREQ_IOWAIT (1U << 2) +#define SCHED_CPUFREQ_INTERCLUSTER_MIG (1U << 3) #ifdef CONFIG_CPU_FREQ struct update_util_data { diff --git a/include/linux/sched/core_ctl.h b/include/linux/sched/core_ctl.h new file mode 100644 index 000000000000..98d7cb3e899b --- /dev/null +++ b/include/linux/sched/core_ctl.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, 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 __CORE_CTL_H +#define __CORE_CTL_H + +#ifdef CONFIG_SCHED_CORE_CTL +void core_ctl_check(u64 wallclock); +int core_ctl_set_boost(bool boost); +#else +static inline void core_ctl_check(u64 wallclock) {} +static inline int core_ctl_set_boost(bool boost) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 167279a4e24b..f63ff97d246b 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -41,11 +41,53 @@ extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_child_runs_first; extern unsigned int sysctl_sched_sync_hint_enable; extern unsigned int sysctl_sched_cstate_aware; -#ifdef CONFIG_SCHED_WALT -extern unsigned int sysctl_sched_use_walt_cpu_util; -extern unsigned int sysctl_sched_use_walt_task_util; -extern unsigned int sysctl_sched_walt_init_task_load_pct; -extern unsigned int sysctl_sched_walt_cpu_high_irqload; + +#ifdef CONFIG_SCHED_HMP + +enum freq_reporting_policy { + FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK, + FREQ_REPORT_CPU_LOAD, + FREQ_REPORT_TOP_TASK, + FREQ_REPORT_INVALID_POLICY +}; + +extern int sysctl_sched_freq_inc_notify; +extern int sysctl_sched_freq_dec_notify; +extern unsigned int sysctl_sched_freq_reporting_policy; +extern unsigned int sysctl_sched_window_stats_policy; +extern unsigned int sysctl_sched_ravg_hist_size; +extern unsigned int sysctl_sched_cpu_high_irqload; +extern unsigned int sysctl_sched_init_task_load_pct; +extern __read_mostly unsigned int sysctl_sched_spill_nr_run; +extern unsigned int sysctl_sched_spill_load_pct; +extern unsigned int sysctl_sched_upmigrate_pct; +extern unsigned int sysctl_sched_downmigrate_pct; +extern unsigned int sysctl_sched_group_upmigrate_pct; +extern unsigned int sysctl_sched_group_downmigrate_pct; +extern unsigned int sysctl_early_detection_duration; +extern unsigned int sysctl_sched_boost; +extern unsigned int sysctl_sched_small_wakee_task_load_pct; +extern unsigned int sysctl_sched_big_waker_task_load_pct; +extern unsigned int sysctl_sched_select_prev_cpu_us; +extern unsigned int sysctl_sched_restrict_cluster_spill; +extern unsigned int sysctl_sched_new_task_windows; +extern unsigned int sysctl_sched_pred_alert_freq; +extern unsigned int sysctl_sched_freq_aggregate; +extern unsigned int sysctl_sched_enable_thread_grouping; +extern unsigned int sysctl_sched_freq_aggregate_threshold_pct; +extern unsigned int sysctl_sched_prefer_sync_wakee_to_waker; +extern unsigned int sysctl_sched_short_burst; +extern unsigned int sysctl_sched_short_sleep; + +#else /* CONFIG_SCHED_HMP */ + +#define sysctl_sched_enable_hmp_task_placement 0 + +#endif /* CONFIG_SCHED_HMP */ + +#if defined(CONFIG_PREEMPT_TRACER) || defined(CONFIG_IRQSOFF_TRACER) +extern unsigned int sysctl_preemptoff_tracing_threshold_ns; +extern unsigned int sysctl_irqsoff_tracing_threshold_ns; #endif enum sched_tunable_scaling { @@ -62,9 +104,9 @@ extern unsigned int sysctl_numa_balancing_scan_period_max; extern unsigned int sysctl_numa_balancing_scan_size; #ifdef CONFIG_SCHED_DEBUG -extern unsigned int sysctl_sched_migration_cost; -extern unsigned int sysctl_sched_nr_migrate; -extern unsigned int sysctl_sched_time_avg; +extern __read_mostly unsigned int sysctl_sched_migration_cost; +extern __read_mostly unsigned int sysctl_sched_nr_migrate; +extern __read_mostly unsigned int sysctl_sched_time_avg; extern unsigned int sysctl_sched_shares_window; int sched_proc_update_handler(struct ctl_table *table, int write, @@ -72,6 +114,18 @@ int sched_proc_update_handler(struct ctl_table *table, int write, loff_t *ppos); #endif +extern int sched_migrate_notify_proc_handler(struct ctl_table *table, + int write, void __user *buffer, size_t *lenp, loff_t *ppos); + +extern int sched_hmp_proc_update_handler(struct ctl_table *table, + int write, void __user *buffer, size_t *lenp, loff_t *ppos); + +extern int sched_boost_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + +extern int sched_window_update_handler(struct ctl_table *table, + int write, void __user *buffer, size_t *lenp, loff_t *ppos); + /* * control realtime throttling: * diff --git a/include/linux/sched_energy.h b/include/linux/sched_energy.h index 1daf3e1f98a7..a1057e481eff 100644 --- a/include/linux/sched_energy.h +++ b/include/linux/sched_energy.h @@ -29,6 +29,8 @@ #define for_each_possible_sd_level(level) \ for (level = 0; level < NR_SD_LEVELS; level++) +extern bool sched_energy_aware; + #ifdef CONFIG_SMP extern struct sched_group_energy *sge_array[NR_CPUS][NR_SD_LEVELS]; diff --git a/include/linux/sde_io_util.h b/include/linux/sde_io_util.h new file mode 100644 index 000000000000..da4a50722984 --- /dev/null +++ b/include/linux/sde_io_util.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2012, 2017, 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 __SDE_IO_UTIL_H__ +#define __SDE_IO_UTIL_H__ + +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/i2c.h> +#include <linux/types.h> + +#ifdef DEBUG +#define DEV_DBG(fmt, args...) pr_err(fmt, ##args) +#else +#define DEV_DBG(fmt, args...) pr_debug(fmt, ##args) +#endif +#define DEV_INFO(fmt, args...) pr_info(fmt, ##args) +#define DEV_WARN(fmt, args...) pr_warn(fmt, ##args) +#define DEV_ERR(fmt, args...) pr_err(fmt, ##args) + +struct dss_io_data { + u32 len; + void __iomem *base; +}; + +void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug); +u32 dss_reg_r(struct dss_io_data *io, u32 offset, u32 debug); +void dss_reg_dump(void __iomem *base, u32 len, const char *prefix, u32 debug); + +#define DSS_REG_W_ND(io, offset, val) dss_reg_w(io, offset, val, false) +#define DSS_REG_W(io, offset, val) dss_reg_w(io, offset, val, true) +#define DSS_REG_R_ND(io, offset) dss_reg_r(io, offset, false) +#define DSS_REG_R(io, offset) dss_reg_r(io, offset, true) + +enum dss_vreg_type { + DSS_REG_LDO, + DSS_REG_VS, +}; + +struct dss_vreg { + struct regulator *vreg; /* vreg handle */ + char vreg_name[32]; + int min_voltage; + int max_voltage; + int enable_load; + int disable_load; + int pre_on_sleep; + int post_on_sleep; + int pre_off_sleep; + int post_off_sleep; + bool lp_disable_allowed; + bool disabled; +}; + +struct dss_gpio { + unsigned int gpio; + unsigned int value; + char gpio_name[32]; +}; + +enum dss_clk_type { + DSS_CLK_AHB, /* no set rate. rate controlled through rpm */ + DSS_CLK_PCLK, + DSS_CLK_OTHER, +}; + +struct dss_clk { + struct clk *clk; /* clk handle */ + char clk_name[32]; + enum dss_clk_type type; + unsigned long rate; + unsigned long max_rate; +}; + +struct dss_module_power { + unsigned int num_vreg; + struct dss_vreg *vreg_config; + unsigned int num_gpio; + struct dss_gpio *gpio_config; + unsigned int num_clk; + struct dss_clk *clk_config; +}; + +int msm_dss_ioremap_byname(struct platform_device *pdev, + struct dss_io_data *io_data, const char *name); +void msm_dss_iounmap(struct dss_io_data *io_data); + +int msm_dss_enable_gpio(struct dss_gpio *in_gpio, int num_gpio, int enable); +int msm_dss_gpio_enable(struct dss_gpio *in_gpio, int num_gpio, int enable); + +int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg, + int num_vreg, int config); +int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable); + +int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk); +void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk); +int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk); +int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable); + +int sde_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr, + uint8_t reg_offset, uint8_t *read_buf); +int sde_i2c_byte_write(struct i2c_client *client, uint8_t slave_addr, + uint8_t reg_offset, uint8_t *value); + +#endif /* __SDE_IO_UTIL_H__ */ diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 5a53d34bba26..50c460a956f1 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -29,19 +29,13 @@ struct seccomp { }; #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -extern int __secure_computing(void); -static inline int secure_computing(void) +extern int __secure_computing(const struct seccomp_data *sd); +static inline int secure_computing(const struct seccomp_data *sd) { if (unlikely(test_thread_flag(TIF_SECCOMP))) - return __secure_computing(); + return __secure_computing(sd); return 0; } - -#define SECCOMP_PHASE1_OK 0 -#define SECCOMP_PHASE1_SKIP 1 - -extern u32 seccomp_phase1(struct seccomp_data *sd); -int seccomp_phase2(u32 phase1_result); #else extern void secure_computing_strict(int this_syscall); #endif @@ -62,7 +56,7 @@ struct seccomp { }; struct seccomp_filter { }; #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -static inline int secure_computing(void) { return 0; } +static inline int secure_computing(struct seccomp_data *sd) { return 0; } #else static inline void secure_computing_strict(int this_syscall) { return; } #endif diff --git a/include/linux/security.h b/include/linux/security.h index 2f4c1f7aa7db..7caf520e6233 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -28,6 +28,7 @@ #include <linux/err.h> #include <linux/string.h> #include <linux/mm.h> +#include <linux/bio.h> struct linux_binprm; struct cred; @@ -244,6 +245,7 @@ int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len); int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode); +int security_inode_post_create(struct inode *dir, struct dentry *dentry, umode_t mode); int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); int security_inode_unlink(struct inode *dir, struct dentry *dentry); @@ -605,6 +607,13 @@ static inline int security_inode_create(struct inode *dir, return 0; } +static inline int security_inode_post_create(struct inode *dir, + struct dentry *dentry, + umode_t mode) +{ + return 0; +} + static inline int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) diff --git a/include/linux/seemp_instrumentation.h b/include/linux/seemp_instrumentation.h new file mode 100644 index 000000000000..bd53d0d22ff2 --- /dev/null +++ b/include/linux/seemp_instrumentation.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 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 __SEEMP_LOGK_STUB__ +#define __SEEMP_LOGK_STUB__ + +#ifdef CONFIG_SEEMP_CORE +#include <linux/kernel.h> + +#define MAX_BUF_SIZE 188 + +#define SEEMP_LOGK_API_SIZE sizeof(int) + +/* Write: api_id + skip encoding byte + params */ +#define SEEMP_LOGK_RECORD(api_id, format, ...) do { \ + *((int *)(buf - SEEMP_LOGK_API_SIZE)) = api_id; \ + snprintf(buf + 1, MAX_BUF_SIZE - 1, format, ##__VA_ARGS__); \ +} while (0) + +extern void *(*seemp_logk_kernel_begin)(char **buf); +extern void (*seemp_logk_kernel_end)(void *blck); + +static inline void *seemp_setup_buf(char **buf) +{ + void *blck; + + if (seemp_logk_kernel_begin && seemp_logk_kernel_end) { + blck = seemp_logk_kernel_begin(buf); + if (!*buf) { + seemp_logk_kernel_end(blck); + return NULL; + } + } else { + return NULL; + } + return blck; +} +/* + * NOTE: only sendto is going to be instrumented + * since send sys call internally calls sendto + * with 2 extra parameters + */ +static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len, + unsigned flags, struct sockaddr __user *addr, int addr_len) +{ + char *buf = NULL; + void *blck = NULL; + + /*sets up buf and blck correctly*/ + blck = seemp_setup_buf(&buf); + if (!blck) + return; + + /*fill the buf*/ + SEEMP_LOGK_RECORD(SEEMP_API_kernel__sendto, "len=%u,fd=%d", + (unsigned int)len, fd); + + seemp_logk_kernel_end(blck); +} + +/* + * NOTE: only recvfrom is going to be instrumented + * since recv sys call internally calls recvfrom + * with 2 extra parameters + */ +static inline void seemp_logk_recvfrom(int fd, void __user *ubuf, + size_t size, unsigned flags, struct sockaddr __user *addr, + int __user *addr_len) +{ + char *buf = NULL; + void *blck = NULL; + + /*sets up buf and blck correctly*/ + blck = seemp_setup_buf(&buf); + if (!blck) + return; + + /*fill the buf*/ + SEEMP_LOGK_RECORD(SEEMP_API_kernel__recvfrom, "size=%u,fd=%d", + (unsigned int)size, fd); + + seemp_logk_kernel_end(blck); +} + +static inline void seemp_logk_oom_adjust_write(pid_t pid, + kuid_t uid, int oom_adj) +{ + char *buf = NULL; + void *blck = NULL; + + /*sets up buf and blck correctly*/ + blck = seemp_setup_buf(&buf); + if (!blck) + return; + + /*fill the buf*/ + SEEMP_LOGK_RECORD(SEEMP_API_kernel__oom_adjust_write, + "app_uid=%d,app_pid=%d,oom_adj=%d", + uid.val, pid, oom_adj); + + seemp_logk_kernel_end(blck); +} + +static inline void seemp_logk_oom_score_adj_write(pid_t pid, kuid_t uid, + int oom_adj_score) +{ + char *buf = NULL; + void *blck = NULL; + + /*sets up buf and blck correctly*/ + blck = seemp_setup_buf(&buf); + if (!blck) + return; + + /*fill the buf*/ + snprintf(buf, MAX_BUF_SIZE, + "-1|kernel|oom_score_adj_write|app_uid=%d,app_pid=%d,oom_adj=%d|--end", + uid.val, pid, oom_adj_score); + + seemp_logk_kernel_end(blck); +} + +#else +static inline void seemp_logk_sendto(int fd, void __user *buff, + size_t len, unsigned flags, struct sockaddr __user *addr, + int addr_len) +{ +} + +static inline void seemp_logk_recvfrom + (int fd, void __user *ubuf, size_t size, + unsigned flags, struct sockaddr __user *addr, + int __user *addr_len) +{ +} + +static inline void seemp_logk_oom_adjust_write + (pid_t pid, kuid_t uid, int oom_adj) +{ +} + +static inline void seemp_logk_oom_score_adj_write + (pid_t pid, kuid_t uid, int oom_adj_score) +{ +} +#endif +#endif diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 5685a2ca38d2..ca15d91bdb36 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -343,22 +343,26 @@ struct earlycon_device { struct earlycon_id { char name[16]; + char compatible[128]; int (*setup)(struct earlycon_device *, const char *options); } __aligned(32); +extern const struct earlycon_id __earlycon_table[]; +extern const struct earlycon_id __earlycon_table_end[]; + +#define OF_EARLYCON_DECLARE(_name, compat, fn) \ + static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \ + __used __section(__earlycon_table) \ + = { .name = __stringify(_name), \ + .compatible = compat, \ + .setup = fn } + +#define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn) + extern int setup_earlycon(char *buf); extern int of_setup_earlycon(unsigned long addr, int (*setup)(struct earlycon_device *, const char *)); -#define EARLYCON_DECLARE(_name, func) \ - static const struct earlycon_id __earlycon_##_name \ - __used __section(__earlycon_table) \ - = { .name = __stringify(_name), \ - .setup = func } - -#define OF_EARLYCON_DECLARE(name, compat, fn) \ - _OF_DECLARE(earlycon, name, compat, fn, void *) - struct uart_port *uart_get_console(struct uart_port *ports, int nr, struct console *c); int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr, @@ -399,7 +403,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port); static inline int uart_tx_stopped(struct uart_port *port) { struct tty_struct *tty = port->state->port.tty; - if (tty->stopped || port->hw_stopped) + if ((tty && tty->stopped) || port->hw_stopped) return 1; return 0; } diff --git a/include/linux/show_mem_notifier.h b/include/linux/show_mem_notifier.h new file mode 100644 index 000000000000..b1265f87edec --- /dev/null +++ b/include/linux/show_mem_notifier.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014, 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. + */ + +#include <linux/notifier.h> + +int show_mem_notifier_register(struct notifier_block *nb); + +int show_mem_notifier_unregister(struct notifier_block *nb); + +void show_mem_call_notifiers(void); diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index 4fcacd915d45..e77f648f9662 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -66,6 +66,7 @@ struct shrinker { /* Flags */ #define SHRINKER_NUMA_AWARE (1 << 0) #define SHRINKER_MEMCG_AWARE (1 << 1) +#define SHRINKER_LMK (1 << 2) extern int register_shrinker(struct shrinker *); extern void unregister_shrinker(struct shrinker *); diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h new file mode 100644 index 000000000000..05fb62e45b52 --- /dev/null +++ b/include/linux/slimbus/slimbus.h @@ -0,0 +1,1216 @@ +/* Copyright (c) 2011-2016, 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 _LINUX_SLIMBUS_H +#define _LINUX_SLIMBUS_H +#include <linux/module.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/mod_devicetable.h> + +/* Interfaces between SLIMbus manager drivers and SLIMbus infrastructure. */ + +extern struct bus_type slimbus_type; + +/* Standard values per SLIMbus spec needed by controllers and devices */ +#define SLIM_CL_PER_SUPERFRAME 6144 +#define SLIM_CL_PER_SUPERFRAME_DIV8 (SLIM_CL_PER_SUPERFRAME >> 3) +#define SLIM_MAX_TXNS 256 +#define SLIM_MAX_CLK_GEAR 10 +#define SLIM_MIN_CLK_GEAR 1 +#define SLIM_CL_PER_SL 4 +#define SLIM_SL_PER_SUPERFRAME (SLIM_CL_PER_SUPERFRAME >> 2) +#define SLIM_FRM_SLOTS_PER_SUPERFRAME 16 +#define SLIM_GDE_SLOTS_PER_SUPERFRAME 2 + +/* + * SLIMbus message types. Related to interpretation of message code. + * Values are defined in Table 32 (slimbus spec 1.01.01) + */ +#define SLIM_MSG_MT_CORE 0x0 +#define SLIM_MSG_MT_DEST_REFERRED_CLASS 0x1 +#define SLIM_MSG_MT_DEST_REFERRED_USER 0x2 +#define SLIM_MSG_MT_SRC_REFERRED_CLASS 0x5 +#define SLIM_MSG_MT_SRC_REFERRED_USER 0x6 + +/* + * SLIMbus core type Message Codes. + * Values are defined in Table 65 (slimbus spec 1.01.01) + */ +/* Device management messages */ +#define SLIM_MSG_MC_REPORT_PRESENT 0x1 +#define SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS 0x2 +#define SLIM_MSG_MC_RESET_DEVICE 0x4 +#define SLIM_MSG_MC_CHANGE_LOGICAL_ADDRESS 0x8 +#define SLIM_MSG_MC_CHANGE_ARBITRATION_PRIORITY 0x9 +#define SLIM_MSG_MC_REQUEST_SELF_ANNOUNCEMENT 0xC +#define SLIM_MSG_MC_REPORT_ABSENT 0xF + +/* Data channel management messages */ +#define SLIM_MSG_MC_CONNECT_SOURCE 0x10 +#define SLIM_MSG_MC_CONNECT_SINK 0x11 +#define SLIM_MSG_MC_DISCONNECT_PORT 0x14 +#define SLIM_MSG_MC_CHANGE_CONTENT 0x18 + +/* Information management messages */ +#define SLIM_MSG_MC_REQUEST_INFORMATION 0x20 +#define SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION 0x21 +#define SLIM_MSG_MC_REPLY_INFORMATION 0x24 +#define SLIM_MSG_MC_CLEAR_INFORMATION 0x28 +#define SLIM_MSG_MC_REPORT_INFORMATION 0x29 + +/* Reconfiguration messages */ +#define SLIM_MSG_MC_BEGIN_RECONFIGURATION 0x40 +#define SLIM_MSG_MC_NEXT_ACTIVE_FRAMER 0x44 +#define SLIM_MSG_MC_NEXT_SUBFRAME_MODE 0x45 +#define SLIM_MSG_MC_NEXT_CLOCK_GEAR 0x46 +#define SLIM_MSG_MC_NEXT_ROOT_FREQUENCY 0x47 +#define SLIM_MSG_MC_NEXT_PAUSE_CLOCK 0x4A +#define SLIM_MSG_MC_NEXT_RESET_BUS 0x4B +#define SLIM_MSG_MC_NEXT_SHUTDOWN_BUS 0x4C +#define SLIM_MSG_MC_NEXT_DEFINE_CHANNEL 0x50 +#define SLIM_MSG_MC_NEXT_DEFINE_CONTENT 0x51 +#define SLIM_MSG_MC_NEXT_ACTIVATE_CHANNEL 0x54 +#define SLIM_MSG_MC_NEXT_DEACTIVATE_CHANNEL 0x55 +#define SLIM_MSG_MC_NEXT_REMOVE_CHANNEL 0x58 +#define SLIM_MSG_MC_RECONFIGURE_NOW 0x5F + +/* + * Clock pause flag to indicate that the reconfig message + * corresponds to clock pause sequence + */ +#define SLIM_MSG_CLK_PAUSE_SEQ_FLG (1U << 8) + +/* Value management messages */ +#define SLIM_MSG_MC_REQUEST_VALUE 0x60 +#define SLIM_MSG_MC_REQUEST_CHANGE_VALUE 0x61 +#define SLIM_MSG_MC_REPLY_VALUE 0x64 +#define SLIM_MSG_MC_CHANGE_VALUE 0x68 + +/* Clock pause values defined in Table 66 (slimbus spec 1.01.01) */ +#define SLIM_CLK_FAST 0 +#define SLIM_CLK_CONST_PHASE 1 +#define SLIM_CLK_UNSPECIFIED 2 + +struct slim_controller; +struct slim_device; + +/* Destination type Values defined in Table 33 (slimbus spec 1.01.01) */ +#define SLIM_MSG_DEST_LOGICALADDR 0 +#define SLIM_MSG_DEST_ENUMADDR 1 +#define SLIM_MSG_DEST_BROADCAST 3 + +/* + * @start_offset: Specifies starting offset in information/value element map + * @num_bytes: Can be 1, 2, 3, 4, 6, 8, 12, 16 per spec. This ensures that the + * message will fit in the 40-byte message limit and the slicesize can be + * compatible with values in table 21 (slimbus spec 1.01.01) + * @comp: Completion to indicate end of message-transfer. Used if client wishes + * to use the API asynchronously. + */ +struct slim_ele_access { + u16 start_offset; + u8 num_bytes; + struct completion *comp; +}; + +/* + * struct slim_framer - Represents Slimbus framer. + * Every controller may have multiple framers. + * Manager is responsible for framer hand-over. + * @e_addr: 6 byte Elemental address of the framer. + * @rootfreq: Root Frequency at which the framer can run. This is maximum + * frequency (clock gear 10 per slimbus spec) at which the bus can operate. + * @superfreq: Superframes per root frequency. Every frame is 6144 cells (bits) + * per slimbus specification. + */ +struct slim_framer { + u8 e_addr[6]; + int rootfreq; + int superfreq; +}; +#define to_slim_framer(d) container_of(d, struct slim_framer, dev); + +/* + * struct slim_addrt: slimbus address used internally by the slimbus framework. + * @valid: If the device is still there or if the address can be reused. + * @eaddr: 6-bytes-long elemental address + * @laddr: It is possible that controller will set a predefined logical address + * rather than the one assigned by framework. (i.e. logical address may + * not be same as index into this table). This entry will store the + * logical address value for this enumeration address. + */ +struct slim_addrt { + bool valid; + u8 eaddr[6]; + u8 laddr; +}; + +/* + * struct slim_val_inf: slimbus value/information element transaction + * @start_offset: Specifies starting offset in information/value element map + * @num_bytes: number of bytes to be read/written + * @wbuf: buffer if this transaction has 'write' component in it + * @rbuf: buffer if this transaction has 'read' component in it + */ +struct slim_val_inf { + u16 start_offset; + u8 num_bytes; + u8 *wbuf; + u8 *rbuf; +}; + +/* + * struct slim_msg_txn: Message to be sent by the controller. + * Linux framework uses this structure with drivers implementing controller. + * This structure has packet header, payload and buffer to be filled (if any) + * For the header information, refer to Table 34-36. + * @rl: Header field. remaining length. + * @mt: Header field. Message type. + * @mc: Header field. LSB is message code for type mt. Framework will set MSB to + * SLIM_MSG_CLK_PAUSE_SEQ_FLG in case "mc" in the reconfiguration sequence + * is for pausing the clock. + * @dt: Header field. Destination type. + * @ec: Element size. Used for elemental access APIs. + * @len: Length of payload. (excludes ec) + * @tid: Transaction ID. Used for messages expecting response. + * (e.g. relevant for mc = SLIM_MSG_MC_REQUEST_INFORMATION) + * @la: Logical address of the device this message is going to. + * (Not used when destination type is broadcast.) + * @async: If this transaction is async + * @rbuf: Buffer to be populated by controller when response is received. + * @wbuf: Payload of the message. (e.g. channel number for DATA channel APIs) + * @comp: Completion structure. Used by controller to notify response. + * (Field is relevant when tid is used) + */ +struct slim_msg_txn { + u8 rl; + u8 mt; + u16 mc; + u8 dt; + u16 ec; + u8 len; + u8 tid; + u8 la; + bool async; + u8 *rbuf; + const u8 *wbuf; + struct completion *comp; +}; + +/* Internal port state used by slimbus framework to manage data-ports */ +enum slim_port_state { + SLIM_P_FREE, + SLIM_P_UNCFG, + SLIM_P_CFG, +}; + +/* + * enum slim_port_req: Request port type by user through APIs to manage ports + * User can request default, half-duplex or port to be used in multi-channel + * configuration. Default indicates a simplex port. + */ +enum slim_port_req { + SLIM_REQ_DEFAULT, + SLIM_REQ_HALF_DUP, + SLIM_REQ_MULTI_CH, +}; + +/* + * enum slim_port_opts: Port options requested. + * User can request no configuration, packed data, and/or MSB aligned data port + */ +enum slim_port_opts { + SLIM_OPT_NONE = 0, + SLIM_OPT_NO_PACK = 1U, + SLIM_OPT_ALIGN_MSB = 1U << 1, +}; + +/* enum slim_port_flow: Port flow type (inbound/outbound). */ +enum slim_port_flow { + SLIM_SRC, + SLIM_SINK, +}; + +/* enum slim_port_err: Port errors */ +enum slim_port_err { + SLIM_P_INPROGRESS, + SLIM_P_OVERFLOW, + SLIM_P_UNDERFLOW, + SLIM_P_DISCONNECT, + SLIM_P_NOT_OWNED, +}; + +/* + * struct slim_port_cfg: Port config for the manager port + * port_opts: port options (bit-map) for this port + * watermark: watermark level set for this port + */ +struct slim_port_cfg { + u32 port_opts; + u32 watermark; +}; + +/* + * struct slim_port: Internal structure used by framework to manage ports + * @err: Port error if any for this port. Refer to enum above. + * @state: Port state. Refer to enum above. + * @req: Port request for this port. + * @cfg: Port configuration for this port. + * @flow: Flow type of this port. + * @ch: Channel association of this port. + * @xcomp: Completion to indicate error, data transfer done event. + * @ctrl: Controller to which this port belongs to. This is useful to associate + * port with the SW since port hardware interrupts may only contain port + * information. + */ +struct slim_port { + enum slim_port_err err; + enum slim_port_state state; + enum slim_port_req req; + struct slim_port_cfg cfg; + enum slim_port_flow flow; + struct slim_ch *ch; + struct completion *xcomp; + struct slim_controller *ctrl; +}; + +/* + * enum slim_ch_state: Channel state of a channel. + * Channel transition happens from free-to-allocated-to-defined-to-pending- + * active-to-active. + * Once active, channel can be removed or suspended. Suspended channels are + * still scheduled, but data transfer doesn't happen. + * Removed channels are not deallocated until dealloc_ch API is used. + * Deallocation reset channel state back to free. + * Removed channels can be defined with different parameters. + */ +enum slim_ch_state { + SLIM_CH_FREE, + SLIM_CH_ALLOCATED, + SLIM_CH_DEFINED, + SLIM_CH_PENDING_ACTIVE, + SLIM_CH_ACTIVE, + SLIM_CH_SUSPENDED, + SLIM_CH_PENDING_REMOVAL, +}; + +/* + * enum slim_ch_proto: Channel protocol used by the channel. + * Hard Isochronous channel is not scheduled if current frequency doesn't allow + * the channel to be run without flow-control. + * Auto isochronous channel will be scheduled as hard-isochronous or push-pull + * depending on current bus frequency. + * Currently, Push-pull or async or extended channels are not supported. + * For more details, refer to slimbus spec + */ +enum slim_ch_proto { + SLIM_HARD_ISO, + SLIM_AUTO_ISO, + SLIM_PUSH, + SLIM_PULL, + SLIM_ASYNC_SMPLX, + SLIM_ASYNC_HALF_DUP, + SLIM_EXT_SMPLX, + SLIM_EXT_HALF_DUP, +}; + +/* + * enum slim_ch_rate: Most commonly used frequency rate families. + * Use 1HZ for push-pull transport. + * 4KHz and 11.025KHz are most commonly used in audio applications. + * Typically, slimbus runs at frequencies to support channels running at 4KHz + * and/or 11.025KHz isochronously. + */ +enum slim_ch_rate { + SLIM_RATE_1HZ, + SLIM_RATE_4000HZ, + SLIM_RATE_11025HZ, +}; + +/* + * enum slim_ch_coeff: Coefficient of a channel used internally by framework. + * Coefficient is applicable to channels running isochronously. + * Coefficient is calculated based on channel rate multiplier. + * (If rate multiplier is power of 2, it's coeff.1 channel. Otherwise it's + * coeff.3 channel. + */ +enum slim_ch_coeff { + SLIM_COEFF_1, + SLIM_COEFF_3, +}; + +/* + * enum slim_ch_control: Channel control. + * Activate will schedule channel and/or group of channels in the TDM frame. + * Suspend will keep the schedule but data-transfer won't happen. + * Remove will remove the channel/group from the TDM frame. + */ +enum slim_ch_control { + SLIM_CH_ACTIVATE, + SLIM_CH_SUSPEND, + SLIM_CH_REMOVE, +}; + +/* enum slim_ch_dataf: Data format per table 60 from slimbus spec 1.01.01 */ +enum slim_ch_dataf { + SLIM_CH_DATAF_NOT_DEFINED = 0, + SLIM_CH_DATAF_LPCM_AUDIO = 1, + SLIM_CH_DATAF_IEC61937_COMP_AUDIO = 2, + SLIM_CH_DATAF_PACKED_PDM_AUDIO = 3, +}; + +/* enum slim_ch_auxf: Auxiliary field format per table 59 from slimbus spec */ +enum slim_ch_auxf { + SLIM_CH_AUXF_NOT_APPLICABLE = 0, + SLIM_CH_AUXF_ZCUV_TUNNEL_IEC60958 = 1, + SLIM_CH_USER_DEFINED = 0xF, +}; + +/* + * struct slim_ch: Channel structure used externally by users of channel APIs. + * @prot: Desired slimbus protocol. + * @baser: Desired base rate. (Typical isochronous rates are: 4KHz, or 11.025KHz + * @dataf: Data format. + * @auxf: Auxiliary format. + * @ratem: Channel rate multiplier. (e.g. 48KHz channel will have 4KHz base rate + * and 12 as rate multiplier. + * @sampleszbits: Sample size in bits. + */ +struct slim_ch { + enum slim_ch_proto prot; + enum slim_ch_rate baser; + enum slim_ch_dataf dataf; + enum slim_ch_auxf auxf; + u32 ratem; + u32 sampleszbits; +}; + +/* + * struct slim_ich: Internal channel structure used by slimbus framework. + * @prop: structure passed by the client. + * @coeff: Coefficient of this channel. + * @state: Current state of the channel. + * @nextgrp: If this channel is part of group, next channel in this group. + * @prrate: Presence rate of this channel (per table 62 of the spec) + * @offset: Offset of this channel in the superframe. + * @newoff: Used during scheduling to hold temporary new offset until the offset + * is accepted/rejected by slimbus reconfiguration. + * @interval: Interval of this channel per superframe. + * @newintr: Used during scheduling to new interval temporarily. + * @seglen: Segment length of this channel. + * @rootexp: root exponent of this channel. Rate can be found using rootexp and + * coefficient. Used during scheduling. + * @srch: Source port used by this channel. + * @sinkh: Sink ports used by this channel. + * @nsink: number of sink ports used by this channel. + * @chan: Channel number sent on hardware lines for this channel. May not be + * equal to array-index into chans if client requested to use number beyond + * channel-array for the controller. + * @ref: Reference number to keep track of how many clients (upto 2) are using + * this channel. + * @def: Used to keep track of how many times the channel definition is sent + * to hardware and this will decide if channel-remove can be sent for the + * channel. Channel definition may be sent upto twice (once per producer + * and once per consumer). Channel removal should be sent only once to + * avoid clients getting underflow/overflow errors. + */ +struct slim_ich { + struct slim_ch prop; + enum slim_ch_coeff coeff; + enum slim_ch_state state; + u16 nextgrp; + u32 prrate; + u32 offset; + u32 newoff; + u32 interval; + u32 newintr; + u32 seglen; + u8 rootexp; + u32 srch; + u32 *sinkh; + int nsink; + u8 chan; + int ref; + int def; +}; + +/* + * struct slim_sched: Framework uses this structure internally for scheduling. + * @chc3: Array of all active coeffient 3 channels. + * @num_cc3: Number of active coeffient 3 channels. + * @chc1: Array of all active coeffient 1 channels. + * @num_cc1: Number of active coeffient 1 channels. + * @subfrmcode: Current subframe-code used by TDM. This is decided based on + * requested message bandwidth and current channels scheduled. + * @usedslots: Slots used by all active channels. + * @msgsl: Slots used by message-bandwidth. + * @pending_msgsl: Used to store pending request of message bandwidth (in slots) + * until the scheduling is accepted by reconfiguration. + * @m_reconf: This mutex is held until current reconfiguration (data channel + * scheduling, message bandwidth reservation) is done. Message APIs can + * use the bus concurrently when this mutex is held since elemental access + * messages can be sent on the bus when reconfiguration is in progress. + * @slots: Used for debugging purposes to debug/verify current schedule in TDM. + */ +struct slim_sched { + struct slim_ich **chc3; + int num_cc3; + struct slim_ich **chc1; + int num_cc1; + u32 subfrmcode; + u32 usedslots; + u32 msgsl; + u32 pending_msgsl; + struct mutex m_reconf; + u8 *slots; +}; + +/* + * enum slim_clk_state: Slimbus controller's clock state used internally for + * maintaining current clock state. + * @SLIM_CLK_ACTIVE: Slimbus clock is active + * @SLIM_CLK_PAUSE_FAILED: Slimbus controlled failed to go in clock pause. + * Hardware-wise, this state is same as active but controller will wait on + * completion before making transition to SLIM_CLK_ACTIVE in framework + * @SLIM_CLK_ENTERING_PAUSE: Slimbus clock pause sequence is being sent on the + * bus. If this succeeds, state changes to SLIM_CLK_PAUSED. If the + * transition fails, state changes to SLIM_CLK_PAUSE_FAILED + * @SLIM_CLK_PAUSED: Slimbus controller clock has paused. + */ +enum slim_clk_state { + SLIM_CLK_ACTIVE, + SLIM_CLK_ENTERING_PAUSE, + SLIM_CLK_PAUSE_FAILED, + SLIM_CLK_PAUSED, +}; +/* + * struct slim_controller: Represents manager for a SlimBUS + * (similar to 'master' on I2C) + * @dev: Device interface to this driver + * @nr: Board-specific number identifier for this controller/bus + * @list: Link with other slimbus controllers + * @name: Name for this controller + * @clkgear: Current clock gear in which this bus is running + * @min_cg: Minimum clock gear supported by this controller (default value: 1) + * @max_cg: Maximum clock gear supported by this controller (default value: 10) + * @clk_state: Controller's clock state from enum slim_clk_state + * @pause_comp: Signals completion of clock pause sequence. This is useful when + * client tries to call slimbus transaction when controller may be entering + * clock pause. + * @a_framer: Active framer which is clocking the bus managed by this controller + * @m_ctrl: Mutex protecting controller data structures (ports, channels etc) + * @addrt: Logical address table + * @num_dev: Number of active slimbus slaves on this bus + * @devs: List of devices on this controller + * @wq: Workqueue per controller used to notify devices when they report present + * @txnt: Table of transactions having transaction ID + * @last_tid: size of the table txnt (can't grow beyond 256 since TID is 8-bits) + * @ports: Ports associated with this controller + * @nports: Number of ports supported by the controller + * @chans: Channels associated with this controller + * @nchans: Number of channels supported + * @reserved: Reserved channels that controller wants to use internally + * Clients will be assigned channel numbers after this number + * @sched: scheduler structure used by the controller + * @dev_released: completion used to signal when sysfs has released this + * controller so that it can be deleted during shutdown + * @xfer_msg: Transfer a message on this controller (this can be a broadcast + * control/status message like data channel setup, or a unicast message + * like value element read/write. + * @set_laddr: Setup logical address at laddr for the slave with elemental + * address e_addr. Drivers implementing controller will be expected to + * send unicast message to this device with its logical address. + * @allocbw: Controller can override default reconfiguration and channel + * scheduling algorithm. + * @get_laddr: It is possible that controller needs to set fixed logical + * address table and get_laddr can be used in that case so that controller + * can do this assignment. + * @wakeup: This function pointer implements controller-specific procedure + * to wake it up from clock-pause. Framework will call this to bring + * the controller out of clock pause. + * @alloc_port: Allocate a port and make it ready for data transfer. This is + * called by framework to make sure controller can take necessary steps + * to initialize its port + * @dealloc_port: Counter-part of alloc_port. This is called by framework so + * that controller can free resources associated with this port + * @framer_handover: If this controller has multiple framers, this API will + * be called to switch between framers if controller desires to change + * the active framer. + * @port_xfer: Called to schedule a transfer on port pn. iobuf is physical + * address and the buffer may have to be DMA friendly since data channels + * will be using data from this buffers without SW intervention. + * @port_xfer_status: Called by framework when client calls get_xfer_status + * API. Returns how much buffer is actually processed and the port + * errors (e.g. overflow/underflow) if any. + * @xfer_user_msg: Send user message to specified logical address. Underlying + * controller has to support sending user messages. Returns error if any. + * @xfer_bulk_wr: Send bulk of write messages to specified logical address. + * Underlying controller has to support this. Typically useful to transfer + * messages to download firmware, or messages where strict ordering for + * slave is necessary + */ +struct slim_controller { + struct device dev; + unsigned int nr; + struct list_head list; + char name[SLIMBUS_NAME_SIZE]; + int clkgear; + int min_cg; + int max_cg; + enum slim_clk_state clk_state; + struct completion pause_comp; + struct slim_framer *a_framer; + struct mutex m_ctrl; + struct slim_addrt *addrt; + u8 num_dev; + struct list_head devs; + struct workqueue_struct *wq; + struct slim_msg_txn *txnt[SLIM_MAX_TXNS]; + u8 last_tid; + spinlock_t txn_lock; + struct slim_port *ports; + int nports; + struct slim_ich *chans; + int nchans; + u8 reserved; + struct slim_sched sched; + struct completion dev_released; + int (*xfer_msg)(struct slim_controller *ctrl, + struct slim_msg_txn *txn); + int (*set_laddr)(struct slim_controller *ctrl, + const u8 *ea, u8 elen, u8 laddr); + int (*allocbw)(struct slim_device *sb, + int *subfrmc, int *clkgear); + int (*get_laddr)(struct slim_controller *ctrl, + const u8 *ea, u8 elen, u8 *laddr); + int (*wakeup)(struct slim_controller *ctrl); + int (*alloc_port)(struct slim_controller *ctrl, + u8 port); + void (*dealloc_port)(struct slim_controller *ctrl, + u8 port); + int (*framer_handover)(struct slim_controller *ctrl, + struct slim_framer *new_framer); + int (*port_xfer)(struct slim_controller *ctrl, + u8 pn, phys_addr_t iobuf, u32 len, + struct completion *comp); + enum slim_port_err (*port_xfer_status)(struct slim_controller *ctr, + u8 pn, phys_addr_t *done_buf, u32 *done_len); + int (*xfer_user_msg)(struct slim_controller *ctrl, + u8 la, u8 mt, u8 mc, + struct slim_ele_access *msg, u8 *buf, u8 len); + int (*xfer_bulk_wr)(struct slim_controller *ctrl, + u8 la, u8 mt, u8 mc, struct slim_val_inf msgs[], + int n, int (*comp_cb)(void *ctx, int err), + void *ctx); +}; +#define to_slim_controller(d) container_of(d, struct slim_controller, dev) + +/* + * struct slim_driver: Manage Slimbus generic/slave device driver + * @probe: Binds this driver to a slimbus device. + * @remove: Unbinds this driver from the slimbus device. + * @shutdown: Standard shutdown callback used during powerdown/halt. + * @suspend: Standard suspend callback used during system suspend + * @resume: Standard resume callback used during system resume + * @device_up: This callback is called when the device reports present and + * gets a logical address assigned to it + * @device_down: This callback is called when device reports absent, or the + * bus goes down. Device will report present when bus is up and + * device_up callback will be called again when that happens + * @reset_device: This callback is called after framer is booted. + * Driver should do the needful to reset the device, + * so that device acquires sync and be operational. + * @driver: Slimbus device drivers should initialize name and owner field of + * this structure + * @id_table: List of slimbus devices supported by this driver + */ +struct slim_driver { + int (*probe)(struct slim_device *sldev); + int (*remove)(struct slim_device *sldev); + void (*shutdown)(struct slim_device *sldev); + int (*suspend)(struct slim_device *sldev, + pm_message_t pmesg); + int (*resume)(struct slim_device *sldev); + int (*device_up)(struct slim_device *sldev); + int (*device_down) + (struct slim_device *sldev); + int (*reset_device) + (struct slim_device *sldev); + + struct device_driver driver; + const struct slim_device_id *id_table; +}; +#define to_slim_driver(d) container_of(d, struct slim_driver, driver) + +/* + * struct slim_pending_ch: List of pending channels used by framework. + * @chan: Channel number + * @pending: list of channels + */ +struct slim_pending_ch { + u8 chan; + struct list_head pending; +}; + +/* + * Client/device handle (struct slim_device): + * ------------------------------------------ + * This is the client/device handle returned when a slimbus + * device is registered with a controller. This structure can be provided + * during register_board_info, or can be allocated using slim_add_device API. + * Pointer to this structure is used by client-driver as a handle. + * @dev: Driver model representation of the device. + * @name: Name of driver to use with this device. + * @e_addr: 6-byte elemental address of this device. + * @driver: Device's driver. Pointer to access routines. + * @ctrl: Slimbus controller managing the bus hosting this device. + * @laddr: 1-byte Logical address of this device. + * @reported: Flag to indicate whether this device reported present. The flag + * is set when device reports present, and is reset when it reports + * absent. This flag alongwith notified flag below is used to call + * device_up, or device_down callbacks for driver of this device. + * @mark_define: List of channels pending definition/activation. + * @mark_suspend: List of channels pending suspend. + * @mark_removal: List of channels pending removal. + * @notified: Flag to indicate whether this device has been notified. The + * device may report present multiple times, but should be notified only + * first time it has reported present. + * @dev_list: List of devices on a controller + * @wd: Work structure associated with workqueue for presence notification + * @sldev_reconf: Mutex to protect the pending data-channel lists. + * @pending_msgsl: Message bandwidth reservation request by this client in + * slots that's pending reconfiguration. + * @cur_msgsl: Message bandwidth reserved by this client in slots. + * These 3 lists are managed by framework. Lists are populated when client + * calls channel control API without reconfig-flag set and the lists are + * emptied when the reconfiguration is done by this client. + */ +struct slim_device { + struct device dev; + const char *name; + u8 e_addr[6]; + struct slim_driver *driver; + struct slim_controller *ctrl; + u8 laddr; + bool reported; + struct list_head mark_define; + struct list_head mark_suspend; + struct list_head mark_removal; + bool notified; + struct list_head dev_list; + struct work_struct wd; + struct mutex sldev_reconf; + u32 pending_msgsl; + u32 cur_msgsl; +}; +#define to_slim_device(d) container_of(d, struct slim_device, dev) + +/* + * struct slim_boardinfo: Declare board info for Slimbus device bringup. + * @bus_num: Controller number (bus) on which this device will sit. + * @slim_slave: Device to be registered with slimbus. + */ +struct slim_boardinfo { + int bus_num; + struct slim_device *slim_slave; +}; + +/* + * slim_get_logical_addr: Return the logical address of a slimbus device. + * @sb: client handle requesting the adddress. + * @e_addr: Elemental address of the device. + * @e_len: Length of e_addr + * @laddr: output buffer to store the address + * context: can sleep + * -EINVAL is returned in case of invalid parameters, and -ENXIO is returned if + * the device with this elemental address is not found. + */ + +extern int slim_get_logical_addr(struct slim_device *sb, const u8 *e_addr, + u8 e_len, u8 *laddr); + + +/* Message APIs Unicast message APIs used by slimbus slave drivers */ + +/* + * Message API access routines. + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to read. + * @rbuf: data buffer to be filled with values read. + * @len: data buffer size + * @wbuf: data buffer containing value/information to be written + * context: can sleep + * Returns: + * -EINVAL: Invalid parameters + * -ETIMEDOUT: If controller could not complete the request. This may happen if + * the bus lines are not clocked, controller is not powered-on, slave with + * given address is not enumerated/responding. + */ +extern int slim_request_val_element(struct slim_device *sb, + struct slim_ele_access *msg, u8 *buf, + u8 len); +extern int slim_request_inf_element(struct slim_device *sb, + struct slim_ele_access *msg, u8 *buf, + u8 len); +extern int slim_change_val_element(struct slim_device *sb, + struct slim_ele_access *msg, + const u8 *buf, u8 len); +extern int slim_clear_inf_element(struct slim_device *sb, + struct slim_ele_access *msg, u8 *buf, + u8 len); +extern int slim_request_change_val_element(struct slim_device *sb, + struct slim_ele_access *msg, u8 *rbuf, + const u8 *wbuf, u8 len); +extern int slim_request_clear_inf_element(struct slim_device *sb, + struct slim_ele_access *msg, u8 *rbuf, + const u8 *wbuf, u8 len); + +/* + * Broadcast message API: + * call this API directly with sbdev = NULL. + * For broadcast reads, make sure that buffers are big-enough to incorporate + * replies from all logical addresses. + * All controllers may not support broadcast + */ +extern int slim_xfer_msg(struct slim_controller *ctrl, + struct slim_device *sbdev, struct slim_ele_access *msg, + u16 mc, u8 *rbuf, const u8 *wbuf, u8 len); + +/* + * User message: + * slim_user_msg: Send user message that is interpreted by destination device + * @sb: Client handle sending the message + * @la: Destination device for this user message + * @mt: Message Type (Soruce-referred, or Destination-referred) + * @mc: Message Code + * @msg: Message structure (start offset, number of bytes) to be sent + * @buf: data buffer to be sent + * @len: data buffer size in bytes + */ +extern int slim_user_msg(struct slim_device *sb, u8 la, u8 mt, u8 mc, + struct slim_ele_access *msg, u8 *buf, u8 len); + +/* + * Queue bulk of message writes: + * slim_bulk_msg_write: Write bulk of messages (e.g. downloading FW) + * @sb: Client handle sending these messages + * @la: Destination device for these messages + * @mt: Message Type + * @mc: Message Code + * @msgs: List of messages to be written in bulk + * @n: Number of messages in the list + * @cb: Callback if client needs this to be non-blocking + * @ctx: Context for this callback + * If supported by controller, this message list will be sent in bulk to the HW + * If the client specifies this to be non-blocking, the callback will be + * called from atomic context. + */ +extern int slim_bulk_msg_write(struct slim_device *sb, u8 mt, u8 mc, + struct slim_val_inf msgs[], int n, + int (*comp_cb)(void *ctx, int err), void *ctx); +/* end of message apis */ + +/* Port management for manager device APIs */ + +/* + * slim_alloc_mgrports: Allocate port on manager side. + * @sb: device/client handle. + * @req: Port request type. + * @nports: Number of ports requested + * @rh: output buffer to store the port handles + * @hsz: size of buffer storing handles + * context: can sleep + * This port will be typically used by SW. e.g. client driver wants to receive + * some data from audio codec HW using a data channel. + * Port allocated using this API will be used to receive the data. + * If half-duplex ports are requested, two adjacent ports are allocated for + * 1 half-duplex port. So the handle-buffer size should be twice the number + * of half-duplex ports to be allocated. + * -EDQUOT is returned if all ports are in use. + */ +extern int slim_alloc_mgrports(struct slim_device *sb, enum slim_port_req req, + int nports, u32 *rh, int hsz); + +/* Deallocate the port(s) allocated using the API above */ +extern int slim_dealloc_mgrports(struct slim_device *sb, u32 *hdl, int hsz); + +/* + * slim_config_mgrports: Configure manager side ports + * @sb: device/client handle. + * @ph: array of port handles for which this configuration is valid + * @nports: Number of ports in ph + * @cfg: configuration requested for port(s) + * Configure port settings if they are different than the default ones. + * Returns success if the config could be applied. Returns -EISCONN if the + * port is in use + */ +extern int slim_config_mgrports(struct slim_device *sb, u32 *ph, int nports, + struct slim_port_cfg *cfg); + +/* + * slim_port_xfer: Schedule buffer to be transferred/received using port-handle. + * @sb: client handle + * @ph: port-handle + * @iobuf: buffer to be transferred or populated + * @len: buffer size. + * @comp: completion signal to indicate transfer done or error. + * context: can sleep + * Returns number of bytes transferred/received if used synchronously. + * Will return 0 if used asynchronously. + * Client will call slim_port_get_xfer_status to get error and/or number of + * bytes transferred if used asynchronously. + */ +extern int slim_port_xfer(struct slim_device *sb, u32 ph, phys_addr_t iobuf, + u32 len, struct completion *comp); + +/* + * slim_port_get_xfer_status: Poll for port transfers, or get transfer status + * after completion is done. + * @sb: client handle + * @ph: port-handle + * @done_buf: return pointer (iobuf from slim_port_xfer) which is processed. + * @done_len: Number of bytes transferred. + * This can be called when port_xfer complition is signalled. + * The API will return port transfer error (underflow/overflow/disconnect) + * and/or done_len will reflect number of bytes transferred. Note that + * done_len may be valid even if port error (overflow/underflow) has happened. + * e.g. If the transfer was scheduled with a few bytes to be transferred and + * client has not supplied more data to be transferred, done_len will indicate + * number of bytes transferred with underflow error. To avoid frequent underflow + * errors, multiple transfers can be queued (e.g. ping-pong buffers) so that + * channel has data to be transferred even if client is not ready to transfer + * data all the time. done_buf will indicate address of the last buffer + * processed from the multiple transfers. + */ +extern enum slim_port_err slim_port_get_xfer_status(struct slim_device *sb, + u32 ph, phys_addr_t *done_buf, u32 *done_len); + +/* + * slim_connect_src: Connect source port to channel. + * @sb: client handle + * @srch: source handle to be connected to this channel + * @chanh: Channel with which the ports need to be associated with. + * Per slimbus specification, a channel may have 1 source port. + * Channel specified in chanh needs to be allocated first. + * Returns -EALREADY if source is already configured for this channel. + * Returns -ENOTCONN if channel is not allocated + * Returns -EINVAL if invalid direction is specified for non-manager port, + * or if the manager side port number is out of bounds, or in incorrect state + */ +extern int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh); + +/* + * slim_connect_sink: Connect sink port(s) to channel. + * @sb: client handle + * @sinkh: sink handle(s) to be connected to this channel + * @nsink: number of sinks + * @chanh: Channel with which the ports need to be associated with. + * Per slimbus specification, a channel may have multiple sink-ports. + * Channel specified in chanh needs to be allocated first. + * Returns -EALREADY if sink is already configured for this channel. + * Returns -ENOTCONN if channel is not allocated + * Returns -EINVAL if invalid parameters are passed, or invalid direction is + * specified for non-manager port, or if the manager side port number is out of + * bounds, or in incorrect state + */ +extern int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink, + u16 chanh); +/* + * slim_disconnect_ports: Disconnect port(s) from channel + * @sb: client handle + * @ph: ports to be disconnected + * @nph: number of ports. + * Disconnects ports from a channel. + */ +extern int slim_disconnect_ports(struct slim_device *sb, u32 *ph, int nph); + +/* + * slim_get_slaveport: Get slave port handle + * @la: slave device logical address. + * @idx: port index at slave + * @rh: return handle + * @flw: Flow type (source or destination) + * This API only returns a slave port's representation as expected by slimbus + * driver. This port is not managed by the slimbus driver. Caller is expected + * to have visibility of this port since it's a device-port. + */ +extern int slim_get_slaveport(u8 la, int idx, u32 *rh, enum slim_port_flow flw); + + +/* Channel functions. */ + +/* + * slim_alloc_ch: Allocate a slimbus channel and return its handle. + * @sb: client handle. + * @chanh: return channel handle + * Slimbus channels are limited to 256 per specification. + * -EXFULL is returned if all channels are in use. + * Although slimbus specification supports 256 channels, a controller may not + * support that many channels. + */ +extern int slim_alloc_ch(struct slim_device *sb, u16 *chanh); + +/* + * slim_query_ch: Get reference-counted handle for a channel number. Every + * channel is reference counted by one as producer and the others as + * consumer) + * @sb: client handle + * @chan: slimbus channel number + * @chanh: return channel handle + * If request channel number is not in use, it is allocated, and reference + * count is set to one. If the channel was was already allocated, this API + * will return handle to that channel and reference count is incremented. + * -EXFULL is returned if all channels are in use + */ +extern int slim_query_ch(struct slim_device *sb, u8 chan, u16 *chanh); +/* + * slim_dealloc_ch: Deallocate channel allocated using the API above + * -EISCONN is returned if the channel is tried to be deallocated without + * being removed first. + * -ENOTCONN is returned if deallocation is tried on a channel that's not + * allocated. + */ +extern int slim_dealloc_ch(struct slim_device *sb, u16 chanh); + + +/* + * slim_define_ch: Define a channel.This API defines channel parameters for a + * given channel. + * @sb: client handle. + * @prop: slim_ch structure with channel parameters desired to be used. + * @chanh: list of channels to be defined. + * @nchan: number of channels in a group (1 if grp is false) + * @grp: Are the channels grouped + * @grph: return group handle if grouping of channels is desired. + * Channels can be grouped if multiple channels use same parameters + * (e.g. 5.1 audio has 6 channels with same parameters. They will all be + * grouped and given 1 handle for simplicity and avoid repeatedly calling + * the API) + * -EISCONN is returned if channel is already used with different parameters. + * -ENXIO is returned if the channel is not yet allocated. + */ +extern int slim_define_ch(struct slim_device *sb, struct slim_ch *prop, + u16 *chanh, u8 nchan, bool grp, u16 *grph); + +/* + * slim_control_ch: Channel control API. + * @sb: client handle + * @grpchanh: group or channel handle to be controlled + * @chctrl: Control command (activate/suspend/remove) + * @commit: flag to indicate whether the control should take effect right-away. + * This API activates, removes or suspends a channel (or group of channels) + * grpchanh indicates the channel or group handle (returned by the define_ch + * API). Reconfiguration may be time-consuming since it can change all other + * active channel allocations on the bus, change in clock gear used by the + * slimbus, and change in the control space width used for messaging. + * commit makes sure that multiple channels can be activated/deactivated before + * reconfiguration is started. + * -EXFULL is returned if there is no space in TDM to reserve the bandwidth. + * -EISCONN/-ENOTCONN is returned if the channel is already connected or not + * yet defined. + * -EINVAL is returned if individual control of a grouped-channel is attempted. + */ +extern int slim_control_ch(struct slim_device *sb, u16 grpchanh, + enum slim_ch_control chctrl, bool commit); + +/* + * slim_get_ch_state: Channel state. + * This API returns the channel's state (active, suspended, inactive etc) + */ +extern enum slim_ch_state slim_get_ch_state(struct slim_device *sb, + u16 chanh); + +/* + * slim_reservemsg_bw: Request to reserve bandwidth for messages. + * @sb: client handle + * @bw_bps: message bandwidth in bits per second to be requested + * @commit: indicates whether the reconfiguration needs to be acted upon. + * This API call can be grouped with slim_control_ch API call with only one of + * the APIs specifying the commit flag to avoid reconfiguration being called too + * frequently. -EXFULL is returned if there is no space in TDM to reserve the + * bandwidth. -EBUSY is returned if reconfiguration is requested, but a request + * is already in progress. + */ +extern int slim_reservemsg_bw(struct slim_device *sb, u32 bw_bps, bool commit); + +/* + * slim_reconfigure_now: Request reconfiguration now. + * @sb: client handle + * This API does what commit flag in other scheduling APIs do. + * -EXFULL is returned if there is no space in TDM to reserve the + * bandwidth. -EBUSY is returned if reconfiguration request is already in + * progress. + */ +extern int slim_reconfigure_now(struct slim_device *sb); + +/* + * slim_ctrl_clk_pause: Called by slimbus controller to request clock to be + * paused or woken up out of clock pause + * @ctrl: controller requesting bus to be paused or woken up + * @wakeup: Wakeup this controller from clock pause. + * @restart: Restart time value per spec used for clock pause. This value + * isn't used when controller is to be woken up. + * This API executes clock pause reconfiguration sequence if wakeup is false. + * If wakeup is true, controller's wakeup is called + * Slimbus clock is idle and can be disabled by the controller later. + */ +extern int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, + u8 restart); + +/* + * slim_driver_register: Client driver registration with slimbus + * @drv:Client driver to be associated with client-device. + * This API will register the client driver with the slimbus + * It is called from the driver's module-init function. + */ +extern int slim_driver_register(struct slim_driver *drv); + +/* + * slim_driver_unregister: Undo effects of slim_driver_register + * @drv: Client driver to be unregistered + */ +extern void slim_driver_unregister(struct slim_driver *drv); + +/* + * slim_add_numbered_controller: Controller bring-up. + * @ctrl: Controller to be registered. + * A controller is registered with the framework using this API. ctrl->nr is the + * desired number with which slimbus framework registers the controller. + * Function will return -EBUSY if the number is in use. + */ +extern int slim_add_numbered_controller(struct slim_controller *ctrl); + +/* + * slim_del_controller: Controller tear-down. + * Controller added with the above API is teared down using this API. + */ +extern int slim_del_controller(struct slim_controller *ctrl); + +/* + * slim_add_device: Add a new device without register board info. + * @ctrl: Controller to which this device is to be added to. + * Called when device doesn't have an explicit client-driver to be probed, or + * the client-driver is a module installed dynamically. + */ +extern int slim_add_device(struct slim_controller *ctrl, + struct slim_device *sbdev); + +/* slim_remove_device: Remove the effect of slim_add_device() */ +extern void slim_remove_device(struct slim_device *sbdev); + +/* + * slim_assign_laddr: Assign logical address to a device enumerated. + * @ctrl: Controller with which device is enumerated. + * @e_addr: 6-byte elemental address of the device. + * @e_len: buffer length for e_addr + * @laddr: Return logical address (if valid flag is false) + * @valid: true if laddr holds a valid address that controller wants to + * set for this enumeration address. Otherwise framework sets index into + * address table as logical address. + * Called by controller in response to REPORT_PRESENT. Framework will assign + * a logical address to this enumeration address. + * Function returns -EXFULL to indicate that all logical addresses are already + * taken. + */ +extern int slim_assign_laddr(struct slim_controller *ctrl, const u8 *e_addr, + u8 e_len, u8 *laddr, bool valid); + +/* + * slim_report_absent: Controller calls this function when a device + * reports absent, OR when the device cannot be communicated with + * @sbdev: Device that cannot be reached, or that sent report absent + */ +void slim_report_absent(struct slim_device *sbdev); + +/* + * slim_framer_booted: This function is called by controller after the active + * framer has booted (using Bus Reset sequence, or after it has shutdown and has + * come back up). Components, devices on the bus may be in undefined state, + * and this function triggers their drivers to do the needful + * to bring them back in Reset state so that they can acquire sync, report + * present and be operational again. + */ +void slim_framer_booted(struct slim_controller *ctrl); + +/* + * slim_msg_response: Deliver Message response received from a device to the + * framework. + * @ctrl: Controller handle + * @reply: Reply received from the device + * @len: Length of the reply + * @tid: Transaction ID received with which framework can associate reply. + * Called by controller to inform framework about the response received. + * This helps in making the API asynchronous, and controller-driver doesn't need + * to manage 1 more table other than the one managed by framework mapping TID + * with buffers + */ +extern void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, + u8 len); + +/* + * slim_busnum_to_ctrl: Map bus number to controller + * @busnum: Bus number + * Returns controller representing this bus number + */ +extern struct slim_controller *slim_busnum_to_ctrl(u32 busnum); + +/* + * slim_ctrl_add_boarddevs: Add devices registered by board-info + * @ctrl: Controller to which these devices are to be added to. + * This API is called by controller when it is up and running. + * If devices on a controller were registered before controller, + * this will make sure that they get probed when controller is up + */ +extern void slim_ctrl_add_boarddevs(struct slim_controller *ctrl); + +extern const +struct slim_device_id *slim_get_device_id(const struct slim_device *sdev); + +/* + * slim_register_board_info: Board-initialization routine. + * @info: List of all devices on all controllers present on the board. + * @n: number of entries. + * API enumerates respective devices on corresponding controller. + * Called from board-init function. + */ +#ifdef CONFIG_SLIMBUS +extern int slim_register_board_info(struct slim_boardinfo const *info, + unsigned n); +#else +static inline int slim_register_board_info(struct slim_boardinfo const *info, + unsigned n) +{ + return 0; +} +#endif + +static inline void *slim_get_ctrldata(const struct slim_controller *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void slim_set_ctrldata(struct slim_controller *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +static inline void *slim_get_devicedata(const struct slim_device *dev) +{ + return dev_get_drvdata(&dev->dev); +} + +static inline void slim_set_clientdata(struct slim_device *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} +#endif /* _LINUX_SLIMBUS_H */ diff --git a/include/linux/soc/qcom/smd-rpm.h b/include/linux/soc/qcom/smd-rpm.h index 2a53dcaeeeed..ebdabd669d93 100644 --- a/include/linux/soc/qcom/smd-rpm.h +++ b/include/linux/soc/qcom/smd-rpm.h @@ -26,6 +26,10 @@ struct qcom_smd_rpm; #define QCOM_SMD_RPM_SMPB 0x62706d73 #define QCOM_SMD_RPM_SPDM 0x63707362 #define QCOM_SMD_RPM_VSA 0x00617376 +#define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d +#define QCOM_SMD_RPM_IPA_CLK 0x617069 +#define QCOM_SMD_RPM_CE_CLK 0x6563 +#define QCOM_SMD_RPM_AGGR_CLK 0x72676761 int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm, int state, diff --git a/include/linux/socket.h b/include/linux/socket.h index 5bf59c8493b7..9d3b16ea92d9 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -200,7 +200,8 @@ struct ucred { #define AF_ALG 38 /* Algorithm sockets */ #define AF_NFC 39 /* NFC sockets */ #define AF_VSOCK 40 /* vSockets */ -#define AF_MAX 41 /* For now.. */ +#define AF_QIPCRTR 42 /* QTI IPC Router */ +#define AF_MAX 43 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -246,6 +247,7 @@ struct ucred { #define PF_ALG AF_ALG #define PF_NFC AF_NFC #define PF_VSOCK AF_VSOCK +#define PF_QIPCRTR AF_QIPCRTR #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/include/linux/soundwire/soundwire.h b/include/linux/soundwire/soundwire.h new file mode 100755 index 000000000000..1287d2b73bf8 --- /dev/null +++ b/include/linux/soundwire/soundwire.h @@ -0,0 +1,312 @@ +/* Copyright (c) 2015-2017, 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 _LINUX_SOUNDWIRE_H +#define _LINUX_SOUNDWIRE_H +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/mod_devicetable.h> + +extern struct bus_type soundwire_type; + +/* Soundwire supports max. of 8 channels per port */ +#define SWR_MAX_CHANNEL_NUM 8 +/* Soundwire supports max. of 14 ports on each device */ +#define SWR_MAX_DEV_PORT_NUM 14 +/* Maximum number of slave devices that a master can control */ +#define SWR_MAX_DEV_NUM 11 +/* Maximum number of ports on master so that it can accomodate all the port + * configurations of all devices + */ +#define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM) + +/* Indicates soundwire devices group information */ +enum { + SWR_GROUP_NONE = 0, + SWR_GROUP_12 = 12, + SWR_GROUP_13 = 13, + SWR_BROADCAST = 15, +}; + +/* + * struct swr_port_info - represent soundwire frame shape + * @dev_id: logical device number of the soundwire slave device + * @port_en: flag indicates whether the port is enabled + * @port_id: logical port number of the soundwire slave device + * @offset1: sample offset indicating the offset of the channel + * from the start of the frame + * @offset2: channel offset indicating offset between to channels + * @sinterval: sample interval indicates spacing from one sample + * event to the next + * @ch_en: channels in a port that need to be enabled + * @num_ch: number of channels enabled in a port + * @ch_rate: sampling rate of the channel with which data will be + * transferred + * + * Soundwire frame shape is created based on swr_port_info struct + * parameters. + */ +struct swr_port_info { + u8 dev_id; + u8 port_en; + u8 port_id; + u8 offset1; + u8 offset2; + u8 sinterval; + u8 ch_en; + u8 num_ch; + u32 ch_rate; +}; + +/* + * struct swr_params - represent transfer of data from soundwire slave + * to soundwire master + * @tid: transaction ID to track each transaction + * @dev_id: logical device number of the soundwire slave device + * @num_port: number of ports that needs to be configured + * @port_id: array of logical port numbers of the soundwire slave device + * @num_ch: array of number of channels enabled + * @ch_rate: array of sampling rate of different channels that need to + * be configured + * @ch_en: array of channels mask for all the ports + */ +struct swr_params { + u8 tid; + u8 dev_id; + u8 num_port; + u8 port_id[SWR_MAX_DEV_PORT_NUM]; + u8 num_ch[SWR_MAX_DEV_PORT_NUM]; + u32 ch_rate[SWR_MAX_DEV_PORT_NUM]; + u8 ch_en[SWR_MAX_DEV_PORT_NUM]; +}; + +/* + * struct swr_reg - struct to handle soundwire slave register read/writes + * @tid: transaction id for reg read/writes + * @dev_id: logical device number of the soundwire slave device + * @regaddr: 16 bit regaddr of soundwire slave + * @buf: value to be written/read to/from regaddr + * @len: length of the buffer buf + */ +struct swr_reg { + u8 tid; + u8 dev_id; + u32 regaddr; + u32 *buf; + u32 len; +}; + +/* + * struct swr_master - Interface to the soundwire master controller + * @dev: device interface to this driver + * @list: link with other soundwire master controllers + * @bus_num: board/SoC specific identifier for a soundwire master + * @mlock: mutex protecting master data structures + * @devices: list of devices on this master + * @port: logical port numbers of the soundwire master. This array + * can hold maximum master ports which is equal to number of slave + * devices multiplied by number of ports in each slave device + * @port_txn: table of port config transactions with transaction id + * @reg_txn: table of register transactions with transaction id + * @last_tid: size of table port_txn (can't grow beyond 256 since + * tid is 8 bits) + * @num_port: number of active ports on soundwire master + * @gr_sid: slave id used by the group for write operations + * @connect_port: callback for configuration of soundwire port(s) + * @disconnect_port: callback for disable of soundwire port(s) + * @read: callback for soundwire slave register read + * @write: callback for soundwire slave register write + * @get_logical_dev_num: callback to get soundwire slave logical + * device number + */ +struct swr_master { + struct device dev; + struct list_head list; + unsigned int bus_num; + struct mutex mlock; + struct list_head devices; + struct swr_port_info port[SWR_MAX_MSTR_PORT_NUM]; + struct swr_params **port_txn; + struct swr_reg **reg_txn; + u8 last_tid; + u8 num_port; + u8 num_dev; + u8 gr_sid; + int (*connect_port)(struct swr_master *mstr, struct swr_params *txn); + int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn); + int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, + void *buf, u32 len); + int (*write)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, + const void *buf); + int (*bulk_write)(struct swr_master *master, u8 dev_num, void *reg, + const void *buf, size_t len); + int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id, + u8 *dev_num); + void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); + bool (*remove_from_group)(struct swr_master *mstr); +}; + +static inline struct swr_master *to_swr_master(struct device *dev) +{ + return dev ? container_of(dev, struct swr_master, dev) : NULL; +} + +/* + * struct swr_device - represent a soundwire slave device + * @name: indicates the name of the device, defined in devicetree + * binding under soundwire slave device node as a compatible field. + * @master: soundwire master managing the bus hosting this device + * @driver: Device's driver. Pointer to access routines + * @dev_list: list of devices on a controller + * @dev_num: logical device number of the soundwire slave device + * @dev: driver model representation of the device + * @addr: represents "ea-addr" which is unique-id of soundwire slave + * device + * @group_id: group id supported by the slave device + */ +struct swr_device { + char name[SOUNDWIRE_NAME_SIZE]; + struct swr_master *master; + struct swr_driver *driver; + struct list_head dev_list; + u8 dev_num; + struct device dev; + unsigned long addr; + u8 group_id; +}; + +static inline struct swr_device *to_swr_device(struct device *dev) +{ + return dev ? container_of(dev, struct swr_device, dev) : NULL; +} + +/* + * struct swr_driver - Manage soundwire slave device driver + * @probe: binds this driver to soundwire device + * @remove: unbinds this driver from soundwire device + * @shutdown: standard shutdown callback used during power down/halt + * @suspend: standard suspend callback used during system suspend + * @resume: standard resume callback used during system resume + * @driver: soundwire device drivers should initialize name and + * owner field of this structure + * @id_table: list of soundwire devices supported by this driver + */ +struct swr_driver { + int (*probe)(struct swr_device *swr); + int (*remove)(struct swr_device *swr); + void (*shutdown)(struct swr_device *swr); + int (*suspend)(struct swr_device *swr, pm_message_t pmesg); + int (*resume)(struct swr_device *swr); + int (*device_up)(struct swr_device *swr); + int (*device_down)(struct swr_device *swr); + int (*reset_device)(struct swr_device *swr); + struct device_driver driver; + const struct swr_device_id *id_table; +}; + +static inline struct swr_driver *to_swr_driver(struct device_driver *drv) +{ + return drv ? container_of(drv, struct swr_driver, driver) : NULL; +} + +/* + * struct swr_boardinfo - Declare board info for soundwire device bringup + * @name: name to initialize swr_device.name + * @bus_num: identifies which soundwire master parents the soundwire + * slave_device + * @addr: represents "ea-addr" of soundwire slave device + * @of_node: pointer to OpenFirmware device node + * @swr_slave: device to be registered with soundwire + */ +struct swr_boardinfo { + char name[SOUNDWIRE_NAME_SIZE]; + int bus_num; + u64 addr; + struct device_node *of_node; + struct swr_device *swr_slave; +}; + +static inline void *swr_get_ctrl_data(const struct swr_master *master) +{ + return master ? dev_get_drvdata(&master->dev) : NULL; +} + +static inline void swr_set_ctrl_data(struct swr_master *master, void *data) +{ + dev_set_drvdata(&master->dev, data); +} + +static inline void *swr_get_dev_data(const struct swr_device *dev) +{ + return dev ? dev_get_drvdata(&dev->dev) : NULL; +} + +static inline void swr_set_dev_data(struct swr_device *dev, void *data) +{ + dev_set_drvdata(&dev->dev, data); +} + +extern int swr_startup_devices(struct swr_device *swr_dev); + +extern struct swr_device *swr_new_device(struct swr_master *master, + struct swr_boardinfo const *info); + +extern int of_register_swr_devices(struct swr_master *master); + +extern void swr_port_response(struct swr_master *mstr, u8 tid); + +extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id, + u8 *dev_num); + +extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr, + void *buf, u32 len); + +extern int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr, + const void *buf); + +extern int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg_addr, + const void *buf, size_t len); + +extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, + u8 *ch_mask, u32 *ch_rate, u8 *num_ch); + +extern int swr_disconnect_port(struct swr_device *dev, + u8 *port_id, u8 num_port); + +extern int swr_set_device_group(struct swr_device *swr_dev, u8 id); + +extern int swr_driver_register(struct swr_driver *drv); + +extern void swr_driver_unregister(struct swr_driver *drv); + +extern int swr_add_device(struct swr_master *master, + struct swr_device *swrdev); +extern void swr_remove_device(struct swr_device *swr); + +extern void swr_master_add_boarddevices(struct swr_master *master); + +extern void swr_unregister_master(struct swr_master *master); + +extern int swr_register_master(struct swr_master *master); + +extern int swr_device_up(struct swr_device *swr_dev); + +extern int swr_device_down(struct swr_device *swr_dev); + +extern int swr_reset_device(struct swr_device *swr_dev); + +extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num, + bool enable); +extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num); + +extern void swr_remove_device(struct swr_device *swr_dev); +#endif /* _LINUX_SOUNDWIRE_H */ diff --git a/include/linux/soundwire/swr-wcd.h b/include/linux/soundwire/swr-wcd.h new file mode 100755 index 000000000000..041b901fd954 --- /dev/null +++ b/include/linux/soundwire/swr-wcd.h @@ -0,0 +1,35 @@ +/* Copyright (c) 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 _LINUX_SWR_WCD_H +#define _LINUX_SWR_WCD_H +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/bitops.h> + +enum { + SWR_CH_MAP, + SWR_DEVICE_DOWN, + SWR_DEVICE_UP, + SWR_SUBSYS_RESTART, + SWR_SET_NUM_RX_CH, +}; + +struct swr_mstr_port { + int num_port; + u8 *port; +}; + +extern int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data); + +#endif /* _LINUX_SWR_WCD_H */ diff --git a/include/linux/spi/qcom-spi.h b/include/linux/spi/qcom-spi.h new file mode 100644 index 000000000000..67ef31c69641 --- /dev/null +++ b/include/linux/spi/qcom-spi.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2014-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. + * + */ +/* + * SPI driver for Qualcomm MSM platforms. + */ + +/** + * msm_spi_platform_data: msm spi-controller's configuration data + * + * @max_clock_speed max spi clock speed + * @active_only when set, votes when system active and removes the vote when + * system goes idle (optimises for performance). When unset, voting using + * runtime pm (optimizes for power). + * @master_id master id number of the controller's wrapper (BLSP or GSBI). + * When zero, clock path voting is disabled. + * @gpio_config pointer to function for configuring gpio + * @gpio_release pointer to function for releasing gpio pins + * @dma_config function poniter for configuring dma engine + * @pm_lat power management latency + * @infinite_mode use FIFO mode in infinite mode + * @ver_reg_exists if the version register exists + * @use_beam true if BAM is available + * @bam_consumer_pipe_index BAM conusmer pipe + * @bam_producer_pipe_index BAM producer pipe + * @rt_priority true if RT thread + * @use_pinctrl true if pinctrl library is used + * @is_shared true when qup is shared between ee's + */ +struct msm_spi_platform_data { + u32 max_clock_speed; + u32 master_id; + u32 bus_width; + int (*gpio_config)(void); + void (*gpio_release)(void); + int (*dma_config)(void); + const char *rsl_id; + u32 pm_lat; + u32 infinite_mode; + bool ver_reg_exists; + bool use_bam; + bool slv_test; + u32 bam_consumer_pipe_index; + u32 bam_producer_pipe_index; + bool rt_priority; + bool use_pinctrl; + bool is_shared; + bool is_slv_ctrl; +}; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d1..01cf8b6ac61a 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -27,8 +27,8 @@ struct spi_master; struct spi_transfer; /* - * INTERFACES between SPI master-side drivers and SPI infrastructure. - * (There's no SPI slave support for Linux yet...) + * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, + * and SPI infrastructure. */ extern struct bus_type spi_bus_type; @@ -303,6 +303,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @min_speed_hz: Lowest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver + * @slave: indicates that this is an SPI slave controller * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use @@ -361,6 +362,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @handle_err: the subsystem calls the driver to handle an error that occurs * in the generic implementation of transfer_one_message(). * @unprepare_message: undo any work done by prepare_message(). + * @slave_abort: abort the ongoing transfer request on an SPI slave controller * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). @@ -425,6 +427,9 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + /* flag indicating this is an SPI slave controller */ + bool slave; + /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; @@ -507,6 +512,7 @@ struct spi_master { struct spi_message *message); int (*unprepare_message)(struct spi_master *master, struct spi_message *message); + int (*slave_abort)(struct spi_master *spi); /* * These hooks are for drivers that use a generic implementation @@ -556,6 +562,11 @@ static inline void spi_master_put(struct spi_master *master) put_device(&master->dev); } +static inline bool spi_controller_is_slave(struct spi_master *ctlr) +{ + return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave; +} + /* PM calls that need to be issued by the driver */ extern int spi_master_suspend(struct spi_master *master); extern int spi_master_resume(struct spi_master *master); @@ -566,8 +577,23 @@ extern void spi_finalize_current_message(struct spi_master *master); extern void spi_finalize_current_transfer(struct spi_master *master); /* the spi driver core manages memory for the spi_master classdev */ -extern struct spi_master * -spi_alloc_master(struct device *host, unsigned size); +extern struct spi_master *__spi_alloc_controller(struct device *host, + unsigned int size, bool slave); + +static inline struct spi_master *spi_alloc_master(struct device *host, + unsigned int size) +{ + return __spi_alloc_controller(host, size, false); +} + +static inline struct spi_master *spi_alloc_slave(struct device *host, + unsigned int size) +{ + if (!IS_ENABLED(CONFIG_SPI_SLAVE)) + return NULL; + + return __spi_alloc_controller(host, size, true); +} extern int spi_register_master(struct spi_master *master); extern int devm_spi_register_master(struct device *dev, @@ -831,6 +857,7 @@ extern int spi_setup(struct spi_device *spi); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, struct spi_message *message); +extern int spi_slave_abort(struct spi_device *spi); /*---------------------------------------------------------------------------*/ diff --git a/include/linux/spmi.h b/include/linux/spmi.h index 1396a255d2a2..319c52a298ef 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 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 @@ -171,6 +171,19 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv) module_driver(__spmi_driver, spmi_driver_register, \ spmi_driver_unregister) +#ifdef CONFIG_QCOM_SHOW_RESUME_IRQ +extern int msm_show_resume_irq_mask; +static inline bool spmi_show_resume_irq(void) +{ + return msm_show_resume_irq_mask; +} +#else +static inline bool spmi_show_resume_irq(void) +{ + return false; +} +#endif + int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf); int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf, size_t len); diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 0a34489a46b6..17a33f31bfa2 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -23,6 +23,8 @@ extern void print_stack_trace(struct stack_trace *trace, int spaces); extern int snprint_stack_trace(char *buf, size_t size, struct stack_trace *trace, int spaces); +#define BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK_ARM + #ifdef CONFIG_USER_STACKTRACE_SUPPORT extern void save_stack_trace_user(struct stack_trace *trace); #else diff --git a/include/linux/stm.h b/include/linux/stm.h index 9d0083d364e6..8369d8a8cabd 100644 --- a/include/linux/stm.h +++ b/include/linux/stm.h @@ -50,6 +50,8 @@ struct stm_device; * @sw_end: last STP master available to software * @sw_nchannels: number of STP channels per master * @sw_mmiosz: size of one channel's IO space, for mmap, optional + * @hw_override: masters in the STP stream will not match the ones + * assigned by software, but are up to the STM hardware * @packet: callback that sends an STP packet * @mmio_addr: mmap callback, optional * @link: called when a new stm_source gets linked to us, optional @@ -67,6 +69,16 @@ struct stm_device; * description. That is, the lowest master that can be allocated to software * writers is @sw_start and data from this writer will appear is @sw_start * master in the STP stream. + * + * The @packet callback should adhere to the following rules: + * 1) it must return the number of bytes it consumed from the payload; + * 2) therefore, if it sent a packet that does not have payload (like FLAG), + * it must return zero; + * 3) if it does not support the requested packet type/flag combination, + * it must return -ENOTSUPP. + * + * The @unlink callback is called when there are no more active writers so + * that the master/channel can be quiesced. */ struct stm_data { const char *name; @@ -75,6 +87,7 @@ struct stm_data { unsigned int sw_end; unsigned int sw_nchannels; unsigned int sw_mmiosz; + unsigned int hw_override; ssize_t (*packet)(struct stm_data *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, diff --git a/include/linux/suspend.h b/include/linux/suspend.h index be1ab158ad1a..04218da27e3a 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -380,6 +380,7 @@ extern unsigned long get_safe_page(gfp_t gfp_mask); extern asmlinkage int swsusp_arch_suspend(void); extern asmlinkage int swsusp_arch_resume(void); +static inline bool get_hibernation_status(void) { return true; }; extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); @@ -393,6 +394,7 @@ static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} static inline void swsusp_unset_page_free(struct page *p) {} +static inline bool get_hibernation_status(void) { return true; }; static inline void hibernation_set_ops(const struct platform_hibernation_ops *ops) {} static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } diff --git a/include/linux/swap.h b/include/linux/swap.h index 0a0b7529dae4..f1007d5abab8 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -150,12 +150,15 @@ enum { SWP_FILE = (1 << 7), /* set after swap_activate success */ SWP_AREA_DISCARD = (1 << 8), /* single-time swap area discards */ SWP_PAGE_DISCARD = (1 << 9), /* freed swap page-cluster discards */ + SWP_STABLE_WRITES = (1 << 10), /* no overwrite PG_writeback pages */ /* add others here before... */ - SWP_SCANNING = (1 << 10), /* refcount in scan_swap_map */ + SWP_FAST = (1 << 11), /* blkdev access is fast and cheap */ + SWP_SCANNING = (1 << 12), /* refcount in scan_swap_map */ }; #define SWAP_CLUSTER_MAX 32UL #define COMPACT_CLUSTER_MAX SWAP_CLUSTER_MAX +#define SWAPFILE_CLUSTER 256 /* * Ratio between zone->managed_pages and the "gap" that above the per-zone @@ -246,6 +249,8 @@ struct swap_info_struct { struct work_struct discard_work; /* discard worker */ struct swap_cluster_info discard_cluster_head; /* list head of discard clusters */ struct swap_cluster_info discard_cluster_tail; /* list tail of discard clusters */ + unsigned int write_pending; + unsigned int max_writes; }; /* linux/mm/workingset.c */ @@ -289,7 +294,6 @@ static inline void workingset_node_shadows_dec(struct radix_tree_node *node) /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; -extern unsigned long dirty_balance_reserve; extern unsigned long nr_free_buffer_pages(void); extern unsigned long nr_free_pagecache_pages(void); @@ -331,6 +335,8 @@ extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, unsigned long *nr_scanned); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; +extern int sysctl_swap_ratio; +extern int sysctl_swap_ratio_enable; extern int remove_mapping(struct address_space *mapping, struct page *page); extern unsigned long vm_total_pages; @@ -417,10 +423,18 @@ extern struct page *swapin_readahead(swp_entry_t, gfp_t, /* linux/mm/swapfile.c */ extern atomic_long_t nr_swap_pages; extern long total_swap_pages; +extern bool is_swap_fast(swp_entry_t entry); /* Swap 50% full? Release swapcache more aggressively.. */ -static inline bool vm_swap_full(void) +static inline bool vm_swap_full(struct swap_info_struct *si) { + /* + * If the swap device is fast, return true + * not to delay swap free. + */ + if (si->flags & SWP_FAST) + return true; + return atomic_long_read(&nr_swap_pages) * 2 < total_swap_pages; } @@ -456,7 +470,7 @@ struct backing_dev_info; #define get_nr_swap_pages() 0L #define total_swap_pages 0L #define total_swapcache_pages() 0UL -#define vm_swap_full() 0 +#define vm_swap_full(si) 0 #define si_swapinfo(val) \ do { (val)->freeswap = (val)->totalswap = 0; } while (0) diff --git a/include/linux/swapfile.h b/include/linux/swapfile.h index e4594de79bc4..9d995cd9009b 100644 --- a/include/linux/swapfile.h +++ b/include/linux/swapfile.h @@ -7,8 +7,13 @@ */ extern spinlock_t swap_lock; extern struct plist_head swap_active_head; +extern spinlock_t swap_avail_lock; +extern struct plist_head swap_avail_head; extern struct swap_info_struct *swap_info[]; extern int try_to_unuse(unsigned int, bool, unsigned long); +extern int swap_ratio(struct swap_info_struct **si); +extern void setup_swap_ratio(struct swap_info_struct *p, int prio); +extern bool is_swap_ratio_group(int prio); extern unsigned long generic_max_swapfile_size(void); extern unsigned long max_swapfile_size(void); diff --git a/include/linux/switch.h b/include/linux/switch.h new file mode 100644 index 000000000000..3e4c748e343a --- /dev/null +++ b/include/linux/switch.h @@ -0,0 +1,53 @@ +/* + * Switch class driver + * + * Copyright (C) 2008 Google, Inc. + * Author: Mike Lockwood <lockwood@android.com> + * + * 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 __LINUX_SWITCH_H__ +#define __LINUX_SWITCH_H__ + +struct switch_dev { + const char *name; + struct device *dev; + int index; + int state; + + ssize_t (*print_name)(struct switch_dev *sdev, char *buf); + ssize_t (*print_state)(struct switch_dev *sdev, char *buf); +}; + +struct gpio_switch_platform_data { + const char *name; + unsigned gpio; + + /* if NULL, switch_dev.name will be printed */ + const char *name_on; + const char *name_off; + /* if NULL, "0" or "1" will be printed */ + const char *state_on; + const char *state_off; +}; + +extern int switch_dev_register(struct switch_dev *sdev); +extern void switch_dev_unregister(struct switch_dev *sdev); + +static inline int switch_get_state(struct switch_dev *sdev) +{ + return sdev->state; +} + +extern void switch_set_state(struct switch_dev *sdev, int state); + +#endif /* __LINUX_SWITCH_H__ */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index c2b66a277e98..5d2779aa4bbe 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -205,6 +205,26 @@ extern struct trace_event_functions exit_syscall_print_funcs; } \ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) +/* + * Called before coming back to user-mode. Returning to user-mode with an + * address limit different than USER_DS can allow to overwrite kernel memory. + */ +static inline void addr_limit_user_check(void) +{ +#ifdef TIF_FSCHECK + if (!test_thread_flag(TIF_FSCHECK)) + return; +#endif + + if (CHECK_DATA_CORRUPTION(!segment_eq(get_fs(), USER_DS), + "Invalid address limit on user-mode return")) + force_sig(SIGKILL, current); + +#ifdef TIF_FSCHECK + clear_thread_flag(TIF_FSCHECK); +#endif +} + asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr); asmlinkage long sys_time(time_t __user *tloc); diff --git a/include/linux/syslog.h b/include/linux/syslog.h index c3a7f0cc3a27..e1c3632f4e81 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h @@ -49,13 +49,4 @@ int do_syslog(int type, char __user *buf, int count, int source); -#ifdef CONFIG_PRINTK -int check_syslog_permissions(int type, int source); -#else -static inline int check_syslog_permissions(int type, int source) -{ - return 0; -} -#endif - #endif /* _LINUX_SYSLOG_H */ diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 387fa7d05c98..d802692acb53 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -42,6 +42,7 @@ struct sysrq_key_op { * are available -- else NULL's). */ +bool sysrq_on(void); void handle_sysrq(int key); void __handle_sysrq(int key, bool check_mask); int register_sysrq_key(int key, struct sysrq_key_op *op); diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h new file mode 100644 index 000000000000..61c15214121c --- /dev/null +++ b/include/linux/test-iosched.h @@ -0,0 +1,277 @@ +/* Copyright (c) 2012-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. + * + * The test scheduler allows to test the block device by dispatching + * specific requests according to the test case and declare PASS/FAIL + * according to the requests completion error code. + * Each test is exposed via debugfs and can be triggered by writing to + * the debugfs file. + * + */ + +#ifndef _LINUX_TEST_IOSCHED_H +#define _LINUX_TEST_IOSCHED_H + +/* + * Patterns definitions for read/write requests data + */ +#define TEST_PATTERN_SEQUENTIAL -1 +#define TEST_PATTERN_5A 0x5A5A5A5A +#define TEST_PATTERN_FF 0xFFFFFFFF +#define TEST_NO_PATTERN 0xDEADBEEF +#define BIO_U32_SIZE 1024 +#define TEST_BIO_SIZE PAGE_SIZE /* use one page bios */ + +struct test_iosched; + +typedef int (prepare_test_fn) (struct test_iosched *); +typedef int (run_test_fn) (struct test_iosched *); +typedef int (check_test_result_fn) (struct test_iosched *); +typedef int (post_test_fn) (struct test_iosched *); +typedef char* (get_test_case_str_fn) (int); +typedef int (blk_dev_test_init_fn) (struct test_iosched *); +typedef void (blk_dev_test_exit_fn) (struct test_iosched *); +typedef struct gendisk* (get_rq_disk_fn) (struct test_iosched *); +typedef bool (check_test_completion_fn) (struct test_iosched *); + +/** + * enum test_state - defines the state of the test + */ +enum test_state { + TEST_IDLE, + TEST_RUNNING, + TEST_COMPLETED, +}; + +/** + * enum test_results - defines the success orfailure of the test + */ +enum test_results { + TEST_NO_RESULT, + TEST_FAILED, + TEST_PASSED, + TEST_NOT_SUPPORTED, +}; + +/** + * enum req_unique_type - defines a unique request type + */ +enum req_unique_type { + REQ_UNIQUE_NONE, + REQ_UNIQUE_DISCARD, + REQ_UNIQUE_FLUSH, +}; + +/** + * struct test_debug - debugfs directories + * @debug_root: The test-iosched debugfs root directory + * @debug_utils_root: test-iosched debugfs utils root + * directory + * @debug_tests_root: test-iosched debugfs tests root + * directory + * @debug_test_result: Exposes the test result to the user + * space + * @start_sector: The start sector for read/write requests + * @sector_range: Range of the test, starting from start_sector + * (in sectors) + */ +struct test_debug { + struct dentry *debug_root; + struct dentry *debug_utils_root; + struct dentry *debug_tests_root; + struct dentry *debug_test_result; + struct dentry *start_sector; + struct dentry *sector_range; +}; + +/** + * struct test_request - defines a test request + * @queuelist: The test requests list + * @bios_buffer: Write/read requests data buffer, one page per bio + * @buf_size: Write/read requests data buffer size (in + * bytes) + * @rq: A block request, to be dispatched + * @req_completed: A flag to indicate if the request was + * completed + * @req_result: Keeps the error code received in the + * request completion callback + * @is_err_expected: A flag to indicate if the request should + * fail + * @wr_rd_data_pattern: A pattern written to the write data + * buffer. Can be used in read requests to + * verify the data + * @req_id: A unique ID to identify a test request + * to ease the debugging of the test cases + */ +struct test_request { + struct list_head queuelist; + void *bios_buffer[BLK_MAX_SEGMENTS]; + int buf_size; + struct request *rq; + bool req_completed; + int req_result; + int is_err_expected; + int wr_rd_data_pattern; + int req_id; +}; + +/** + * struct test_info - specific test information + * @testcase: The current running test case + * @timeout_msec: Test specific test timeout + * @buf_size: Write/read requests data buffer size (in + * bytes) + * @prepare_test_fn: Test specific test preparation callback + * @run_test_fn: Test specific test running callback + * @check_test_result_fn: Test specific test result checking + * callback + * @get_test_case_str_fn: Test specific function to get the test name + * @test_duration: A ktime value saved for timing + * calculations + * @data: Test specific private data + * @test_byte_count: Total number of bytes dispatched in + * the test + */ +struct test_info { + int testcase; + unsigned timeout_msec; + prepare_test_fn *prepare_test_fn; + run_test_fn *run_test_fn; + check_test_result_fn *check_test_result_fn; + post_test_fn *post_test_fn; + get_test_case_str_fn *get_test_case_str_fn; + ktime_t test_duration; + get_rq_disk_fn *get_rq_disk_fn; + check_test_completion_fn *check_test_completion_fn; + void *data; + unsigned long test_byte_count; +}; + +/** + * struct blk_dev_test_type - identifies block device test + * @list: list head pointer + * @type_prefix: prefix of device class name, i.e. "mmc"/ "sd" + * @init_fn: block device test init callback + * @exit_fn: block device test exit callback + */ +struct blk_dev_test_type { + struct list_head list; + const char *type_prefix; + blk_dev_test_init_fn *init_fn; + blk_dev_test_exit_fn *exit_fn; +}; + +/** + * struct test_data - global test iosched data + * @queue: The test IO scheduler requests list + * @test_queue: The test requests list + * @dispatched_queue: The queue contains requests dispatched + * from @test_queue + * @reinsert_queue: The queue contains reinserted from underlying + * driver requests + * @urgent_queue: The queue contains requests for urgent delivery + * These requests will be delivered before @test_queue + * and @reinsert_queue requests + * @test_count: Number of requests in the @test_queue + * @dispatched_count: Number of requests in the @dispatched_queue + * @reinsert_count: Number of requests in the @reinsert_queue + * @urgent_count: Number of requests in the @urgent_queue + * @wait_q: A wait queue for waiting for the test + * requests completion + * @test_state: Indicates if there is a running test. + * Used for dispatch function + * @test_result: Indicates if the test passed or failed + * @debug: The test debugfs entries + * @req_q: The block layer request queue + * @num_of_write_bios: The number of write BIOs added to the test requests. + * Used to calcualte the sector number of + * new BIOs. + * @start_sector: The address of the first sector that can + * be accessed by the test + * @sector_range: Range of the test, starting from start_sector + * (in sectors) + * @wr_rd_next_req_id: A unique ID to identify WRITE/READ + * request to ease the debugging of the + * test cases + * @unique_next_req_id: A unique ID to identify + * FLUSH/DISCARD/SANITIZE request to ease + * the debugging of the test cases + * @lock: A lock to verify running a single test + * at a time + * @test_info: A specific test data to be set by the + * test invokation function + * @ignore_round: A boolean variable indicating that a + * test round was disturbed by an external + * flush request, therefore disqualifying + * the results + * @blk_dev_test_data: associated specific block device test utility + */ +struct test_iosched { + struct list_head queue; + struct list_head test_queue; + struct list_head dispatched_queue; + struct list_head reinsert_queue; + struct list_head urgent_queue; + unsigned int test_count; + unsigned int dispatched_count; + unsigned int reinsert_count; + unsigned int urgent_count; + wait_queue_head_t wait_q; + enum test_state test_state; + enum test_results test_result; + struct test_debug debug; + struct request_queue *req_q; + int num_of_write_bios; + u32 start_sector; + u32 sector_range; + int wr_rd_next_req_id; + int unique_next_req_id; + spinlock_t lock; + struct test_info test_info; + bool fs_wr_reqs_during_test; + bool ignore_round; + bool notified_urgent; + void *blk_dev_test_data; +}; + +extern int test_iosched_start_test(struct test_iosched *, + struct test_info *t_info); +extern void test_iosched_mark_test_completion(struct test_iosched *); +extern void check_test_completion(struct test_iosched *); +extern int test_iosched_add_unique_test_req(struct test_iosched *, + int is_err_expcted, enum req_unique_type req_unique, + int start_sec, int nr_sects, rq_end_io_fn *end_req_io); +extern int test_iosched_add_wr_rd_test_req(struct test_iosched *, + int is_err_expcted, int direction, int start_sec, int num_bios, + int pattern, rq_end_io_fn *end_req_io); +extern struct test_request *test_iosched_create_test_req(struct test_iosched *, + int is_err_expcted, int direction, int start_sec, int num_bios, + int pattern, rq_end_io_fn *end_req_io); + +extern void test_iosched_free_test_req_data_buffer(struct test_request *); + +extern void test_iosched_set_test_result(struct test_iosched*, int test_result); + +extern void test_iosched_set_ignore_round(struct test_iosched *, + bool ignore_round); + +extern void test_iosched_register(struct blk_dev_test_type *bdt); + +extern void test_iosched_unregister(struct blk_dev_test_type *bdt); + +extern void test_iosched_add_urgent_req(struct test_iosched *, + struct test_request *); + +extern void check_test_completion(struct test_iosched *); + +extern int compare_buffer_to_pattern(struct test_request *test_rq); + +#endif /* _LINUX_TEST_IOSCHED_H */ diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 4a849f19e6c9..4d2cf47aba27 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -77,11 +77,19 @@ enum thermal_device_mode { THERMAL_DEVICE_ENABLED, }; +enum thermal_trip_activation_mode { + THERMAL_TRIP_ACTIVATION_DISABLED = 0, + THERMAL_TRIP_ACTIVATION_ENABLED, +}; + enum thermal_trip_type { THERMAL_TRIP_ACTIVE = 0, THERMAL_TRIP_PASSIVE, THERMAL_TRIP_HOT, THERMAL_TRIP_CRITICAL, + THERMAL_TRIP_CONFIGURABLE_HI, + THERMAL_TRIP_CONFIGURABLE_LOW, + THERMAL_TRIP_CRITICAL_LOW, }; enum thermal_trend { @@ -110,6 +118,8 @@ struct thermal_zone_device_ops { int (*set_trip_hyst) (struct thermal_zone_device *, int, int); int (*get_crit_temp) (struct thermal_zone_device *, int *); int (*set_emul_temp) (struct thermal_zone_device *, int); + int (*activate_trip_type) (struct thermal_zone_device *, int, + enum thermal_trip_activation_mode); int (*get_trend) (struct thermal_zone_device *, int, enum thermal_trend *); int (*notify) (struct thermal_zone_device *, int, @@ -146,6 +156,31 @@ struct thermal_attr { char name[THERMAL_NAME_LENGTH]; }; +struct sensor_threshold { + long temp; + enum thermal_trip_type trip; + int (*notify)(enum thermal_trip_type type, int temp, void *data); + void *data; + uint8_t active; + struct list_head list; +}; + +struct sensor_info { + uint32_t sensor_id; + struct thermal_zone_device *tz; + int threshold_min; + int threshold_max; + int max_idx; + int min_idx; + struct list_head sensor_list; + struct list_head threshold_list; + struct mutex lock; + struct work_struct work; + struct task_struct *sysfs_notify_thread; + struct completion sysfs_notify_complete; + bool deregister_active; +}; + /** * struct thermal_zone_device - structure for a thermal zone * @id: unique id number for each thermal zone @@ -210,6 +245,8 @@ struct thermal_zone_device { struct mutex lock; struct list_head node; struct delayed_work poll_queue; + struct sensor_threshold tz_threshold[2]; + struct sensor_info sensor; }; /** @@ -420,6 +457,16 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, struct thermal_cooling_device *, int); void thermal_cdev_update(struct thermal_cooling_device *); void thermal_notify_framework(struct thermal_zone_device *, int); + +int sensor_get_temp(uint32_t sensor_id, int *temp); +int sensor_get_id(char *name); +int sensor_set_trip(uint32_t sensor_id, struct sensor_threshold *threshold); +int sensor_cancel_trip(uint32_t sensor_id, struct sensor_threshold *threshold); +int sensor_activate_trip(uint32_t sensor_id, struct sensor_threshold *threshold, + bool enable); +int thermal_sensor_trip(struct thermal_zone_device *tz, + enum thermal_trip_type trip, long temp); + #else static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) { return false; } @@ -482,6 +529,20 @@ static inline void thermal_cdev_update(struct thermal_cooling_device *cdev) static inline void thermal_notify_framework(struct thermal_zone_device *tz, int trip) { } +static inline int sensor_get_id(char *name){ return -ENODEV;} +static inline int sensor_set_trip(uint32_t sensor_id, + struct sensor_threshold *threshold) +{ return ENODEV;} +static inline int sensor_cancel_trip(uint32_t sensor_id, + struct sensor_threshold *threshold) +{ return -ENODEV;} + +static inline int thermal_sensor_trip(struct thermal_zone_device *tz, + enum thermal_trip_type trip, unsigned long temp) +{ return -ENODEV;} +static inline int sensor_get_temp(uint32_t sensor_id, long *temp) +{ return -ENODEV;} + #endif /* CONFIG_THERMAL */ #if defined(CONFIG_NET) && IS_ENABLED(CONFIG_THERMAL) diff --git a/include/linux/tick.h b/include/linux/tick.h index af5ac7f91a3b..d1162e9b7a36 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -27,6 +27,8 @@ static inline void tick_handover_do_timer(void) { } static inline void tick_cleanup_dead_cpu(int cpu) { } #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ +extern u64 jiffy_to_ktime_ns(u64 *now, u64 *jiffy_ktime_ns); + #if defined(CONFIG_GENERIC_CLOCKEVENTS) && defined(CONFIG_SUSPEND) extern void tick_freeze(void); extern void tick_unfreeze(void); @@ -160,7 +162,15 @@ extern void __tick_nohz_task_switch(void); #else static inline int housekeeping_any_cpu(void) { - return smp_processor_id(); + cpumask_t available; + int cpu; + + cpumask_andnot(&available, cpu_online_mask, cpu_isolated_mask); + cpu = cpumask_any(&available); + if (cpu >= nr_cpu_ids) + cpu = smp_processor_id(); + + return cpu; } static inline bool tick_nohz_full_enabled(void) { return false; } static inline bool tick_nohz_full_cpu(int cpu) { return false; } @@ -186,7 +196,7 @@ static inline bool is_housekeeping_cpu(int cpu) if (tick_nohz_full_enabled()) return cpumask_test_cpu(cpu, housekeeping_mask); #endif - return true; + return !cpu_isolated(cpu); } static inline void housekeeping_affine(struct task_struct *t) @@ -204,4 +214,5 @@ static inline void tick_nohz_task_switch(void) __tick_nohz_task_switch(); } +ktime_t *get_next_event_cpu(unsigned int cpu); #endif diff --git a/include/linux/timer.h b/include/linux/timer.h index 61aa61dc410c..5ea2c58406de 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -21,11 +21,6 @@ struct timer_list { u32 flags; int slack; -#ifdef CONFIG_TIMER_STATS - int start_pid; - void *start_site; - char start_comm[16]; -#endif #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif @@ -63,6 +58,7 @@ struct timer_list { #define TIMER_BASEMASK (TIMER_CPUMASK | TIMER_MIGRATING) #define TIMER_DEFERRABLE 0x00100000 #define TIMER_IRQSAFE 0x00200000 +#define TIMER_PINNED_ON_CPU 0x00400000 #define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \ .entry = { .next = TIMER_ENTRY_STATIC }, \ @@ -172,6 +168,9 @@ extern int mod_timer_pending(struct timer_list *timer, unsigned long expires); extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires); extern void set_timer_slack(struct timer_list *time, int slack_hz); +#ifdef CONFIG_SMP +extern bool check_pending_deferrable_timers(int cpu); +#endif #define TIMER_NOT_PINNED 0 #define TIMER_PINNED 1 @@ -181,45 +180,8 @@ extern void set_timer_slack(struct timer_list *time, int slack_hz); */ #define NEXT_TIMER_MAX_DELTA ((1UL << 30) - 1) -/* - * Timer-statistics info: - */ -#ifdef CONFIG_TIMER_STATS - -extern int timer_stats_active; - -extern void init_timer_stats(void); - -extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, - void *timerf, char *comm, u32 flags); - -extern void __timer_stats_timer_set_start_info(struct timer_list *timer, - void *addr); - -static inline void timer_stats_timer_set_start_info(struct timer_list *timer) -{ - if (likely(!timer_stats_active)) - return; - __timer_stats_timer_set_start_info(timer, __builtin_return_address(0)); -} - -static inline void timer_stats_timer_clear_start_info(struct timer_list *timer) -{ - timer->start_site = NULL; -} -#else -static inline void init_timer_stats(void) -{ -} - -static inline void timer_stats_timer_set_start_info(struct timer_list *timer) -{ -} - -static inline void timer_stats_timer_clear_start_info(struct timer_list *timer) -{ -} -#endif +/* To be used from cpusets, only */ +extern void timer_quiesce_cpu(void *cpup); extern void add_timer(struct timer_list *timer); @@ -241,6 +203,8 @@ extern enum hrtimer_restart it_real_fn(struct hrtimer *); #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) #include <linux/sysctl.h> +extern struct tvec_base tvec_base_deferrable; + extern unsigned int sysctl_timer_migration; int timer_migration_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 311176f290b2..2181ae5db42e 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -8,6 +8,7 @@ #include <linux/hardirq.h> #include <linux/perf_event.h> #include <linux/tracepoint.h> +#include <linux/coresight-stm.h> struct trace_array; struct trace_buffer; @@ -231,7 +232,8 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer, struct trace_event_file *trace_file, unsigned long len); -void trace_event_buffer_commit(struct trace_event_buffer *fbuffer); +void trace_event_buffer_commit(struct trace_event_buffer *fbuffer, + unsigned long len); enum { TRACE_EVENT_FL_FILTERED_BIT, @@ -501,6 +503,7 @@ __event_trigger_test_discard(struct trace_event_file *file, * @entry: The event itself * @irq_flags: The state of the interrupts at the start of the event * @pc: The state of the preempt count at the start of the event. + * @len: The length of the payload data required for stm logging. * * This is a helper function to handle triggers that require data * from the event itself. It also tests the event against filters and @@ -510,12 +513,16 @@ static inline void event_trigger_unlock_commit(struct trace_event_file *file, struct ring_buffer *buffer, struct ring_buffer_event *event, - void *entry, unsigned long irq_flags, int pc) + void *entry, unsigned long irq_flags, int pc, + unsigned long len) { enum event_trigger_type tt = ETT_NONE; - if (!__event_trigger_test_discard(file, buffer, event, entry, &tt)) + if (!__event_trigger_test_discard(file, buffer, event, entry, &tt)) { + if (len) + stm_log(OST_ENTITY_FTRACE_EVENTS, entry, len); trace_buffer_unlock_commit(file->tr, buffer, event, irq_flags, pc); + } if (tt) event_triggers_post_call(file, tt); diff --git a/include/linux/tty.h b/include/linux/tty.h index 812cdd8cff22..1c1bb90f6819 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -12,7 +12,7 @@ #include <uapi/linux/tty.h> #include <linux/rwsem.h> #include <linux/llist.h> - +#include <linux/kthread.h> /* * Lock subclasses for tty locks @@ -82,7 +82,7 @@ static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs) struct tty_bufhead { struct tty_buffer *head; /* Queue head */ - struct work_struct work; + struct kthread_work work; struct mutex lock; atomic_t priority; struct tty_buffer sentinel; @@ -240,6 +240,8 @@ struct tty_port { based drain is needed else set to size of fifo */ struct kref kref; /* Ref counter */ + struct kthread_worker worker; /* worker thread */ + struct task_struct *worker_thread; /* worker thread */ }; /* @@ -580,6 +582,8 @@ static inline int tty_port_users(struct tty_port *port) { return port->count + port->blocked_open; } +extern int tty_port_set_policy(struct tty_port *port, int policy, + int sched_priority); extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); extern int tty_unregister_ldisc(int disc); diff --git a/include/linux/types.h b/include/linux/types.h index 70dd3dfde631..9f2d2f46b459 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -9,6 +9,9 @@ #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] +#define DECLARE_BITMAP_ARRAY(name,nr,bits) \ + unsigned long name[nr][BITS_TO_LONGS(bits)] + typedef __u32 __kernel_dev_t; typedef __kernel_fd_set fd_set; diff --git a/include/linux/usb.h b/include/linux/usb.h index 02bffcc611c3..eab41e3be816 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -328,7 +328,9 @@ struct usb_host_bos { struct usb_ss_cap_descriptor *ss_cap; struct usb_ssp_cap_descriptor *ssp_cap; struct usb_ss_container_id_descriptor *ss_id; - struct usb_ptm_cap_descriptor *ptm_cap; + struct usb_ptm_cap_descriptor *ptm_cap; + struct usb_config_summary_descriptor *config_summary; + unsigned int num_config_summary_desc; }; int __usb_get_extra_descriptor(char *buffer, unsigned size, @@ -393,6 +395,15 @@ struct usb_bus { struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif + unsigned skip_resume:1; /* All USB devices are brought into full + * power state after system resume. It + * is desirable for some buses to keep + * their devices in suspend state even + * after system resume. The devices + * are resumed later when a remote + * wakeup is detected or an interface + * driver starts I/O. + */ }; struct usb_dev_state; @@ -732,6 +743,17 @@ static inline bool usb_device_no_sg_constraint(struct usb_device *udev) /* for drivers using iso endpoints */ extern int usb_get_current_frame_number(struct usb_device *usb_dev); +extern int usb_sec_event_ring_setup(struct usb_device *dev, + unsigned intr_num); +extern int usb_sec_event_ring_cleanup(struct usb_device *dev, + unsigned intr_num); + +extern dma_addr_t +usb_get_sec_event_ring_dma_addr(struct usb_device *dev, + unsigned intr_num); +extern dma_addr_t usb_get_dcba_dma_addr(struct usb_device *dev); +extern dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev, + struct usb_host_endpoint *ep); /* Sets up a group of bulk endpoints to support multiple stream IDs. */ extern int usb_alloc_streams(struct usb_interface *interface, @@ -1883,8 +1905,11 @@ static inline int usb_translate_errors(int error_code) #define USB_DEVICE_REMOVE 0x0002 #define USB_BUS_ADD 0x0003 #define USB_BUS_REMOVE 0x0004 +#define USB_BUS_DIED 0x0005 extern void usb_register_notify(struct notifier_block *nb); extern void usb_unregister_notify(struct notifier_block *nb); +extern void usb_register_atomic_notify(struct notifier_block *nb); +extern void usb_unregister_atomic_notify(struct notifier_block *nb); /* debugfs stuff */ extern struct dentry *usb_debug_root; diff --git a/include/linux/usb/audio-v3.h b/include/linux/usb/audio-v3.h new file mode 100644 index 000000000000..f2322f3c74f7 --- /dev/null +++ b/include/linux/usb/audio-v3.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2017, 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. + * + * This file holds USB constants and structures defined + * by the USB Device Class Definition for Audio Devices in version 3.0. + * Comments below reference relevant sections of the documents contained + * in http://www.usb.org/developers/docs/devclass_docs/USB_Audio_v3.0.zip + */ + +#ifndef __LINUX_USB_AUDIO_V3_H +#define __LINUX_USB_AUDIO_V3_H + +#include <linux/types.h> + +#define UAC3_MIXER_UNIT_V3 0x05 +#define UAC3_FEATURE_UNIT_V3 0x07 +#define UAC3_CLOCK_SOURCE 0x0b + +#define BADD_MAXPSIZE_SYNC_MONO_16 0x0060 +#define BADD_MAXPSIZE_SYNC_MONO_24 0x0090 +#define BADD_MAXPSIZE_SYNC_STEREO_16 0x00c0 +#define BADD_MAXPSIZE_SYNC_STEREO_24 0x0120 + +#define BADD_MAXPSIZE_ASYNC_MONO_16 0x0062 +#define BADD_MAXPSIZE_ASYNC_MONO_24 0x0093 +#define BADD_MAXPSIZE_ASYNC_STEREO_16 0x00c4 +#define BADD_MAXPSIZE_ASYNC_STEREO_24 0x0126 + +#define BIT_RES_16_BIT 0x10 +#define BIT_RES_24_BIT 0x18 + +#define SUBSLOTSIZE_16_BIT 0x02 +#define SUBSLOTSIZE_24_BIT 0x03 + +#define BADD_SAMPLING_RATE 48000 + +#define NUM_CHANNELS_MONO 1 +#define NUM_CHANNELS_STEREO 2 +#define BADD_CH_CONFIG_MONO 0 +#define BADD_CH_CONFIG_STEREO 3 +#define CLUSTER_ID_MONO 0x0001 +#define CLUSTER_ID_STEREO 0x0002 + +#define FULL_ADC_PROFILE 0x01 + +/* BADD Profile IDs */ +#define PROF_GENERIC_IO 0x20 +#define PROF_HEADPHONE 0x21 +#define PROF_SPEAKER 0x22 +#define PROF_MICROPHONE 0x23 +#define PROF_HEADSET 0x24 +#define PROF_HEADSET_ADAPTER 0x25 +#define PROF_SPEAKERPHONE 0x26 + +/* BADD Entity IDs */ +#define BADD_OUT_TERM_ID_BAOF 0x03 +#define BADD_OUT_TERM_ID_BAIF 0x06 +#define BADD_IN_TERM_ID_BAOF 0x01 +#define BADD_IN_TERM_ID_BAIF 0x04 +#define BADD_FU_ID_BAOF 0x02 +#define BADD_FU_ID_BAIF 0x05 +#define BADD_CLOCK_SOURCE 0x09 +#define BADD_FU_ID_BAIOF 0x07 +#define BADD_MU_ID_BAIOF 0x08 + +#define UAC_BIDIR_TERMINAL_HEADSET 0x0402 +#define UAC_BIDIR_TERMINAL_SPEAKERPHONE 0x0403 + +#define NUM_BADD_DESCS 7 + +struct uac3_input_terminal_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bCSourceID; + __u32 bmControls; + __u16 wClusterDescrID; + __u16 wExTerminalDescrID; + __u16 wConnectorsDescrID; + __u16 wTerminalDescrStr; +} __packed; + +#define UAC3_DT_INPUT_TERMINAL_SIZE 0x14 + +extern struct uac3_input_terminal_descriptor badd_baif_in_term_desc; +extern struct uac3_input_terminal_descriptor badd_baof_in_term_desc; + +struct uac3_output_terminal_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bSourceID; + __u8 bCSourceID; + __u32 bmControls; + __u16 wExTerminalDescrID; + __u16 wConnectorsDescrID; + __u16 wTerminalDescrStr; +} __packed; + +#define UAC3_DT_OUTPUT_TERMINAL_SIZE 0x13 + +extern struct uac3_output_terminal_descriptor badd_baif_out_term_desc; +extern struct uac3_output_terminal_descriptor badd_baof_out_term_desc; + +extern __u8 monoControls[]; +extern __u8 stereoControls[]; +extern __u8 badd_mu_src_ids[]; + +struct uac3_mixer_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bNrInPins; + __u8 *baSourceID; + __u16 wClusterDescrID; + __u8 bmMixerControls; + __u32 bmControls; + __u16 wMixerDescrStr; +} __packed; + +#define UAC3_DT_MIXER_UNIT_SIZE 0x10 + +extern struct uac3_mixer_unit_descriptor badd_baiof_mu_desc; + +struct uac3_feature_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bUnitID; + __u8 bSourceID; + __u8 *bmaControls; + __u16 wFeatureDescrStr; +} __packed; + +extern struct uac3_feature_unit_descriptor badd_baif_fu_desc; +extern struct uac3_feature_unit_descriptor badd_baof_fu_desc; +extern struct uac3_feature_unit_descriptor badd_baiof_fu_desc; + +struct uac3_clock_source_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubtype; + __u8 bClockID; + __u8 bmAttributes; + __u32 bmControls; + __u8 bReferenceTerminal; + __u16 wClockSourceStr; +} __packed; + +#define UAC3_DT_CLOCK_SRC_SIZE 0x0c + +extern struct uac3_clock_source_descriptor badd_clock_desc; + +extern void *badd_desc_list[]; + +#endif /* __LINUX_USB_AUDIO_V3_H */ diff --git a/include/linux/usb/ccid_desc.h b/include/linux/usb/ccid_desc.h new file mode 100644 index 000000000000..2e6dbb5afe71 --- /dev/null +++ b/include/linux/usb/ccid_desc.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011, 2017 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 __LINUX_USB_CCID_DESC_H +#define __LINUX_USB_CCID_DESC_H + +/*CCID specification version 1.10*/ +#define CCID1_10 0x0110 + +#define SMART_CARD_DEVICE_CLASS 0x0B +/* Smart Card Device Class Descriptor Type */ +#define CCID_DECRIPTOR_TYPE 0x21 + +/* Table 5.3-1 Summary of CCID Class Specific Request */ +#define CCIDGENERICREQ_ABORT 0x01 +#define CCIDGENERICREQ_GET_CLOCK_FREQUENCIES 0x02 +#define CCIDGENERICREQ_GET_DATA_RATES 0x03 + +/* 6.1 Command Pipe, Bulk-OUT Messages */ +#define PC_TO_RDR_ICCPOWERON 0x62 +#define PC_TO_RDR_ICCPOWEROFF 0x63 +#define PC_TO_RDR_GETSLOTSTATUS 0x65 +#define PC_TO_RDR_XFRBLOCK 0x6F +#define PC_TO_RDR_GETPARAMETERS 0x6C +#define PC_TO_RDR_RESETPARAMETERS 0x6D +#define PC_TO_RDR_SETPARAMETERS 0x61 +#define PC_TO_RDR_ESCAPE 0x6B +#define PC_TO_RDR_ICCCLOCK 0x6E +#define PC_TO_RDR_T0APDU 0x6A +#define PC_TO_RDR_SECURE 0x69 +#define PC_TO_RDR_MECHANICAL 0x71 +#define PC_TO_RDR_ABORT 0x72 +#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73 + +/* 6.2 Response Pipe, Bulk-IN Messages */ +#define RDR_TO_PC_DATABLOCK 0x80 +#define RDR_TO_PC_SLOTSTATUS 0x81 +#define RDR_TO_PC_PARAMETERS 0x82 +#define RDR_TO_PC_ESCAPE 0x83 +#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84 + +/* 6.3 Interrupt-IN Messages */ +#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50 +#define RDR_TO_PC_HARDWAREERROR 0x51 + +/* Table 6.2-2 Slot error register when bmCommandStatus = 1 */ +#define CMD_ABORTED 0xFF +#define ICC_MUTE 0xFE +#define XFR_PARITY_ERROR 0xFD +#define XFR_OVERRUN 0xFC +#define HW_ERROR 0xFB +#define BAD_ATR_TS 0xF8 +#define BAD_ATR_TCK 0xF7 +#define ICC_PROTOCOL_NOT_SUPPORTED 0xF6 +#define ICC_CLASS_NOT_SUPPORTED 0xF5 +#define PROCEDURE_BYTE_CONFLICT 0xF4 +#define DEACTIVATED_PROTOCOL 0xF3 +#define BUSY_WITH_AUTO_SEQUENCE 0xF2 +#define PIN_TIMEOUT 0xF0 +#define PIN_CANCELLED 0xEF +#define CMD_SLOT_BUSY 0xE0 + +/* CCID rev 1.1, p.27 */ +#define VOLTS_AUTO 0x00 +#define VOLTS_5_0 0x01 +#define VOLTS_3_0 0x02 +#define VOLTS_1_8 0x03 + +/* 6.3.1 RDR_to_PC_NotifySlotChange */ +#define ICC_NOT_PRESENT 0x00 +#define ICC_PRESENT 0x01 +#define ICC_CHANGE 0x02 +#define ICC_INSERTED_EVENT (ICC_PRESENT+ICC_CHANGE) + +/* Identifies the length of type of subordinate descriptors of a CCID device + * Table 5.1-1 Smart Card Device Class descriptors + */ +struct usb_ccid_class_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u16 bcdCCID; + __u8 bMaxSlotIndex; + __u8 bVoltageSupport; + __u32 dwProtocols; + __u32 dwDefaultClock; + __u32 dwMaximumClock; + __u8 bNumClockSupported; + __u32 dwDataRate; + __u32 dwMaxDataRate; + __u8 bNumDataRatesSupported; + __u32 dwMaxIFSD; + __u32 dwSynchProtocols; + __u32 dwMechanical; + __u32 dwFeatures; + __u32 dwMaxCCIDMessageLength; + __u8 bClassGetResponse; + __u8 bClassEnvelope; + __u16 wLcdLayout; + __u8 bPINSupport; + __u8 bMaxCCIDBusySlots; +} __packed; +#endif diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index ccb4fcb454d6..dc35fa77b3d2 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -41,6 +41,10 @@ #include <linux/log2.h> #include <linux/configfs.h> +/* FUNCTION_SUSPEND: suspend options from usb 3.0 spec Table 9-7 */ +#define FUNC_SUSPEND_OPT_SUSP_MASK BIT(0) +#define FUNC_SUSPEND_OPT_RW_EN_MASK BIT(1) + /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they * wish to delay the data/status stages of the control transfer till they @@ -51,7 +55,7 @@ #define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ /* big enough to hold our biggest descriptor */ -#define USB_COMP_EP0_BUFSIZ 1024 +#define USB_COMP_EP0_BUFSIZ 4096 /* OS feature descriptor length <= 4kB */ #define USB_COMP_EP0_OS_DESC_BUFSIZ 4096 @@ -157,7 +161,14 @@ struct usb_os_desc_table { * @get_status: Returns function status as a reply to * GetStatus() request when the recipient is Interface. * @func_suspend: callback to be called when - * SetFeature(FUNCTION_SUSPEND) is reseived + * SetFeature(FUNCTION_SUSPEND) is received + * @func_is_suspended: Tells whether the function is currently in + * Function Suspend state (used in Super Speed mode only). + * @func_wakeup_allowed: Tells whether Function Remote Wakeup has been allowed + * by the USB host (used in Super Speed mode only). + * @func_wakeup_pending: Marks that the function has issued a Function Wakeup + * while the USB bus was suspended and therefore a Function Wakeup + * notification needs to be sent once the USB bus is resumed. * * A single USB function uses one or more interfaces, and should in most * cases support operation at both full and high speeds. Each function is @@ -185,6 +196,7 @@ struct usb_os_desc_table { struct usb_function { const char *name; + int intf_id; struct usb_gadget_strings **strings; struct usb_descriptor_header **fs_descriptors; struct usb_descriptor_header **hs_descriptors; @@ -226,6 +238,9 @@ struct usb_function { int (*get_status)(struct usb_function *); int (*func_suspend)(struct usb_function *, u8 suspend_opt); + unsigned func_is_suspended:1; + unsigned func_wakeup_allowed:1; + unsigned func_wakeup_pending:1; /* private: */ /* internals */ struct list_head list; @@ -241,6 +256,9 @@ int usb_function_deactivate(struct usb_function *); int usb_function_activate(struct usb_function *); int usb_interface_id(struct usb_configuration *, struct usb_function *); +int usb_func_wakeup(struct usb_function *func); + +int usb_get_func_interface_id(struct usb_function *func); int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, struct usb_ep *_ep); @@ -321,6 +339,10 @@ struct usb_configuration { unsigned highspeed:1; unsigned fullspeed:1; struct usb_function *interface[MAX_CONFIG_INTERFACES]; + + /* number of in and out eps used in this configuration */ + int num_ineps_used; + int num_outeps_used; }; int usb_add_config(struct usb_composite_dev *, diff --git a/include/linux/usb/diag_bridge.h b/include/linux/usb/diag_bridge.h new file mode 100644 index 000000000000..e82c65330722 --- /dev/null +++ b/include/linux/usb/diag_bridge.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2011, 2013, 2018, 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 __LINUX_USB_DIAG_BRIDGE_H__ +#define __LINUX_USB_DIAG_BRIDGE_H__ + +struct diag_bridge_ops { + void *ctxt; + void (*read_complete_cb)(void *ctxt, char *buf, + int buf_size, int actual); + void (*write_complete_cb)(void *ctxt, char *buf, + int buf_size, int actual); + int (*suspend)(void *ctxt); + void (*resume)(void *ctxt); +}; + +#if IS_ENABLED(CONFIG_USB_QCOM_DIAG_BRIDGE) + +extern int diag_bridge_read(int id, char *data, int size); +extern int diag_bridge_write(int id, char *data, int size); +extern int diag_bridge_open(int id, struct diag_bridge_ops *ops); +extern void diag_bridge_close(int id); + +#else + +static int __maybe_unused diag_bridge_read(int id, char *data, int size) +{ + return -ENODEV; +} + +static int __maybe_unused diag_bridge_write(int id, char *data, int size) +{ + return -ENODEV; +} + +static int __maybe_unused diag_bridge_open(int id, struct diag_bridge_ops *ops) +{ + return -ENODEV; +} + +static void __maybe_unused diag_bridge_close(int id) { } + +#endif + +#endif diff --git a/include/linux/usb/f_mtp.h b/include/linux/usb/f_mtp.h index 4e8417791bea..8def1431f03e 100644 --- a/include/linux/usb/f_mtp.h +++ b/include/linux/usb/f_mtp.h @@ -19,5 +19,35 @@ #define __LINUX_USB_F_MTP_H #include <uapi/linux/usb/f_mtp.h> +#include <linux/ioctl.h> +#ifdef CONFIG_COMPAT +#include <linux/compat.h> +#endif +#ifdef __KERNEL__ + +#ifdef CONFIG_COMPAT +struct __compat_mtp_file_range { + compat_int_t fd; + compat_loff_t offset; + int64_t length; + uint16_t command; + uint32_t transaction_id; +}; + +struct __compat_mtp_event { + compat_size_t length; + compat_caddr_t data; +}; + +#define COMPAT_MTP_SEND_FILE _IOW('M', 0, \ + struct __compat_mtp_file_range) +#define COMPAT_MTP_RECEIVE_FILE _IOW('M', 1, \ + struct __compat_mtp_file_range) +#define COMPAT_MTP_SEND_EVENT _IOW('M', 3, \ + struct __compat_mtp_event) +#define COMPAT_MTP_SEND_FILE_WITH_HEADER _IOW('M', 4, \ + struct __compat_mtp_file_range) +#endif +#endif #endif /* __LINUX_USB_F_MTP_H */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index abf9887322a1..8874ed16c836 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -24,9 +24,82 @@ #include <linux/types.h> #include <linux/workqueue.h> #include <linux/usb/ch9.h> +#include <linux/pm_runtime.h> struct usb_ep; +enum ep_type { + EP_TYPE_NORMAL = 0, + EP_TYPE_GSI, +}; + +/* Operations codes for GSI enabled EPs */ +enum gsi_ep_op { + GSI_EP_OP_CONFIG = 0, + GSI_EP_OP_STARTXFER, + GSI_EP_OP_STORE_DBL_INFO, + GSI_EP_OP_ENABLE_GSI, + GSI_EP_OP_UPDATEXFER, + GSI_EP_OP_RING_IN_DB, + GSI_EP_OP_ENDXFER, + GSI_EP_OP_GET_CH_INFO, + GSI_EP_OP_GET_XFER_IDX, + GSI_EP_OP_PREPARE_TRBS, + GSI_EP_OP_FREE_TRBS, + GSI_EP_OP_SET_CLR_BLOCK_DBL, + GSI_EP_OP_CHECK_FOR_SUSPEND, + GSI_EP_OP_DISABLE, +}; + +/* + * @buf_base_addr: Base pointer to buffer allocated for each GSI enabled EP. + * TRBs point to buffers that are split from this pool. The size of the + * buffer is num_bufs times buf_len. num_bufs and buf_len are determined + based on desired performance and aggregation size. + * @dma: DMA address corresponding to buf_base_addr. + * @num_bufs: Number of buffers associated with the GSI enabled EP. This + * corresponds to the number of non-zlp TRBs allocated for the EP. + * The value is determined based on desired performance for the EP. + * @buf_len: Size of each individual buffer is determined based on aggregation + * negotiated as per the protocol. In case of no aggregation supported by + * the protocol, we use default values. + */ +struct usb_gsi_request { + void *buf_base_addr; + dma_addr_t dma; + size_t num_bufs; + size_t buf_len; +}; + +/* + * @last_trb_addr: Address (LSB - based on alignment restrictions) of + * last TRB in queue. Used to identify rollover 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 by GSI hardware to write "Update Transfer" cmd + * @depcmd_hi_addr: Used to write "Update Transfer" command. + * @gevntcount_low_addr: GEVNCOUNT low address for GSI hardware to read and + * clear processed events. + * @gevntcount_hi_addr: GEVNCOUNT high address. + * @xfer_ring_len: length of transfer ring in bytes (must be integral + * multiple of TRB size - 16B for xDCI). + * @xfer_ring_base_addr: physical base address of transfer ring. Address must + * be aligned to xfer_ring_len rounded to power of two. + * @ch_req: Used to pass request specific info for certain operations on GSI EP + */ +struct gsi_channel_info { + u16 last_trb_addr; + u8 const_buffer_size; + u32 depcmd_low_addr; + u8 depcmd_hi_addr; + u32 gevntcount_low_addr; + u8 gevntcount_hi_addr; + u16 xfer_ring_len; + u64 xfer_ring_base_addr; + struct usb_gsi_request *ch_req; +}; + /** * struct usb_request - describes one i/o request * @buf: Buffer used for data. Always provide this; some controllers @@ -46,6 +119,11 @@ struct usb_ep; * by adding a zero length packet as needed; * @short_not_ok: When reading data, makes short packets be * treated as errors (queue stops advancing till cleanup). + * @dma_pre_mapped: Tells the USB core driver whether this request should be + * DMA-mapped before it is queued to the USB HW. When set to true, it means + * that the request has already been mapped in advance and therefore the + * USB core driver does NOT need to do DMA-mapping when the request is + * queued to the USB HW. * @complete: Function called when request completes, so this request and * its buffer may be re-used. The function will always be called with * interrupts disabled, and it must not sleep. @@ -69,6 +147,7 @@ struct usb_ep; * Note that for writes (IN transfers) some data bytes may still * reside in a device-side FIFO when the request is reported as * complete. + * @udc_priv: Vendor private data in usage by the UDC. * * These are allocated/freed through the endpoint they're used with. The * hardware's driver can add extra per-request data to the memory it returns, @@ -101,6 +180,7 @@ struct usb_request { unsigned no_interrupt:1; unsigned zero:1; unsigned short_not_ok:1; + unsigned dma_pre_mapped:1; void (*complete)(struct usb_ep *ep, struct usb_request *req); @@ -109,6 +189,7 @@ struct usb_request { int status; unsigned actual; + unsigned udc_priv; }; /*-------------------------------------------------------------------------*/ @@ -138,6 +219,8 @@ struct usb_ep_ops { int (*fifo_status) (struct usb_ep *ep); void (*fifo_flush) (struct usb_ep *ep); + int (*gsi_ep_op)(struct usb_ep *ep, void *op_data, + enum gsi_ep_op op); }; /** @@ -201,6 +284,10 @@ struct usb_ep_caps { * enabled and remains valid until the endpoint is disabled. * @comp_desc: In case of SuperSpeed support, this is the endpoint companion * descriptor that is used to configure the endpoint + * @ep_type: Used to specify type of EP eg. normal vs h/w accelerated. + * @ep_intr_num: Interrupter number for EP. + * @endless: In case where endless transfer is being initiated, this is set + * to disable usb event interrupt for few events. * * the bus controller driver lists all the general purpose endpoints in * gadget->ep_list. the control endpoint (gadget->ep0) is not in that list, @@ -224,6 +311,10 @@ struct usb_ep { u8 address; const struct usb_endpoint_descriptor *desc; const struct usb_ss_ep_comp_descriptor *comp_desc; + enum ep_type ep_type; + u8 ep_num; + u8 ep_intr_num; + bool endless; }; /*-------------------------------------------------------------------------*/ @@ -536,7 +627,20 @@ static inline void usb_ep_fifo_flush(struct usb_ep *ep) ep->ops->fifo_flush(ep); } +/** + * usb_gsi_ep_op - performs operation on GSI accelerated EP based on EP op code + * + * Operations such as EP configuration, TRB allocation, StartXfer etc. + * See gsi_ep_op for more details. + */ +static inline int usb_gsi_ep_op(struct usb_ep *ep, + struct usb_gsi_request *req, enum gsi_ep_op op) +{ + if (ep->ops->gsi_ep_op) + return ep->ops->gsi_ep_op(ep, req, op); + return -EOPNOTSUPP; +} /*-------------------------------------------------------------------------*/ struct usb_dcd_config_params { @@ -557,10 +661,12 @@ struct usb_udc; struct usb_gadget_ops { int (*get_frame)(struct usb_gadget *); int (*wakeup)(struct usb_gadget *); + int (*func_wakeup)(struct usb_gadget *, int interface_id); int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); int (*vbus_session) (struct usb_gadget *, int is_active); int (*vbus_draw) (struct usb_gadget *, unsigned mA); int (*pullup) (struct usb_gadget *, int is_on); + int (*restart)(struct usb_gadget *); int (*ioctl)(struct usb_gadget *, unsigned code, unsigned long param); void (*get_config_params)(struct usb_dcd_config_params *); @@ -656,6 +762,7 @@ struct usb_gadget { unsigned is_selfpowered:1; unsigned deactivated:1; unsigned connected:1; + bool remote_wakeup; }; #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) @@ -797,6 +904,26 @@ static inline int usb_gadget_wakeup(struct usb_gadget *gadget) } /** + * usb_gadget_func_wakeup - send a function remote wakeup up notification + * to the host connected to this gadget + * @gadget: controller used to wake up the host + * @interface_id: the interface which triggered the remote wakeup event + * + * Returns zero on success. Otherwise, negative error code is returned. + */ +static inline int usb_gadget_func_wakeup(struct usb_gadget *gadget, + int interface_id) +{ + if (gadget->speed != USB_SPEED_SUPER) + return -EOPNOTSUPP; + + if (!gadget->ops->func_wakeup) + return -EOPNOTSUPP; + + return gadget->ops->func_wakeup(gadget, interface_id); +} + +/** * usb_gadget_set_selfpowered - sets the device selfpowered feature. * @gadget:the device being declared as self-powered * @@ -952,6 +1079,20 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) } /** + * usb_gadget_restart - software-controlled reset of USB peripheral connection + * @gadget:the peripheral being reset + * + * Informs controller driver for Vbus LOW followed by Vbus HIGH notification. + * This performs full hardware reset and re-initialization. + */ +static inline int usb_gadget_restart(struct usb_gadget *gadget) +{ + if (!gadget->ops->restart) + return -EOPNOTSUPP; + return gadget->ops->restart(gadget); +} + +/** * usb_gadget_deactivate - deactivate function which is not ready to work * @gadget: the peripheral being deactivated * @@ -1010,6 +1151,129 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) return 0; } +/** + * usb_gadget_autopm_get - increment PM-usage counter of usb gadget's parent + * device. + * @gadget: usb gadget whose parent device counter is incremented + * + * This routine should be called by function driver when it wants to use + * gadget's parent device and needs to guarantee that it is not suspended. In + * addition, the routine prevents subsequent autosuspends of gadget's parent + * device. However if the autoresume fails then the counter is re-decremented. + * + * This routine can run only in process context. + */ +static inline int usb_gadget_autopm_get(struct usb_gadget *gadget) +{ + int status = -ENODEV; + + if (!gadget || !gadget->dev.parent) + return status; + + status = pm_runtime_get_sync(gadget->dev.parent); + if (status < 0) + pm_runtime_put_sync(gadget->dev.parent); + + if (status > 0) + status = 0; + return status; +} + +/** + * usb_gadget_autopm_get_async - increment PM-usage counter of usb gadget's + * parent device. + * @gadget: usb gadget whose parent device counter is incremented + * + * This routine increments @gadget parent device PM usage counter and queue an + * autoresume request if the device is suspended. It does not autoresume device + * directly (it only queues a request). After a successful call, the device may + * not yet be resumed. + * + * This routine can run in atomic context. + */ +static inline int usb_gadget_autopm_get_async(struct usb_gadget *gadget) +{ + int status = -ENODEV; + + if (!gadget || !gadget->dev.parent) + return status; + + status = pm_runtime_get(gadget->dev.parent); + if (status < 0 && status != -EINPROGRESS) + pm_runtime_put_noidle(gadget->dev.parent); + + if (status > 0 || status == -EINPROGRESS) + status = 0; + return status; +} + +/** + * usb_gadget_autopm_get_noresume - increment PM-usage counter of usb gadget's + * parent device. + * @gadget: usb gadget whose parent device counter is incremented + * + * This routine increments PM-usage count of @gadget parent device but does not + * carry out an autoresume. + * + * This routine can run in atomic context. + */ +static inline void usb_gadget_autopm_get_noresume(struct usb_gadget *gadget) +{ + if (gadget && gadget->dev.parent) + pm_runtime_get_noresume(gadget->dev.parent); +} + +/** + * usb_gadget_autopm_put - decrement PM-usage counter of usb gadget's parent + * device. + * @gadget: usb gadget whose parent device counter is decremented. + * + * This routine should be called by function driver when it is finished using + * @gadget parent device and wants to allow it to autosuspend. It decrements + * PM-usage counter of @gadget parent device, when the counter reaches 0, a + * delayed autosuspend request is attempted. + * + * This routine can run only in process context. + */ +static inline void usb_gadget_autopm_put(struct usb_gadget *gadget) +{ + if (gadget && gadget->dev.parent) + pm_runtime_put_sync(gadget->dev.parent); +} + +/** + * usb_gadget_autopm_put_async - decrement PM-usage counter of usb gadget's + * parent device. + * @gadget: usb gadget whose parent device counter is decremented. + * + * This routine decrements PM-usage counter of @gadget parent device and + * schedules a delayed autosuspend request if the counter is <= 0. + * + * This routine can run in atomic context. + */ +static inline void usb_gadget_autopm_put_async(struct usb_gadget *gadget) +{ + if (gadget && gadget->dev.parent) + pm_runtime_put(gadget->dev.parent); +} + +/** + * usb_gadget_autopm_put_no_suspend - decrement PM-usage counter of usb gadget +'s + * parent device. + * @gadget: usb gadget whose parent device counter is decremented. + * + * This routine decrements PM-usage counter of @gadget parent device but does + * not carry out an autosuspend. + * + * This routine can run in atomic context. + */ +static inline void usb_gadget_autopm_put_no_suspend(struct usb_gadget *gadget) +{ + if (gadget && gadget->dev.parent) + pm_runtime_put_noidle(gadget->dev.parent); +} + /*-------------------------------------------------------------------------*/ /** @@ -1204,6 +1468,7 @@ struct usb_descriptor_header **usb_copy_descriptors( static inline void usb_free_descriptors(struct usb_descriptor_header **v) { kfree(v); + v = NULL; } struct usb_function; @@ -1219,6 +1484,24 @@ int usb_otg_descriptor_init(struct usb_gadget *gadget, struct usb_descriptor_header *otg_desc); /*-------------------------------------------------------------------------*/ +/** + * usb_func_ep_queue - queues (submits) an I/O request to a function endpoint. + * This function is similar to the usb_ep_queue function, but in addition it + * also checks whether the function is in Super Speed USB Function Suspend + * state, and if so a Function Wake notification is sent to the host + * (USB 3.0 spec, section 9.2.5.2). + * @func: the function which issues the USB I/O request. + * @ep:the endpoint associated with the request + * @req:the request being submitted + * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't + * pre-allocate all necessary memory with the request. + * + */ +int usb_func_ep_queue(struct usb_function *func, struct usb_ep *ep, + struct usb_request *req, gfp_t gfp_flags); + +/*-------------------------------------------------------------------------*/ + /* utility to simplify map/unmap of usb_requests to/from DMA */ extern int usb_gadget_map_request(struct usb_gadget *gadget, @@ -1282,5 +1565,8 @@ extern struct usb_ep *usb_ep_autoconfig_ss(struct usb_gadget *, extern void usb_ep_autoconfig_release(struct usb_ep *); extern void usb_ep_autoconfig_reset(struct usb_gadget *); +extern struct usb_ep *usb_ep_autoconfig_by_name(struct usb_gadget *, + struct usb_endpoint_descriptor *, + const char *ep_name); #endif /* __LINUX_USB_GADGET_H */ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 757c554408ce..dff7adbc60bb 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -397,6 +397,14 @@ struct hc_driver { /* Call for power on/off the port if necessary */ int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable); + int (*sec_event_ring_setup)(struct usb_hcd *hcd, unsigned intr_num); + int (*sec_event_ring_cleanup)(struct usb_hcd *hcd, unsigned intr_num); + dma_addr_t (*get_sec_event_ring_dma_addr)(struct usb_hcd *hcd, + unsigned intr_num); + dma_addr_t (*get_xfer_ring_dma_addr)(struct usb_hcd *hcd, + struct usb_device *udev, struct usb_host_endpoint *ep); + dma_addr_t (*get_dcba_dma_addr)(struct usb_hcd *hcd, + struct usb_device *udev); }; static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd) @@ -435,6 +443,17 @@ extern int usb_hcd_alloc_bandwidth(struct usb_device *udev, struct usb_host_interface *old_alt, struct usb_host_interface *new_alt); extern int usb_hcd_get_frame_number(struct usb_device *udev); +extern int usb_hcd_sec_event_ring_setup(struct usb_device *udev, + unsigned intr_num); +extern int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev, + unsigned intr_num); +extern dma_addr_t +usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev, + unsigned intr_num); +extern dma_addr_t usb_hcd_get_dcba_dma_addr(struct usb_device *udev); +extern dma_addr_t +usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev, + struct usb_host_endpoint *ep); extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, struct device *dev, const char *bus_name); @@ -484,7 +503,7 @@ extern void usb_hc_died(struct usb_hcd *hcd); extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); extern void usb_wakeup_notification(struct usb_device *hdev, unsigned int portnum); - +extern void usb_flush_hub_wq(void); extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum); extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum); diff --git a/include/linux/usb/ipc_bridge.h b/include/linux/usb/ipc_bridge.h new file mode 100644 index 000000000000..a0e12d6f9af5 --- /dev/null +++ b/include/linux/usb/ipc_bridge.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2013 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 __MSM_IPC_BRIDGE_H__ +#define __MSM_IPC_BRIDGE_H__ + +#include <linux/platform_device.h> + +/* + * The IPC bridge driver adds a IPC bridge platform device when the + * underlying transport is ready. The IPC transport driver acts as a + * platform driver for this device. The platform data is populated by + * IPC bridge driver to facilitate I/O. The callback functions are + * passed in platform data to avoid export functions. This would allow + * different bridge drivers to exist in the kernel. The IPC bridge driver + * removes the platform device when the underly transport is no longer + * available. It typically happens during shutdown and remote processor's + * subsystem restart. + */ + +/** + * struct ipc_bridge_platform_data - platform device data for IPC + * transport driver. + * @max_read_size: The maximum possible read size. + * @max_write_size: The maximum possible write size. + * @open: The open must be called before starting I/O. The IPC bridge + * driver use the platform device pointer to identify the + * underlying transport channel. The IPC bridge driver may + * notify that remote processor that it is ready to receive + * data. Returns 0 upon success and appropriate error code + * upon failure. + * @read: The read is done synchronously and should be called from process + * context. Returns the number of bytes read from remote + * processor or error code upon failure. The IPC transport + * driver may pass the buffer of max_read_size length if the + * available data size is not known in advance. + * @write: The write is done synchronously and should be called from process + * context. The IPC bridge driver uses the same buffer for DMA + * to avoid additional memcpy. So it must be physically contiguous. + * Returns the number of bytes written or error code upon failure. + * @close: The close must be called when the IPC bridge platform device + * is removed. The IPC transport driver may call close when + * it is no longer required to communicate with remote processor. + */ +struct ipc_bridge_platform_data { + unsigned int max_read_size; + unsigned int max_write_size; + int (*open)(struct platform_device *pdev); + int (*read)(struct platform_device *pdev, char *buf, + unsigned int count); + int (*write)(struct platform_device *pdev, char *buf, + unsigned int count); + void (*close)(struct platform_device *pdev); +}; + +#endif diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 8c8f6854c993..21fddf0cbf09 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -1,8 +1,8 @@ -/* linux/include/asm-arm/arch-msm/hsusb.h +/* include/linux/usb/msm_hsusb.h * * Copyright (C) 2008 Google, Inc. * Author: Brian Swetland <swetland@google.com> - * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -20,8 +20,24 @@ #include <linux/extcon.h> #include <linux/types.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> #include <linux/usb/otg.h> -#include <linux/clk.h> +/* + * The following are bit fields describing the usb_request.udc_priv word. + * These bit fields are set by function drivers that wish to queue + * usb_requests with sps/bam parameters. + */ +#define MSM_PIPE_ID_MASK (0x1F) +#define MSM_TX_PIPE_ID_OFS (16) +#define MSM_SPS_MODE BIT(5) +#define MSM_IS_FINITE_TRANSFER BIT(6) +#define MSM_PRODUCER BIT(7) +#define MSM_DISABLE_WB BIT(8) +#define MSM_ETD_IOC BIT(9) +#define MSM_INTERNAL_MEM BIT(10) +#define MSM_VENDOR_ID BIT(16) + /** * OTG control @@ -99,6 +115,25 @@ enum usb_chg_type { }; /** + * Supported USB controllers + */ +enum usb_ctrl { + DWC3_CTRL = 0, /* DWC3 controller */ + CI_CTRL, /* ChipIdea controller */ + HSIC_CTRL, /* HSIC controller */ + NUM_CTRL, +}; + + +/** + * USB ID state + */ +enum usb_id_state { + USB_ID_GROUND = 0, + USB_ID_FLOAT, +}; + +/** * struct msm_otg_platform_data - platform device data * for msm_otg driver. * @phy_init_seq: PHY configuration sequence values. Value of -1 is reserved as @@ -131,6 +166,21 @@ struct msm_usb_cable { struct extcon_dev *extcon; }; + +/* phy related flags */ +#define ENABLE_DP_MANUAL_PULLUP BIT(0) +#define ENABLE_SECONDARY_PHY BIT(1) +#define PHY_HOST_MODE BIT(2) +#define PHY_CHARGER_CONNECTED BIT(3) +#define PHY_VBUS_VALID_OVERRIDE BIT(4) +#define DEVICE_IN_SS_MODE BIT(5) +#define PHY_LANE_A BIT(6) +#define PHY_LANE_B BIT(7) +#define PHY_HSFS_MODE BIT(8) +#define PHY_LS_MODE BIT(9) + +#define USB_NUM_BUS_CLOCKS 3 + /** * struct msm_otg: OTG driver data. Shared by HCD and DCD. * @otg: USB OTG Transceiver structure. @@ -197,4 +247,94 @@ struct msm_otg { struct notifier_block reboot; }; +#ifdef CONFIG_USB_BAM +void msm_bam_set_usb_host_dev(struct device *dev); +void msm_bam_set_hsic_host_dev(struct device *dev); +void msm_bam_wait_for_usb_host_prod_granted(void); +void msm_bam_wait_for_hsic_host_prod_granted(void); +bool msm_bam_hsic_lpm_ok(void); +void msm_bam_usb_host_notify_on_resume(void); +void msm_bam_hsic_host_notify_on_resume(void); +bool msm_bam_hsic_host_pipe_empty(void); +bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable); +#else +static inline void msm_bam_set_usb_host_dev(struct device *dev) {} +static inline void msm_bam_set_hsic_host_dev(struct device *dev) {} +static inline void msm_bam_wait_for_usb_host_prod_granted(void) {} +static inline void msm_bam_wait_for_hsic_host_prod_granted(void) {} +static inline bool msm_bam_hsic_lpm_ok(void) { return true; } +static inline void msm_bam_hsic_host_notify_on_resume(void) {} +static inline void msm_bam_usb_host_notify_on_resume(void) {} +static inline bool msm_bam_hsic_host_pipe_empty(void) { return true; } +static inline bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable) +{ + return true; +} +#endif + +/* CONFIG_PM */ +#ifdef CONFIG_PM +static inline int get_pm_runtime_counter(struct device *dev) +{ + return atomic_read(&dev->power.usage_count); +} +#else /* !CONFIG_PM */ +static inline int get_pm_runtime_counter(struct device *dev) { return -ENOSYS; } +#endif + +#ifdef CONFIG_USB_CI13XXX_MSM +void msm_hw_bam_disable(bool bam_disable); +void msm_usb_irq_disable(bool disable); +#else +static inline void msm_hw_bam_disable(bool bam_disable) +{ +} + +static inline void msm_usb_irq_disable(bool disable) +{ +} +#endif + +#ifdef CONFIG_USB_DWC3_QCOM +int msm_ep_config(struct usb_ep *ep, struct usb_request *request); +int msm_ep_unconfig(struct usb_ep *ep); +void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable); +int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, u32 size, + u8 dst_pipe_idx); +bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget); +int msm_dwc3_reset_dbm_ep(struct usb_ep *ep); + +#else +static inline int msm_data_fifo_config(struct usb_ep *ep, phys_addr_t addr, + u32 size, u8 dst_pipe_idx) +{ + return -ENODEV; +} + +static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request) +{ + return -ENODEV; +} + +static inline int msm_ep_unconfig(struct usb_ep *ep) +{ + return -ENODEV; +} + +static inline void dwc3_tx_fifo_resize_request( + struct usb_ep *ep, bool qdss_enable) +{ +} + +static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget) +{ + return false; +} + +static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep) +{ + return -ENODEV; +} + +#endif #endif diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 31a8068c42a5..f066d65ac3dd 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -44,6 +44,7 @@ enum usb_otg_state { OTG_STATE_B_IDLE, OTG_STATE_B_SRP_INIT, OTG_STATE_B_PERIPHERAL, + OTG_STATE_B_SUSPEND, /* extra dual-role default-b states */ OTG_STATE_B_WAIT_ACON, @@ -122,6 +123,12 @@ struct usb_phy { enum usb_device_speed speed); int (*notify_disconnect)(struct usb_phy *x, enum usb_device_speed speed); + + /* reset the PHY clocks */ + int (*reset)(struct usb_phy *x); + + /* return linestate with Idp_src (used for DCD with USB2 PHY) */ + int (*dpdm_with_idp_src)(struct usb_phy *x); }; /** @@ -196,6 +203,24 @@ usb_phy_vbus_off(struct usb_phy *x) return x->set_vbus(x, false); } +static inline int +usb_phy_reset(struct usb_phy *x) +{ + if (x && x->reset) + return x->reset(x); + + return 0; +} + +static inline int +usb_phy_dpdm_with_idp_src(struct usb_phy *x) +{ + if (x && x->dpdm_with_idp_src) + return x->dpdm_with_idp_src(x); + + return 0; +} + /* for usb host and peripheral controller drivers */ #if IS_ENABLED(CONFIG_USB_PHY) extern struct usb_phy *usb_get_phy(enum usb_phy_type type); diff --git a/include/linux/usb/usb_qdss.h b/include/linux/usb/usb_qdss.h new file mode 100644 index 000000000000..f2b8782528a8 --- /dev/null +++ b/include/linux/usb/usb_qdss.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2012-2013, 2017, 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 __LINUX_USB_QDSS_H +#define __LINUX_USB_QDSS_H + +#include <linux/kernel.h> + +#define USB_QDSS_CH_MDM "qdss_mdm" +#define USB_QDSS_CH_MSM "qdss" + +struct qdss_request { + char *buf; + int length; + int actual; + int status; + void *context; +}; + +struct usb_qdss_ch { + const char *name; + struct list_head list; + void (*notify)(void *priv, unsigned event, struct qdss_request *d_req, + struct usb_qdss_ch *); + void *priv; + void *priv_usb; + int app_conn; +}; + +enum qdss_state { + USB_QDSS_CONNECT, + USB_QDSS_DISCONNECT, + USB_QDSS_CTRL_READ_DONE, + USB_QDSS_DATA_WRITE_DONE, + USB_QDSS_CTRL_WRITE_DONE, +}; + +#if IS_ENABLED(CONFIG_USB_F_QDSS) +struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, + void (*notify)(void *, unsigned, struct qdss_request *, + struct usb_qdss_ch *)); +void usb_qdss_close(struct usb_qdss_ch *ch); +int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int n_write, int n_read); +void usb_qdss_free_req(struct usb_qdss_ch *ch); +int usb_qdss_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); +int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); +int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req); +int usb_qdss_ctrl_read(struct usb_qdss_ch *ch, struct qdss_request *d_req); +#else +static inline struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv, + void (*n)(void *, u32, struct qdss_request *, struct usb_qdss_ch *)) +{ + return ERR_PTR(-ENODEV); +} + +static inline int usb_qdss_read(struct usb_qdss_ch *c, struct qdss_request *d) +{ + return -ENODEV; +} + +static inline int usb_qdss_write(struct usb_qdss_ch *c, struct qdss_request *d) +{ + return -ENODEV; +} + +static inline int usb_qdss_ctrl_write(struct usb_qdss_ch *c, + struct qdss_request *d) +{ + return -ENODEV; +} + +static inline int usb_qdss_ctrl_read(struct usb_qdss_ch *c, + struct qdss_request *d) +{ + return -ENODEV; +} +static inline int usb_qdss_alloc_req(struct usb_qdss_ch *c, int n_wr, int n_rd) +{ + return -ENODEV; +} + + +static inline void usb_qdss_close(struct usb_qdss_ch *ch) { } + +static inline void usb_qdss_free_req(struct usb_qdss_ch *ch) { } +#endif /* CONFIG_USB_F_QDSS */ + +#endif diff --git a/include/linux/usb/usbdiag.h b/include/linux/usb/usbdiag.h new file mode 100644 index 000000000000..f66762800368 --- /dev/null +++ b/include/linux/usb/usbdiag.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2008-2010, 2012-2014, The Linux Foundation. + * All rights reserved. + * + * All source code in this file is licensed under the following license except + * where indicated. + * + * 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. + * + * 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, you can find it at http://www.fsf.org + */ + +#ifndef _DRIVERS_USB_DIAG_H_ +#define _DRIVERS_USB_DIAG_H_ + +#include <linux/err.h> + +#define DIAG_LEGACY "diag" +#define DIAG_MDM "diag_mdm" +#define DIAG_QSC "diag_qsc" +#define DIAG_MDM2 "diag_mdm2" + +#define USB_DIAG_CONNECT 0 +#define USB_DIAG_DISCONNECT 1 +#define USB_DIAG_WRITE_DONE 2 +#define USB_DIAG_READ_DONE 3 + +struct diag_request { + char *buf; + int length; + int actual; + int status; + void *context; +}; + +struct usb_diag_ch { + const char *name; + struct list_head list; + void (*notify)(void *priv, unsigned event, struct diag_request *d_req); + void *priv; + void *priv_usb; +}; + +#if IS_ENABLED(CONFIG_USB_F_DIAG) +int usb_diag_request_size(struct usb_diag_ch *ch); +struct usb_diag_ch *usb_diag_open(const char *name, void *priv, + void (*notify)(void *, unsigned, struct diag_request *)); +void usb_diag_close(struct usb_diag_ch *ch); +int usb_diag_alloc_req(struct usb_diag_ch *ch, int n_write, int n_read); +int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req); +int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req); +#else +static inline struct usb_diag_ch *usb_diag_open(const char *name, void *priv, + void (*notify)(void *, unsigned, struct diag_request *)) +{ + return ERR_PTR(-ENODEV); +} +static inline void usb_diag_close(struct usb_diag_ch *ch) +{ +} +static inline +int usb_diag_alloc_req(struct usb_diag_ch *ch, int n_write, int n_read) +{ + return -ENODEV; +} +static inline +int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req) +{ + return -ENODEV; +} +static inline +int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req) +{ + return -ENODEV; +} +#endif /* CONFIG_USB_F_DIAG */ +#endif /* _DRIVERS_USB_DIAG_H_ */ diff --git a/include/linux/usb/usbpd.h b/include/linux/usb/usbpd.h new file mode 100644 index 000000000000..3566a7a974d1 --- /dev/null +++ b/include/linux/usb/usbpd.h @@ -0,0 +1,159 @@ +/* Copyright (c) 2016, 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 __LINUX_USB_USBPD_H +#define __LINUX_USB_USBPD_H + +#include <linux/list.h> + +struct usbpd; + +/* Standard IDs */ +#define USBPD_SID 0xff00 + +/* Structured VDM Command Type */ +enum usbpd_svdm_cmd_type { + SVDM_CMD_TYPE_INITIATOR, + SVDM_CMD_TYPE_RESP_ACK, + SVDM_CMD_TYPE_RESP_NAK, + SVDM_CMD_TYPE_RESP_BUSY, +}; + +/* Structured VDM Commands */ +#define USBPD_SVDM_DISCOVER_IDENTITY 0x1 +#define USBPD_SVDM_DISCOVER_SVIDS 0x2 +#define USBPD_SVDM_DISCOVER_MODES 0x3 +#define USBPD_SVDM_ENTER_MODE 0x4 +#define USBPD_SVDM_EXIT_MODE 0x5 +#define USBPD_SVDM_ATTENTION 0x6 + +/* + * Implemented by client + */ +struct usbpd_svid_handler { + u16 svid; + + /* Notified when VDM session established/reset; must be implemented */ + void (*connect)(struct usbpd_svid_handler *hdlr); + void (*disconnect)(struct usbpd_svid_handler *hdlr); + + /* Unstructured VDM */ + void (*vdm_received)(struct usbpd_svid_handler *hdlr, u32 vdm_hdr, + const u32 *vdos, int num_vdos); + + /* Structured VDM */ + void (*svdm_received)(struct usbpd_svid_handler *hdlr, u8 cmd, + enum usbpd_svdm_cmd_type cmd_type, const u32 *vdos, + int num_vdos); + + /* client should leave these blank; private members used by PD driver */ + struct list_head entry; + bool discovered; +}; + +enum plug_orientation { + ORIENTATION_NONE, + ORIENTATION_CC1, + ORIENTATION_CC2, +}; + +#if IS_ENABLED(CONFIG_USB_PD_POLICY) +/* + * Obtains an instance of usbpd from a DT phandle + */ +struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, + const char *phandle); + +/* + * Called by client to handle specific SVID messages. + * Specify callback functions in the usbpd_svid_handler argument + */ +int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr); + +void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr); + +/* + * Transmit a VDM message. + */ +int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, + int num_vdos); + +/* + * Transmit a Structured VDM message. + */ +int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, + enum usbpd_svdm_cmd_type cmd_type, int obj_pos, + const u32 *vdos, int num_vdos); + +/* + * Get current status of CC pin orientation. + * + * Return: ORIENTATION_CC1 or ORIENTATION_CC2 if attached, + * otherwise ORIENTATION_NONE if not attached + */ +enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd); +#else +static inline struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, + const char *phandle) +{ + return ERR_PTR(-ENODEV); +} + +static inline int usbpd_register_svid(struct usbpd *pd, + struct usbpd_svid_handler *hdlr) +{ + return -EINVAL; +} + +static inline void usbpd_unregister_svid(struct usbpd *pd, + struct usbpd_svid_handler *hdlr) +{ +} + +static inline int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, + int num_vdos) +{ + return -EINVAL; +} + +static inline int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, + enum usbpd_svdm_cmd_type cmd_type, int obj_pos, + const u32 *vdos, int num_vdos) +{ + return -EINVAL; +} + +static inline enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd) +{ + return ORIENTATION_NONE; +} +#endif /* IS_ENABLED(CONFIG_USB_PD_POLICY) */ + +/* + * Additional helpers for Enter/Exit Mode commands + */ + +static inline int usbpd_enter_mode(struct usbpd *pd, u16 svid, int mode, + const u32 *vdo) +{ + return usbpd_send_svdm(pd, svid, USBPD_SVDM_ENTER_MODE, + SVDM_CMD_TYPE_INITIATOR, mode, vdo, vdo ? 1 : 0); +} + +static inline int usbpd_exit_mode(struct usbpd *pd, u16 svid, int mode, + const u32 *vdo) +{ + return usbpd_send_svdm(pd, svid, USBPD_SVDM_EXIT_MODE, + SVDM_CMD_TYPE_INITIATOR, mode, vdo, vdo ? 1 : 0); +} + +#endif /* __LINUX_USB_USBPD_H */ diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h index 376654b5b0f7..a44b53c33e75 100644 --- a/include/linux/usb/xhci_pdriver.h +++ b/include/linux/usb/xhci_pdriver.h @@ -19,9 +19,13 @@ * @usb3_lpm_capable: determines if this xhci platform supports USB3 * LPM capability * + * @imod_interval: minimum inter-interrupt interval. Specified in + * 250nsec increments. + * */ struct usb_xhci_pdata { unsigned usb3_lpm_capable:1; + unsigned imod_interval; }; #endif /* __USB_CORE_XHCI_PDRIVER_H */ diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h new file mode 100644 index 000000000000..b5b9edaab783 --- /dev/null +++ b/include/linux/usb_bam.h @@ -0,0 +1,529 @@ +/* Copyright (c) 2011-2017, 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 _USB_BAM_H_ +#define _USB_BAM_H_ +#include <linux/msm-sps.h> +#include <linux/ipa.h> +#include <linux/usb/msm_hsusb.h> + +#define MAX_BAMS NUM_CTRL /* Bam per USB controllers */ + + +enum usb_bam_mode { + USB_BAM_DEVICE = 0, + USB_BAM_HOST, +}; + +enum peer_bam { + QDSS_P_BAM = 0, + IPA_P_BAM, + MAX_PEER_BAMS, +}; + +enum usb_bam_pipe_dir { + USB_TO_PEER_PERIPHERAL, + PEER_PERIPHERAL_TO_USB, +}; + +enum usb_pipe_mem_type { + SPS_PIPE_MEM = 0, /* Default, SPS dedicated pipe memory */ + SYSTEM_MEM, /* System RAM, requires allocation */ + OCI_MEM, /* Shared memory among peripherals */ +}; + +enum usb_bam_event_type { + USB_BAM_EVENT_WAKEUP_PIPE = 0, /* Wake a pipe */ + USB_BAM_EVENT_WAKEUP, /* Wake a bam (first pipe waked) */ + USB_BAM_EVENT_INACTIVITY, /* Inactivity on all pipes */ +}; + +enum usb_bam_pipe_type { + USB_BAM_PIPE_BAM2BAM = 0, /* Connection is BAM2BAM (default) */ + USB_BAM_PIPE_SYS2BAM, /* Connection is SYS2BAM or BAM2SYS + * depending on usb_bam_pipe_dir + */ + USB_BAM_MAX_PIPE_TYPES, +}; + +/** +* struct usb_bam_connect_ipa_params: Connect Bam pipe to IPA peer infromation. +* @ src_idx: Source pipe index in usb bam pipes lists. +* @ dst_idx: Destination pipe index in usb bam pipes lists. +* @ src_pipe: The source pipe index in the sps level. +* @ dst_pipe: The destination pipe index in the sps level. +* @ keep_ipa_awake: When true, IPA will not be clock gated. +* @ ipa_cons_ep_idx: The pipe index on the IPA peer bam side, consumer. +* @ ipa_prod_ep_idx: The pipe index on the IPA peer bam side, producer. +* @ prod_clnt_hdl: Producer client handle returned by IPA driver +* @ cons_clnt_hdl: Consumer client handle returned by IPA driver +* @ src_client: Source IPA client type. +* @ dst_client: Destination IPA client type. +* @ ipa_ep_cfg: Configuration of IPA end-point (see struct ipa_ep_cfg) +* @priv: Callback cookie to the notify event. +* @notify: Callback on data path event by IPA (see enum ipa_dp_evt_type) +* This call back gets back the priv cookie. +* for Bam2Bam mode, this callback is in the tethering bridge. +* @ activity_notify: Callback to be notified on and data being pushed into the +* USB consumer pipe. +* @ inactivity_notify: Callback to be notified on inactivity of all the current +* open pipes between the USB bam and its peer. +* @ skip_ep_cfg: boolean field that determines if Apps-processor +* should or should not confiugre this end-point. +* (Please see struct teth_bridge_init_params) +* @ reset_pipe_after_lpm: bool to indicate if IPA should reset pipe after LPM. +* @ usb_connection_speed: The actual speed the USB core currently works at. +*/ +struct usb_bam_connect_ipa_params { + u8 src_idx; + u8 dst_idx; + u32 *src_pipe; + u32 *dst_pipe; + bool keep_ipa_awake; + enum usb_bam_pipe_dir dir; + /* Parameters for Port Mapper */ + u32 ipa_cons_ep_idx; + u32 ipa_prod_ep_idx; + /* client handle assigned by IPA to client */ + u32 prod_clnt_hdl; + u32 cons_clnt_hdl; + /* params assigned by the CD */ + enum ipa_client_type src_client; + enum ipa_client_type dst_client; + struct ipa_ep_cfg ipa_ep_cfg; + void *priv; + void (*notify)(void *priv, enum ipa_dp_evt_type evt, + unsigned long data); + int (*activity_notify)(void *priv); + int (*inactivity_notify)(void *priv); + bool skip_ep_cfg; + bool reset_pipe_after_lpm; + enum usb_device_speed usb_connection_speed; +}; + +/** +* struct usb_bam_event_info: suspend/resume event information. +* @type: usb bam event type. +* @event: holds event data. +* @callback: suspend/resume callback. +* @param: port num (for suspend) or NULL (for resume). +* @event_w: holds work queue parameters. +*/ +struct usb_bam_event_info { + enum usb_bam_event_type type; + struct sps_register_event event; + int (*callback)(void *); + void *param; + struct work_struct event_w; +}; + +/** +* struct usb_bam_pipe_connect: pipe connection information +* between USB/HSIC BAM and another BAM. USB/HSIC BAM can be +* either src BAM or dst BAM +* @name: pipe description. +* @mem_type: type of memory used for BAM FIFOs +* @src_phy_addr: src bam physical address. +* @src_pipe_index: src bam pipe index. +* @dst_phy_addr: dst bam physical address. +* @dst_pipe_index: dst bam pipe index. +* @data_fifo_base_offset: data fifo offset. +* @data_fifo_size: data fifo size. +* @desc_fifo_base_offset: descriptor fifo offset. +* @desc_fifo_size: descriptor fifo size. +* @data_mem_buf: data fifo buffer. +* @desc_mem_buf: descriptor fifo buffer. +* @event: event for wakeup. +* @enabled: true if pipe is enabled. +* @suspended: true if pipe is suspended. +* @cons_stopped: true is pipe has consumer requests stopped. +* @prod_stopped: true if pipe has producer requests stopped. +* @ipa_clnt_hdl : pipe handle to ipa api. +* @priv: private data to return upon activity_notify +* or inactivity_notify callbacks. +* @activity_notify: callback to invoke on activity on one of the in pipes. +* @inactivity_notify: callback to invoke on inactivity on all pipes. +* @start: callback to invoke to enqueue transfers on a pipe. +* @stop: callback to invoke on dequeue transfers on a pipe. +* @start_stop_param: param for the start/stop callbacks. +*/ +struct usb_bam_pipe_connect { + const char *name; + u32 pipe_num; + enum usb_pipe_mem_type mem_type; + enum usb_bam_pipe_dir dir; + enum usb_ctrl bam_type; + enum usb_bam_mode bam_mode; + enum peer_bam peer_bam; + enum usb_bam_pipe_type pipe_type; + u32 src_phy_addr; + u32 src_pipe_index; + u32 dst_phy_addr; + u32 dst_pipe_index; + u32 data_fifo_base_offset; + u32 data_fifo_size; + u32 desc_fifo_base_offset; + u32 desc_fifo_size; + struct sps_mem_buffer data_mem_buf; + struct sps_mem_buffer desc_mem_buf; + struct usb_bam_event_info event; + bool enabled; + bool suspended; + bool cons_stopped; + bool prod_stopped; + int ipa_clnt_hdl; + void *priv; + int (*activity_notify)(void *priv); + int (*inactivity_notify)(void *priv); + void (*start)(void *, enum usb_bam_pipe_dir); + void (*stop)(void *, enum usb_bam_pipe_dir); + void *start_stop_param; + bool reset_pipe_after_lpm; +}; + +/** + * struct msm_usb_bam_data: pipe connection information + * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be + * either src BAM or dst BAM + * @usb_bam_num_pipes: max number of pipes to use. + * @active_conn_num: number of active pipe connections. + * @usb_bam_fifo_baseaddr: base address for bam pipe's data and descriptor + * fifos. This can be on chip memory (ocimem) or usb + * private memory. + * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET + * @reset_on_connect: BAM must be reset before its first pipe connect + * @reset_on_disconnect: BAM must be reset after its last pipe disconnect + * @disable_clk_gating: Disable clock gating + * @override_threshold: Override the default threshold value for Read/Write + * event generation by the BAM towards another BAM. + * @max_mbps_highspeed: Maximum Mbits per seconds that the USB core + * can work at in bam2bam mode when connected to HS host. + * @max_mbps_superspeed: Maximum Mbits per seconds that the USB core + * can work at in bam2bam mode when connected to SS host. + * @enable_hsusb_bam_on_boot: Enable HSUSB BAM (non-NDP) on bootup itself + */ +struct msm_usb_bam_data { + u8 max_connections; + int usb_bam_num_pipes; + phys_addr_t usb_bam_fifo_baseaddr; + bool ignore_core_reset_ack; + bool reset_on_connect; + bool reset_on_disconnect; + bool disable_clk_gating; + u32 override_threshold; + u32 max_mbps_highspeed; + u32 max_mbps_superspeed; + bool enable_hsusb_bam_on_boot; + enum usb_ctrl bam_type; +}; + +#if IS_ENABLED(CONFIG_USB_BAM) +/** + * Connect USB-to-Peripheral SPS connection. + * + * This function returns the allocated pipe number. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @idx - Connection index. + * + * @bam_pipe_idx - allocated pipe index. + * + * @return 0 on success, negative value on error + * + */ +int usb_bam_connect(enum usb_ctrl bam_type, int idx, u32 *bam_pipe_idx); + +/** + * Connect USB-to-IPA SPS connection. + * + * This function returns the allocated pipes number and clnt + * handles. Assumes that the user first connects producer pipes + * and only after that consumer pipes, since that's the correct + * sequence for the handshake with the IPA. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @ipa_params - in/out parameters + * + * @return 0 on success, negative value on error + */ +int usb_bam_connect_ipa(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params); + +/** + * Disconnect USB-to-IPA SPS connection. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @ipa_params - in/out parameters + * + * @return 0 on success, negative value on error + */ +int usb_bam_disconnect_ipa(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params); + +/** + * Register a wakeup callback from peer BAM. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @idx - Connection index. + * + * @callback - the callback function + * + * @return 0 on success, negative value on error + */ +int usb_bam_register_wake_cb(enum usb_ctrl bam_type, u8 idx, + int (*callback)(void *), void *param); + +/** + * Register callbacks for start/stop of transfers. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @idx - Connection index + * + * @start - the callback function that will be called in USB + * driver to start transfers + * @stop - the callback function that will be called in USB + * driver to stop transfers + * + * @param - context that the caller can supply + * + * @return 0 on success, negative value on error + */ +int usb_bam_register_start_stop_cbs(enum usb_ctrl bam_type, + u8 idx, + void (*start)(void *, enum usb_bam_pipe_dir), + void (*stop)(void *, enum usb_bam_pipe_dir), + void *param); + +/** + * Start usb suspend sequence + * + * @ipa_params - in/out parameters + * + * @bam_type - USB BAM type - dwc3/CI/hsic + */ +void usb_bam_suspend(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params); + +/** + * Start usb resume sequence + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @ipa_params - in/out parameters + */ +void usb_bam_resume(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params); +/** + * Disconnect USB-to-Periperal SPS connection. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @idx - Connection index. + * + * @return 0 on success, negative value on error + */ +int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx); + +/** + * Returns usb bam connection parameters. + * + * @bam_type - USB BAM type - dwc3/CI/hsic + * + * @idx - Connection index. + * + * @usb_bam_pipe_idx - Usb bam pipe index. + * + * @desc_fifo - Descriptor fifo parameters. + * + * @data_fifo - Data fifo parameters. + * + * @return pipe index on success, negative value on error. + */ +int get_bam2bam_connection_info(enum usb_ctrl bam_type, u8 idx, + u32 *usb_bam_pipe_idx, struct sps_mem_buffer *desc_fifo, + struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type); + +/** + * Returns usb bam connection parameters for qdss pipe. + * @usb_bam_handle - Usb bam handle. + * @usb_bam_pipe_idx - Usb bam pipe index. + * @peer_pipe_idx - Peer pipe index. + * @desc_fifo - Descriptor fifo parameters. + * @data_fifo - Data fifo parameters. + * @return pipe index on success, negative value on error. + */ +int get_qdss_bam_connection_info( + unsigned long *usb_bam_handle, u32 *usb_bam_pipe_idx, + u32 *peer_pipe_idx, struct sps_mem_buffer *desc_fifo, + struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type); + +/** +* Indicates if the client of the USB BAM is ready to start +* sending/receiving transfers. +* +*@bam_type - USB BAM type - dwc3/CI/hsic +* +* @client - Usb pipe peer (a2, ipa, qdss...) +* +* @dir - In (from peer to usb) or out (from usb to peer) +* +* @num - Pipe number. +* +* @return 0 on success, negative value on error +*/ +int usb_bam_get_connection_idx(enum usb_ctrl bam_type, enum peer_bam client, + enum usb_bam_pipe_dir dir, enum usb_bam_mode bam_mode, u32 num); + +/** +* return the usb controller bam type used for the supplied connection index +* +* @core_name - Core name (ssusb/hsusb/hsic). +* +* @return usb control bam type +*/ +int usb_bam_get_bam_type(const char *core_name); + +/** +* Indicates the type of connection the USB side of the connection is. +* +* @bam_type - USB BAM type - dwc3/CI/hsic +* +* @idx - Pipe number. +* +* @type - Type of connection +* +* @return 0 on success, negative value on error +*/ +int usb_bam_get_pipe_type(enum usb_ctrl bam_type, + u8 idx, enum usb_bam_pipe_type *type); + +/** +* Indicates whether USB producer is granted to IPA resource manager. +* +* @return true when producer granted, false when prodcuer is released. +*/ +bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx); + +/** +* Allocates memory for data fifo and descriptor fifos. +*/ +int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx); + +/** +* Frees memory for data fifo and descriptor fifos. +*/ +int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx); + +#else +static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx) +{ + return -ENODEV; +} + +static inline int usb_bam_connect_ipa(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params) +{ + return -ENODEV; +} + +static inline int usb_bam_disconnect_ipa(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params) +{ + return -ENODEV; +} + +static inline void usb_bam_wait_for_cons_granted( + struct usb_bam_connect_ipa_params *ipa_params) +{ + return; +} + +static inline int usb_bam_register_wake_cb(enum usb_ctrl bam_type, u8 idx, + int (*callback)(void *), void *param) +{ + return -ENODEV; +} + +static inline int usb_bam_register_start_stop_cbs(enum usb_ctrl bam, u8 idx, + void (*start)(void *, enum usb_bam_pipe_dir), + void (*stop)(void *, enum usb_bam_pipe_dir), + void *param) +{ + return -ENODEV; +} + +static inline void usb_bam_suspend(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params){} + +static inline void usb_bam_resume(enum usb_ctrl bam_type, + struct usb_bam_connect_ipa_params *ipa_params) {} + +static inline int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx) +{ + return -ENODEV; +} + +static inline int get_bam2bam_connection_info(enum usb_ctrl bam_type, u8 idx, + u32 *usb_bam_pipe_idx, struct sps_mem_buffer *desc_fifo, + struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type) +{ + return -ENODEV; +} + +static inline int get_qdss_bam_connection_info( + unsigned long *usb_bam_handle, u32 *usb_bam_pipe_idx, + u32 *peer_pipe_idx, struct sps_mem_buffer *desc_fifo, + struct sps_mem_buffer *data_fifo, enum usb_pipe_mem_type *mem_type) +{ + return -ENODEV; +} + +static inline int usb_bam_get_connection_idx(enum usb_ctrl bam_type, + enum peer_bam client, enum usb_bam_pipe_dir dir, + enum usb_bam_mode bam_mode, u32 num) +{ + return -ENODEV; +} + +static inline int usb_bam_get_bam_type(const char *core_nam) +{ + return -ENODEV; +} + +static inline int usb_bam_get_pipe_type(enum usb_ctrl bam_type, u8 idx, + enum usb_bam_pipe_type *type) +{ + return -ENODEV; +} + +static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx) +{ + return false; +} + +int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx) +{ + return false; +} + +int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx) +{ + return false; +} + +#endif +#endif /* _USB_BAM_H_ */ diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index fdac5800872d..d31afe5d790d 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -21,7 +21,7 @@ #define FOR_ALL_ZONES(xx) DMA_ZONE(xx) DMA32_ZONE(xx) xx##_NORMAL, HIGHMEM_ZONE(xx) xx##_MOVABLE -enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, +enum vm_event_item { PGPGIN, PGPGOUT, PGPGOUTCLEAN, PSWPIN, PSWPOUT, FOR_ALL_ZONES(PGALLOC), PGFREE, PGACTIVATE, PGDEACTIVATE, PGFAULT, PGMAJFAULT, @@ -52,6 +52,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, COMPACTMIGRATE_SCANNED, COMPACTFREE_SCANNED, COMPACTISOLATED, COMPACTSTALL, COMPACTFAIL, COMPACTSUCCESS, + KCOMPACTD_WAKE, #endif #ifdef CONFIG_HUGETLB_PAGE HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index ecc63f320a54..4df88614319a 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -4,6 +4,7 @@ #include <linux/spinlock.h> #include <linux/init.h> #include <linux/list.h> +#include <linux/llist.h> #include <asm/page.h> /* pgprot_t */ #include <linux/rbtree.h> @@ -18,6 +19,8 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ #define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ +#define VM_LOWMEM 0x00000100 /* Tracking of direct mapped lowmem */ + /* bits [20..32] reserved for arch specific ioremap internals */ /* @@ -45,7 +48,7 @@ struct vmap_area { unsigned long flags; struct rb_node rb_node; /* address sorted rbtree */ struct list_head list; /* address sorted list */ - struct list_head purge_list; /* "lazy purge" list */ + struct llist_node purge_list; /* "lazy purge" list */ struct vm_struct *vm; struct rcu_head rcu_head; }; @@ -81,6 +84,7 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align, const void *caller); extern void vfree(const void *addr); +extern void vfree_atomic(const void *addr); extern void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot); @@ -159,6 +163,13 @@ extern long vwrite(char *buf, char *addr, unsigned long count); extern struct list_head vmap_area_list; extern __init void vm_area_add_early(struct vm_struct *vm); extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); +extern __init int vm_area_check_early(struct vm_struct *vm); +#ifdef CONFIG_ENABLE_VMALLOC_SAVING +extern void mark_vmalloc_reserved_area(void *addr, unsigned long size); +#else +static inline void mark_vmalloc_reserved_area(void *addr, unsigned long size) +{ }; +#endif #ifdef CONFIG_SMP # ifdef CONFIG_MMU @@ -184,7 +195,12 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) #endif #ifdef CONFIG_MMU +#ifdef CONFIG_ENABLE_VMALLOC_SAVING +extern unsigned long total_vmalloc_size; +#define VMALLOC_TOTAL total_vmalloc_size +#else #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) +#endif #else #define VMALLOC_TOTAL 0UL #endif diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h index 3e4535876d37..3219db333b36 100644 --- a/include/linux/vmpressure.h +++ b/include/linux/vmpressure.h @@ -12,6 +12,7 @@ struct vmpressure { unsigned long scanned; unsigned long reclaimed; + unsigned long stall; /* The lock is used to keep the scanned/reclaimed above in sync. */ struct spinlock sr_lock; @@ -25,11 +26,13 @@ struct vmpressure { struct mem_cgroup; -#ifdef CONFIG_MEMCG +extern int vmpressure_notifier_register(struct notifier_block *nb); +extern int vmpressure_notifier_unregister(struct notifier_block *nb); extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, unsigned long scanned, unsigned long reclaimed); extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); +#ifdef CONFIG_MEMCG extern void vmpressure_init(struct vmpressure *vmpr); extern void vmpressure_cleanup(struct vmpressure *vmpr); extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg); @@ -40,9 +43,9 @@ extern int vmpressure_register_event(struct mem_cgroup *memcg, extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); #else -static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, - unsigned long scanned, unsigned long reclaimed) {} -static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, - int prio) {} +static inline struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg) +{ + return NULL; +} #endif /* CONFIG_MEMCG */ #endif /* __LINUX_VMPRESSURE_H */ diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 73fae8c4a5fb..51a2c1179ee6 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -160,6 +160,26 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone, return x; } +static inline unsigned long global_page_state_snapshot(enum zone_stat_item item) +{ + long x = atomic_long_read(&vm_stat[item]); + +#ifdef CONFIG_SMP + struct zone *zone; + int cpu; + + for_each_online_cpu(cpu) { + for_each_populated_zone(zone) + x += per_cpu_ptr(zone->pageset, + cpu)->vm_stat_diff[item]; + } + + if (x < 0) + x = 0; +#endif + return x; +} + #ifdef CONFIG_NUMA extern unsigned long node_page_state(int node, enum zone_stat_item item); diff --git a/include/linux/wakeup_reason.h b/include/linux/wakeup_reason.h index d84d8c301546..a015ce5c830f 100644 --- a/include/linux/wakeup_reason.h +++ b/include/linux/wakeup_reason.h @@ -18,15 +18,87 @@ #ifndef _LINUX_WAKEUP_REASON_H #define _LINUX_WAKEUP_REASON_H +#include <linux/types.h> +#include <linux/completion.h> + #define MAX_SUSPEND_ABORT_LEN 256 -void log_wakeup_reason(int irq); -int check_wakeup_reason(int irq); +struct wakeup_irq_node { + /* @leaf is a linked list of all leaf nodes in the interrupts trees. + */ + struct list_head next; + /* @irq: IRQ number of this node. + */ + int irq; + struct irq_desc *desc; + + /* @siblings contains the list of irq nodes at the same depth; at a + * depth of zero, this is the list of base wakeup interrupts. + */ + struct list_head siblings; + /* @parent: only one node in a siblings list has a pointer to the + * parent; that node is the head of the list of siblings. + */ + struct wakeup_irq_node *parent; + /* @child: any node can have one child + */ + struct wakeup_irq_node *child; + /* @handled: this flag is set to true when the interrupt handler (one of + * handle_.*_irq in kernel/irq/handle.c) for this node gets called; it is set + * to false otherwise. We use this flag to determine whether a subtree rooted + * at a node has been handled. When all trees rooted at + * base-wakeup-interrupt nodes have been handled, we stop logging + * potential wakeup interrupts, and construct the list of actual + * wakeups from the leaves of these trees. + */ + bool handled; +}; + +#ifdef CONFIG_DEDUCE_WAKEUP_REASONS + +/* Called in the resume path, with interrupts and nonboot cpus disabled; on + * need for a spinlock. + */ +static inline void start_logging_wakeup_reasons(void) +{ + extern bool log_wakeups; + extern struct completion wakeups_completion; + ACCESS_ONCE(log_wakeups) = true; + init_completion(&wakeups_completion); +} + +static inline bool logging_wakeup_reasons_nosync(void) +{ + extern bool log_wakeups; + return ACCESS_ONCE(log_wakeups); +} + +static inline bool logging_wakeup_reasons(void) +{ + smp_rmb(); + return logging_wakeup_reasons_nosync(); +} + +bool log_possible_wakeup_reason(int irq, + struct irq_desc *desc, + bool (*handler)(struct irq_desc *)); -#ifdef CONFIG_SUSPEND -void log_suspend_abort_reason(const char *fmt, ...); #else -static inline void log_suspend_abort_reason(const char *fmt, ...) { } + +static inline void start_logging_wakeup_reasons(void) {} +static inline bool logging_wakeup_reasons_nosync(void) { return false; } +static inline bool logging_wakeup_reasons(void) { return false; } +static inline bool log_possible_wakeup_reason(int irq, + struct irq_desc *desc, + bool (*handler)(struct irq_desc *)) { return true; } + #endif +const struct list_head* +get_wakeup_reasons(unsigned long timeout, struct list_head *unfinished); +void log_base_wakeup_reason(int irq); +void clear_wakeup_reasons(void); +void log_suspend_abort_reason(const char *fmt, ...); +int check_wakeup_reason(int irq); + #endif /* _LINUX_WAKEUP_REASON_H */ diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h new file mode 100644 index 000000000000..06c652cfb6af --- /dev/null +++ b/include/linux/wcnss_wlan.h @@ -0,0 +1,166 @@ +/* Copyright (c) 2011-2018, 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 _WCNSS_WLAN_H_ +#define _WCNSS_WLAN_H_ + +#include <linux/device.h> +#include <linux/sched.h> + +#define IRIS_REGULATORS 4 +#define PRONTO_REGULATORS 3 + +enum wcnss_opcode { + WCNSS_WLAN_SWITCH_OFF = 0, + WCNSS_WLAN_SWITCH_ON, +}; + +enum wcnss_hw_type { + WCNSS_RIVA_HW = 0, + WCNSS_PRONTO_HW, +}; + +struct vregs_level { + int nominal_min; + int low_power_min; + int max_voltage; + int uA_load; +}; + +struct wcnss_wlan_config { + int use_48mhz_xo; + int is_pronto_vadc; + int is_pronto_v3; + void __iomem *msm_wcnss_base; + int iris_id; + int vbatt; + struct vregs_level pronto_vlevel[PRONTO_REGULATORS]; + struct vregs_level iris_vlevel[IRIS_REGULATORS]; +}; + +enum { + WCNSS_XO_48MHZ = 1, + WCNSS_XO_19MHZ, + WCNSS_XO_INVALID, +}; + +enum { + WCNSS_WLAN_DATA2, + WCNSS_WLAN_DATA1, + WCNSS_WLAN_DATA0, + WCNSS_WLAN_SET, + WCNSS_WLAN_CLK, + WCNSS_WLAN_MAX_GPIO, +}; + +#define WCNSS_VBATT_THRESHOLD 3500000 +#define WCNSS_VBATT_GUARD 20000 +#define WCNSS_VBATT_HIGH 3700000 +#define WCNSS_VBATT_LOW 3300000 +#define WCNSS_VBATT_INITIAL 3000000 +#define WCNSS_WLAN_IRQ_INVALID -1 +#define HAVE_WCNSS_SUSPEND_RESUME_NOTIFY 1 +#define HAVE_WCNSS_RESET_INTR 1 +#define HAVE_WCNSS_CAL_DOWNLOAD 1 +#define HAVE_CBC_DONE 1 +#define HAVE_WCNSS_RX_BUFF_COUNT 1 +#define HAVE_WCNSS_SNOC_HIGH_FREQ_VOTING 1 +#define HAVE_WCNSS_5G_DISABLE 1 +#define WLAN_MAC_ADDR_SIZE (6) +#define WLAN_RF_REG_ADDR_START_OFFSET 0x3 +#define WLAN_RF_REG_DATA_START_OFFSET 0xf +#define WLAN_RF_READ_REG_CMD 0x3 +#define WLAN_RF_WRITE_REG_CMD 0x2 +#define WLAN_RF_READ_CMD_MASK 0x3fff +#define WLAN_RF_CLK_WAIT_CYCLE 2 +#define WLAN_RF_PREPARE_CMD_DATA 5 +#define WLAN_RF_READ_DATA 6 +#define WLAN_RF_DATA_LEN 3 +#define WLAN_RF_DATA0_SHIFT 0 +#define WLAN_RF_DATA1_SHIFT 1 +#define WLAN_RF_DATA2_SHIFT 2 +#define PRONTO_PMU_OFFSET 0x1004 +#define WCNSS_PMU_CFG_GC_BUS_MUX_SEL_TOP BIT(5) + +struct device *wcnss_wlan_get_device(void); +void wcnss_get_monotonic_boottime(struct timespec *ts); +struct resource *wcnss_wlan_get_memory_map(struct device *dev); +int wcnss_wlan_get_dxe_tx_irq(struct device *dev); +int wcnss_wlan_get_dxe_rx_irq(struct device *dev); +void wcnss_wlan_register_pm_ops(struct device *dev, + const struct dev_pm_ops *pm_ops); +void wcnss_wlan_unregister_pm_ops(struct device *dev, + const struct dev_pm_ops *pm_ops); +void wcnss_register_thermal_mitigation(struct device *dev, + void (*tm_notify)(struct device *dev, int)); +void wcnss_unregister_thermal_mitigation( + void (*tm_notify)(struct device *dev, int)); +struct platform_device *wcnss_get_platform_device(void); +struct wcnss_wlan_config *wcnss_get_wlan_config(void); +void wcnss_set_iris_xo_mode(int iris_xo_mode_set); +int wcnss_wlan_power(struct device *dev, + struct wcnss_wlan_config *cfg, + enum wcnss_opcode opcode, + int *iris_xo_mode_set); +int wcnss_req_power_on_lock(char *driver_name); +int wcnss_free_power_on_lock(char *driver_name); +unsigned int wcnss_get_serial_number(void); +int wcnss_get_wlan_mac_address(char mac_addr[WLAN_MAC_ADDR_SIZE]); +void wcnss_allow_suspend(void); +void wcnss_prevent_suspend(void); +int wcnss_hardware_type(void); +void *wcnss_prealloc_get(size_t size); +int wcnss_prealloc_put(void *ptr); +void wcnss_reset_fiq(bool clk_chk_en); +void wcnss_suspend_notify(void); +void wcnss_resume_notify(void); +void wcnss_riva_log_debug_regs(void); +void wcnss_pronto_log_debug_regs(void); +int wcnss_is_hw_pronto_ver3(void); +int wcnss_device_ready(void); +bool wcnss_cbc_complete(void); +int wcnss_device_is_shutdown(void); +void wcnss_riva_dump_pmic_regs(void); +int wcnss_xo_auto_detect_enabled(void); +u32 wcnss_get_wlan_rx_buff_count(void); +int wcnss_wlan_iris_xo_mode(void); +int wcnss_wlan_dual_band_disabled(void); +void wcnss_flush_work(struct work_struct *work); +void wcnss_flush_delayed_work(struct delayed_work *dwork); +void wcnss_init_work(struct work_struct *work , void *callbackptr); +void wcnss_init_delayed_work(struct delayed_work *dwork , void *callbackptr); +int wcnss_get_iris_name(char *iris_version); +void wcnss_dump_stack(struct task_struct *task); +void wcnss_snoc_vote(bool clk_chk_en); +int wcnss_parse_voltage_regulator(struct wcnss_wlan_config *wlan_config, + struct device *dev); + +#ifdef CONFIG_WCNSS_REGISTER_DUMP_ON_BITE +void wcnss_log_debug_regs_on_bite(void); +#else +static inline void wcnss_log_debug_regs_on_bite(void) +{ +} +#endif +int wcnss_set_wlan_unsafe_channel( + u16 *unsafe_ch_list, u16 ch_count); +int wcnss_get_wlan_unsafe_channel( + u16 *unsafe_ch_list, u16 buffer_size, + u16 *ch_count); +#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev) +#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data)) +/* WLAN driver uses these names */ +#define req_riva_power_on_lock(name) wcnss_req_power_on_lock(name) +#define free_riva_power_on_lock(name) wcnss_free_power_on_lock(name) + +#endif /* _WCNSS_WLAN_H_ */ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index f63ce973b27b..58f3d8ed5727 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -443,6 +443,7 @@ extern int schedule_on_each_cpu(work_func_t func); int execute_in_process_context(work_func_t fn, struct execute_work *); extern bool flush_work(struct work_struct *work); +extern bool cancel_work(struct work_struct *work); extern bool cancel_work_sync(struct work_struct *work); extern bool flush_delayed_work(struct delayed_work *dwork); @@ -621,4 +622,10 @@ static inline int workqueue_sysfs_register(struct workqueue_struct *wq) { return 0; } #endif /* CONFIG_SYSFS */ +#ifdef CONFIG_WQ_WATCHDOG +void wq_watchdog_touch(int cpu); +#else /* CONFIG_WQ_WATCHDOG */ +static inline void wq_watchdog_touch(int cpu) { } +#endif /* CONFIG_WQ_WATCHDOG */ + #endif diff --git a/include/linux/writeback.h b/include/linux/writeback.h index d0b5ca5d4e08..6c1cbbedc79c 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -224,6 +224,7 @@ static inline void inode_attach_wb(struct inode *inode, struct page *page) static inline void inode_detach_wb(struct inode *inode) { if (inode->i_wb) { + WARN_ON_ONCE(!(inode->i_state & I_CLEAR)); wb_put(inode->i_wb); inode->i_wb = NULL; } diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h new file mode 100644 index 000000000000..9e1f42cb57e9 --- /dev/null +++ b/include/linux/xxhash.h @@ -0,0 +1,236 @@ +/* + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2016, Yann Collet. + * + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + * + * You can contact the author at: + * - xxHash homepage: http://cyan4973.github.io/xxHash/ + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ + +/* + * Notice extracted from xxHash homepage: + * + * xxHash is an extremely fast Hash algorithm, running at RAM speed limits. + * It also successfully passes all tests from the SMHasher suite. + * + * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 + * Duo @3GHz) + * + * Name Speed Q.Score Author + * xxHash 5.4 GB/s 10 + * CrapWow 3.2 GB/s 2 Andrew + * MumurHash 3a 2.7 GB/s 10 Austin Appleby + * SpookyHash 2.0 GB/s 10 Bob Jenkins + * SBox 1.4 GB/s 9 Bret Mulvey + * Lookup3 1.2 GB/s 9 Bob Jenkins + * SuperFastHash 1.2 GB/s 1 Paul Hsieh + * CityHash64 1.05 GB/s 10 Pike & Alakuijala + * FNV 0.55 GB/s 5 Fowler, Noll, Vo + * CRC32 0.43 GB/s 9 + * MD5-32 0.33 GB/s 10 Ronald L. Rivest + * SHA1-32 0.28 GB/s 10 + * + * Q.Score is a measure of quality of the hash function. + * It depends on successfully passing SMHasher test set. + * 10 is a perfect score. + * + * A 64-bits version, named xxh64 offers much better speed, + * but for 64-bits applications only. + * Name Speed on 64 bits Speed on 32 bits + * xxh64 13.8 GB/s 1.9 GB/s + * xxh32 6.8 GB/s 6.0 GB/s + */ + +#ifndef XXHASH_H +#define XXHASH_H + +#include <linux/types.h> + +/*-**************************** + * Simple Hash Functions + *****************************/ + +/** + * xxh32() - calculate the 32-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s + * + * Return: The 32-bit hash of the data. + */ +uint32_t xxh32(const void *input, size_t length, uint32_t seed); + +/** + * xxh64() - calculate the 64-bit hash of the input with a given seed. + * + * @input: The data to hash. + * @length: The length of the data to hash. + * @seed: The seed can be used to alter the result predictably. + * + * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems. + * + * Return: The 64-bit hash of the data. + */ +uint64_t xxh64(const void *input, size_t length, uint64_t seed); + +/*-**************************** + * Streaming Hash Functions + *****************************/ + +/* + * These definitions are only meant to allow allocation of XXH state + * statically, on stack, or in a struct for example. + * Do not use members directly. + */ + +/** + * struct xxh32_state - private xxh32 state, do not use members directly + */ +struct xxh32_state { + uint32_t total_len_32; + uint32_t large_len; + uint32_t v1; + uint32_t v2; + uint32_t v3; + uint32_t v4; + uint32_t mem32[4]; + uint32_t memsize; +}; + +/** + * struct xxh32_state - private xxh64 state, do not use members directly + */ +struct xxh64_state { + uint64_t total_len; + uint64_t v1; + uint64_t v2; + uint64_t v3; + uint64_t v4; + uint64_t mem64[4]; + uint32_t memsize; +}; + +/** + * xxh32_reset() - reset the xxh32 state to start a new hashing operation + * + * @state: The xxh32 state to reset. + * @seed: Initialize the hash state with this seed. + * + * Call this function on any xxh32_state to prepare for a new hashing operation. + */ +void xxh32_reset(struct xxh32_state *state, uint32_t seed); + +/** + * xxh32_update() - hash the data given and update the xxh32 state + * + * @state: The xxh32 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh32_reset() call xxh32_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +int xxh32_update(struct xxh32_state *state, const void *input, size_t length); + +/** + * xxh32_digest() - produce the current xxh32 hash + * + * @state: Produce the current xxh32 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh32_digest(), and + * generate new hashes later on, by calling xxh32_digest() again. + * + * Return: The xxh32 hash stored in the state. + */ +uint32_t xxh32_digest(const struct xxh32_state *state); + +/** + * xxh64_reset() - reset the xxh64 state to start a new hashing operation + * + * @state: The xxh64 state to reset. + * @seed: Initialize the hash state with this seed. + */ +void xxh64_reset(struct xxh64_state *state, uint64_t seed); + +/** + * xxh64_update() - hash the data given and update the xxh64 state + * @state: The xxh64 state to update. + * @input: The data to hash. + * @length: The length of the data to hash. + * + * After calling xxh64_reset() call xxh64_update() as many times as necessary. + * + * Return: Zero on success, otherwise an error code. + */ +int xxh64_update(struct xxh64_state *state, const void *input, size_t length); + +/** + * xxh64_digest() - produce the current xxh64 hash + * + * @state: Produce the current xxh64 hash of this state. + * + * A hash value can be produced at any time. It is still possible to continue + * inserting input into the hash state after a call to xxh64_digest(), and + * generate new hashes later on, by calling xxh64_digest() again. + * + * Return: The xxh64 hash stored in the state. + */ +uint64_t xxh64_digest(const struct xxh64_state *state); + +/*-************************** + * Utils + ***************************/ + +/** + * xxh32_copy_state() - copy the source state into the destination state + * + * @src: The source xxh32 state. + * @dst: The destination xxh32 state. + */ +void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src); + +/** + * xxh64_copy_state() - copy the source state into the destination state + * + * @src: The source xxh64 state. + * @dst: The destination xxh64 state. + */ +void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src); + +#endif /* XXHASH_H */ diff --git a/include/linux/zcache.h b/include/linux/zcache.h new file mode 100644 index 000000000000..2db7e4bbb662 --- /dev/null +++ b/include/linux/zcache.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 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 _LINUX_ZCACHE_H +#define _LINUX_ZCACHE_H + +#ifdef CONFIG_ZCACHE +extern u64 zcache_pages(void); +#else +u64 zcache_pages(void) { return 0; } +#endif + +#endif /* _LINUX_ZCACHE_H */ diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h index 34eb16098a33..2219cce81ca4 100644 --- a/include/linux/zsmalloc.h +++ b/include/linux/zsmalloc.h @@ -41,12 +41,14 @@ struct zs_pool_stats { struct zs_pool; -struct zs_pool *zs_create_pool(const char *name, gfp_t flags); +struct zs_pool *zs_create_pool(const char *name); void zs_destroy_pool(struct zs_pool *pool); -unsigned long zs_malloc(struct zs_pool *pool, size_t size); +unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t flags); void zs_free(struct zs_pool *pool, unsigned long obj); +size_t zs_huge_class_size(struct zs_pool *pool); + void *zs_map_object(struct zs_pool *pool, unsigned long handle, enum zs_mapmode mm); void zs_unmap_object(struct zs_pool *pool, unsigned long handle); diff --git a/include/linux/zstd.h b/include/linux/zstd.h new file mode 100644 index 000000000000..249575e2485f --- /dev/null +++ b/include/linux/zstd.h @@ -0,0 +1,1157 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of https://github.com/facebook/zstd. + * An additional grant of patent rights can be found in the PATENTS file in the + * same directory. + * + * 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. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +#ifndef ZSTD_H +#define ZSTD_H + +/* ====== Dependency ======*/ +#include <linux/types.h> /* size_t */ + + +/*-***************************************************************************** + * Introduction + * + * zstd, short for Zstandard, is a fast lossless compression algorithm, + * targeting real-time compression scenarios at zlib-level and better + * compression ratios. The zstd compression library provides in-memory + * compression and decompression functions. The library supports compression + * levels from 1 up to ZSTD_maxCLevel() which is 22. Levels >= 20, labeled + * ultra, should be used with caution, as they require more memory. + * Compression can be done in: + * - a single step, reusing a context (described as Explicit memory management) + * - unbounded multiple steps (described as Streaming compression) + * The compression ratio achievable on small data can be highly improved using + * compression with a dictionary in: + * - a single step (described as Simple dictionary API) + * - a single step, reusing a dictionary (described as Fast dictionary API) + ******************************************************************************/ + +/*====== Helper functions ======*/ + +/** + * enum ZSTD_ErrorCode - zstd error codes + * + * Functions that return size_t can be checked for errors using ZSTD_isError() + * and the ZSTD_ErrorCode can be extracted using ZSTD_getErrorCode(). + */ +typedef enum { + ZSTD_error_no_error, + ZSTD_error_GENERIC, + ZSTD_error_prefix_unknown, + ZSTD_error_version_unsupported, + ZSTD_error_parameter_unknown, + ZSTD_error_frameParameter_unsupported, + ZSTD_error_frameParameter_unsupportedBy32bits, + ZSTD_error_frameParameter_windowTooLarge, + ZSTD_error_compressionParameter_unsupported, + ZSTD_error_init_missing, + ZSTD_error_memory_allocation, + ZSTD_error_stage_wrong, + ZSTD_error_dstSize_tooSmall, + ZSTD_error_srcSize_wrong, + ZSTD_error_corruption_detected, + ZSTD_error_checksum_wrong, + ZSTD_error_tableLog_tooLarge, + ZSTD_error_maxSymbolValue_tooLarge, + ZSTD_error_maxSymbolValue_tooSmall, + ZSTD_error_dictionary_corrupted, + ZSTD_error_dictionary_wrong, + ZSTD_error_dictionaryCreation_failed, + ZSTD_error_maxCode +} ZSTD_ErrorCode; + +/** + * ZSTD_maxCLevel() - maximum compression level available + * + * Return: Maximum compression level available. + */ +int ZSTD_maxCLevel(void); +/** + * ZSTD_compressBound() - maximum compressed size in worst case scenario + * @srcSize: The size of the data to compress. + * + * Return: The maximum compressed size in the worst case scenario. + */ +size_t ZSTD_compressBound(size_t srcSize); +/** + * ZSTD_isError() - tells if a size_t function result is an error code + * @code: The function result to check for error. + * + * Return: Non-zero iff the code is an error. + */ +static __attribute__((unused)) unsigned int ZSTD_isError(size_t code) +{ + return code > (size_t)-ZSTD_error_maxCode; +} +/** + * ZSTD_getErrorCode() - translates an error function result to a ZSTD_ErrorCode + * @functionResult: The result of a function for which ZSTD_isError() is true. + * + * Return: The ZSTD_ErrorCode corresponding to the functionResult or 0 + * if the functionResult isn't an error. + */ +static __attribute__((unused)) ZSTD_ErrorCode ZSTD_getErrorCode( + size_t functionResult) +{ + if (!ZSTD_isError(functionResult)) + return (ZSTD_ErrorCode)0; + return (ZSTD_ErrorCode)(0 - functionResult); +} + +/** + * enum ZSTD_strategy - zstd compression search strategy + * + * From faster to stronger. + */ +typedef enum { + ZSTD_fast, + ZSTD_dfast, + ZSTD_greedy, + ZSTD_lazy, + ZSTD_lazy2, + ZSTD_btlazy2, + ZSTD_btopt, + ZSTD_btopt2 +} ZSTD_strategy; + +/** + * struct ZSTD_compressionParameters - zstd compression parameters + * @windowLog: Log of the largest match distance. Larger means more + * compression, and more memory needed during decompression. + * @chainLog: Fully searched segment. Larger means more compression, slower, + * and more memory (useless for fast). + * @hashLog: Dispatch table. Larger means more compression, + * slower, and more memory. + * @searchLog: Number of searches. Larger means more compression and slower. + * @searchLength: Match length searched. Larger means faster decompression, + * sometimes less compression. + * @targetLength: Acceptable match size for optimal parser (only). Larger means + * more compression, and slower. + * @strategy: The zstd compression strategy. + */ +typedef struct { + unsigned int windowLog; + unsigned int chainLog; + unsigned int hashLog; + unsigned int searchLog; + unsigned int searchLength; + unsigned int targetLength; + ZSTD_strategy strategy; +} ZSTD_compressionParameters; + +/** + * struct ZSTD_frameParameters - zstd frame parameters + * @contentSizeFlag: Controls whether content size will be present in the frame + * header (when known). + * @checksumFlag: Controls whether a 32-bit checksum is generated at the end + * of the frame for error detection. + * @noDictIDFlag: Controls whether dictID will be saved into the frame header + * when using dictionary compression. + * + * The default value is all fields set to 0. + */ +typedef struct { + unsigned int contentSizeFlag; + unsigned int checksumFlag; + unsigned int noDictIDFlag; +} ZSTD_frameParameters; + +/** + * struct ZSTD_parameters - zstd parameters + * @cParams: The compression parameters. + * @fParams: The frame parameters. + */ +typedef struct { + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; +} ZSTD_parameters; + +/** + * ZSTD_getCParams() - returns ZSTD_compressionParameters for selected level + * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel(). + * @estimatedSrcSize: The estimated source size to compress or 0 if unknown. + * @dictSize: The dictionary size or 0 if a dictionary isn't being used. + * + * Return: The selected ZSTD_compressionParameters. + */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, + unsigned long long estimatedSrcSize, size_t dictSize); + +/** + * ZSTD_getParams() - returns ZSTD_parameters for selected level + * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel(). + * @estimatedSrcSize: The estimated source size to compress or 0 if unknown. + * @dictSize: The dictionary size or 0 if a dictionary isn't being used. + * + * The same as ZSTD_getCParams() except also selects the default frame + * parameters (all zero). + * + * Return: The selected ZSTD_parameters. + */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, + unsigned long long estimatedSrcSize, size_t dictSize); + +/*-************************************* + * Explicit memory management + **************************************/ + +/** + * ZSTD_CCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_CCtx + * @cParams: The compression parameters to be used for compression. + * + * If multiple compression parameters might be used, the caller must call + * ZSTD_CCtxWorkspaceBound() for each set of parameters and use the maximum + * size. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCCtx(). + */ +size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CCtx - the zstd compression context + * + * When compressing many times it is recommended to allocate a context just once + * and reuse it for each successive compression operation. + */ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; +/** + * ZSTD_initCCtx() - initialize a zstd compression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Use ZSTD_CCtxWorkspaceBound() to + * determine how large the workspace must be. + * + * Return: A compression context emplaced into workspace. + */ +ZSTD_CCtx *ZSTD_initCCtx(void *workspace, size_t workspaceSize); + +/** + * ZSTD_compressCCtx() - compress src into dst + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(params.cParams). + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compressCCtx(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, ZSTD_parameters params); + +/** + * ZSTD_DCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_DCtx + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDCtx(). + */ +size_t ZSTD_DCtxWorkspaceBound(void); + +/** + * struct ZSTD_DCtx - the zstd decompression context + * + * When decompressing many times it is recommended to allocate a context just + * once and reuse it for each successive decompression operation. + */ +typedef struct ZSTD_DCtx_s ZSTD_DCtx; +/** + * ZSTD_initDCtx() - initialize a zstd decompression context + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Use ZSTD_DCtxWorkspaceBound() to + * determine how large the workspace must be. + * + * Return: A decompression context emplaced into workspace. + */ +ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize); + +/** + * ZSTD_decompressDCtx() - decompress zstd compressed src into dst + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompressDCtx(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); + +/*-************************ + * Simple dictionary API + **************************/ + +/** + * ZSTD_compress_usingDict() - compress src into dst using a dictionary + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(params.cParams). + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @dict: The dictionary to use for compression. + * @dictSize: The size of the dictionary. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Compression using a predefined dictionary. The same dictionary must be used + * during decompression. + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compress_usingDict(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const void *dict, size_t dictSize, + ZSTD_parameters params); + +/** + * ZSTD_decompress_usingDict() - decompress src into dst using a dictionary + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * @dict: The dictionary to use for decompression. The same dictionary + * must've been used to compress the data. + * @dictSize: The size of the dictionary. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompress_usingDict(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const void *dict, size_t dictSize); + +/*-************************** + * Fast dictionary API + ***************************/ + +/** + * ZSTD_CDictWorkspaceBound() - memory needed to initialize a ZSTD_CDict + * @cParams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCDict(). + */ +size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CDict - a digested dictionary to be used for compression + */ +typedef struct ZSTD_CDict_s ZSTD_CDict; + +/** + * ZSTD_initCDict() - initialize a digested dictionary for compression + * @dictBuffer: The dictionary to digest. The buffer is referenced by the + * ZSTD_CDict so it must outlive the returned ZSTD_CDict. + * @dictSize: The size of the dictionary. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * @workspace: The workspace. It must outlive the returned ZSTD_CDict. + * @workspaceSize: The workspace size. Must be at least + * ZSTD_CDictWorkspaceBound(params.cParams). + * + * When compressing multiple messages / blocks with the same dictionary it is + * recommended to load it just once. The ZSTD_CDict merely references the + * dictBuffer, so it must outlive the returned ZSTD_CDict. + * + * Return: The digested dictionary emplaced into workspace. + */ +ZSTD_CDict *ZSTD_initCDict(const void *dictBuffer, size_t dictSize, + ZSTD_parameters params, void *workspace, size_t workspaceSize); + +/** + * ZSTD_compress_usingCDict() - compress src into dst using a ZSTD_CDict + * @ctx: The context. Must have been initialized with a workspace at + * least as large as ZSTD_CCtxWorkspaceBound(cParams) where + * cParams are the compression parameters used to initialize the + * cdict. + * @dst: The buffer to compress src into. + * @dstCapacity: The size of the destination buffer. May be any size, but + * ZSTD_compressBound(srcSize) is guaranteed to be large enough. + * @src: The data to compress. + * @srcSize: The size of the data to compress. + * @cdict: The digested dictionary to use for compression. + * @params: The parameters to use for compression. See ZSTD_getParams(). + * + * Compression using a digested dictionary. The same dictionary must be used + * during decompression. + * + * Return: The compressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize, const ZSTD_CDict *cdict); + + +/** + * ZSTD_DDictWorkspaceBound() - memory needed to initialize a ZSTD_DDict + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDDict(). + */ +size_t ZSTD_DDictWorkspaceBound(void); + +/** + * struct ZSTD_DDict - a digested dictionary to be used for decompression + */ +typedef struct ZSTD_DDict_s ZSTD_DDict; + +/** + * ZSTD_initDDict() - initialize a digested dictionary for decompression + * @dictBuffer: The dictionary to digest. The buffer is referenced by the + * ZSTD_DDict so it must outlive the returned ZSTD_DDict. + * @dictSize: The size of the dictionary. + * @workspace: The workspace. It must outlive the returned ZSTD_DDict. + * @workspaceSize: The workspace size. Must be at least + * ZSTD_DDictWorkspaceBound(). + * + * When decompressing multiple messages / blocks with the same dictionary it is + * recommended to load it just once. The ZSTD_DDict merely references the + * dictBuffer, so it must outlive the returned ZSTD_DDict. + * + * Return: The digested dictionary emplaced into workspace. + */ +ZSTD_DDict *ZSTD_initDDict(const void *dictBuffer, size_t dictSize, + void *workspace, size_t workspaceSize); + +/** + * ZSTD_decompress_usingDDict() - decompress src into dst using a ZSTD_DDict + * @ctx: The decompression context. + * @dst: The buffer to decompress src into. + * @dstCapacity: The size of the destination buffer. Must be at least as large + * as the decompressed size. If the caller cannot upper bound the + * decompressed size, then it's better to use the streaming API. + * @src: The zstd compressed data to decompress. Multiple concatenated + * frames and skippable frames are allowed. + * @srcSize: The exact size of the data to decompress. + * @ddict: The digested dictionary to use for decompression. The same + * dictionary must've been used to compress the data. + * + * Return: The decompressed size or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, + size_t dstCapacity, const void *src, size_t srcSize, + const ZSTD_DDict *ddict); + + +/*-************************** + * Streaming + ***************************/ + +/** + * struct ZSTD_inBuffer - input buffer for streaming + * @src: Start of the input buffer. + * @size: Size of the input buffer. + * @pos: Position where reading stopped. Will be updated. + * Necessarily 0 <= pos <= size. + */ +typedef struct ZSTD_inBuffer_s { + const void *src; + size_t size; + size_t pos; +} ZSTD_inBuffer; + +/** + * struct ZSTD_outBuffer - output buffer for streaming + * @dst: Start of the output buffer. + * @size: Size of the output buffer. + * @pos: Position where writing stopped. Will be updated. + * Necessarily 0 <= pos <= size. + */ +typedef struct ZSTD_outBuffer_s { + void *dst; + size_t size; + size_t pos; +} ZSTD_outBuffer; + + + +/*-***************************************************************************** + * Streaming compression - HowTo + * + * A ZSTD_CStream object is required to track streaming operation. + * Use ZSTD_initCStream() to initialize a ZSTD_CStream object. + * ZSTD_CStream objects can be reused multiple times on consecutive compression + * operations. It is recommended to re-use ZSTD_CStream in situations where many + * streaming operations will be achieved consecutively. Use one separate + * ZSTD_CStream per thread for parallel execution. + * + * Use ZSTD_compressStream() repetitively to consume input stream. + * The function will automatically update both `pos` fields. + * Note that it may not consume the entire input, in which case `pos < size`, + * and it's up to the caller to present again remaining data. + * It returns a hint for the preferred number of bytes to use as an input for + * the next function call. + * + * At any moment, it's possible to flush whatever data remains within internal + * buffer, using ZSTD_flushStream(). `output->pos` will be updated. There might + * still be some content left within the internal buffer if `output->size` is + * too small. It returns the number of bytes left in the internal buffer and + * must be called until it returns 0. + * + * ZSTD_endStream() instructs to finish a frame. It will perform a flush and + * write frame epilogue. The epilogue is required for decoders to consider a + * frame completed. Similar to ZSTD_flushStream(), it may not be able to flush + * the full content if `output->size` is too small. In which case, call again + * ZSTD_endStream() to complete the flush. It returns the number of bytes left + * in the internal buffer and must be called until it returns 0. + ******************************************************************************/ + +/** + * ZSTD_CStreamWorkspaceBound() - memory needed to initialize a ZSTD_CStream + * @cParams: The compression parameters to be used for compression. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initCStream() and ZSTD_initCStream_usingCDict(). + */ +size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams); + +/** + * struct ZSTD_CStream - the zstd streaming compression context + */ +typedef struct ZSTD_CStream_s ZSTD_CStream; + +/*===== ZSTD_CStream management functions =====*/ +/** + * ZSTD_initCStream() - initialize a zstd streaming compression context + * @params: The zstd compression parameters. + * @pledgedSrcSize: If params.fParams.contentSizeFlag == 1 then the caller must + * pass the source size (zero means empty source). Otherwise, + * the caller may optionally pass the source size, or zero if + * unknown. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_CStreamWorkspaceBound(params.cParams) to determine + * how large the workspace must be. + * + * Return: The zstd streaming compression context. + */ +ZSTD_CStream *ZSTD_initCStream(ZSTD_parameters params, + unsigned long long pledgedSrcSize, void *workspace, + size_t workspaceSize); + +/** + * ZSTD_initCStream_usingCDict() - initialize a streaming compression context + * @cdict: The digested dictionary to use for compression. + * @pledgedSrcSize: Optionally the source size, or zero if unknown. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. Call ZSTD_CStreamWorkspaceBound() + * with the cParams used to initialize the cdict to determine + * how large the workspace must be. + * + * Return: The zstd streaming compression context. + */ +ZSTD_CStream *ZSTD_initCStream_usingCDict(const ZSTD_CDict *cdict, + unsigned long long pledgedSrcSize, void *workspace, + size_t workspaceSize); + +/*===== Streaming compression functions =====*/ +/** + * ZSTD_resetCStream() - reset the context using parameters from creation + * @zcs: The zstd streaming compression context to reset. + * @pledgedSrcSize: Optionally the source size, or zero if unknown. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. If `pledgedSrcSize` is non-zero the frame + * content size is always written into the frame header. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize); +/** + * ZSTD_compressStream() - streaming compress some of input into output + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * @input: Source buffer. `input->pos` is updated to indicate how much data was + * read. Note that it may not consume the entire input, in which case + * `input->pos < input->size`, and it's up to the caller to present + * remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * + * Return: A hint for the number of bytes to use as the input for the next + * function call or an error, which can be checked using + * ZSTD_isError(). + */ +size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, + ZSTD_inBuffer *input); +/** + * ZSTD_flushStream() - flush internal buffers into output + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * ZSTD_flushStream() must be called until it returns 0, meaning all the data + * has been flushed. Since ZSTD_flushStream() causes a block to be ended, + * calling it too often will degrade the compression ratio. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output); +/** + * ZSTD_endStream() - flush internal buffers into output and end the frame + * @zcs: The zstd streaming compression context. + * @output: Destination buffer. `output->pos` is updated to indicate how much + * compressed data was written. + * + * ZSTD_endStream() must be called until it returns 0, meaning all the data has + * been flushed and the frame epilogue has been written. + * + * Return: The number of bytes still present within internal buffers or an + * error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output); + +/** + * ZSTD_CStreamInSize() - recommended size for the input buffer + * + * Return: The recommended size for the input buffer. + */ +size_t ZSTD_CStreamInSize(void); +/** + * ZSTD_CStreamOutSize() - recommended size for the output buffer + * + * When the output buffer is at least this large, it is guaranteed to be large + * enough to flush at least one complete compressed block. + * + * Return: The recommended size for the output buffer. + */ +size_t ZSTD_CStreamOutSize(void); + + + +/*-***************************************************************************** + * Streaming decompression - HowTo + * + * A ZSTD_DStream object is required to track streaming operations. + * Use ZSTD_initDStream() to initialize a ZSTD_DStream object. + * ZSTD_DStream objects can be re-used multiple times. + * + * Use ZSTD_decompressStream() repetitively to consume your input. + * The function will update both `pos` fields. + * If `input->pos < input->size`, some input has not been consumed. + * It's up to the caller to present again remaining data. + * If `output->pos < output->size`, decoder has flushed everything it could. + * Returns 0 iff a frame is completely decoded and fully flushed. + * Otherwise it returns a suggested next input size that will never load more + * than the current frame. + ******************************************************************************/ + +/** + * ZSTD_DStreamWorkspaceBound() - memory needed to initialize a ZSTD_DStream + * @maxWindowSize: The maximum window size allowed for compressed frames. + * + * Return: A lower bound on the size of the workspace that is passed to + * ZSTD_initDStream() and ZSTD_initDStream_usingDDict(). + */ +size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize); + +/** + * struct ZSTD_DStream - the zstd streaming decompression context + */ +typedef struct ZSTD_DStream_s ZSTD_DStream; +/*===== ZSTD_DStream management functions =====*/ +/** + * ZSTD_initDStream() - initialize a zstd streaming decompression context + * @maxWindowSize: The maximum window size allowed for compressed frames. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine + * how large the workspace must be. + * + * Return: The zstd streaming decompression context. + */ +ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, + size_t workspaceSize); +/** + * ZSTD_initDStream_usingDDict() - initialize streaming decompression context + * @maxWindowSize: The maximum window size allowed for compressed frames. + * @ddict: The digested dictionary to use for decompression. + * @workspace: The workspace to emplace the context into. It must outlive + * the returned context. + * @workspaceSize: The size of workspace. + * Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine + * how large the workspace must be. + * + * Return: The zstd streaming decompression context. + */ +ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize, + const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize); + +/*===== Streaming decompression functions =====*/ +/** + * ZSTD_resetDStream() - reset the context using parameters from creation + * @zds: The zstd streaming decompression context to reset. + * + * Resets the context using the parameters from creation. Skips dictionary + * loading, since it can be reused. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_resetDStream(ZSTD_DStream *zds); +/** + * ZSTD_decompressStream() - streaming decompress some of input into output + * @zds: The zstd streaming decompression context. + * @output: Destination buffer. `output.pos` is updated to indicate how much + * decompressed data was written. + * @input: Source buffer. `input.pos` is updated to indicate how much data was + * read. Note that it may not consume the entire input, in which case + * `input.pos < input.size`, and it's up to the caller to present + * remaining data again. + * + * The `input` and `output` buffers may be any size. Guaranteed to make some + * forward progress if `input` and `output` are not empty. + * ZSTD_decompressStream() will not consume the last byte of the frame until + * the entire frame is flushed. + * + * Return: Returns 0 iff a frame is completely decoded and fully flushed. + * Otherwise returns a hint for the number of bytes to use as the input + * for the next function call or an error, which can be checked using + * ZSTD_isError(). The size hint will never load more than the frame. + */ +size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, + ZSTD_inBuffer *input); + +/** + * ZSTD_DStreamInSize() - recommended size for the input buffer + * + * Return: The recommended size for the input buffer. + */ +size_t ZSTD_DStreamInSize(void); +/** + * ZSTD_DStreamOutSize() - recommended size for the output buffer + * + * When the output buffer is at least this large, it is guaranteed to be large + * enough to flush at least one complete decompressed block. + * + * Return: The recommended size for the output buffer. + */ +size_t ZSTD_DStreamOutSize(void); + + +/* --- Constants ---*/ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */ +#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U + +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) + +#define ZSTD_WINDOWLOG_MAX_32 27 +#define ZSTD_WINDOWLOG_MAX_64 27 +#define ZSTD_WINDOWLOG_MAX \ + ((unsigned int)(sizeof(size_t) == 4 \ + ? ZSTD_WINDOWLOG_MAX_32 \ + : ZSTD_WINDOWLOG_MAX_64)) +#define ZSTD_WINDOWLOG_MIN 10 +#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX +#define ZSTD_HASHLOG_MIN 6 +#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1) +#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN +#define ZSTD_HASHLOG3_MAX 17 +#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1) +#define ZSTD_SEARCHLOG_MIN 1 +/* only for ZSTD_fast, other strategies are limited to 6 */ +#define ZSTD_SEARCHLENGTH_MAX 7 +/* only for ZSTD_btopt, other strategies are limited to 4 */ +#define ZSTD_SEARCHLENGTH_MIN 3 +#define ZSTD_TARGETLENGTH_MIN 4 +#define ZSTD_TARGETLENGTH_MAX 999 + +/* for static allocation */ +#define ZSTD_FRAMEHEADERSIZE_MAX 18 +#define ZSTD_FRAMEHEADERSIZE_MIN 6 +static const size_t ZSTD_frameHeaderSize_prefix = 5; +static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN; +static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX; +/* magic number + skippable frame length */ +static const size_t ZSTD_skippableHeaderSize = 8; + + +/*-************************************* + * Compressed size functions + **************************************/ + +/** + * ZSTD_findFrameCompressedSize() - returns the size of a compressed frame + * @src: Source buffer. It should point to the start of a zstd encoded frame + * or a skippable frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * size of the frame. + * + * Return: The compressed size of the frame pointed to by `src` or an error, + * which can be check with ZSTD_isError(). + * Suitable to pass to ZSTD_decompress() or similar functions. + */ +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize); + +/*-************************************* + * Decompressed size functions + **************************************/ +/** + * ZSTD_getFrameContentSize() - returns the content size in a zstd frame header + * @src: It should point to the start of a zstd encoded frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * frame header. `ZSTD_frameHeaderSize_max` is always large enough. + * + * Return: The frame content size stored in the frame header if known. + * `ZSTD_CONTENTSIZE_UNKNOWN` if the content size isn't stored in the + * frame header. `ZSTD_CONTENTSIZE_ERROR` on invalid input. + */ +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/** + * ZSTD_findDecompressedSize() - returns decompressed size of a series of frames + * @src: It should point to the start of a series of zstd encoded and/or + * skippable frames. + * @srcSize: The exact size of the series of frames. + * + * If any zstd encoded frame in the series doesn't have the frame content size + * set, `ZSTD_CONTENTSIZE_UNKNOWN` is returned. But frame content size is always + * set when using ZSTD_compress(). The decompressed size can be very large. + * If the source is untrusted, the decompressed size could be wrong or + * intentionally modified. Always ensure the result fits within the + * application's authorized limits. ZSTD_findDecompressedSize() handles multiple + * frames, and so it must traverse the input to read each frame header. This is + * efficient as most of the data is skipped, however it does mean that all frame + * data must be present and valid. + * + * Return: Decompressed size of all the data contained in the frames if known. + * `ZSTD_CONTENTSIZE_UNKNOWN` if the decompressed size is unknown. + * `ZSTD_CONTENTSIZE_ERROR` if an error occurred. + */ +unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize); + +/*-************************************* + * Advanced compression functions + **************************************/ +/** + * ZSTD_checkCParams() - ensure parameter values remain within authorized range + * @cParams: The zstd compression parameters. + * + * Return: Zero or an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams); + +/** + * ZSTD_adjustCParams() - optimize parameters for a given srcSize and dictSize + * @srcSize: Optionally the estimated source size, or zero if unknown. + * @dictSize: Optionally the estimated dictionary size, or zero if unknown. + * + * Return: The optimized parameters. + */ +ZSTD_compressionParameters ZSTD_adjustCParams( + ZSTD_compressionParameters cParams, unsigned long long srcSize, + size_t dictSize); + +/*--- Advanced decompression functions ---*/ + +/** + * ZSTD_isFrame() - returns true iff the buffer starts with a valid frame + * @buffer: The source buffer to check. + * @size: The size of the source buffer, must be at least 4 bytes. + * + * Return: True iff the buffer starts with a zstd or skippable frame identifier. + */ +unsigned int ZSTD_isFrame(const void *buffer, size_t size); + +/** + * ZSTD_getDictID_fromDict() - returns the dictionary id stored in a dictionary + * @dict: The dictionary buffer. + * @dictSize: The size of the dictionary buffer. + * + * Return: The dictionary id stored within the dictionary or 0 if the + * dictionary is not a zstd dictionary. If it returns 0 the + * dictionary can still be loaded as a content-only dictionary. + */ +unsigned int ZSTD_getDictID_fromDict(const void *dict, size_t dictSize); + +/** + * ZSTD_getDictID_fromDDict() - returns the dictionary id stored in a ZSTD_DDict + * @ddict: The ddict to find the id of. + * + * Return: The dictionary id stored within `ddict` or 0 if the dictionary is not + * a zstd dictionary. If it returns 0 `ddict` will be loaded as a + * content-only dictionary. + */ +unsigned int ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict); + +/** + * ZSTD_getDictID_fromFrame() - returns the dictionary id stored in a zstd frame + * @src: Source buffer. It must be a zstd encoded frame. + * @srcSize: The size of the source buffer. It must be at least as large as the + * frame header. `ZSTD_frameHeaderSize_max` is always large enough. + * + * Return: The dictionary id required to decompress the frame stored within + * `src` or 0 if the dictionary id could not be decoded. It can return + * 0 if the frame does not require a dictionary, the dictionary id + * wasn't stored in the frame, `src` is not a zstd frame, or `srcSize` + * is too small. + */ +unsigned int ZSTD_getDictID_fromFrame(const void *src, size_t srcSize); + +/** + * struct ZSTD_frameParams - zstd frame parameters stored in the frame header + * @frameContentSize: The frame content size, or 0 if not present. + * @windowSize: The window size, or 0 if the frame is a skippable frame. + * @dictID: The dictionary id, or 0 if not present. + * @checksumFlag: Whether a checksum was used. + */ +typedef struct { + unsigned long long frameContentSize; + unsigned int windowSize; + unsigned int dictID; + unsigned int checksumFlag; +} ZSTD_frameParams; + +/** + * ZSTD_getFrameParams() - extracts parameters from a zstd or skippable frame + * @fparamsPtr: On success the frame parameters are written here. + * @src: The source buffer. It must point to a zstd or skippable frame. + * @srcSize: The size of the source buffer. `ZSTD_frameHeaderSize_max` is + * always large enough to succeed. + * + * Return: 0 on success. If more data is required it returns how many bytes + * must be provided to make forward progress. Otherwise it returns + * an error, which can be checked using ZSTD_isError(). + */ +size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src, + size_t srcSize); + +/*-***************************************************************************** + * Buffer-less and synchronous inner streaming functions + * + * This is an advanced API, giving full control over buffer management, for + * users which need direct control over memory. + * But it's also a complex one, with many restrictions (documented below). + * Prefer using normal streaming API for an easier experience + ******************************************************************************/ + +/*-***************************************************************************** + * Buffer-less streaming compression (synchronous mode) + * + * A ZSTD_CCtx object is required to track streaming operations. + * Use ZSTD_initCCtx() to initialize a context. + * ZSTD_CCtx object can be re-used multiple times within successive compression + * operations. + * + * Start by initializing a context. + * Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary + * compression, + * or ZSTD_compressBegin_advanced(), for finer parameter control. + * It's also possible to duplicate a reference context which has already been + * initialized, using ZSTD_copyCCtx() + * + * Then, consume your input using ZSTD_compressContinue(). + * There are some important considerations to keep in mind when using this + * advanced function : + * - ZSTD_compressContinue() has no internal buffer. It uses externally provided + * buffer only. + * - Interface is synchronous : input is consumed entirely and produce 1+ + * (or more) compressed blocks. + * - Caller must ensure there is enough space in `dst` to store compressed data + * under worst case scenario. Worst case evaluation is provided by + * ZSTD_compressBound(). + * ZSTD_compressContinue() doesn't guarantee recover after a failed + * compression. + * - ZSTD_compressContinue() presumes prior input ***is still accessible and + * unmodified*** (up to maximum distance size, see WindowLog). + * It remembers all previous contiguous blocks, plus one separated memory + * segment (which can itself consists of multiple contiguous blocks) + * - ZSTD_compressContinue() detects that prior input has been overwritten when + * `src` buffer overlaps. In which case, it will "discard" the relevant memory + * section from its history. + * + * Finish a frame with ZSTD_compressEnd(), which will write the last block(s) + * and optional checksum. It's possible to use srcSize==0, in which case, it + * will write a final empty block to end the frame. Without last block mark, + * frames will be considered unfinished (corrupted) by decoders. + * + * `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress some new + * frame. + ******************************************************************************/ + +/*===== Buffer-less streaming compression functions =====*/ +size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel); +size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict, + size_t dictSize, int compressionLevel); +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict, + size_t dictSize, ZSTD_parameters params, + unsigned long long pledgedSrcSize); +size_t ZSTD_copyCCtx(ZSTD_CCtx *cctx, const ZSTD_CCtx *preparedCCtx, + unsigned long long pledgedSrcSize); +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, + unsigned long long pledgedSrcSize); +size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); + + + +/*-***************************************************************************** + * Buffer-less streaming decompression (synchronous mode) + * + * A ZSTD_DCtx object is required to track streaming operations. + * Use ZSTD_initDCtx() to initialize a context. + * A ZSTD_DCtx object can be re-used multiple times. + * + * First typical operation is to retrieve frame parameters, using + * ZSTD_getFrameParams(). It fills a ZSTD_frameParams structure which provide + * important information to correctly decode the frame, such as the minimum + * rolling buffer size to allocate to decompress data (`windowSize`), and the + * dictionary ID used. + * Note: content size is optional, it may not be present. 0 means unknown. + * Note that these values could be wrong, either because of data malformation, + * or because an attacker is spoofing deliberate false information. As a + * consequence, check that values remain within valid application range, + * especially `windowSize`, before allocation. Each application can set its own + * limit, depending on local restrictions. For extended interoperability, it is + * recommended to support at least 8 MB. + * Frame parameters are extracted from the beginning of the compressed frame. + * Data fragment must be large enough to ensure successful decoding, typically + * `ZSTD_frameHeaderSize_max` bytes. + * Result: 0: successful decoding, the `ZSTD_frameParams` structure is filled. + * >0: `srcSize` is too small, provide at least this many bytes. + * errorCode, which can be tested using ZSTD_isError(). + * + * Start decompression, with ZSTD_decompressBegin() or + * ZSTD_decompressBegin_usingDict(). Alternatively, you can copy a prepared + * context, using ZSTD_copyDCtx(). + * + * Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() + * alternatively. + * ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' + * to ZSTD_decompressContinue(). + * ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will + * fail. + * + * The result of ZSTD_decompressContinue() is the number of bytes regenerated + * within 'dst' (necessarily <= dstCapacity). It can be zero, which is not an + * error; it just means ZSTD_decompressContinue() has decoded some metadata + * item. It can also be an error code, which can be tested with ZSTD_isError(). + * + * ZSTD_decompressContinue() needs previous data blocks during decompression, up + * to `windowSize`. They should preferably be located contiguously, prior to + * current block. Alternatively, a round buffer of sufficient size is also + * possible. Sufficient size is determined by frame parameters. + * ZSTD_decompressContinue() is very sensitive to contiguity, if 2 blocks don't + * follow each other, make sure that either the compressor breaks contiguity at + * the same place, or that previous contiguous segment is large enough to + * properly handle maximum back-reference. + * + * A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + * Context can then be reset to start a new decompression. + * + * Note: it's possible to know if next input to present is a header or a block, + * using ZSTD_nextInputType(). This information is not required to properly + * decode a frame. + * + * == Special case: skippable frames == + * + * Skippable frames allow integration of user-defined data into a flow of + * concatenated frames. Skippable frames will be ignored (skipped) by a + * decompressor. The format of skippable frames is as follows: + * a) Skippable frame ID - 4 Bytes, Little endian format, any value from + * 0x184D2A50 to 0x184D2A5F + * b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + * c) Frame Content - any content (User Data) of length equal to Frame Size + * For skippable frames ZSTD_decompressContinue() always returns 0. + * For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 + * what means that a frame is skippable. + * Note: If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might + * actually be a zstd encoded frame with no content. For purposes of + * decompression, it is valid in both cases to skip the frame using + * ZSTD_findFrameCompressedSize() to find its size in bytes. + * It also returns frame size as fparamsPtr->frameContentSize. + ******************************************************************************/ + +/*===== Buffer-less streaming decompression functions =====*/ +size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx); +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, + size_t dictSize); +void ZSTD_copyDCtx(ZSTD_DCtx *dctx, const ZSTD_DCtx *preparedDCtx); +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx); +size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +typedef enum { + ZSTDnit_frameHeader, + ZSTDnit_blockHeader, + ZSTDnit_block, + ZSTDnit_lastBlock, + ZSTDnit_checksum, + ZSTDnit_skippableFrame +} ZSTD_nextInputType_e; +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx); + +/*-***************************************************************************** + * Block functions + * + * Block functions produce and decode raw zstd blocks, without frame metadata. + * Frame metadata cost is typically ~18 bytes, which can be non-negligible for + * very small blocks (< 100 bytes). User will have to take in charge required + * information to regenerate data, such as compressed and content sizes. + * + * A few rules to respect: + * - Compressing and decompressing require a context structure + * + Use ZSTD_initCCtx() and ZSTD_initDCtx() + * - It is necessary to init context before starting + * + compression : ZSTD_compressBegin() + * + decompression : ZSTD_decompressBegin() + * + variants _usingDict() are also allowed + * + copyCCtx() and copyDCtx() work too + * - Block size is limited, it must be <= ZSTD_getBlockSizeMax() + * + If you need to compress more, cut data into multiple blocks + * + Consider using the regular ZSTD_compress() instead, as frame metadata + * costs become negligible when source size is large. + * - When a block is considered not compressible enough, ZSTD_compressBlock() + * result will be zero. In which case, nothing is produced into `dst`. + * + User must test for such outcome and deal directly with uncompressed data + * + ZSTD_decompressBlock() doesn't accept uncompressed data as input!!! + * + In case of multiple successive blocks, decoder must be informed of + * uncompressed block existence to follow proper history. Use + * ZSTD_insertBlock() in such a case. + ******************************************************************************/ + +/* Define for static allocation */ +#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) +/*===== Raw zstd block functions =====*/ +size_t ZSTD_getBlockSizeMax(ZSTD_CCtx *cctx); +size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, + const void *src, size_t srcSize); +size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, + size_t blockSize); + +#endif /* ZSTD_H */ |