All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Majewski <l.majewski@samsung.com>
To: Chanwoo Choi <cw00.choi@samsung.com>, edubezval@gmail.com
Cc: rui.zhang@intel.com, kgene@kernel.org, inki.dae@samsung.com,
	chanho61.park@samsung.com, linux-pm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] thermal: exynos: Add the support for Exynos5433 TMU
Date: Fri, 20 Mar 2015 08:48:50 +0100	[thread overview]
Message-ID: <20150320084850.539010f5@amdc2363> (raw)
In-Reply-To: <1425954224-31035-1-git-send-email-cw00.choi@samsung.com>

Hi Chanwoo,

> This patch adds the support for Exynos5433's TMU (Thermal Management
> Unit). Exynos5433 has a little different register bit fields as
> following description:
> - Support the eight trip points for rising/falling interrupt by using
> two registers
> - Read the calibration type (1-point or 2-point) and sensor id from
> TRIMINFO register
> - Use a little different register address
> 
> Cc: Zhang Rui <rui.zhang@intel.com>
> Cc: Eduardo Valentin <edubezval@gmail.com>
> Cc: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
> Changes from v1:
> (https://lkml.org/lkml/2015/2/26/234)
> - Add exynos5433_tmu_control() instead of using exynos7_tmu_control()
> on both Exynos5433 and Exynos7.
> - Separate the patches related to devicetree and then send send
> Exnos5433's tmu patches[1] with other Exynos5433 devicetree patches.
>   [1] https://lkml.org/lkml/2015/3/9/1036
> 
>  drivers/thermal/samsung/exynos_tmu.c | 187
> ++++++++++++++++++++++++++++++++++-
> drivers/thermal/samsung/exynos_tmu.h |   1 + 2 files changed, 186
> insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/thermal/samsung/exynos_tmu.c
> b/drivers/thermal/samsung/exynos_tmu.c index 1d30b09..531f4b17 100644
> --- a/drivers/thermal/samsung/exynos_tmu.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -97,6 +97,32 @@
>  #define EXYNOS4412_MUX_ADDR_VALUE          6
>  #define EXYNOS4412_MUX_ADDR_SHIFT          20
>  
> +/* Exynos5433 specific registers */
> +#define EXYNOS5433_TMU_REG_CONTROL1		0x024
> +#define EXYNOS5433_TMU_SAMPLING_INTERVAL	0x02c
> +#define EXYNOS5433_TMU_COUNTER_VALUE0		0x030
> +#define EXYNOS5433_TMU_COUNTER_VALUE1		0x034
> +#define EXYNOS5433_TMU_REG_CURRENT_TEMP1	0x044
> +#define EXYNOS5433_THD_TEMP_RISE3_0		0x050
> +#define EXYNOS5433_THD_TEMP_RISE7_4		0x054
> +#define EXYNOS5433_THD_TEMP_FALL3_0		0x060
> +#define EXYNOS5433_THD_TEMP_FALL7_4		0x064
> +#define EXYNOS5433_TMU_REG_INTEN		0x0c0
> +#define EXYNOS5433_TMU_REG_INTPEND		0x0c8
> +#define EXYNOS5433_TMU_EMUL_CON			0x110
> +#define EXYNOS5433_TMU_PD_DET_EN		0x130
> +
> +#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT	16
> +#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT	23
> +#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK	\
> +			(0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
> +#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK	BIT(23)
> +
> +#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING	0
> +#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING	1
> +
> +#define EXYNOS5433_PD_DET_EN			1
> +
>  /*exynos5440 specific registers*/
>  #define EXYNOS5440_TMU_S0_7_TRIM		0x000
>  #define EXYNOS5440_TMU_S0_7_CTRL		0x020
> @@ -484,6 +510,101 @@ out:
>  	return ret;
>  }
>  
> +static int exynos5433_tmu_initialize(struct platform_device *pdev)
> +{
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	struct exynos_tmu_platform_data *pdata = data->pdata;
> +	struct thermal_zone_device *tz = data->tzd;
> +	unsigned int status, trim_info;
> +	unsigned int rising_threshold = 0, falling_threshold = 0;
> +	unsigned long temp, temp_hist;
> +	int ret = 0, threshold_code, i, sensor_id, cal_type;
> +
> +	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
> +	if (!status) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> +	sanitize_temp_error(data, trim_info);
> +
> +	/* Read the temperature sensor id */
> +	sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
> +				>>
> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
> +	dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n",
> sensor_id); +
> +	/* Read the calibration mode */
> +	writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
> +	cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
> +				>>
> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; +
> +	switch (cal_type) {
> +	case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
> +		pdata->cal_type = TYPE_ONE_POINT_TRIMMING;
> +		break;
> +	case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
> +		pdata->cal_type = TYPE_TWO_POINT_TRIMMING;
> +		break;
> +	default:
> +		pdata->cal_type = TYPE_ONE_POINT_TRIMMING;
> +		break;
> +	};
> +
> +	dev_info(&pdev->dev, "Calibration type is %d-point
> calibration\n",
> +			cal_type ?  2 : 1);
> +
> +	/* Write temperature code for rising and falling threshold */
> +	for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
> +		int rising_reg_offset, falling_reg_offset;
> +		int j = 0;
> +
> +		switch (i) {
> +		case 0:
> +		case 1:
> +		case 2:
> +		case 3:
> +			rising_reg_offset =
> EXYNOS5433_THD_TEMP_RISE3_0;
> +			falling_reg_offset =
> EXYNOS5433_THD_TEMP_FALL3_0;
> +			j = i;
> +			break;
> +		case 4:
> +		case 5:
> +		case 6:
> +		case 7:
> +			rising_reg_offset =
> EXYNOS5433_THD_TEMP_RISE7_4;
> +			falling_reg_offset =
> EXYNOS5433_THD_TEMP_FALL7_4;
> +			j = i - 4;
> +			break;
> +		default:
> +			continue;
> +		}
> +
> +		/* Write temperature code for rising threshold */
> +		tz->ops->get_trip_temp(tz, i, &temp);
> +		temp /= MCELSIUS;
> +		threshold_code = temp_to_code(data, temp);
> +
> +		rising_threshold = readl(data->base +
> rising_reg_offset);
> +		rising_threshold |= (threshold_code << j * 8);
> +		writel(rising_threshold, data->base +
> rising_reg_offset); +
> +		/* Write temperature code for falling threshold */
> +		tz->ops->get_trip_hyst(tz, i, &temp_hist);
> +		temp_hist = temp - (temp_hist / MCELSIUS);
> +		threshold_code = temp_to_code(data, temp_hist);
> +
> +		falling_threshold = readl(data->base +
> falling_reg_offset);
> +		falling_threshold &= ~(0xff << j * 8);
> +		falling_threshold |= (threshold_code << j * 8);
> +		writel(falling_threshold, data->base +
> falling_reg_offset);
> +	}
> +
> +	data->tmu_clear_irqs(data);
> +out:
> +	return ret;
> +}
> +
>  static int exynos5440_tmu_initialize(struct platform_device *pdev)
>  {
>  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> @@ -643,6 +764,48 @@ static void exynos4210_tmu_control(struct
> platform_device *pdev, bool on) writel(con, data->base +
> EXYNOS_TMU_REG_CONTROL); }
>  
> +static void exynos5433_tmu_control(struct platform_device *pdev,
> bool on) +{
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	struct thermal_zone_device *tz = data->tzd;
> +	unsigned int con, interrupt_en, pd_det_en;
> +
> +	con = get_con_reg(data, readl(data->base +
> EXYNOS_TMU_REG_CONTROL)); +
> +	if (on) {
> +		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
> +		interrupt_en =
> +			(of_thermal_is_trip_valid(tz, 7)
> +			<< EXYNOS7_TMU_INTEN_RISE7_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 6)
> +			<< EXYNOS7_TMU_INTEN_RISE6_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 5)
> +			<< EXYNOS7_TMU_INTEN_RISE5_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 4)
> +			<< EXYNOS7_TMU_INTEN_RISE4_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 3)
> +			<< EXYNOS7_TMU_INTEN_RISE3_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 2)
> +			<< EXYNOS7_TMU_INTEN_RISE2_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 1)
> +			<< EXYNOS7_TMU_INTEN_RISE1_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 0)
> +			<< EXYNOS7_TMU_INTEN_RISE0_SHIFT);
> +
> +		interrupt_en |=
> +			interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
> +	} else {
> +		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
> +		interrupt_en = 0; /* Disable all interrupts */
> +	}
> +
> +	pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
> +
> +	writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
> +	writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN);
> +	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
> +}
> +
>  static void exynos5440_tmu_control(struct platform_device *pdev,
> bool on) {
>  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> @@ -770,6 +933,8 @@ static void exynos4412_tmu_set_emulation(struct
> exynos_tmu_data *data, 
>  	if (data->soc == SOC_ARCH_EXYNOS5260)
>  		emul_con = EXYNOS5260_EMUL_CON;
> +	if (data->soc == SOC_ARCH_EXYNOS5433)
> +		emul_con = EXYNOS5433_TMU_EMUL_CON;
>  	else if (data->soc == SOC_ARCH_EXYNOS7)
>  		emul_con = EXYNOS7_TMU_REG_EMUL_CON;
>  	else
> @@ -882,6 +1047,9 @@ static void exynos4210_tmu_clear_irqs(struct
> exynos_tmu_data *data) } else if (data->soc == SOC_ARCH_EXYNOS7) {
>  		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
>  		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
> +	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
> +		tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
> +		tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
>  	} else {
>  		tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
>  		tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
> @@ -926,6 +1094,7 @@ static const struct of_device_id
> exynos_tmu_match[] = { { .compatible = "samsung,exynos5260-tmu", },
>  	{ .compatible = "samsung,exynos5420-tmu", },
>  	{ .compatible = "samsung,exynos5420-tmu-ext-triminfo", },
> +	{ .compatible = "samsung,exynos5433-tmu", },
>  	{ .compatible = "samsung,exynos5440-tmu", },
>  	{ .compatible = "samsung,exynos7-tmu", },
>  	{ /* sentinel */ },
> @@ -949,6 +1118,8 @@ static int exynos_of_get_soc_type(struct
> device_node *np) else if (of_device_is_compatible(np,
>  					 "samsung,exynos5420-tmu-ext-triminfo"))
>  		return SOC_ARCH_EXYNOS5420_TRIMINFO;
> +	else if (of_device_is_compatible(np,
> "samsung,exynos5433-tmu"))
> +		return SOC_ARCH_EXYNOS5433;
>  	else if (of_device_is_compatible(np,
> "samsung,exynos5440-tmu")) return SOC_ARCH_EXYNOS5440;
>  	else if (of_device_is_compatible(np, "samsung,exynos7-tmu"))
> @@ -1069,6 +1240,13 @@ static int exynos_map_dt_data(struct
> platform_device *pdev) data->tmu_set_emulation =
> exynos4412_tmu_set_emulation; data->tmu_clear_irqs =
> exynos4210_tmu_clear_irqs; break;
> +	case SOC_ARCH_EXYNOS5433:
> +		data->tmu_initialize = exynos5433_tmu_initialize;
> +		data->tmu_control = exynos5433_tmu_control;
> +		data->tmu_read = exynos4412_tmu_read;
> +		data->tmu_set_emulation =
> exynos4412_tmu_set_emulation;
> +		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
> +		break;
>  	case SOC_ARCH_EXYNOS5440:
>  		data->tmu_initialize = exynos5440_tmu_initialize;
>  		data->tmu_control = exynos5440_tmu_control;
> @@ -1172,7 +1350,9 @@ static int exynos_tmu_probe(struct
> platform_device *pdev) goto err_clk_sec;
>  	}
>  
> -	if (data->soc == SOC_ARCH_EXYNOS7) {
> +	switch (data->soc) {
> +	case SOC_ARCH_EXYNOS5433:
> +	case SOC_ARCH_EXYNOS7:
>  		data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk");
>  		if (IS_ERR(data->sclk)) {
>  			dev_err(&pdev->dev, "Failed to get sclk\n");
> @@ -1184,7 +1364,10 @@ static int exynos_tmu_probe(struct
> platform_device *pdev) goto err_clk;
>  			}
>  		}
> -	}
> +		break;
> +	default:
> +		break;
> +	};
>  
>  	ret = exynos_tmu_initialize(pdev);
>  	if (ret) {
> diff --git a/drivers/thermal/samsung/exynos_tmu.h
> b/drivers/thermal/samsung/exynos_tmu.h index 4d71ec6..440c714 100644
> --- a/drivers/thermal/samsung/exynos_tmu.h
> +++ b/drivers/thermal/samsung/exynos_tmu.h
> @@ -33,6 +33,7 @@ enum soc_type {
>  	SOC_ARCH_EXYNOS5260,
>  	SOC_ARCH_EXYNOS5420,
>  	SOC_ARCH_EXYNOS5420_TRIMINFO,
> +	SOC_ARCH_EXYNOS5433,
>  	SOC_ARCH_EXYNOS5440,
>  	SOC_ARCH_EXYNOS7,
>  };

Acked-by: Lukasz Majewski <l.majewski@samsung.com>

I will test this patch (@ Odroid U3) when linux-samusng-thermal/next
branch would be updated to newest mainline.

Eduardo, could you update your -next branch?

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

WARNING: multiple messages have this Message-ID (diff)
From: l.majewski@samsung.com (Lukasz Majewski)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] thermal: exynos: Add the support for Exynos5433 TMU
Date: Fri, 20 Mar 2015 08:48:50 +0100	[thread overview]
Message-ID: <20150320084850.539010f5@amdc2363> (raw)
In-Reply-To: <1425954224-31035-1-git-send-email-cw00.choi@samsung.com>

Hi Chanwoo,

> This patch adds the support for Exynos5433's TMU (Thermal Management
> Unit). Exynos5433 has a little different register bit fields as
> following description:
> - Support the eight trip points for rising/falling interrupt by using
> two registers
> - Read the calibration type (1-point or 2-point) and sensor id from
> TRIMINFO register
> - Use a little different register address
> 
> Cc: Zhang Rui <rui.zhang@intel.com>
> Cc: Eduardo Valentin <edubezval@gmail.com>
> Cc: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
> Changes from v1:
> (https://lkml.org/lkml/2015/2/26/234)
> - Add exynos5433_tmu_control() instead of using exynos7_tmu_control()
> on both Exynos5433 and Exynos7.
> - Separate the patches related to devicetree and then send send
> Exnos5433's tmu patches[1] with other Exynos5433 devicetree patches.
>   [1] https://lkml.org/lkml/2015/3/9/1036
> 
>  drivers/thermal/samsung/exynos_tmu.c | 187
> ++++++++++++++++++++++++++++++++++-
> drivers/thermal/samsung/exynos_tmu.h |   1 + 2 files changed, 186
> insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/thermal/samsung/exynos_tmu.c
> b/drivers/thermal/samsung/exynos_tmu.c index 1d30b09..531f4b17 100644
> --- a/drivers/thermal/samsung/exynos_tmu.c
> +++ b/drivers/thermal/samsung/exynos_tmu.c
> @@ -97,6 +97,32 @@
>  #define EXYNOS4412_MUX_ADDR_VALUE          6
>  #define EXYNOS4412_MUX_ADDR_SHIFT          20
>  
> +/* Exynos5433 specific registers */
> +#define EXYNOS5433_TMU_REG_CONTROL1		0x024
> +#define EXYNOS5433_TMU_SAMPLING_INTERVAL	0x02c
> +#define EXYNOS5433_TMU_COUNTER_VALUE0		0x030
> +#define EXYNOS5433_TMU_COUNTER_VALUE1		0x034
> +#define EXYNOS5433_TMU_REG_CURRENT_TEMP1	0x044
> +#define EXYNOS5433_THD_TEMP_RISE3_0		0x050
> +#define EXYNOS5433_THD_TEMP_RISE7_4		0x054
> +#define EXYNOS5433_THD_TEMP_FALL3_0		0x060
> +#define EXYNOS5433_THD_TEMP_FALL7_4		0x064
> +#define EXYNOS5433_TMU_REG_INTEN		0x0c0
> +#define EXYNOS5433_TMU_REG_INTPEND		0x0c8
> +#define EXYNOS5433_TMU_EMUL_CON			0x110
> +#define EXYNOS5433_TMU_PD_DET_EN		0x130
> +
> +#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT	16
> +#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT	23
> +#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK	\
> +			(0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT)
> +#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK	BIT(23)
> +
> +#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING	0
> +#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING	1
> +
> +#define EXYNOS5433_PD_DET_EN			1
> +
>  /*exynos5440 specific registers*/
>  #define EXYNOS5440_TMU_S0_7_TRIM		0x000
>  #define EXYNOS5440_TMU_S0_7_CTRL		0x020
> @@ -484,6 +510,101 @@ out:
>  	return ret;
>  }
>  
> +static int exynos5433_tmu_initialize(struct platform_device *pdev)
> +{
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	struct exynos_tmu_platform_data *pdata = data->pdata;
> +	struct thermal_zone_device *tz = data->tzd;
> +	unsigned int status, trim_info;
> +	unsigned int rising_threshold = 0, falling_threshold = 0;
> +	unsigned long temp, temp_hist;
> +	int ret = 0, threshold_code, i, sensor_id, cal_type;
> +
> +	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
> +	if (!status) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
> +	sanitize_temp_error(data, trim_info);
> +
> +	/* Read the temperature sensor id */
> +	sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK)
> +				>>
> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT;
> +	dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n",
> sensor_id); +
> +	/* Read the calibration mode */
> +	writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO);
> +	cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK)
> +				>>
> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; +
> +	switch (cal_type) {
> +	case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING:
> +		pdata->cal_type = TYPE_ONE_POINT_TRIMMING;
> +		break;
> +	case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING:
> +		pdata->cal_type = TYPE_TWO_POINT_TRIMMING;
> +		break;
> +	default:
> +		pdata->cal_type = TYPE_ONE_POINT_TRIMMING;
> +		break;
> +	};
> +
> +	dev_info(&pdev->dev, "Calibration type is %d-point
> calibration\n",
> +			cal_type ?  2 : 1);
> +
> +	/* Write temperature code for rising and falling threshold */
> +	for (i = 0; i < of_thermal_get_ntrips(tz); i++) {
> +		int rising_reg_offset, falling_reg_offset;
> +		int j = 0;
> +
> +		switch (i) {
> +		case 0:
> +		case 1:
> +		case 2:
> +		case 3:
> +			rising_reg_offset =
> EXYNOS5433_THD_TEMP_RISE3_0;
> +			falling_reg_offset =
> EXYNOS5433_THD_TEMP_FALL3_0;
> +			j = i;
> +			break;
> +		case 4:
> +		case 5:
> +		case 6:
> +		case 7:
> +			rising_reg_offset =
> EXYNOS5433_THD_TEMP_RISE7_4;
> +			falling_reg_offset =
> EXYNOS5433_THD_TEMP_FALL7_4;
> +			j = i - 4;
> +			break;
> +		default:
> +			continue;
> +		}
> +
> +		/* Write temperature code for rising threshold */
> +		tz->ops->get_trip_temp(tz, i, &temp);
> +		temp /= MCELSIUS;
> +		threshold_code = temp_to_code(data, temp);
> +
> +		rising_threshold = readl(data->base +
> rising_reg_offset);
> +		rising_threshold |= (threshold_code << j * 8);
> +		writel(rising_threshold, data->base +
> rising_reg_offset); +
> +		/* Write temperature code for falling threshold */
> +		tz->ops->get_trip_hyst(tz, i, &temp_hist);
> +		temp_hist = temp - (temp_hist / MCELSIUS);
> +		threshold_code = temp_to_code(data, temp_hist);
> +
> +		falling_threshold = readl(data->base +
> falling_reg_offset);
> +		falling_threshold &= ~(0xff << j * 8);
> +		falling_threshold |= (threshold_code << j * 8);
> +		writel(falling_threshold, data->base +
> falling_reg_offset);
> +	}
> +
> +	data->tmu_clear_irqs(data);
> +out:
> +	return ret;
> +}
> +
>  static int exynos5440_tmu_initialize(struct platform_device *pdev)
>  {
>  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> @@ -643,6 +764,48 @@ static void exynos4210_tmu_control(struct
> platform_device *pdev, bool on) writel(con, data->base +
> EXYNOS_TMU_REG_CONTROL); }
>  
> +static void exynos5433_tmu_control(struct platform_device *pdev,
> bool on) +{
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	struct thermal_zone_device *tz = data->tzd;
> +	unsigned int con, interrupt_en, pd_det_en;
> +
> +	con = get_con_reg(data, readl(data->base +
> EXYNOS_TMU_REG_CONTROL)); +
> +	if (on) {
> +		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
> +		interrupt_en =
> +			(of_thermal_is_trip_valid(tz, 7)
> +			<< EXYNOS7_TMU_INTEN_RISE7_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 6)
> +			<< EXYNOS7_TMU_INTEN_RISE6_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 5)
> +			<< EXYNOS7_TMU_INTEN_RISE5_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 4)
> +			<< EXYNOS7_TMU_INTEN_RISE4_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 3)
> +			<< EXYNOS7_TMU_INTEN_RISE3_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 2)
> +			<< EXYNOS7_TMU_INTEN_RISE2_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 1)
> +			<< EXYNOS7_TMU_INTEN_RISE1_SHIFT) |
> +			(of_thermal_is_trip_valid(tz, 0)
> +			<< EXYNOS7_TMU_INTEN_RISE0_SHIFT);
> +
> +		interrupt_en |=
> +			interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
> +	} else {
> +		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);
> +		interrupt_en = 0; /* Disable all interrupts */
> +	}
> +
> +	pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0;
> +
> +	writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN);
> +	writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN);
> +	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
> +}
> +
>  static void exynos5440_tmu_control(struct platform_device *pdev,
> bool on) {
>  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> @@ -770,6 +933,8 @@ static void exynos4412_tmu_set_emulation(struct
> exynos_tmu_data *data, 
>  	if (data->soc == SOC_ARCH_EXYNOS5260)
>  		emul_con = EXYNOS5260_EMUL_CON;
> +	if (data->soc == SOC_ARCH_EXYNOS5433)
> +		emul_con = EXYNOS5433_TMU_EMUL_CON;
>  	else if (data->soc == SOC_ARCH_EXYNOS7)
>  		emul_con = EXYNOS7_TMU_REG_EMUL_CON;
>  	else
> @@ -882,6 +1047,9 @@ static void exynos4210_tmu_clear_irqs(struct
> exynos_tmu_data *data) } else if (data->soc == SOC_ARCH_EXYNOS7) {
>  		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
>  		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
> +	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
> +		tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
> +		tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
>  	} else {
>  		tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
>  		tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
> @@ -926,6 +1094,7 @@ static const struct of_device_id
> exynos_tmu_match[] = { { .compatible = "samsung,exynos5260-tmu", },
>  	{ .compatible = "samsung,exynos5420-tmu", },
>  	{ .compatible = "samsung,exynos5420-tmu-ext-triminfo", },
> +	{ .compatible = "samsung,exynos5433-tmu", },
>  	{ .compatible = "samsung,exynos5440-tmu", },
>  	{ .compatible = "samsung,exynos7-tmu", },
>  	{ /* sentinel */ },
> @@ -949,6 +1118,8 @@ static int exynos_of_get_soc_type(struct
> device_node *np) else if (of_device_is_compatible(np,
>  					 "samsung,exynos5420-tmu-ext-triminfo"))
>  		return SOC_ARCH_EXYNOS5420_TRIMINFO;
> +	else if (of_device_is_compatible(np,
> "samsung,exynos5433-tmu"))
> +		return SOC_ARCH_EXYNOS5433;
>  	else if (of_device_is_compatible(np,
> "samsung,exynos5440-tmu")) return SOC_ARCH_EXYNOS5440;
>  	else if (of_device_is_compatible(np, "samsung,exynos7-tmu"))
> @@ -1069,6 +1240,13 @@ static int exynos_map_dt_data(struct
> platform_device *pdev) data->tmu_set_emulation =
> exynos4412_tmu_set_emulation; data->tmu_clear_irqs =
> exynos4210_tmu_clear_irqs; break;
> +	case SOC_ARCH_EXYNOS5433:
> +		data->tmu_initialize = exynos5433_tmu_initialize;
> +		data->tmu_control = exynos5433_tmu_control;
> +		data->tmu_read = exynos4412_tmu_read;
> +		data->tmu_set_emulation =
> exynos4412_tmu_set_emulation;
> +		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
> +		break;
>  	case SOC_ARCH_EXYNOS5440:
>  		data->tmu_initialize = exynos5440_tmu_initialize;
>  		data->tmu_control = exynos5440_tmu_control;
> @@ -1172,7 +1350,9 @@ static int exynos_tmu_probe(struct
> platform_device *pdev) goto err_clk_sec;
>  	}
>  
> -	if (data->soc == SOC_ARCH_EXYNOS7) {
> +	switch (data->soc) {
> +	case SOC_ARCH_EXYNOS5433:
> +	case SOC_ARCH_EXYNOS7:
>  		data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk");
>  		if (IS_ERR(data->sclk)) {
>  			dev_err(&pdev->dev, "Failed to get sclk\n");
> @@ -1184,7 +1364,10 @@ static int exynos_tmu_probe(struct
> platform_device *pdev) goto err_clk;
>  			}
>  		}
> -	}
> +		break;
> +	default:
> +		break;
> +	};
>  
>  	ret = exynos_tmu_initialize(pdev);
>  	if (ret) {
> diff --git a/drivers/thermal/samsung/exynos_tmu.h
> b/drivers/thermal/samsung/exynos_tmu.h index 4d71ec6..440c714 100644
> --- a/drivers/thermal/samsung/exynos_tmu.h
> +++ b/drivers/thermal/samsung/exynos_tmu.h
> @@ -33,6 +33,7 @@ enum soc_type {
>  	SOC_ARCH_EXYNOS5260,
>  	SOC_ARCH_EXYNOS5420,
>  	SOC_ARCH_EXYNOS5420_TRIMINFO,
> +	SOC_ARCH_EXYNOS5433,
>  	SOC_ARCH_EXYNOS5440,
>  	SOC_ARCH_EXYNOS7,
>  };

Acked-by: Lukasz Majewski <l.majewski@samsung.com>

I will test this patch (@ Odroid U3) when linux-samusng-thermal/next
branch would be updated to newest mainline.

Eduardo, could you update your -next branch?

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

  parent reply	other threads:[~2015-03-20  7:49 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-10  2:23 [PATCH v2] thermal: exynos: Add the support for Exynos5433 TMU Chanwoo Choi
2015-03-10  2:23 ` Chanwoo Choi
2015-03-18  0:19 ` Chanwoo Choi
2015-03-18  0:19   ` Chanwoo Choi
2015-03-18  7:39   ` Lukasz Majewski
2015-03-18  7:39     ` Lukasz Majewski
2015-04-27  2:20     ` Chanwoo Choi
2015-04-27  2:20       ` Chanwoo Choi
2015-04-28  7:01       ` Lukasz Majewski
2015-04-28  7:01         ` Lukasz Majewski
2015-03-20  7:48 ` Lukasz Majewski [this message]
2015-03-20  7:48   ` Lukasz Majewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150320084850.539010f5@amdc2363 \
    --to=l.majewski@samsung.com \
    --cc=chanho61.park@samsung.com \
    --cc=cw00.choi@samsung.com \
    --cc=edubezval@gmail.com \
    --cc=inki.dae@samsung.com \
    --cc=kgene@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.