diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index f0de72a62fd7..bd52663f1a5a 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -116,6 +116,43 @@
 #define EXYNOS7_EMUL_DATA_SHIFT			7
 #define EXYNOS7_EMUL_DATA_MASK			0x1ff
 
+/* Exynos850 specific registers */
+#define EXYNOS850_TMU_REG_AVG_CON		0x58
+#define EXYNOS850_TMU_REG_CONTROL1		0x24
+#define EXYNOS850_TMU_REG_COUNTER_VALUE0	0x30
+#define EXYNOS850_TMU_REG_COUNTER_VALUE1	0x34
+#define EXYNOS850_TMU_REG_CURRENT_TEMP1_0	0x40
+#define EXYNOS850_TMU_REG_THD_TEMP0_RISE	0x50
+#define EXYNOS850_TMU_REG_THD_TEMP0_FALL	0x60
+#define EXYNOS850_TMU_REG_TRIM0			0x3C
+
+#define EXYNOS850_TMU_AVG_CON_SHIFT		18
+#define EXYNOS850_TMU_AVG_MODE_MASK		0x7
+#define EXYNOS850_TMU_BGRI_TRIM_MASK		0xF
+#define EXYNOS850_TMU_BGRI_TRIM_SHIFT		20
+#define EXYNOS850_TMU_CLK_SENSE_ON_MASK		0xffff
+#define EXYNOS850_TMU_CLK_SENSE_ON_SHIFT	16
+#define EXYNOS850_TMU_DEM_ENABLE		1
+#define EXYNOS850_TMU_DEM_SHIFT			4
+#define EXYNOS850_TMU_EN_TEMP_SEN_OFF_MASK	0xffff
+#define EXYNOS850_TMU_EN_TEMP_SEN_OFF_SHIFT	0
+#define EXYNOS850_TMU_LPI_MODE_MASK		1
+#define EXYNOS850_TMU_LPI_MODE_SHIFT		10
+#define EXYNOS850_TMU_T_BUF_SLOPE_SEL_MASK	0xF
+#define EXYNOS850_TMU_T_BUF_SLOPE_SEL_SHIFT	18
+#define EXYNOS850_TMU_T_BUF_VREF_SEL_MASK	0x1F
+#define EXYNOS850_TMU_T_BUF_VREF_SEL_SHIFT	18
+#define EXYNOS850_TMU_TEM1051X_SENSE_VALUE	0x028A
+#define EXYNOS850_TMU_TEM1456X_SENSE_VALUE	0x0A28
+#define EXYNOS850_TMU_TEMP_SHIFT		9
+#define EXYNOS850_TMU_TRIMINFO_SHIFT		4
+#define EXYNOS850_TMU_T_TRIM0_MASK		0xF
+#define EXYNOS850_TMU_T_TRIM0_SHIFT		18
+#define EXYNOS850_TMU_VBEI_TRIM_MASK		0xF
+#define EXYNOS850_TMU_VBEI_TRIM_SHIFT		8
+#define EXYNOS850_TMU_VREF_TRIM_MASK		0xF
+#define EXYNOS850_TMU_VREF_TRIM_SHIFT		12
+
 #define EXYNOS_FIRST_POINT_TRIM			25
 #define EXYNOS_SECOND_POINT_TRIM		85
 
@@ -133,6 +170,7 @@ enum soc_type {
 	SOC_ARCH_EXYNOS5420_TRIMINFO,
 	SOC_ARCH_EXYNOS5433,
 	SOC_ARCH_EXYNOS7,
+	SOC_ARCH_EXYNOS850,
 };
 
 /**
@@ -231,13 +269,16 @@ static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
 
 static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
 {
-	u16 tmu_temp_mask =
-		(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
-						: EXYNOS_TMU_TEMP_MASK;
+	u16 tmu_temp_mask = (data->soc == SOC_ARCH_EXYNOS7 ||
+			     data->soc == SOC_ARCH_EXYNOS850) ?
+				    EXYNOS7_TMU_TEMP_MASK :
+				    EXYNOS_TMU_TEMP_MASK;
+	int tmu_85_shift = (data->soc == SOC_ARCH_EXYNOS850) ?
+				   EXYNOS850_TMU_TEMP_SHIFT :
+				   EXYNOS_TRIMINFO_85_SHIFT;
 
 	data->temp_error1 = trim_info & tmu_temp_mask;
-	data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
-				tmu_temp_mask);
+	data->temp_error2 = ((trim_info >> tmu_85_shift) & tmu_temp_mask);
 
 	if (!data->temp_error1 ||
 	    (data->min_efuse_value > data->temp_error1) ||
@@ -245,9 +286,8 @@ static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
 		data->temp_error1 = data->efuse_value & tmu_temp_mask;
 
 	if (!data->temp_error2)
-		data->temp_error2 =
-			(data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
-			tmu_temp_mask;
+		data->temp_error2 = (data->efuse_value >> tmu_85_shift) &
+				    tmu_temp_mask;
 }
 
 static int exynos_tmu_initialize(struct platform_device *pdev)
@@ -588,6 +628,129 @@ static void exynos7_tmu_initialize(struct platform_device *pdev)
 	sanitize_temp_error(data, trim_info);
 }
 
+static void exynos850_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
+{
+	exynos_tmu_update_temp(data, EXYNOS850_TMU_REG_THD_TEMP0_FALL + 12, 0,
+			       temp);
+	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
+			      EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, true);
+}
+
+static void exynos850_tmu_set_high_temp(struct exynos_tmu_data *data, u8 temp)
+{
+	exynos_tmu_update_temp(data, EXYNOS850_TMU_REG_THD_TEMP0_RISE + 12, 16,
+			       temp);
+	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
+			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, true);
+}
+
+static void exynos850_tmu_disable_low(struct exynos_tmu_data *data)
+{
+	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
+			      EXYNOS_TMU_INTEN_FALL0_SHIFT + 0, false);
+}
+
+static void exynos850_tmu_disable_high(struct exynos_tmu_data *data)
+{
+	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
+			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 1, false);
+}
+
+static void exynos850_tmu_set_crit_temp(struct exynos_tmu_data *data, u8 temp)
+{
+	exynos_tmu_update_temp(data, EXYNOS850_TMU_REG_THD_TEMP0_RISE + 0, 16,
+			       temp);
+	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_CONTROL,
+			      EXYNOS_TMU_THERM_TRIP_EN_SHIFT, true);
+	exynos_tmu_update_bit(data, EXYNOS7_TMU_REG_INTEN,
+			      EXYNOS7_TMU_INTEN_RISE0_SHIFT + 7, true);
+}
+
+static void exynos850_tmu_initialize(struct platform_device *pdev)
+{
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	int cal_type;
+	unsigned int avg_mode, buf, bgri, vref, vbei;
+
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+	cal_type = (buf & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) >>
+		   EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT;
+	data->reference_voltage = (buf >> EXYNOS850_TMU_T_BUF_VREF_SEL_SHIFT) &
+				  EXYNOS850_TMU_T_BUF_VREF_SEL_MASK;
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO +
+		    EXYNOS850_TMU_TRIMINFO_SHIFT);
+	data->gain = (buf >> EXYNOS850_TMU_T_BUF_SLOPE_SEL_SHIFT) &
+		     EXYNOS850_TMU_T_BUF_SLOPE_SEL_MASK;
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO +
+		    2 * EXYNOS850_TMU_TRIMINFO_SHIFT);
+	avg_mode = (buf >> EXYNOS850_TMU_AVG_CON_SHIFT) &
+		   EXYNOS850_TMU_AVG_MODE_MASK;
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO +
+		    3 * EXYNOS850_TMU_TRIMINFO_SHIFT);
+	bgri = (buf >> EXYNOS850_TMU_T_TRIM0_SHIFT) &
+	       EXYNOS850_TMU_T_TRIM0_MASK;
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO +
+		    4 * EXYNOS850_TMU_TRIMINFO_SHIFT);
+	vref = (buf >> EXYNOS850_TMU_T_TRIM0_SHIFT) &
+	       EXYNOS850_TMU_T_TRIM0_MASK;
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO +
+		    5 * EXYNOS850_TMU_TRIMINFO_SHIFT);
+	vbei = (buf >> EXYNOS850_TMU_T_TRIM0_SHIFT) &
+	       EXYNOS850_TMU_T_TRIM0_MASK;
+
+	buf = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+	sanitize_temp_error(data, buf);
+
+	switch (cal_type) {
+	case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
+		data->cal_type = TYPE_TWO_POINT_TRIMMING;
+		break;
+	case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
+	default:
+		data->cal_type = TYPE_ONE_POINT_TRIMMING;
+		break;
+	}
+
+	dev_info(&pdev->dev, "Calibration type is %d-point calibration\n",
+		 cal_type ? 2 : 1);
+
+	buf = readl(data->base + EXYNOS850_TMU_REG_AVG_CON);
+	buf &= ~(EXYNOS850_TMU_AVG_MODE_MASK);
+	buf &= ~(EXYNOS850_TMU_DEM_ENABLE << EXYNOS850_TMU_DEM_SHIFT);
+	if (avg_mode) {
+		buf |= avg_mode;
+		buf |= (EXYNOS850_TMU_DEM_ENABLE << EXYNOS850_TMU_DEM_SHIFT);
+	}
+	writel(buf, data->base + EXYNOS850_TMU_REG_AVG_CON);
+
+	buf = readl(data->base + EXYNOS850_TMU_REG_COUNTER_VALUE0);
+	buf &= ~(EXYNOS850_TMU_EN_TEMP_SEN_OFF_MASK
+		 << EXYNOS850_TMU_EN_TEMP_SEN_OFF_SHIFT);
+	buf |= EXYNOS850_TMU_TEM1051X_SENSE_VALUE
+	       << EXYNOS850_TMU_EN_TEMP_SEN_OFF_SHIFT;
+	writel(buf, data->base + EXYNOS850_TMU_REG_COUNTER_VALUE0);
+
+	buf = readl(data->base + EXYNOS850_TMU_REG_COUNTER_VALUE1);
+	buf &= ~(EXYNOS850_TMU_CLK_SENSE_ON_MASK
+		 << EXYNOS850_TMU_CLK_SENSE_ON_SHIFT);
+	buf |= EXYNOS850_TMU_TEM1051X_SENSE_VALUE
+	       << EXYNOS850_TMU_CLK_SENSE_ON_SHIFT;
+	writel(buf, data->base + EXYNOS850_TMU_REG_COUNTER_VALUE1);
+
+	buf = readl(data->base + EXYNOS850_TMU_REG_TRIM0);
+	buf &= ~(EXYNOS850_TMU_BGRI_TRIM_MASK << EXYNOS850_TMU_BGRI_TRIM_SHIFT);
+	buf &= ~(EXYNOS850_TMU_VREF_TRIM_MASK << EXYNOS850_TMU_VREF_TRIM_SHIFT);
+	buf &= ~(EXYNOS850_TMU_VBEI_TRIM_MASK << EXYNOS850_TMU_VBEI_TRIM_SHIFT);
+	buf |= (bgri << EXYNOS850_TMU_BGRI_TRIM_SHIFT);
+	buf |= (vref << EXYNOS850_TMU_VREF_TRIM_SHIFT);
+	buf |= (vbei << EXYNOS850_TMU_VBEI_TRIM_SHIFT);
+	writel(buf, data->base + EXYNOS850_TMU_REG_TRIM0);
+
+	buf = readl(data->base + EXYNOS850_TMU_REG_CONTROL1);
+	buf &= ~(EXYNOS850_TMU_LPI_MODE_MASK << EXYNOS850_TMU_LPI_MODE_SHIFT);
+	writel(buf, data->base + EXYNOS850_TMU_REG_CONTROL1);
+}
+
 static void exynos4210_tmu_control(struct platform_device *pdev, bool on)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
@@ -679,7 +842,8 @@ static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
 
 		val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
 		val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
-		if (data->soc == SOC_ARCH_EXYNOS7) {
+		if (data->soc == SOC_ARCH_EXYNOS7 ||
+		    data->soc == SOC_ARCH_EXYNOS850) {
 			val &= ~(EXYNOS7_EMUL_DATA_MASK <<
 				EXYNOS7_EMUL_DATA_SHIFT);
 			val |= (temp_to_code(data, temp) <<
@@ -709,7 +873,8 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 		emul_con = EXYNOS5260_EMUL_CON;
 	else if (data->soc == SOC_ARCH_EXYNOS5433)
 		emul_con = EXYNOS5433_TMU_EMUL_CON;
-	else if (data->soc == SOC_ARCH_EXYNOS7)
+	else if (data->soc == SOC_ARCH_EXYNOS7 ||
+		 data->soc == SOC_ARCH_EXYNOS850)
 		emul_con = EXYNOS7_TMU_REG_EMUL_CON;
 	else
 		emul_con = EXYNOS_EMUL_CON;
@@ -766,6 +931,12 @@ static int exynos7_tmu_read(struct exynos_tmu_data *data)
 		EXYNOS7_TMU_TEMP_MASK;
 }
 
+static int exynos850_tmu_read(struct exynos_tmu_data *data)
+{
+	return readw(data->base + EXYNOS850_TMU_REG_CURRENT_TEMP1_0) &
+	       EXYNOS7_TMU_TEMP_MASK;
+}
+
 static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
 {
 	struct exynos_tmu_data *data = id;
@@ -794,7 +965,8 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
 	if (data->soc == SOC_ARCH_EXYNOS5260) {
 		tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
 		tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
-	} else if (data->soc == SOC_ARCH_EXYNOS7) {
+	} else if (data->soc == SOC_ARCH_EXYNOS7 ||
+		   data->soc == SOC_ARCH_EXYNOS850) {
 		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
 		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
 	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
@@ -845,6 +1017,9 @@ static const struct of_device_id exynos_tmu_match[] = {
 	}, {
 		.compatible = "samsung,exynos7-tmu",
 		.data = (const void *)SOC_ARCH_EXYNOS7,
+	}, {
+		.compatible = "samsung,exynos850-tmu",
+		.data = (const void *)SOC_ARCH_EXYNOS850,
 	},
 	{ },
 };
@@ -957,6 +1132,21 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		data->min_efuse_value = 15;
 		data->max_efuse_value = 100;
 		break;
+	case SOC_ARCH_EXYNOS850:
+		data->tmu_set_low_temp = exynos850_tmu_set_low_temp;
+		data->tmu_set_high_temp = exynos850_tmu_set_high_temp;
+		data->tmu_disable_low = exynos850_tmu_disable_low;
+		data->tmu_disable_high = exynos850_tmu_disable_high;
+		data->tmu_set_crit_temp = exynos850_tmu_set_crit_temp;
+		data->tmu_initialize = exynos850_tmu_initialize;
+		data->tmu_control = exynos4210_tmu_control;
+		data->tmu_read = exynos850_tmu_read;
+		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
+		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+		data->efuse_value = 55;
+		data->min_efuse_value = 0;
+		data->max_efuse_value = 511;
+		break;
 	default:
 		dev_err(&pdev->dev, "Platform not supported\n");
 		return -EINVAL;
@@ -1051,7 +1241,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 		return ret;
 
 	data->clk = devm_clk_get(dev, "tmu_apbif");
-	if (IS_ERR(data->clk))
+	if (IS_ERR(data->clk) && data->soc != SOC_ARCH_EXYNOS850)
 		return dev_err_probe(dev, PTR_ERR(data->clk), "Failed to get clock\n");
 
 	data->clk_sec = devm_clk_get(dev, "tmu_triminfo_apbif");
