2019-05-29 16:57:50 -07:00
/* SPDX-License-Identifier: GPL-2.0-only */
2012-07-12 19:02:29 +03:00
/*
* OMAP4 Bandgap temperature sensor driver
*
* Copyright ( C ) 2011 Texas Instruments Incorporated - http : //www.ti.com/
* Contact :
* Eduardo Valentin < eduardo . valentin @ ti . com >
*/
2013-03-19 10:54:21 -04:00
# ifndef __TI_BANDGAP_H
# define __TI_BANDGAP_H
2012-07-12 19:02:29 +03:00
2013-03-15 09:00:35 -04:00
# include <linux/spinlock.h>
2012-07-12 19:02:29 +03:00
# include <linux/types.h>
# include <linux/err.h>
/**
2013-03-15 08:59:52 -04:00
* DOC : bandgap driver data structure
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2013-03-19 10:54:23 -04:00
*
* + - - - - - - - - - - + - - - - - - - - - - - - - - - - +
* | struct temp_sensor_regval |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* * ( Array of )
* |
* |
2013-03-19 10:54:21 -04:00
* + - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - +
* | struct ti_bandgap | - - > | struct device * |
* + - - - - - - - - - - + - - - - - - - - + + - - - - - - - - - - - - - - - - - +
2013-03-15 08:59:52 -04:00
* |
* |
* V
2013-03-19 10:54:21 -04:00
* + - - - - - - - - - - - - - - - - - - - - - - - - +
* | struct ti_bandgap_data |
* + - - - - - - - - - - - - - - - - - - - - - - - - +
2013-03-15 08:59:52 -04:00
* |
* |
* * ( Array of )
* + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2013-03-19 10:54:21 -04:00
* | + - - - - - - - - - - + - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + |
* | | struct ti_temp_sensor | - - > | struct temp_sensor_data | |
* | + - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + - - - - - - - - - - - - + |
2013-03-15 08:59:52 -04:00
* | | |
2013-03-19 10:54:23 -04:00
* | + |
* | V |
* | + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + |
* | | struct temp_sensor_registers | |
* | + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |
2013-03-15 08:59:52 -04:00
* | |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
* Above is a simple diagram describing how the data structure below
2013-03-19 10:54:21 -04:00
* are organized . For each bandgap device there should be a ti_bandgap_data
2013-03-15 08:59:52 -04:00
* containing the device instance configuration , as well as , an array of
* sensors , representing every sensor instance present in this bandgap .
*/
/**
* struct temp_sensor_registers - descriptor to access registers and bitfields
* @ temp_sensor_ctrl : TEMP_SENSOR_CTRL register offset
* @ bgap_tempsoff_mask : mask to temp_sensor_ctrl . tempsoff
* @ bgap_soc_mask : mask to temp_sensor_ctrl . soc
* @ bgap_eocz_mask : mask to temp_sensor_ctrl . eocz
* @ bgap_dtemp_mask : mask to temp_sensor_ctrl . dtemp
* @ bgap_mask_ctrl : BANDGAP_MASK_CTRL register offset
* @ mask_hot_mask : mask to bandgap_mask_ctrl . mask_hot
* @ mask_cold_mask : mask to bandgap_mask_ctrl . mask_cold
2013-04-01 12:04:38 -04:00
* @ mask_counter_delay_mask : mask to bandgap_mask_ctrl . mask_counter_delay
2013-03-15 08:59:52 -04:00
* @ mask_freeze_mask : mask to bandgap_mask_ctrl . mask_free
* @ bgap_mode_ctrl : BANDGAP_MODE_CTRL register offset
* @ mode_ctrl_mask : mask to bandgap_mode_ctrl . mode_ctrl
* @ bgap_counter : BANDGAP_COUNTER register offset
* @ counter_mask : mask to bandgap_counter . counter
* @ bgap_threshold : BANDGAP_THRESHOLD register offset ( TALERT thresholds )
* @ threshold_thot_mask : mask to bandgap_threhold . thot
* @ threshold_tcold_mask : mask to bandgap_threhold . tcold
* @ tshut_threshold : TSHUT_THRESHOLD register offset ( TSHUT thresholds )
* @ tshut_hot_mask : mask to tshut_threhold . thot
* @ tshut_cold_mask : mask to tshut_threhold . thot
* @ bgap_status : BANDGAP_STATUS register offset
* @ status_hot_mask : mask to bandgap_status . hot
* @ status_cold_mask : mask to bandgap_status . cold
* @ ctrl_dtemp_1 : CTRL_DTEMP1 register offset
* @ ctrl_dtemp_2 : CTRL_DTEMP2 register offset
* @ bgap_efuse : BANDGAP_EFUSE register offset
*
* The register offsets and bitfields might change across
* OMAP and variants versions . Hence this struct serves as a
* descriptor map on how to access the registers and the bitfields .
*
* This descriptor contains registers of all versions of bandgap chips .
* Not all versions will use all registers , depending on the available
* features . Please read TRMs for descriptive explanation on each bitfield .
2012-07-12 19:02:29 +03:00
*/
struct temp_sensor_registers {
u32 temp_sensor_ctrl ;
u32 bgap_tempsoff_mask ;
u32 bgap_soc_mask ;
2018-05-02 15:20:35 +02:00
u32 bgap_eocz_mask ;
2012-07-12 19:02:29 +03:00
u32 bgap_dtemp_mask ;
u32 bgap_mask_ctrl ;
u32 mask_hot_mask ;
u32 mask_cold_mask ;
2013-04-01 12:04:38 -04:00
u32 mask_counter_delay_mask ;
2013-02-26 18:53:29 -04:00
u32 mask_freeze_mask ;
2012-07-12 19:02:29 +03:00
u32 bgap_mode_ctrl ;
u32 mode_ctrl_mask ;
u32 bgap_counter ;
u32 counter_mask ;
u32 bgap_threshold ;
u32 threshold_thot_mask ;
u32 threshold_tcold_mask ;
u32 tshut_threshold ;
u32 tshut_hot_mask ;
u32 tshut_cold_mask ;
u32 bgap_status ;
u32 status_hot_mask ;
u32 status_cold_mask ;
2018-05-02 15:20:35 +02:00
u32 ctrl_dtemp_1 ;
u32 ctrl_dtemp_2 ;
2012-07-12 19:02:29 +03:00
u32 bgap_efuse ;
} ;
/**
2013-03-15 08:59:52 -04:00
* struct temp_sensor_data - The thresholds and limits for temperature sensors .
* @ tshut_hot : temperature to trigger a thermal reset ( initial value )
* @ tshut_cold : temp to get the plat out of reset due to thermal ( init val )
* @ t_hot : temperature to trigger a thermal alert ( high initial value )
* @ t_cold : temperature to trigger a thermal alert ( low initial value )
* @ min_freq : sensor minimum clock rate
* @ max_freq : sensor maximum clock rate
*
* This data structure will hold the required thresholds and temperature limits
* for a specific temperature sensor , like shutdown temperature , alert
* temperature , clock / rate used , ADC conversion limits and update intervals
2012-07-12 19:02:29 +03:00
*/
struct temp_sensor_data {
u32 tshut_hot ;
u32 tshut_cold ;
u32 t_hot ;
u32 t_cold ;
u32 min_freq ;
u32 max_freq ;
} ;
2013-03-19 10:54:21 -04:00
struct ti_bandgap_data ;
2012-07-12 19:02:29 +03:00
2013-03-19 10:54:23 -04:00
/**
* struct temp_sensor_regval - temperature sensor register values and priv data
* @ bg_mode_ctrl : temp sensor control register value
* @ bg_ctrl : bandgap ctrl register value
* @ bg_counter : bandgap counter value
* @ bg_threshold : bandgap threshold register value
* @ tshut_threshold : bandgap tshut register value
* @ data : private data
*
* Data structure to save and restore bandgap register set context . Only
* required registers are shadowed , when needed .
*/
struct temp_sensor_regval {
u32 bg_mode_ctrl ;
u32 bg_ctrl ;
u32 bg_counter ;
u32 bg_threshold ;
u32 tshut_threshold ;
void * data ;
} ;
2012-07-12 19:02:29 +03:00
/**
2013-03-19 10:54:21 -04:00
* struct ti_bandgap - bandgap device structure
2013-03-15 08:59:52 -04:00
* @ dev : struct device pointer
* @ base : io memory base address
* @ conf : struct with bandgap configuration set ( # sensors , conv_table , etc )
2013-03-19 10:54:23 -04:00
* @ regval : temperature sensor register values
2012-07-12 19:02:29 +03:00
* @ fclock : pointer to functional clock of temperature sensor
2013-03-15 08:59:52 -04:00
* @ div_clk : pointer to divider clock of temperature sensor fclk
2013-03-19 10:54:25 -04:00
* @ lock : spinlock for ti_bandgap structure
2013-03-15 08:59:52 -04:00
* @ irq : MPU IRQ number for thermal alert
2012-07-12 19:02:29 +03:00
* @ tshut_gpio : GPIO where Tshut signal is routed
* @ clk_rate : Holds current clock rate
2013-03-15 08:59:52 -04:00
*
* The bandgap device structure representing the bandgap device instance .
* It holds most of the dynamic stuff . Configurations and sensor specific
* entries are inside the @ conf structure .
2012-07-12 19:02:29 +03:00
*/
2013-03-19 10:54:21 -04:00
struct ti_bandgap {
2012-07-12 19:02:29 +03:00
struct device * dev ;
void __iomem * base ;
2013-03-19 10:54:23 -04:00
const struct ti_bandgap_data * conf ;
struct temp_sensor_regval * regval ;
2012-07-12 19:02:29 +03:00
struct clk * fclock ;
struct clk * div_clk ;
2013-03-15 09:00:35 -04:00
spinlock_t lock ; /* shields this struct */
2012-07-12 19:02:29 +03:00
int irq ;
int tshut_gpio ;
u32 clk_rate ;
} ;
/**
2013-03-19 10:54:21 -04:00
* struct ti_temp_sensor - bandgap temperature sensor configuration data
2012-07-12 19:02:29 +03:00
* @ ts_data : pointer to struct with thresholds , limits of temperature sensor
* @ registers : pointer to the list of register offsets and bitfields
* @ domain : the name of the domain where the sensor is located
2013-03-15 08:59:52 -04:00
* @ slope_pcb : sensor gradient slope info for hotspot extrapolation equation
2012-07-12 19:02:29 +03:00
* with no external influence
2013-03-15 08:59:52 -04:00
* @ constant_pcb : sensor gradient const info for hotspot extrapolation equation
2012-07-12 19:02:29 +03:00
* with no external influence
* @ register_cooling : function to describe how this sensor is going to be cooled
* @ unregister_cooling : function to release cooling data
2013-03-15 08:59:52 -04:00
*
* Data structure to describe a temperature sensor handled by a bandgap device .
* It should provide configuration details on this sensor , such as how to
* access the registers affecting this sensor , shadow register buffer , how to
* assess the gradient from hotspot , how to cooldown the domain when sensor
* reports too hot temperature .
2012-07-12 19:02:29 +03:00
*/
2013-03-19 10:54:21 -04:00
struct ti_temp_sensor {
2012-07-12 19:02:29 +03:00
struct temp_sensor_data * ts_data ;
struct temp_sensor_registers * registers ;
char * domain ;
/* for hotspot extrapolation */
const int slope_pcb ;
const int constant_pcb ;
2013-03-19 10:54:21 -04:00
int ( * register_cooling ) ( struct ti_bandgap * bgp , int id ) ;
int ( * unregister_cooling ) ( struct ti_bandgap * bgp , int id ) ;
2012-07-12 19:02:29 +03:00
} ;
/**
2013-03-19 10:54:25 -04:00
* DOC : ti bandgap feature types
2013-03-15 08:59:52 -04:00
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_TSHUT - used when the thermal shutdown signal output
2013-03-15 08:59:52 -04:00
* of a bandgap device instance is routed to the processor . This means
* the system must react and perform the shutdown by itself ( handle an
* IRQ , for instance ) .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_TSHUT_CONFIG - used when the bandgap device has control
2013-03-15 08:59:52 -04:00
* over the thermal shutdown configuration . This means that the thermal
* shutdown thresholds are programmable , for instance .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_TALERT - used when the bandgap device instance outputs
2013-03-15 08:59:52 -04:00
* a signal representing violation of programmable alert thresholds .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_MODE_CONFIG - used when it is possible to choose which
2013-03-15 08:59:52 -04:00
* mode , continuous or one shot , the bandgap device instance will operate .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_COUNTER - used when the bandgap device instance allows
2013-03-15 08:59:52 -04:00
* programming the update interval of its internal state machine .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_POWER_SWITCH - used when the bandgap device allows
2013-03-15 08:59:52 -04:00
* itself to be switched on / off .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_CLK_CTRL - used when the clocks feeding the bandgap
2013-03-15 08:59:52 -04:00
* device are gateable or not .
*
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_FEATURE_FREEZE_BIT - used when the bandgap device features
2013-03-15 08:59:52 -04:00
* a history buffer that its update can be freezed / unfreezed .
*
2013-04-01 12:04:40 -04:00
* TI_BANDGAP_FEATURE_COUNTER_DELAY - used when the bandgap device features
* a delay programming based on distinct values .
*
2013-04-01 12:04:43 -04:00
* TI_BANDGAP_FEATURE_HISTORY_BUFFER - used when the bandgap device features
* a history buffer of temperatures .
*
2015-04-22 18:21:41 +05:30
* TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device
* has Errata 814
2015-04-02 16:49:07 +02:00
* TI_BANDGAP_FEATURE_UNRELIABLE - used when the sensor readings are too
* inaccurate .
2013-03-19 10:54:21 -04:00
* TI_BANDGAP_HAS ( b , f ) - macro to check if a bandgap device is capable of a
2013-03-15 08:59:52 -04:00
* specific feature ( above ) or not . Return non - zero , if yes .
2012-07-12 19:02:29 +03:00
*/
2013-03-19 10:54:21 -04:00
# define TI_BANDGAP_FEATURE_TSHUT BIT(0)
# define TI_BANDGAP_FEATURE_TSHUT_CONFIG BIT(1)
# define TI_BANDGAP_FEATURE_TALERT BIT(2)
# define TI_BANDGAP_FEATURE_MODE_CONFIG BIT(3)
# define TI_BANDGAP_FEATURE_COUNTER BIT(4)
# define TI_BANDGAP_FEATURE_POWER_SWITCH BIT(5)
# define TI_BANDGAP_FEATURE_CLK_CTRL BIT(6)
# define TI_BANDGAP_FEATURE_FREEZE_BIT BIT(7)
2013-04-01 12:04:40 -04:00
# define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8)
2013-04-01 12:04:43 -04:00
# define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
2015-04-22 18:21:41 +05:30
# define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
2018-05-02 15:20:35 +02:00
# define TI_BANDGAP_FEATURE_UNRELIABLE BIT(11)
2013-03-19 10:54:21 -04:00
# define TI_BANDGAP_HAS(b, f) \
( ( b ) - > conf - > features & TI_BANDGAP_FEATURE_ # # f )
2013-03-15 08:59:52 -04:00
/**
2013-03-19 10:54:25 -04:00
* struct ti_bandgap_data - ti bandgap data configuration structure
2013-03-15 08:59:52 -04:00
* @ features : a bitwise flag set to describe the device features
* @ conv_table : Pointer to ADC to temperature conversion table
2013-03-15 09:00:14 -04:00
* @ adc_start_val : ADC conversion table starting value
* @ adc_end_val : ADC conversion table ending value
2013-03-15 08:59:52 -04:00
* @ fclock_name : clock name of the functional clock
* @ div_ck_name : clock name of the clock divisor
* @ sensor_count : count of temperature sensor within this bandgap device
* @ report_temperature : callback to report thermal alert to thermal API
* @ expose_sensor : callback to export sensor to thermal API
* @ remove_sensor : callback to destroy sensor from thermal API
* @ sensors : array of sensors present in this bandgap instance
*
* This is a data structure which should hold most of the static configuration
* of a bandgap device instance . It should describe which features this instance
* is capable of , the clock names to feed this device , the amount of sensors and
* their configuration representation , and how to export and unexport them to
* a thermal API .
*/
2013-03-19 10:54:21 -04:00
struct ti_bandgap_data {
2012-07-12 19:02:29 +03:00
unsigned int features ;
const int * conv_table ;
2013-03-15 09:00:14 -04:00
u32 adc_start_val ;
u32 adc_end_val ;
2012-07-12 19:02:29 +03:00
char * fclock_name ;
char * div_ck_name ;
int sensor_count ;
2013-03-19 10:54:21 -04:00
int ( * report_temperature ) ( struct ti_bandgap * bgp , int id ) ;
int ( * expose_sensor ) ( struct ti_bandgap * bgp , int id , char * domain ) ;
int ( * remove_sensor ) ( struct ti_bandgap * bgp , int id ) ;
2012-07-12 19:02:29 +03:00
/* this needs to be at the end */
2013-03-19 10:54:21 -04:00
struct ti_temp_sensor sensors [ ] ;
2012-07-12 19:02:29 +03:00
} ;
2013-03-19 10:54:21 -04:00
int ti_bandgap_read_thot ( struct ti_bandgap * bgp , int id , int * thot ) ;
int ti_bandgap_write_thot ( struct ti_bandgap * bgp , int id , int val ) ;
int ti_bandgap_read_tcold ( struct ti_bandgap * bgp , int id , int * tcold ) ;
int ti_bandgap_write_tcold ( struct ti_bandgap * bgp , int id , int val ) ;
int ti_bandgap_read_update_interval ( struct ti_bandgap * bgp , int id ,
int * interval ) ;
int ti_bandgap_write_update_interval ( struct ti_bandgap * bgp , int id ,
u32 interval ) ;
int ti_bandgap_read_temperature ( struct ti_bandgap * bgp , int id ,
2012-07-12 19:02:29 +03:00
int * temperature ) ;
2013-03-19 10:54:21 -04:00
int ti_bandgap_set_sensor_data ( struct ti_bandgap * bgp , int id , void * data ) ;
void * ti_bandgap_get_sensor_data ( struct ti_bandgap * bgp , int id ) ;
2013-04-01 12:04:45 -04:00
int ti_bandgap_get_trend ( struct ti_bandgap * bgp , int id , int * trend ) ;
2012-07-12 19:02:29 +03:00
2015-04-02 16:49:07 +02:00
# ifdef CONFIG_OMAP3_THERMAL
extern const struct ti_bandgap_data omap34xx_data ;
2015-09-21 17:32:15 -07:00
extern const struct ti_bandgap_data omap36xx_data ;
2015-04-02 16:49:07 +02:00
# else
# define omap34xx_data NULL
2015-09-21 17:32:15 -07:00
# define omap36xx_data NULL
2015-04-02 16:49:07 +02:00
# endif
2012-07-12 19:02:31 +03:00
# ifdef CONFIG_OMAP4_THERMAL
2013-03-19 10:54:21 -04:00
extern const struct ti_bandgap_data omap4430_data ;
extern const struct ti_bandgap_data omap4460_data ;
extern const struct ti_bandgap_data omap4470_data ;
2012-07-12 19:02:31 +03:00
# else
# define omap4430_data NULL
# define omap4460_data NULL
# define omap4470_data NULL
# endif
2012-07-12 19:02:32 +03:00
# ifdef CONFIG_OMAP5_THERMAL
2013-03-19 10:54:21 -04:00
extern const struct ti_bandgap_data omap5430_data ;
2012-07-12 19:02:32 +03:00
# else
# define omap5430_data NULL
# endif
2013-05-29 15:07:45 +00:00
# ifdef CONFIG_DRA752_THERMAL
extern const struct ti_bandgap_data dra752_data ;
# else
# define dra752_data NULL
# endif
2012-07-12 19:02:29 +03:00
# endif