/* For now assume only one entry */
struct i2c_board_info __initdata tgr_i2c_board_info[1];
+/* T30 USB Base address: USB1, USB2, USB3 */
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+static unsigned int s_tegra_usb_base[] = {0x7D000000, 0x7D004000, 0x7D008000};
+#endif
+
+/* Fuse USB Calib Value. */
+static unsigned int s_fuse_usb_calib_value;
+
+static void get_fuse_usb_calib_value(void)
+{
+ s_fuse_usb_calib_value = readl(IO_TO_VIRT(TEGRA_FUSE_BASE +
+ FUSE_USB_CALIB_0));
+}
+
static inline void pg_writel(unsigned long value, unsigned long offset)
{
writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE) + offset);
}
+static void utmip_temp_dep_update(int curr_rtemp, int utmip_temp_bound)
+{
+ static int prev_temp;
+ static char initial_update = 1;
+ unsigned int fuse_usb_calib_value = s_fuse_usb_calib_value;
+ int i;
+ char utmip_update_require = 0;
+
+ /* Extract bits[3:0]. */
+ fuse_usb_calib_value = fuse_usb_calib_value & 0xF;
+
+ /* If previous and currentt temperatures falls in the same temperature
+ boundary then no need to update the UTMIP_SPARE_CFG */
+ if ((prev_temp >= utmip_temp_bound) && (curr_rtemp >= utmip_temp_bound))
+ utmip_update_require = 0;
+ else if ((prev_temp < utmip_temp_bound) &&
+ (curr_rtemp < utmip_temp_bound))
+ utmip_update_require = 0;
+ else
+ utmip_update_require = 1;
+
+ /* For Initial call , need to update the UTMIP_SPARE_CFG */
+ if (initial_update) {
+ utmip_update_require = 1;
+ initial_update = 0;
+ prev_temp = curr_rtemp;
+ }
+
+ if (utmip_update_require) {
+ prev_temp = curr_rtemp;
+ if (curr_rtemp >= utmip_temp_bound) {
+ fuse_usb_calib_value += 0x1;
+ /* Check if there is a overflow. */
+ if (fuse_usb_calib_value > UTMIP_XCVR_SETUP_MAX_VAL)
+ fuse_usb_calib_value = UTMIP_XCVR_SETUP_MAX_VAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(s_tegra_usb_base); i++) {
+ unsigned int regval;
+ regval = readl(IO_TO_VIRT(s_tegra_usb_base[i] +
+ UTMIP_SPARE_CFG0));
+ regval &= ~FUSE_SETUP_SEL;
+ writel(regval, IO_TO_VIRT(s_tegra_usb_base[i] +
+ UTMIP_SPARE_CFG0));
+
+ regval = readl(IO_TO_VIRT(s_tegra_usb_base[i] +
+ UTMIP_XCVR_CFG0));
+ /* If low_to_high, then write 0x2 to HSSLEW_MSB
+ else write 0x8 */
+ regval &= ~UTMIP_XCVR_HSSLEW_MSB_MSK;
+ regval |= (curr_rtemp >= utmip_temp_bound) ?
+ UTMIP_XCVR_HSSLEW_MSB_HIGH_TEMP_VAL :
+ UTMIP_XCVR_HSSLEW_MSB_LOW_TEMP_VAL;
+ /* write fuse_usb_calib_value to SETUP field
+ of UTMIP_XCVR_CFG0. */
+ regval &= ~UTMIP_XCVR_SETUP_MSK;
+ regval |= fuse_usb_calib_value;
+ writel(regval, IO_TO_VIRT(s_tegra_usb_base[i] +
+ UTMIP_XCVR_CFG0));
+ }
+ }
+}
+
/* Call back function, invoked by driver */
static void ltemp_dependent_reg_update(int curr_ltemp)
{
tmon_pdata.ltemp_dependent_reg_update =
ltemp_dependent_reg_update;
- /* Remote temperature monitoring: Used for USB registers */
- if (brd_therm_monitor_data->remote_temp_update) {
- tmon_pdata.rtemp_low_boundary =
- brd_therm_monitor_data->rtemp_low_boundary;
- tmon_pdata.rtemp_high_boundary =
- brd_therm_monitor_data->rtemp_high_boundary;
- /*tmon_pdata.rtemp_dependent_reg_update =
- rtemp_dependent_reg_update;*/
+ /* utmip registers update */
+ if (brd_therm_monitor_data->utmip_reg_update) {
+ tmon_pdata.utmip_temp_bound =
+ brd_therm_monitor_data->utmip_temp_bound;
+ tmon_pdata.utmip_temp_dep_update =
+ utmip_temp_dep_update;
}
/* Fill the i2c board info */
i2c_register_board_info(brd_therm_monitor_data->i2c_bus_num,
tgr_i2c_board_info, 1);
+ get_fuse_usb_calib_value();
}
#define MAX_NUM_TEMPERAT 10
#define INVALID_ADDR 0xffffffff
+#define UTMIP_XCVR_CFG0 0x808
+#define UTMIP_SPARE_CFG0 0x834
+#define FUSE_SETUP_SEL (1 << 3)
+#define UTMIP_XCVR_SETUP_MSK 0xF
+#define UTMIP_XCVR_HSSLEW_MSB_MSK (0x7F << 25)
+#define FUSE_USB_CALIB_0 0x1F0
+#define UTMIP_XCVR_SETUP_MAX_VAL 0xF
+#define UTMIP_XCVR_HSSLEW_MSB_BIT_OFFS 25
+/* Remote Temp < rtemp_boundary. */
+#define UTMIP_XCVR_HSSLEW_MSB_LOW_TEMP_VAL \
+ (0x8 << UTMIP_XCVR_HSSLEW_MSB_BIT_OFFS)
+/* Remote Temp >= rtemp_boundary. */
+#define UTMIP_XCVR_HSSLEW_MSB_HIGH_TEMP_VAL \
+ (0x2 << UTMIP_XCVR_HSSLEW_MSB_BIT_OFFS)
+
+
struct therm_monitor_ldep_data {
unsigned int reg_addr;
int temperat[MAX_NUM_TEMPERAT];
unsigned int delta_temp;
unsigned int delta_time;
unsigned int remote_offset;
- int rtemp_low_boundary;
- int rtemp_high_boundary;
+ int utmip_temp_bound;
unsigned char local_temp_update;
- unsigned char remote_temp_update;
+ unsigned char utmip_reg_update;
unsigned char i2c_bus_num;
unsigned int i2c_dev_addrs;
unsigned char *i2c_dev_name;