1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602 |
- From 5e3aac197a74914ccec2732a89c29d960730d28f Mon Sep 17 00:00:00 2001
- From: Balsam CHIHI <[email protected]>
- Date: Thu, 9 Feb 2023 11:56:23 +0100
- Subject: [PATCH 05/42] thermal/drivers/mediatek: Relocate driver to mediatek
- folder
- Add MediaTek proprietary folder to upstream more thermal zone and cooler
- drivers, relocate the original thermal controller driver to it, and rename it
- as "auxadc_thermal.c" to show its purpose more clearly.
- Signed-off-by: Balsam CHIHI <[email protected]>
- Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Daniel Lezcano <[email protected]>
- Signed-off-by: Rafael J. Wysocki <[email protected]>
- ---
- drivers/thermal/Kconfig | 14 ++++---------
- drivers/thermal/Makefile | 2 +-
- drivers/thermal/mediatek/Kconfig | 21 +++++++++++++++++++
- drivers/thermal/mediatek/Makefile | 1 +
- .../auxadc_thermal.c} | 2 +-
- 5 files changed, 28 insertions(+), 12 deletions(-)
- create mode 100644 drivers/thermal/mediatek/Kconfig
- create mode 100644 drivers/thermal/mediatek/Makefile
- rename drivers/thermal/{mtk_thermal.c => mediatek/auxadc_thermal.c} (99%)
- --- a/drivers/thermal/Kconfig
- +++ b/drivers/thermal/Kconfig
- @@ -412,16 +412,10 @@ config DA9062_THERMAL
- zone.
- Compatible with the DA9062 and DA9061 PMICs.
-
- -config MTK_THERMAL
- - tristate "Temperature sensor driver for mediatek SoCs"
- - depends on ARCH_MEDIATEK || COMPILE_TEST
- - depends on HAS_IOMEM
- - depends on NVMEM || NVMEM=n
- - depends on RESET_CONTROLLER
- - default y
- - help
- - Enable this option if you want to have support for thermal management
- - controller present in Mediatek SoCs
- +menu "Mediatek thermal drivers"
- +depends on ARCH_MEDIATEK || COMPILE_TEST
- +source "drivers/thermal/mediatek/Kconfig"
- +endmenu
-
- config AMLOGIC_THERMAL
- tristate "Amlogic Thermal Support"
- --- a/drivers/thermal/Makefile
- +++ b/drivers/thermal/Makefile
- @@ -55,7 +55,7 @@ obj-y += st/
- obj-y += qcom/
- obj-y += tegra/
- obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
- -obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
- +obj-y += mediatek/
- obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
- obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
- obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
- --- /dev/null
- +++ b/drivers/thermal/mediatek/Kconfig
- @@ -0,0 +1,21 @@
- +config MTK_THERMAL
- + tristate "MediaTek thermal drivers"
- + depends on THERMAL_OF
- + help
- + This is the option for MediaTek thermal software solutions.
- + Please enable corresponding options to get temperature
- + information from thermal sensors or turn on throttle
- + mechaisms for thermal mitigation.
- +
- +if MTK_THERMAL
- +
- +config MTK_SOC_THERMAL
- + tristate "AUXADC temperature sensor driver for MediaTek SoCs"
- + depends on HAS_IOMEM
- + help
- + Enable this option if you want to get SoC temperature
- + information for MediaTek platforms.
- + This driver configures thermal controllers to collect
- + temperature via AUXADC interface.
- +
- +endif
- --- /dev/null
- +++ b/drivers/thermal/mediatek/Makefile
- @@ -0,0 +1 @@
- +obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
- --- a/drivers/thermal/mtk_thermal.c
- +++ /dev/null
- @@ -1,1254 +0,0 @@
- -// SPDX-License-Identifier: GPL-2.0-only
- -/*
- - * Copyright (c) 2015 MediaTek Inc.
- - * Author: Hanyi Wu <[email protected]>
- - * Sascha Hauer <[email protected]>
- - * Dawei Chien <[email protected]>
- - * Louis Yu <[email protected]>
- - */
- -
- -#include <linux/clk.h>
- -#include <linux/delay.h>
- -#include <linux/interrupt.h>
- -#include <linux/kernel.h>
- -#include <linux/module.h>
- -#include <linux/nvmem-consumer.h>
- -#include <linux/of.h>
- -#include <linux/of_address.h>
- -#include <linux/of_device.h>
- -#include <linux/platform_device.h>
- -#include <linux/slab.h>
- -#include <linux/io.h>
- -#include <linux/thermal.h>
- -#include <linux/reset.h>
- -#include <linux/types.h>
- -
- -#include "thermal_hwmon.h"
- -
- -/* AUXADC Registers */
- -#define AUXADC_CON1_SET_V 0x008
- -#define AUXADC_CON1_CLR_V 0x00c
- -#define AUXADC_CON2_V 0x010
- -#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
- -
- -#define APMIXED_SYS_TS_CON1 0x604
- -
- -/* Thermal Controller Registers */
- -#define TEMP_MONCTL0 0x000
- -#define TEMP_MONCTL1 0x004
- -#define TEMP_MONCTL2 0x008
- -#define TEMP_MONIDET0 0x014
- -#define TEMP_MONIDET1 0x018
- -#define TEMP_MSRCTL0 0x038
- -#define TEMP_MSRCTL1 0x03c
- -#define TEMP_AHBPOLL 0x040
- -#define TEMP_AHBTO 0x044
- -#define TEMP_ADCPNP0 0x048
- -#define TEMP_ADCPNP1 0x04c
- -#define TEMP_ADCPNP2 0x050
- -#define TEMP_ADCPNP3 0x0b4
- -
- -#define TEMP_ADCMUX 0x054
- -#define TEMP_ADCEN 0x060
- -#define TEMP_PNPMUXADDR 0x064
- -#define TEMP_ADCMUXADDR 0x068
- -#define TEMP_ADCENADDR 0x074
- -#define TEMP_ADCVALIDADDR 0x078
- -#define TEMP_ADCVOLTADDR 0x07c
- -#define TEMP_RDCTRL 0x080
- -#define TEMP_ADCVALIDMASK 0x084
- -#define TEMP_ADCVOLTAGESHIFT 0x088
- -#define TEMP_ADCWRITECTRL 0x08c
- -#define TEMP_MSR0 0x090
- -#define TEMP_MSR1 0x094
- -#define TEMP_MSR2 0x098
- -#define TEMP_MSR3 0x0B8
- -
- -#define TEMP_SPARE0 0x0f0
- -
- -#define TEMP_ADCPNP0_1 0x148
- -#define TEMP_ADCPNP1_1 0x14c
- -#define TEMP_ADCPNP2_1 0x150
- -#define TEMP_MSR0_1 0x190
- -#define TEMP_MSR1_1 0x194
- -#define TEMP_MSR2_1 0x198
- -#define TEMP_ADCPNP3_1 0x1b4
- -#define TEMP_MSR3_1 0x1B8
- -
- -#define PTPCORESEL 0x400
- -
- -#define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff)
- -
- -#define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16)
- -#define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff)
- -
- -#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x)
- -
- -#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0)
- -#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1)
- -
- -#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
- -#define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
- -
- -/* MT8173 thermal sensors */
- -#define MT8173_TS1 0
- -#define MT8173_TS2 1
- -#define MT8173_TS3 2
- -#define MT8173_TS4 3
- -#define MT8173_TSABB 4
- -
- -/* AUXADC channel 11 is used for the temperature sensors */
- -#define MT8173_TEMP_AUXADC_CHANNEL 11
- -
- -/* The total number of temperature sensors in the MT8173 */
- -#define MT8173_NUM_SENSORS 5
- -
- -/* The number of banks in the MT8173 */
- -#define MT8173_NUM_ZONES 4
- -
- -/* The number of sensing points per bank */
- -#define MT8173_NUM_SENSORS_PER_ZONE 4
- -
- -/* The number of controller in the MT8173 */
- -#define MT8173_NUM_CONTROLLER 1
- -
- -/* The calibration coefficient of sensor */
- -#define MT8173_CALIBRATION 165
- -
- -/*
- - * Layout of the fuses providing the calibration data
- - * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
- - * MT8183 has 6 sensors and needs 6 VTS calibration data.
- - * MT8173 has 5 sensors and needs 5 VTS calibration data.
- - * MT2701 has 3 sensors and needs 3 VTS calibration data.
- - * MT2712 has 4 sensors and needs 4 VTS calibration data.
- - */
- -#define CALIB_BUF0_VALID_V1 BIT(0)
- -#define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
- -#define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
- -#define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
- -#define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
- -#define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
- -#define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
- -#define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
- -#define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
- -#define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
- -#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
- -#define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
- -
- -/*
- - * Layout of the fuses providing the calibration data
- - * These macros could be used for MT7622.
- - */
- -#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff)
- -#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff)
- -#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f)
- -#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f)
- -#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff)
- -#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff)
- -#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff)
- -#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
- -#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
- -
- -/*
- - * Layout of the fuses providing the calibration data
- - * These macros can be used for MT7981 and MT7986.
- - */
- -#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
- -#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
- -#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
- -#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
- -#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
- -#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
- -#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
- -#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
- -#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
- -
- -enum {
- - VTS1,
- - VTS2,
- - VTS3,
- - VTS4,
- - VTS5,
- - VTSABB,
- - MAX_NUM_VTS,
- -};
- -
- -enum mtk_thermal_version {
- - MTK_THERMAL_V1 = 1,
- - MTK_THERMAL_V2,
- - MTK_THERMAL_V3,
- -};
- -
- -/* MT2701 thermal sensors */
- -#define MT2701_TS1 0
- -#define MT2701_TS2 1
- -#define MT2701_TSABB 2
- -
- -/* AUXADC channel 11 is used for the temperature sensors */
- -#define MT2701_TEMP_AUXADC_CHANNEL 11
- -
- -/* The total number of temperature sensors in the MT2701 */
- -#define MT2701_NUM_SENSORS 3
- -
- -/* The number of sensing points per bank */
- -#define MT2701_NUM_SENSORS_PER_ZONE 3
- -
- -/* The number of controller in the MT2701 */
- -#define MT2701_NUM_CONTROLLER 1
- -
- -/* The calibration coefficient of sensor */
- -#define MT2701_CALIBRATION 165
- -
- -/* MT2712 thermal sensors */
- -#define MT2712_TS1 0
- -#define MT2712_TS2 1
- -#define MT2712_TS3 2
- -#define MT2712_TS4 3
- -
- -/* AUXADC channel 11 is used for the temperature sensors */
- -#define MT2712_TEMP_AUXADC_CHANNEL 11
- -
- -/* The total number of temperature sensors in the MT2712 */
- -#define MT2712_NUM_SENSORS 4
- -
- -/* The number of sensing points per bank */
- -#define MT2712_NUM_SENSORS_PER_ZONE 4
- -
- -/* The number of controller in the MT2712 */
- -#define MT2712_NUM_CONTROLLER 1
- -
- -/* The calibration coefficient of sensor */
- -#define MT2712_CALIBRATION 165
- -
- -#define MT7622_TEMP_AUXADC_CHANNEL 11
- -#define MT7622_NUM_SENSORS 1
- -#define MT7622_NUM_ZONES 1
- -#define MT7622_NUM_SENSORS_PER_ZONE 1
- -#define MT7622_TS1 0
- -#define MT7622_NUM_CONTROLLER 1
- -
- -/* The maximum number of banks */
- -#define MAX_NUM_ZONES 8
- -
- -/* The calibration coefficient of sensor */
- -#define MT7622_CALIBRATION 165
- -
- -/* MT8183 thermal sensors */
- -#define MT8183_TS1 0
- -#define MT8183_TS2 1
- -#define MT8183_TS3 2
- -#define MT8183_TS4 3
- -#define MT8183_TS5 4
- -#define MT8183_TSABB 5
- -
- -/* AUXADC channel is used for the temperature sensors */
- -#define MT8183_TEMP_AUXADC_CHANNEL 11
- -
- -/* The total number of temperature sensors in the MT8183 */
- -#define MT8183_NUM_SENSORS 6
- -
- -/* The number of banks in the MT8183 */
- -#define MT8183_NUM_ZONES 1
- -
- -/* The number of sensing points per bank */
- -#define MT8183_NUM_SENSORS_PER_ZONE 6
- -
- -/* The number of controller in the MT8183 */
- -#define MT8183_NUM_CONTROLLER 2
- -
- -/* The calibration coefficient of sensor */
- -#define MT8183_CALIBRATION 153
- -
- -/* AUXADC channel 11 is used for the temperature sensors */
- -#define MT7986_TEMP_AUXADC_CHANNEL 11
- -
- -/* The total number of temperature sensors in the MT7986 */
- -#define MT7986_NUM_SENSORS 1
- -
- -/* The number of banks in the MT7986 */
- -#define MT7986_NUM_ZONES 1
- -
- -/* The number of sensing points per bank */
- -#define MT7986_NUM_SENSORS_PER_ZONE 1
- -
- -/* MT7986 thermal sensors */
- -#define MT7986_TS1 0
- -
- -/* The number of controller in the MT7986 */
- -#define MT7986_NUM_CONTROLLER 1
- -
- -/* The calibration coefficient of sensor */
- -#define MT7986_CALIBRATION 165
- -
- -struct mtk_thermal;
- -
- -struct thermal_bank_cfg {
- - unsigned int num_sensors;
- - const int *sensors;
- -};
- -
- -struct mtk_thermal_bank {
- - struct mtk_thermal *mt;
- - int id;
- -};
- -
- -struct mtk_thermal_data {
- - s32 num_banks;
- - s32 num_sensors;
- - s32 auxadc_channel;
- - const int *vts_index;
- - const int *sensor_mux_values;
- - const int *msr;
- - const int *adcpnp;
- - const int cali_val;
- - const int num_controller;
- - const int *controller_offset;
- - bool need_switch_bank;
- - struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
- - enum mtk_thermal_version version;
- -};
- -
- -struct mtk_thermal {
- - struct device *dev;
- - void __iomem *thermal_base;
- -
- - struct clk *clk_peri_therm;
- - struct clk *clk_auxadc;
- - /* lock: for getting and putting banks */
- - struct mutex lock;
- -
- - /* Calibration values */
- - s32 adc_ge;
- - s32 adc_oe;
- - s32 degc_cali;
- - s32 o_slope;
- - s32 o_slope_sign;
- - s32 vts[MAX_NUM_VTS];
- -
- - const struct mtk_thermal_data *conf;
- - struct mtk_thermal_bank banks[MAX_NUM_ZONES];
- -
- - int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
- -};
- -
- -/* MT8183 thermal sensor data */
- -static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
- - MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
- -};
- -
- -static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
- - TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
- -};
- -
- -static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
- - TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
- - TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
- -};
- -
- -static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
- -static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
- -
- -static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
- - VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
- -};
- -
- -/* MT8173 thermal sensor data */
- -static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
- - { MT8173_TS2, MT8173_TS3 },
- - { MT8173_TS2, MT8173_TS4 },
- - { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
- - { MT8173_TS2 },
- -};
- -
- -static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
- - TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
- -};
- -
- -static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
- - TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
- -};
- -
- -static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
- -static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
- -
- -static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
- - VTS1, VTS2, VTS3, VTS4, VTSABB
- -};
- -
- -/* MT2701 thermal sensor data */
- -static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
- - MT2701_TS1, MT2701_TS2, MT2701_TSABB
- -};
- -
- -static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
- - TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
- -};
- -
- -static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
- - TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
- -};
- -
- -static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
- -static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
- -
- -static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
- - VTS1, VTS2, VTS3
- -};
- -
- -/* MT2712 thermal sensor data */
- -static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
- - MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
- -};
- -
- -static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
- - TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
- -};
- -
- -static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
- - TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
- -};
- -
- -static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
- -static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
- -
- -static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
- - VTS1, VTS2, VTS3, VTS4
- -};
- -
- -/* MT7622 thermal sensor data */
- -static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
- -static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
- -static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
- -static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
- -static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
- -static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
- -
- -/* MT7986 thermal sensor data */
- -static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
- -static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
- -static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
- -static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
- -static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
- -static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
- -
- -/*
- - * The MT8173 thermal controller has four banks. Each bank can read up to
- - * four temperature sensors simultaneously. The MT8173 has a total of 5
- - * temperature sensors. We use each bank to measure a certain area of the
- - * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
- - * areas, hence is used in different banks.
- - *
- - * The thermal core only gets the maximum temperature of all banks, so
- - * the bank concept wouldn't be necessary here. However, the SVS (Smart
- - * Voltage Scaling) unit makes its decisions based on the same bank
- - * data, and this indeed needs the temperatures of the individual banks
- - * for making better decisions.
- - */
- -static const struct mtk_thermal_data mt8173_thermal_data = {
- - .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
- - .num_banks = MT8173_NUM_ZONES,
- - .num_sensors = MT8173_NUM_SENSORS,
- - .vts_index = mt8173_vts_index,
- - .cali_val = MT8173_CALIBRATION,
- - .num_controller = MT8173_NUM_CONTROLLER,
- - .controller_offset = mt8173_tc_offset,
- - .need_switch_bank = true,
- - .bank_data = {
- - {
- - .num_sensors = 2,
- - .sensors = mt8173_bank_data[0],
- - }, {
- - .num_sensors = 2,
- - .sensors = mt8173_bank_data[1],
- - }, {
- - .num_sensors = 3,
- - .sensors = mt8173_bank_data[2],
- - }, {
- - .num_sensors = 1,
- - .sensors = mt8173_bank_data[3],
- - },
- - },
- - .msr = mt8173_msr,
- - .adcpnp = mt8173_adcpnp,
- - .sensor_mux_values = mt8173_mux_values,
- - .version = MTK_THERMAL_V1,
- -};
- -
- -/*
- - * The MT2701 thermal controller has one bank, which can read up to
- - * three temperature sensors simultaneously. The MT2701 has a total of 3
- - * temperature sensors.
- - *
- - * The thermal core only gets the maximum temperature of this one bank,
- - * so the bank concept wouldn't be necessary here. However, the SVS (Smart
- - * Voltage Scaling) unit makes its decisions based on the same bank
- - * data.
- - */
- -static const struct mtk_thermal_data mt2701_thermal_data = {
- - .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
- - .num_banks = 1,
- - .num_sensors = MT2701_NUM_SENSORS,
- - .vts_index = mt2701_vts_index,
- - .cali_val = MT2701_CALIBRATION,
- - .num_controller = MT2701_NUM_CONTROLLER,
- - .controller_offset = mt2701_tc_offset,
- - .need_switch_bank = true,
- - .bank_data = {
- - {
- - .num_sensors = 3,
- - .sensors = mt2701_bank_data,
- - },
- - },
- - .msr = mt2701_msr,
- - .adcpnp = mt2701_adcpnp,
- - .sensor_mux_values = mt2701_mux_values,
- - .version = MTK_THERMAL_V1,
- -};
- -
- -/*
- - * The MT2712 thermal controller has one bank, which can read up to
- - * four temperature sensors simultaneously. The MT2712 has a total of 4
- - * temperature sensors.
- - *
- - * The thermal core only gets the maximum temperature of this one bank,
- - * so the bank concept wouldn't be necessary here. However, the SVS (Smart
- - * Voltage Scaling) unit makes its decisions based on the same bank
- - * data.
- - */
- -static const struct mtk_thermal_data mt2712_thermal_data = {
- - .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
- - .num_banks = 1,
- - .num_sensors = MT2712_NUM_SENSORS,
- - .vts_index = mt2712_vts_index,
- - .cali_val = MT2712_CALIBRATION,
- - .num_controller = MT2712_NUM_CONTROLLER,
- - .controller_offset = mt2712_tc_offset,
- - .need_switch_bank = true,
- - .bank_data = {
- - {
- - .num_sensors = 4,
- - .sensors = mt2712_bank_data,
- - },
- - },
- - .msr = mt2712_msr,
- - .adcpnp = mt2712_adcpnp,
- - .sensor_mux_values = mt2712_mux_values,
- - .version = MTK_THERMAL_V1,
- -};
- -
- -/*
- - * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
- - * access.
- - */
- -static const struct mtk_thermal_data mt7622_thermal_data = {
- - .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
- - .num_banks = MT7622_NUM_ZONES,
- - .num_sensors = MT7622_NUM_SENSORS,
- - .vts_index = mt7622_vts_index,
- - .cali_val = MT7622_CALIBRATION,
- - .num_controller = MT7622_NUM_CONTROLLER,
- - .controller_offset = mt7622_tc_offset,
- - .need_switch_bank = true,
- - .bank_data = {
- - {
- - .num_sensors = 1,
- - .sensors = mt7622_bank_data,
- - },
- - },
- - .msr = mt7622_msr,
- - .adcpnp = mt7622_adcpnp,
- - .sensor_mux_values = mt7622_mux_values,
- - .version = MTK_THERMAL_V2,
- -};
- -
- -/*
- - * The MT8183 thermal controller has one bank for the current SW framework.
- - * The MT8183 has a total of 6 temperature sensors.
- - * There are two thermal controller to control the six sensor.
- - * The first one bind 2 sensor, and the other bind 4 sensors.
- - * The thermal core only gets the maximum temperature of all sensor, so
- - * the bank concept wouldn't be necessary here. However, the SVS (Smart
- - * Voltage Scaling) unit makes its decisions based on the same bank
- - * data, and this indeed needs the temperatures of the individual banks
- - * for making better decisions.
- - */
- -static const struct mtk_thermal_data mt8183_thermal_data = {
- - .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
- - .num_banks = MT8183_NUM_ZONES,
- - .num_sensors = MT8183_NUM_SENSORS,
- - .vts_index = mt8183_vts_index,
- - .cali_val = MT8183_CALIBRATION,
- - .num_controller = MT8183_NUM_CONTROLLER,
- - .controller_offset = mt8183_tc_offset,
- - .need_switch_bank = false,
- - .bank_data = {
- - {
- - .num_sensors = 6,
- - .sensors = mt8183_bank_data,
- - },
- - },
- -
- - .msr = mt8183_msr,
- - .adcpnp = mt8183_adcpnp,
- - .sensor_mux_values = mt8183_mux_values,
- - .version = MTK_THERMAL_V1,
- -};
- -
- -/*
- - * MT7986 uses AUXADC Channel 11 for raw data access.
- - */
- -static const struct mtk_thermal_data mt7986_thermal_data = {
- - .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
- - .num_banks = MT7986_NUM_ZONES,
- - .num_sensors = MT7986_NUM_SENSORS,
- - .vts_index = mt7986_vts_index,
- - .cali_val = MT7986_CALIBRATION,
- - .num_controller = MT7986_NUM_CONTROLLER,
- - .controller_offset = mt7986_tc_offset,
- - .need_switch_bank = true,
- - .bank_data = {
- - {
- - .num_sensors = 1,
- - .sensors = mt7986_bank_data,
- - },
- - },
- - .msr = mt7986_msr,
- - .adcpnp = mt7986_adcpnp,
- - .sensor_mux_values = mt7986_mux_values,
- - .version = MTK_THERMAL_V3,
- -};
- -
- -/**
- - * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
- - * @mt: The thermal controller
- - * @sensno: sensor number
- - * @raw: raw ADC value
- - *
- - * This converts the raw ADC value to mcelsius using the SoC specific
- - * calibration constants
- - */
- -static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
- -{
- - s32 tmp;
- -
- - raw &= 0xfff;
- -
- - tmp = 203450520 << 3;
- - tmp /= mt->conf->cali_val + mt->o_slope;
- - tmp /= 10000 + mt->adc_ge;
- - tmp *= raw - mt->vts[sensno] - 3350;
- - tmp >>= 3;
- -
- - return mt->degc_cali * 500 - tmp;
- -}
- -
- -static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
- -{
- - s32 format_1;
- - s32 format_2;
- - s32 g_oe;
- - s32 g_gain;
- - s32 g_x_roomt;
- - s32 tmp;
- -
- - if (raw == 0)
- - return 0;
- -
- - raw &= 0xfff;
- - g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
- - g_oe = mt->adc_oe - 512;
- - format_1 = mt->vts[VTS2] + 3105 - g_oe;
- - format_2 = (mt->degc_cali * 10) >> 1;
- - g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
- -
- - tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
- - tmp = tmp * 10 * 100 / 11;
- -
- - if (mt->o_slope_sign == 0)
- - tmp = tmp / (165 - mt->o_slope);
- - else
- - tmp = tmp / (165 + mt->o_slope);
- -
- - return (format_2 - tmp) * 100;
- -}
- -
- -static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
- -{
- - s32 tmp;
- -
- - if (raw == 0)
- - return 0;
- -
- - raw &= 0xfff;
- - tmp = 100000 * 15 / 16 * 10000;
- - tmp /= 4096 - 512 + mt->adc_ge;
- - tmp /= 1490;
- - tmp *= raw - mt->vts[sensno] - 2900;
- -
- - return mt->degc_cali * 500 - tmp;
- -}
- -
- -/**
- - * mtk_thermal_get_bank - get bank
- - * @bank: The bank
- - *
- - * The bank registers are banked, we have to select a bank in the
- - * PTPCORESEL register to access it.
- - */
- -static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
- -{
- - struct mtk_thermal *mt = bank->mt;
- - u32 val;
- -
- - if (mt->conf->need_switch_bank) {
- - mutex_lock(&mt->lock);
- -
- - val = readl(mt->thermal_base + PTPCORESEL);
- - val &= ~0xf;
- - val |= bank->id;
- - writel(val, mt->thermal_base + PTPCORESEL);
- - }
- -}
- -
- -/**
- - * mtk_thermal_put_bank - release bank
- - * @bank: The bank
- - *
- - * release a bank previously taken with mtk_thermal_get_bank,
- - */
- -static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
- -{
- - struct mtk_thermal *mt = bank->mt;
- -
- - if (mt->conf->need_switch_bank)
- - mutex_unlock(&mt->lock);
- -}
- -
- -/**
- - * mtk_thermal_bank_temperature - get the temperature of a bank
- - * @bank: The bank
- - *
- - * The temperature of a bank is considered the maximum temperature of
- - * the sensors associated to the bank.
- - */
- -static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
- -{
- - struct mtk_thermal *mt = bank->mt;
- - const struct mtk_thermal_data *conf = mt->conf;
- - int i, temp = INT_MIN, max = INT_MIN;
- - u32 raw;
- -
- - for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
- - raw = readl(mt->thermal_base + conf->msr[i]);
- -
- - temp = mt->raw_to_mcelsius(
- - mt, conf->bank_data[bank->id].sensors[i], raw);
- -
- -
- - /*
- - * The first read of a sensor often contains very high bogus
- - * temperature value. Filter these out so that the system does
- - * not immediately shut down.
- - */
- - if (temp > 200000)
- - temp = 0;
- -
- - if (temp > max)
- - max = temp;
- - }
- -
- - return max;
- -}
- -
- -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
- -{
- - struct mtk_thermal *mt = tz->devdata;
- - int i;
- - int tempmax = INT_MIN;
- -
- - for (i = 0; i < mt->conf->num_banks; i++) {
- - struct mtk_thermal_bank *bank = &mt->banks[i];
- -
- - mtk_thermal_get_bank(bank);
- -
- - tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
- -
- - mtk_thermal_put_bank(bank);
- - }
- -
- - *temperature = tempmax;
- -
- - return 0;
- -}
- -
- -static const struct thermal_zone_device_ops mtk_thermal_ops = {
- - .get_temp = mtk_read_temp,
- -};
- -
- -static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
- - u32 apmixed_phys_base, u32 auxadc_phys_base,
- - int ctrl_id)
- -{
- - struct mtk_thermal_bank *bank = &mt->banks[num];
- - const struct mtk_thermal_data *conf = mt->conf;
- - int i;
- -
- - int offset = mt->conf->controller_offset[ctrl_id];
- - void __iomem *controller_base = mt->thermal_base + offset;
- -
- - bank->id = num;
- - bank->mt = mt;
- -
- - mtk_thermal_get_bank(bank);
- -
- - /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
- - writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
- -
- - /*
- - * filt interval is 1 * 46.540us = 46.54us,
- - * sen interval is 429 * 46.540us = 19.96ms
- - */
- - writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
- - TEMP_MONCTL2_SENSOR_INTERVAL(429),
- - controller_base + TEMP_MONCTL2);
- -
- - /* poll is set to 10u */
- - writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
- - controller_base + TEMP_AHBPOLL);
- -
- - /* temperature sampling control, 1 sample */
- - writel(0x0, controller_base + TEMP_MSRCTL0);
- -
- - /* exceed this polling time, IRQ would be inserted */
- - writel(0xffffffff, controller_base + TEMP_AHBTO);
- -
- - /* number of interrupts per event, 1 is enough */
- - writel(0x0, controller_base + TEMP_MONIDET0);
- - writel(0x0, controller_base + TEMP_MONIDET1);
- -
- - /*
- - * The MT8173 thermal controller does not have its own ADC. Instead it
- - * uses AHB bus accesses to control the AUXADC. To do this the thermal
- - * controller has to be programmed with the physical addresses of the
- - * AUXADC registers and with the various bit positions in the AUXADC.
- - * Also the thermal controller controls a mux in the APMIXEDSYS register
- - * space.
- - */
- -
- - /*
- - * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
- - * automatically by hw
- - */
- - writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
- -
- - /* AHB address for auxadc mux selection */
- - writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
- - controller_base + TEMP_ADCMUXADDR);
- -
- - if (mt->conf->version == MTK_THERMAL_V1) {
- - /* AHB address for pnp sensor mux selection */
- - writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
- - controller_base + TEMP_PNPMUXADDR);
- - }
- -
- - /* AHB value for auxadc enable */
- - writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
- -
- - /* AHB address for auxadc enable (channel 0 immediate mode selected) */
- - writel(auxadc_phys_base + AUXADC_CON1_SET_V,
- - controller_base + TEMP_ADCENADDR);
- -
- - /* AHB address for auxadc valid bit */
- - writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
- - controller_base + TEMP_ADCVALIDADDR);
- -
- - /* AHB address for auxadc voltage output */
- - writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
- - controller_base + TEMP_ADCVOLTADDR);
- -
- - /* read valid & voltage are at the same register */
- - writel(0x0, controller_base + TEMP_RDCTRL);
- -
- - /* indicate where the valid bit is */
- - writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
- - controller_base + TEMP_ADCVALIDMASK);
- -
- - /* no shift */
- - writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
- -
- - /* enable auxadc mux write transaction */
- - writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
- - controller_base + TEMP_ADCWRITECTRL);
- -
- - for (i = 0; i < conf->bank_data[num].num_sensors; i++)
- - writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
- - mt->thermal_base + conf->adcpnp[i]);
- -
- - writel((1 << conf->bank_data[num].num_sensors) - 1,
- - controller_base + TEMP_MONCTL0);
- -
- - writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
- - TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
- - controller_base + TEMP_ADCWRITECTRL);
- -
- - mtk_thermal_put_bank(bank);
- -}
- -
- -static u64 of_get_phys_base(struct device_node *np)
- -{
- - u64 size64;
- - const __be32 *regaddr_p;
- -
- - regaddr_p = of_get_address(np, 0, &size64, NULL);
- - if (!regaddr_p)
- - return OF_BAD_ADDR;
- -
- - return of_translate_address(np, regaddr_p);
- -}
- -
- -static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
- -{
- - int i;
- -
- - if (!(buf[0] & CALIB_BUF0_VALID_V1))
- - return -EINVAL;
- -
- - mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
- -
- - for (i = 0; i < mt->conf->num_sensors; i++) {
- - switch (mt->conf->vts_index[i]) {
- - case VTS1:
- - mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
- - break;
- - case VTS2:
- - mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
- - break;
- - case VTS3:
- - mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
- - break;
- - case VTS4:
- - mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
- - break;
- - case VTS5:
- - mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
- - break;
- - case VTSABB:
- - mt->vts[VTSABB] =
- - CALIB_BUF2_VTS_TSABB_V1(buf[2]);
- - break;
- - default:
- - break;
- - }
- - }
- -
- - mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
- - if (CALIB_BUF1_ID_V1(buf[1]) &
- - CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
- - mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
- - else
- - mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
- -
- - return 0;
- -}
- -
- -static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
- -{
- - if (!CALIB_BUF1_VALID_V2(buf[1]))
- - return -EINVAL;
- -
- - mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
- - mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
- - mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
- - mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
- - mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
- - mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
- - mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
- - mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
- -
- - return 0;
- -}
- -
- -static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
- -{
- - if (!CALIB_BUF1_VALID_V3(buf[1]))
- - return -EINVAL;
- -
- - mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
- - mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
- - mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
- - mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
- - mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
- - mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
- - mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
- -
- - if (CALIB_BUF1_ID_V3(buf[1]) == 0)
- - mt->o_slope = 0;
- -
- - return 0;
- -}
- -
- -static int mtk_thermal_get_calibration_data(struct device *dev,
- - struct mtk_thermal *mt)
- -{
- - struct nvmem_cell *cell;
- - u32 *buf;
- - size_t len;
- - int i, ret = 0;
- -
- - /* Start with default values */
- - mt->adc_ge = 512;
- - mt->adc_oe = 512;
- - for (i = 0; i < mt->conf->num_sensors; i++)
- - mt->vts[i] = 260;
- - mt->degc_cali = 40;
- - mt->o_slope = 0;
- -
- - cell = nvmem_cell_get(dev, "calibration-data");
- - if (IS_ERR(cell)) {
- - if (PTR_ERR(cell) == -EPROBE_DEFER)
- - return PTR_ERR(cell);
- - return 0;
- - }
- -
- - buf = (u32 *)nvmem_cell_read(cell, &len);
- -
- - nvmem_cell_put(cell);
- -
- - if (IS_ERR(buf))
- - return PTR_ERR(buf);
- -
- - if (len < 3 * sizeof(u32)) {
- - dev_warn(dev, "invalid calibration data\n");
- - ret = -EINVAL;
- - goto out;
- - }
- -
- - switch (mt->conf->version) {
- - case MTK_THERMAL_V1:
- - ret = mtk_thermal_extract_efuse_v1(mt, buf);
- - break;
- - case MTK_THERMAL_V2:
- - ret = mtk_thermal_extract_efuse_v2(mt, buf);
- - break;
- - case MTK_THERMAL_V3:
- - ret = mtk_thermal_extract_efuse_v3(mt, buf);
- - break;
- - default:
- - ret = -EINVAL;
- - break;
- - }
- -
- - if (ret) {
- - dev_info(dev, "Device not calibrated, using default calibration values\n");
- - ret = 0;
- - }
- -
- -out:
- - kfree(buf);
- -
- - return ret;
- -}
- -
- -static const struct of_device_id mtk_thermal_of_match[] = {
- - {
- - .compatible = "mediatek,mt8173-thermal",
- - .data = (void *)&mt8173_thermal_data,
- - },
- - {
- - .compatible = "mediatek,mt2701-thermal",
- - .data = (void *)&mt2701_thermal_data,
- - },
- - {
- - .compatible = "mediatek,mt2712-thermal",
- - .data = (void *)&mt2712_thermal_data,
- - },
- - {
- - .compatible = "mediatek,mt7622-thermal",
- - .data = (void *)&mt7622_thermal_data,
- - },
- - {
- - .compatible = "mediatek,mt7986-thermal",
- - .data = (void *)&mt7986_thermal_data,
- - },
- - {
- - .compatible = "mediatek,mt8183-thermal",
- - .data = (void *)&mt8183_thermal_data,
- - }, {
- - },
- -};
- -MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
- -
- -static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
- -{
- - int tmp;
- -
- - tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
- - tmp &= ~(0x37);
- - tmp |= 0x1;
- - writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
- - udelay(200);
- -}
- -
- -static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
- - void __iomem *auxadc_base)
- -{
- - int tmp;
- -
- - writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
- - writel(0x1, mt->thermal_base + TEMP_MONCTL0);
- - tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
- - writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
- -}
- -
- -static int mtk_thermal_probe(struct platform_device *pdev)
- -{
- - int ret, i, ctrl_id;
- - struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
- - struct mtk_thermal *mt;
- - u64 auxadc_phys_base, apmixed_phys_base;
- - struct thermal_zone_device *tzdev;
- - void __iomem *apmixed_base, *auxadc_base;
- -
- - mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
- - if (!mt)
- - return -ENOMEM;
- -
- - mt->conf = of_device_get_match_data(&pdev->dev);
- -
- - mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
- - if (IS_ERR(mt->clk_peri_therm))
- - return PTR_ERR(mt->clk_peri_therm);
- -
- - mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
- - if (IS_ERR(mt->clk_auxadc))
- - return PTR_ERR(mt->clk_auxadc);
- -
- - mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- - if (IS_ERR(mt->thermal_base))
- - return PTR_ERR(mt->thermal_base);
- -
- - ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
- - if (ret)
- - return ret;
- -
- - mutex_init(&mt->lock);
- -
- - mt->dev = &pdev->dev;
- -
- - auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
- - if (!auxadc) {
- - dev_err(&pdev->dev, "missing auxadc node\n");
- - return -ENODEV;
- - }
- -
- - auxadc_base = of_iomap(auxadc, 0);
- - auxadc_phys_base = of_get_phys_base(auxadc);
- -
- - of_node_put(auxadc);
- -
- - if (auxadc_phys_base == OF_BAD_ADDR) {
- - dev_err(&pdev->dev, "Can't get auxadc phys address\n");
- - return -EINVAL;
- - }
- -
- - apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
- - if (!apmixedsys) {
- - dev_err(&pdev->dev, "missing apmixedsys node\n");
- - return -ENODEV;
- - }
- -
- - apmixed_base = of_iomap(apmixedsys, 0);
- - apmixed_phys_base = of_get_phys_base(apmixedsys);
- -
- - of_node_put(apmixedsys);
- -
- - if (apmixed_phys_base == OF_BAD_ADDR) {
- - dev_err(&pdev->dev, "Can't get auxadc phys address\n");
- - return -EINVAL;
- - }
- -
- - ret = device_reset_optional(&pdev->dev);
- - if (ret)
- - return ret;
- -
- - ret = clk_prepare_enable(mt->clk_auxadc);
- - if (ret) {
- - dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
- - return ret;
- - }
- -
- - ret = clk_prepare_enable(mt->clk_peri_therm);
- - if (ret) {
- - dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
- - goto err_disable_clk_auxadc;
- - }
- -
- - if (mt->conf->version != MTK_THERMAL_V1) {
- - mtk_thermal_turn_on_buffer(apmixed_base);
- - mtk_thermal_release_periodic_ts(mt, auxadc_base);
- - }
- -
- - if (mt->conf->version == MTK_THERMAL_V1)
- - mt->raw_to_mcelsius = raw_to_mcelsius_v1;
- - else if (mt->conf->version == MTK_THERMAL_V2)
- - mt->raw_to_mcelsius = raw_to_mcelsius_v2;
- - else
- - mt->raw_to_mcelsius = raw_to_mcelsius_v3;
- -
- - for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
- - for (i = 0; i < mt->conf->num_banks; i++)
- - mtk_thermal_init_bank(mt, i, apmixed_phys_base,
- - auxadc_phys_base, ctrl_id);
- -
- - platform_set_drvdata(pdev, mt);
- -
- - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- - &mtk_thermal_ops);
- - if (IS_ERR(tzdev)) {
- - ret = PTR_ERR(tzdev);
- - goto err_disable_clk_peri_therm;
- - }
- -
- - ret = devm_thermal_add_hwmon_sysfs(tzdev);
- - if (ret)
- - dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
- -
- - return 0;
- -
- -err_disable_clk_peri_therm:
- - clk_disable_unprepare(mt->clk_peri_therm);
- -err_disable_clk_auxadc:
- - clk_disable_unprepare(mt->clk_auxadc);
- -
- - return ret;
- -}
- -
- -static int mtk_thermal_remove(struct platform_device *pdev)
- -{
- - struct mtk_thermal *mt = platform_get_drvdata(pdev);
- -
- - clk_disable_unprepare(mt->clk_peri_therm);
- - clk_disable_unprepare(mt->clk_auxadc);
- -
- - return 0;
- -}
- -
- -static struct platform_driver mtk_thermal_driver = {
- - .probe = mtk_thermal_probe,
- - .remove = mtk_thermal_remove,
- - .driver = {
- - .name = "mtk-thermal",
- - .of_match_table = mtk_thermal_of_match,
- - },
- -};
- -
- -module_platform_driver(mtk_thermal_driver);
- -
- -MODULE_AUTHOR("Michael Kao <[email protected]>");
- -MODULE_AUTHOR("Louis Yu <[email protected]>");
- -MODULE_AUTHOR("Dawei Chien <[email protected]>");
- -MODULE_AUTHOR("Sascha Hauer <[email protected]>");
- -MODULE_AUTHOR("Hanyi Wu <[email protected]>");
- -MODULE_DESCRIPTION("Mediatek thermal driver");
- -MODULE_LICENSE("GPL v2");
- --- /dev/null
- +++ b/drivers/thermal/mediatek/auxadc_thermal.c
- @@ -0,0 +1,1254 @@
- +// SPDX-License-Identifier: GPL-2.0-only
- +/*
- + * Copyright (c) 2015 MediaTek Inc.
- + * Author: Hanyi Wu <[email protected]>
- + * Sascha Hauer <[email protected]>
- + * Dawei Chien <[email protected]>
- + * Louis Yu <[email protected]>
- + */
- +
- +#include <linux/clk.h>
- +#include <linux/delay.h>
- +#include <linux/interrupt.h>
- +#include <linux/kernel.h>
- +#include <linux/module.h>
- +#include <linux/nvmem-consumer.h>
- +#include <linux/of.h>
- +#include <linux/of_address.h>
- +#include <linux/of_device.h>
- +#include <linux/platform_device.h>
- +#include <linux/slab.h>
- +#include <linux/io.h>
- +#include <linux/thermal.h>
- +#include <linux/reset.h>
- +#include <linux/types.h>
- +
- +#include "../thermal_hwmon.h"
- +
- +/* AUXADC Registers */
- +#define AUXADC_CON1_SET_V 0x008
- +#define AUXADC_CON1_CLR_V 0x00c
- +#define AUXADC_CON2_V 0x010
- +#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
- +
- +#define APMIXED_SYS_TS_CON1 0x604
- +
- +/* Thermal Controller Registers */
- +#define TEMP_MONCTL0 0x000
- +#define TEMP_MONCTL1 0x004
- +#define TEMP_MONCTL2 0x008
- +#define TEMP_MONIDET0 0x014
- +#define TEMP_MONIDET1 0x018
- +#define TEMP_MSRCTL0 0x038
- +#define TEMP_MSRCTL1 0x03c
- +#define TEMP_AHBPOLL 0x040
- +#define TEMP_AHBTO 0x044
- +#define TEMP_ADCPNP0 0x048
- +#define TEMP_ADCPNP1 0x04c
- +#define TEMP_ADCPNP2 0x050
- +#define TEMP_ADCPNP3 0x0b4
- +
- +#define TEMP_ADCMUX 0x054
- +#define TEMP_ADCEN 0x060
- +#define TEMP_PNPMUXADDR 0x064
- +#define TEMP_ADCMUXADDR 0x068
- +#define TEMP_ADCENADDR 0x074
- +#define TEMP_ADCVALIDADDR 0x078
- +#define TEMP_ADCVOLTADDR 0x07c
- +#define TEMP_RDCTRL 0x080
- +#define TEMP_ADCVALIDMASK 0x084
- +#define TEMP_ADCVOLTAGESHIFT 0x088
- +#define TEMP_ADCWRITECTRL 0x08c
- +#define TEMP_MSR0 0x090
- +#define TEMP_MSR1 0x094
- +#define TEMP_MSR2 0x098
- +#define TEMP_MSR3 0x0B8
- +
- +#define TEMP_SPARE0 0x0f0
- +
- +#define TEMP_ADCPNP0_1 0x148
- +#define TEMP_ADCPNP1_1 0x14c
- +#define TEMP_ADCPNP2_1 0x150
- +#define TEMP_MSR0_1 0x190
- +#define TEMP_MSR1_1 0x194
- +#define TEMP_MSR2_1 0x198
- +#define TEMP_ADCPNP3_1 0x1b4
- +#define TEMP_MSR3_1 0x1B8
- +
- +#define PTPCORESEL 0x400
- +
- +#define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff)
- +
- +#define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16)
- +#define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff)
- +
- +#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x)
- +
- +#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0)
- +#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1)
- +
- +#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
- +#define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
- +
- +/* MT8173 thermal sensors */
- +#define MT8173_TS1 0
- +#define MT8173_TS2 1
- +#define MT8173_TS3 2
- +#define MT8173_TS4 3
- +#define MT8173_TSABB 4
- +
- +/* AUXADC channel 11 is used for the temperature sensors */
- +#define MT8173_TEMP_AUXADC_CHANNEL 11
- +
- +/* The total number of temperature sensors in the MT8173 */
- +#define MT8173_NUM_SENSORS 5
- +
- +/* The number of banks in the MT8173 */
- +#define MT8173_NUM_ZONES 4
- +
- +/* The number of sensing points per bank */
- +#define MT8173_NUM_SENSORS_PER_ZONE 4
- +
- +/* The number of controller in the MT8173 */
- +#define MT8173_NUM_CONTROLLER 1
- +
- +/* The calibration coefficient of sensor */
- +#define MT8173_CALIBRATION 165
- +
- +/*
- + * Layout of the fuses providing the calibration data
- + * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
- + * MT8183 has 6 sensors and needs 6 VTS calibration data.
- + * MT8173 has 5 sensors and needs 5 VTS calibration data.
- + * MT2701 has 3 sensors and needs 3 VTS calibration data.
- + * MT2712 has 4 sensors and needs 4 VTS calibration data.
- + */
- +#define CALIB_BUF0_VALID_V1 BIT(0)
- +#define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
- +#define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
- +#define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
- +#define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
- +#define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
- +#define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
- +#define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
- +#define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
- +#define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
- +#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
- +#define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
- +
- +/*
- + * Layout of the fuses providing the calibration data
- + * These macros could be used for MT7622.
- + */
- +#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff)
- +#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff)
- +#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f)
- +#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f)
- +#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff)
- +#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff)
- +#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff)
- +#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
- +#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
- +
- +/*
- + * Layout of the fuses providing the calibration data
- + * These macros can be used for MT7981 and MT7986.
- + */
- +#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
- +#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
- +#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
- +#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
- +#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
- +#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
- +#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
- +#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
- +#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
- +
- +enum {
- + VTS1,
- + VTS2,
- + VTS3,
- + VTS4,
- + VTS5,
- + VTSABB,
- + MAX_NUM_VTS,
- +};
- +
- +enum mtk_thermal_version {
- + MTK_THERMAL_V1 = 1,
- + MTK_THERMAL_V2,
- + MTK_THERMAL_V3,
- +};
- +
- +/* MT2701 thermal sensors */
- +#define MT2701_TS1 0
- +#define MT2701_TS2 1
- +#define MT2701_TSABB 2
- +
- +/* AUXADC channel 11 is used for the temperature sensors */
- +#define MT2701_TEMP_AUXADC_CHANNEL 11
- +
- +/* The total number of temperature sensors in the MT2701 */
- +#define MT2701_NUM_SENSORS 3
- +
- +/* The number of sensing points per bank */
- +#define MT2701_NUM_SENSORS_PER_ZONE 3
- +
- +/* The number of controller in the MT2701 */
- +#define MT2701_NUM_CONTROLLER 1
- +
- +/* The calibration coefficient of sensor */
- +#define MT2701_CALIBRATION 165
- +
- +/* MT2712 thermal sensors */
- +#define MT2712_TS1 0
- +#define MT2712_TS2 1
- +#define MT2712_TS3 2
- +#define MT2712_TS4 3
- +
- +/* AUXADC channel 11 is used for the temperature sensors */
- +#define MT2712_TEMP_AUXADC_CHANNEL 11
- +
- +/* The total number of temperature sensors in the MT2712 */
- +#define MT2712_NUM_SENSORS 4
- +
- +/* The number of sensing points per bank */
- +#define MT2712_NUM_SENSORS_PER_ZONE 4
- +
- +/* The number of controller in the MT2712 */
- +#define MT2712_NUM_CONTROLLER 1
- +
- +/* The calibration coefficient of sensor */
- +#define MT2712_CALIBRATION 165
- +
- +#define MT7622_TEMP_AUXADC_CHANNEL 11
- +#define MT7622_NUM_SENSORS 1
- +#define MT7622_NUM_ZONES 1
- +#define MT7622_NUM_SENSORS_PER_ZONE 1
- +#define MT7622_TS1 0
- +#define MT7622_NUM_CONTROLLER 1
- +
- +/* The maximum number of banks */
- +#define MAX_NUM_ZONES 8
- +
- +/* The calibration coefficient of sensor */
- +#define MT7622_CALIBRATION 165
- +
- +/* MT8183 thermal sensors */
- +#define MT8183_TS1 0
- +#define MT8183_TS2 1
- +#define MT8183_TS3 2
- +#define MT8183_TS4 3
- +#define MT8183_TS5 4
- +#define MT8183_TSABB 5
- +
- +/* AUXADC channel is used for the temperature sensors */
- +#define MT8183_TEMP_AUXADC_CHANNEL 11
- +
- +/* The total number of temperature sensors in the MT8183 */
- +#define MT8183_NUM_SENSORS 6
- +
- +/* The number of banks in the MT8183 */
- +#define MT8183_NUM_ZONES 1
- +
- +/* The number of sensing points per bank */
- +#define MT8183_NUM_SENSORS_PER_ZONE 6
- +
- +/* The number of controller in the MT8183 */
- +#define MT8183_NUM_CONTROLLER 2
- +
- +/* The calibration coefficient of sensor */
- +#define MT8183_CALIBRATION 153
- +
- +/* AUXADC channel 11 is used for the temperature sensors */
- +#define MT7986_TEMP_AUXADC_CHANNEL 11
- +
- +/* The total number of temperature sensors in the MT7986 */
- +#define MT7986_NUM_SENSORS 1
- +
- +/* The number of banks in the MT7986 */
- +#define MT7986_NUM_ZONES 1
- +
- +/* The number of sensing points per bank */
- +#define MT7986_NUM_SENSORS_PER_ZONE 1
- +
- +/* MT7986 thermal sensors */
- +#define MT7986_TS1 0
- +
- +/* The number of controller in the MT7986 */
- +#define MT7986_NUM_CONTROLLER 1
- +
- +/* The calibration coefficient of sensor */
- +#define MT7986_CALIBRATION 165
- +
- +struct mtk_thermal;
- +
- +struct thermal_bank_cfg {
- + unsigned int num_sensors;
- + const int *sensors;
- +};
- +
- +struct mtk_thermal_bank {
- + struct mtk_thermal *mt;
- + int id;
- +};
- +
- +struct mtk_thermal_data {
- + s32 num_banks;
- + s32 num_sensors;
- + s32 auxadc_channel;
- + const int *vts_index;
- + const int *sensor_mux_values;
- + const int *msr;
- + const int *adcpnp;
- + const int cali_val;
- + const int num_controller;
- + const int *controller_offset;
- + bool need_switch_bank;
- + struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
- + enum mtk_thermal_version version;
- +};
- +
- +struct mtk_thermal {
- + struct device *dev;
- + void __iomem *thermal_base;
- +
- + struct clk *clk_peri_therm;
- + struct clk *clk_auxadc;
- + /* lock: for getting and putting banks */
- + struct mutex lock;
- +
- + /* Calibration values */
- + s32 adc_ge;
- + s32 adc_oe;
- + s32 degc_cali;
- + s32 o_slope;
- + s32 o_slope_sign;
- + s32 vts[MAX_NUM_VTS];
- +
- + const struct mtk_thermal_data *conf;
- + struct mtk_thermal_bank banks[MAX_NUM_ZONES];
- +
- + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
- +};
- +
- +/* MT8183 thermal sensor data */
- +static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
- + MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
- +};
- +
- +static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
- + TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
- +};
- +
- +static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
- + TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
- + TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
- +};
- +
- +static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
- +static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
- +
- +static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
- + VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
- +};
- +
- +/* MT8173 thermal sensor data */
- +static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
- + { MT8173_TS2, MT8173_TS3 },
- + { MT8173_TS2, MT8173_TS4 },
- + { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
- + { MT8173_TS2 },
- +};
- +
- +static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
- + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
- +};
- +
- +static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
- + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
- +};
- +
- +static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
- +static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
- +
- +static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
- + VTS1, VTS2, VTS3, VTS4, VTSABB
- +};
- +
- +/* MT2701 thermal sensor data */
- +static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
- + MT2701_TS1, MT2701_TS2, MT2701_TSABB
- +};
- +
- +static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
- + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
- +};
- +
- +static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
- + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
- +};
- +
- +static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
- +static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
- +
- +static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
- + VTS1, VTS2, VTS3
- +};
- +
- +/* MT2712 thermal sensor data */
- +static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
- + MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
- +};
- +
- +static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
- + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
- +};
- +
- +static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
- + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
- +};
- +
- +static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
- +static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
- +
- +static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
- + VTS1, VTS2, VTS3, VTS4
- +};
- +
- +/* MT7622 thermal sensor data */
- +static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
- +static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
- +static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
- +static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
- +static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
- +static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
- +
- +/* MT7986 thermal sensor data */
- +static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
- +static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
- +static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
- +static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
- +static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
- +static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
- +
- +/*
- + * The MT8173 thermal controller has four banks. Each bank can read up to
- + * four temperature sensors simultaneously. The MT8173 has a total of 5
- + * temperature sensors. We use each bank to measure a certain area of the
- + * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
- + * areas, hence is used in different banks.
- + *
- + * The thermal core only gets the maximum temperature of all banks, so
- + * the bank concept wouldn't be necessary here. However, the SVS (Smart
- + * Voltage Scaling) unit makes its decisions based on the same bank
- + * data, and this indeed needs the temperatures of the individual banks
- + * for making better decisions.
- + */
- +static const struct mtk_thermal_data mt8173_thermal_data = {
- + .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
- + .num_banks = MT8173_NUM_ZONES,
- + .num_sensors = MT8173_NUM_SENSORS,
- + .vts_index = mt8173_vts_index,
- + .cali_val = MT8173_CALIBRATION,
- + .num_controller = MT8173_NUM_CONTROLLER,
- + .controller_offset = mt8173_tc_offset,
- + .need_switch_bank = true,
- + .bank_data = {
- + {
- + .num_sensors = 2,
- + .sensors = mt8173_bank_data[0],
- + }, {
- + .num_sensors = 2,
- + .sensors = mt8173_bank_data[1],
- + }, {
- + .num_sensors = 3,
- + .sensors = mt8173_bank_data[2],
- + }, {
- + .num_sensors = 1,
- + .sensors = mt8173_bank_data[3],
- + },
- + },
- + .msr = mt8173_msr,
- + .adcpnp = mt8173_adcpnp,
- + .sensor_mux_values = mt8173_mux_values,
- + .version = MTK_THERMAL_V1,
- +};
- +
- +/*
- + * The MT2701 thermal controller has one bank, which can read up to
- + * three temperature sensors simultaneously. The MT2701 has a total of 3
- + * temperature sensors.
- + *
- + * The thermal core only gets the maximum temperature of this one bank,
- + * so the bank concept wouldn't be necessary here. However, the SVS (Smart
- + * Voltage Scaling) unit makes its decisions based on the same bank
- + * data.
- + */
- +static const struct mtk_thermal_data mt2701_thermal_data = {
- + .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
- + .num_banks = 1,
- + .num_sensors = MT2701_NUM_SENSORS,
- + .vts_index = mt2701_vts_index,
- + .cali_val = MT2701_CALIBRATION,
- + .num_controller = MT2701_NUM_CONTROLLER,
- + .controller_offset = mt2701_tc_offset,
- + .need_switch_bank = true,
- + .bank_data = {
- + {
- + .num_sensors = 3,
- + .sensors = mt2701_bank_data,
- + },
- + },
- + .msr = mt2701_msr,
- + .adcpnp = mt2701_adcpnp,
- + .sensor_mux_values = mt2701_mux_values,
- + .version = MTK_THERMAL_V1,
- +};
- +
- +/*
- + * The MT2712 thermal controller has one bank, which can read up to
- + * four temperature sensors simultaneously. The MT2712 has a total of 4
- + * temperature sensors.
- + *
- + * The thermal core only gets the maximum temperature of this one bank,
- + * so the bank concept wouldn't be necessary here. However, the SVS (Smart
- + * Voltage Scaling) unit makes its decisions based on the same bank
- + * data.
- + */
- +static const struct mtk_thermal_data mt2712_thermal_data = {
- + .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
- + .num_banks = 1,
- + .num_sensors = MT2712_NUM_SENSORS,
- + .vts_index = mt2712_vts_index,
- + .cali_val = MT2712_CALIBRATION,
- + .num_controller = MT2712_NUM_CONTROLLER,
- + .controller_offset = mt2712_tc_offset,
- + .need_switch_bank = true,
- + .bank_data = {
- + {
- + .num_sensors = 4,
- + .sensors = mt2712_bank_data,
- + },
- + },
- + .msr = mt2712_msr,
- + .adcpnp = mt2712_adcpnp,
- + .sensor_mux_values = mt2712_mux_values,
- + .version = MTK_THERMAL_V1,
- +};
- +
- +/*
- + * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
- + * access.
- + */
- +static const struct mtk_thermal_data mt7622_thermal_data = {
- + .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
- + .num_banks = MT7622_NUM_ZONES,
- + .num_sensors = MT7622_NUM_SENSORS,
- + .vts_index = mt7622_vts_index,
- + .cali_val = MT7622_CALIBRATION,
- + .num_controller = MT7622_NUM_CONTROLLER,
- + .controller_offset = mt7622_tc_offset,
- + .need_switch_bank = true,
- + .bank_data = {
- + {
- + .num_sensors = 1,
- + .sensors = mt7622_bank_data,
- + },
- + },
- + .msr = mt7622_msr,
- + .adcpnp = mt7622_adcpnp,
- + .sensor_mux_values = mt7622_mux_values,
- + .version = MTK_THERMAL_V2,
- +};
- +
- +/*
- + * The MT8183 thermal controller has one bank for the current SW framework.
- + * The MT8183 has a total of 6 temperature sensors.
- + * There are two thermal controller to control the six sensor.
- + * The first one bind 2 sensor, and the other bind 4 sensors.
- + * The thermal core only gets the maximum temperature of all sensor, so
- + * the bank concept wouldn't be necessary here. However, the SVS (Smart
- + * Voltage Scaling) unit makes its decisions based on the same bank
- + * data, and this indeed needs the temperatures of the individual banks
- + * for making better decisions.
- + */
- +static const struct mtk_thermal_data mt8183_thermal_data = {
- + .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
- + .num_banks = MT8183_NUM_ZONES,
- + .num_sensors = MT8183_NUM_SENSORS,
- + .vts_index = mt8183_vts_index,
- + .cali_val = MT8183_CALIBRATION,
- + .num_controller = MT8183_NUM_CONTROLLER,
- + .controller_offset = mt8183_tc_offset,
- + .need_switch_bank = false,
- + .bank_data = {
- + {
- + .num_sensors = 6,
- + .sensors = mt8183_bank_data,
- + },
- + },
- +
- + .msr = mt8183_msr,
- + .adcpnp = mt8183_adcpnp,
- + .sensor_mux_values = mt8183_mux_values,
- + .version = MTK_THERMAL_V1,
- +};
- +
- +/*
- + * MT7986 uses AUXADC Channel 11 for raw data access.
- + */
- +static const struct mtk_thermal_data mt7986_thermal_data = {
- + .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
- + .num_banks = MT7986_NUM_ZONES,
- + .num_sensors = MT7986_NUM_SENSORS,
- + .vts_index = mt7986_vts_index,
- + .cali_val = MT7986_CALIBRATION,
- + .num_controller = MT7986_NUM_CONTROLLER,
- + .controller_offset = mt7986_tc_offset,
- + .need_switch_bank = true,
- + .bank_data = {
- + {
- + .num_sensors = 1,
- + .sensors = mt7986_bank_data,
- + },
- + },
- + .msr = mt7986_msr,
- + .adcpnp = mt7986_adcpnp,
- + .sensor_mux_values = mt7986_mux_values,
- + .version = MTK_THERMAL_V3,
- +};
- +
- +/**
- + * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
- + * @mt: The thermal controller
- + * @sensno: sensor number
- + * @raw: raw ADC value
- + *
- + * This converts the raw ADC value to mcelsius using the SoC specific
- + * calibration constants
- + */
- +static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
- +{
- + s32 tmp;
- +
- + raw &= 0xfff;
- +
- + tmp = 203450520 << 3;
- + tmp /= mt->conf->cali_val + mt->o_slope;
- + tmp /= 10000 + mt->adc_ge;
- + tmp *= raw - mt->vts[sensno] - 3350;
- + tmp >>= 3;
- +
- + return mt->degc_cali * 500 - tmp;
- +}
- +
- +static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
- +{
- + s32 format_1;
- + s32 format_2;
- + s32 g_oe;
- + s32 g_gain;
- + s32 g_x_roomt;
- + s32 tmp;
- +
- + if (raw == 0)
- + return 0;
- +
- + raw &= 0xfff;
- + g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
- + g_oe = mt->adc_oe - 512;
- + format_1 = mt->vts[VTS2] + 3105 - g_oe;
- + format_2 = (mt->degc_cali * 10) >> 1;
- + g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
- +
- + tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
- + tmp = tmp * 10 * 100 / 11;
- +
- + if (mt->o_slope_sign == 0)
- + tmp = tmp / (165 - mt->o_slope);
- + else
- + tmp = tmp / (165 + mt->o_slope);
- +
- + return (format_2 - tmp) * 100;
- +}
- +
- +static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
- +{
- + s32 tmp;
- +
- + if (raw == 0)
- + return 0;
- +
- + raw &= 0xfff;
- + tmp = 100000 * 15 / 16 * 10000;
- + tmp /= 4096 - 512 + mt->adc_ge;
- + tmp /= 1490;
- + tmp *= raw - mt->vts[sensno] - 2900;
- +
- + return mt->degc_cali * 500 - tmp;
- +}
- +
- +/**
- + * mtk_thermal_get_bank - get bank
- + * @bank: The bank
- + *
- + * The bank registers are banked, we have to select a bank in the
- + * PTPCORESEL register to access it.
- + */
- +static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
- +{
- + struct mtk_thermal *mt = bank->mt;
- + u32 val;
- +
- + if (mt->conf->need_switch_bank) {
- + mutex_lock(&mt->lock);
- +
- + val = readl(mt->thermal_base + PTPCORESEL);
- + val &= ~0xf;
- + val |= bank->id;
- + writel(val, mt->thermal_base + PTPCORESEL);
- + }
- +}
- +
- +/**
- + * mtk_thermal_put_bank - release bank
- + * @bank: The bank
- + *
- + * release a bank previously taken with mtk_thermal_get_bank,
- + */
- +static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
- +{
- + struct mtk_thermal *mt = bank->mt;
- +
- + if (mt->conf->need_switch_bank)
- + mutex_unlock(&mt->lock);
- +}
- +
- +/**
- + * mtk_thermal_bank_temperature - get the temperature of a bank
- + * @bank: The bank
- + *
- + * The temperature of a bank is considered the maximum temperature of
- + * the sensors associated to the bank.
- + */
- +static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
- +{
- + struct mtk_thermal *mt = bank->mt;
- + const struct mtk_thermal_data *conf = mt->conf;
- + int i, temp = INT_MIN, max = INT_MIN;
- + u32 raw;
- +
- + for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
- + raw = readl(mt->thermal_base + conf->msr[i]);
- +
- + temp = mt->raw_to_mcelsius(
- + mt, conf->bank_data[bank->id].sensors[i], raw);
- +
- +
- + /*
- + * The first read of a sensor often contains very high bogus
- + * temperature value. Filter these out so that the system does
- + * not immediately shut down.
- + */
- + if (temp > 200000)
- + temp = 0;
- +
- + if (temp > max)
- + max = temp;
- + }
- +
- + return max;
- +}
- +
- +static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
- +{
- + struct mtk_thermal *mt = tz->devdata;
- + int i;
- + int tempmax = INT_MIN;
- +
- + for (i = 0; i < mt->conf->num_banks; i++) {
- + struct mtk_thermal_bank *bank = &mt->banks[i];
- +
- + mtk_thermal_get_bank(bank);
- +
- + tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
- +
- + mtk_thermal_put_bank(bank);
- + }
- +
- + *temperature = tempmax;
- +
- + return 0;
- +}
- +
- +static const struct thermal_zone_device_ops mtk_thermal_ops = {
- + .get_temp = mtk_read_temp,
- +};
- +
- +static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
- + u32 apmixed_phys_base, u32 auxadc_phys_base,
- + int ctrl_id)
- +{
- + struct mtk_thermal_bank *bank = &mt->banks[num];
- + const struct mtk_thermal_data *conf = mt->conf;
- + int i;
- +
- + int offset = mt->conf->controller_offset[ctrl_id];
- + void __iomem *controller_base = mt->thermal_base + offset;
- +
- + bank->id = num;
- + bank->mt = mt;
- +
- + mtk_thermal_get_bank(bank);
- +
- + /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
- + writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
- +
- + /*
- + * filt interval is 1 * 46.540us = 46.54us,
- + * sen interval is 429 * 46.540us = 19.96ms
- + */
- + writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
- + TEMP_MONCTL2_SENSOR_INTERVAL(429),
- + controller_base + TEMP_MONCTL2);
- +
- + /* poll is set to 10u */
- + writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
- + controller_base + TEMP_AHBPOLL);
- +
- + /* temperature sampling control, 1 sample */
- + writel(0x0, controller_base + TEMP_MSRCTL0);
- +
- + /* exceed this polling time, IRQ would be inserted */
- + writel(0xffffffff, controller_base + TEMP_AHBTO);
- +
- + /* number of interrupts per event, 1 is enough */
- + writel(0x0, controller_base + TEMP_MONIDET0);
- + writel(0x0, controller_base + TEMP_MONIDET1);
- +
- + /*
- + * The MT8173 thermal controller does not have its own ADC. Instead it
- + * uses AHB bus accesses to control the AUXADC. To do this the thermal
- + * controller has to be programmed with the physical addresses of the
- + * AUXADC registers and with the various bit positions in the AUXADC.
- + * Also the thermal controller controls a mux in the APMIXEDSYS register
- + * space.
- + */
- +
- + /*
- + * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
- + * automatically by hw
- + */
- + writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
- +
- + /* AHB address for auxadc mux selection */
- + writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
- + controller_base + TEMP_ADCMUXADDR);
- +
- + if (mt->conf->version == MTK_THERMAL_V1) {
- + /* AHB address for pnp sensor mux selection */
- + writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
- + controller_base + TEMP_PNPMUXADDR);
- + }
- +
- + /* AHB value for auxadc enable */
- + writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
- +
- + /* AHB address for auxadc enable (channel 0 immediate mode selected) */
- + writel(auxadc_phys_base + AUXADC_CON1_SET_V,
- + controller_base + TEMP_ADCENADDR);
- +
- + /* AHB address for auxadc valid bit */
- + writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
- + controller_base + TEMP_ADCVALIDADDR);
- +
- + /* AHB address for auxadc voltage output */
- + writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
- + controller_base + TEMP_ADCVOLTADDR);
- +
- + /* read valid & voltage are at the same register */
- + writel(0x0, controller_base + TEMP_RDCTRL);
- +
- + /* indicate where the valid bit is */
- + writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
- + controller_base + TEMP_ADCVALIDMASK);
- +
- + /* no shift */
- + writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
- +
- + /* enable auxadc mux write transaction */
- + writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
- + controller_base + TEMP_ADCWRITECTRL);
- +
- + for (i = 0; i < conf->bank_data[num].num_sensors; i++)
- + writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
- + mt->thermal_base + conf->adcpnp[i]);
- +
- + writel((1 << conf->bank_data[num].num_sensors) - 1,
- + controller_base + TEMP_MONCTL0);
- +
- + writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
- + TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
- + controller_base + TEMP_ADCWRITECTRL);
- +
- + mtk_thermal_put_bank(bank);
- +}
- +
- +static u64 of_get_phys_base(struct device_node *np)
- +{
- + u64 size64;
- + const __be32 *regaddr_p;
- +
- + regaddr_p = of_get_address(np, 0, &size64, NULL);
- + if (!regaddr_p)
- + return OF_BAD_ADDR;
- +
- + return of_translate_address(np, regaddr_p);
- +}
- +
- +static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
- +{
- + int i;
- +
- + if (!(buf[0] & CALIB_BUF0_VALID_V1))
- + return -EINVAL;
- +
- + mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
- +
- + for (i = 0; i < mt->conf->num_sensors; i++) {
- + switch (mt->conf->vts_index[i]) {
- + case VTS1:
- + mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
- + break;
- + case VTS2:
- + mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
- + break;
- + case VTS3:
- + mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
- + break;
- + case VTS4:
- + mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
- + break;
- + case VTS5:
- + mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
- + break;
- + case VTSABB:
- + mt->vts[VTSABB] =
- + CALIB_BUF2_VTS_TSABB_V1(buf[2]);
- + break;
- + default:
- + break;
- + }
- + }
- +
- + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
- + if (CALIB_BUF1_ID_V1(buf[1]) &
- + CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
- + mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
- + else
- + mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
- +
- + return 0;
- +}
- +
- +static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
- +{
- + if (!CALIB_BUF1_VALID_V2(buf[1]))
- + return -EINVAL;
- +
- + mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
- + mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
- + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
- + mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
- + mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
- + mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
- + mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
- + mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
- +
- + return 0;
- +}
- +
- +static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
- +{
- + if (!CALIB_BUF1_VALID_V3(buf[1]))
- + return -EINVAL;
- +
- + mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
- + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
- + mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
- + mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
- + mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
- + mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
- + mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
- +
- + if (CALIB_BUF1_ID_V3(buf[1]) == 0)
- + mt->o_slope = 0;
- +
- + return 0;
- +}
- +
- +static int mtk_thermal_get_calibration_data(struct device *dev,
- + struct mtk_thermal *mt)
- +{
- + struct nvmem_cell *cell;
- + u32 *buf;
- + size_t len;
- + int i, ret = 0;
- +
- + /* Start with default values */
- + mt->adc_ge = 512;
- + mt->adc_oe = 512;
- + for (i = 0; i < mt->conf->num_sensors; i++)
- + mt->vts[i] = 260;
- + mt->degc_cali = 40;
- + mt->o_slope = 0;
- +
- + cell = nvmem_cell_get(dev, "calibration-data");
- + if (IS_ERR(cell)) {
- + if (PTR_ERR(cell) == -EPROBE_DEFER)
- + return PTR_ERR(cell);
- + return 0;
- + }
- +
- + buf = (u32 *)nvmem_cell_read(cell, &len);
- +
- + nvmem_cell_put(cell);
- +
- + if (IS_ERR(buf))
- + return PTR_ERR(buf);
- +
- + if (len < 3 * sizeof(u32)) {
- + dev_warn(dev, "invalid calibration data\n");
- + ret = -EINVAL;
- + goto out;
- + }
- +
- + switch (mt->conf->version) {
- + case MTK_THERMAL_V1:
- + ret = mtk_thermal_extract_efuse_v1(mt, buf);
- + break;
- + case MTK_THERMAL_V2:
- + ret = mtk_thermal_extract_efuse_v2(mt, buf);
- + break;
- + case MTK_THERMAL_V3:
- + ret = mtk_thermal_extract_efuse_v3(mt, buf);
- + break;
- + default:
- + ret = -EINVAL;
- + break;
- + }
- +
- + if (ret) {
- + dev_info(dev, "Device not calibrated, using default calibration values\n");
- + ret = 0;
- + }
- +
- +out:
- + kfree(buf);
- +
- + return ret;
- +}
- +
- +static const struct of_device_id mtk_thermal_of_match[] = {
- + {
- + .compatible = "mediatek,mt8173-thermal",
- + .data = (void *)&mt8173_thermal_data,
- + },
- + {
- + .compatible = "mediatek,mt2701-thermal",
- + .data = (void *)&mt2701_thermal_data,
- + },
- + {
- + .compatible = "mediatek,mt2712-thermal",
- + .data = (void *)&mt2712_thermal_data,
- + },
- + {
- + .compatible = "mediatek,mt7622-thermal",
- + .data = (void *)&mt7622_thermal_data,
- + },
- + {
- + .compatible = "mediatek,mt7986-thermal",
- + .data = (void *)&mt7986_thermal_data,
- + },
- + {
- + .compatible = "mediatek,mt8183-thermal",
- + .data = (void *)&mt8183_thermal_data,
- + }, {
- + },
- +};
- +MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
- +
- +static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
- +{
- + int tmp;
- +
- + tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
- + tmp &= ~(0x37);
- + tmp |= 0x1;
- + writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
- + udelay(200);
- +}
- +
- +static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
- + void __iomem *auxadc_base)
- +{
- + int tmp;
- +
- + writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
- + writel(0x1, mt->thermal_base + TEMP_MONCTL0);
- + tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
- + writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
- +}
- +
- +static int mtk_thermal_probe(struct platform_device *pdev)
- +{
- + int ret, i, ctrl_id;
- + struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
- + struct mtk_thermal *mt;
- + u64 auxadc_phys_base, apmixed_phys_base;
- + struct thermal_zone_device *tzdev;
- + void __iomem *apmixed_base, *auxadc_base;
- +
- + mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
- + if (!mt)
- + return -ENOMEM;
- +
- + mt->conf = of_device_get_match_data(&pdev->dev);
- +
- + mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
- + if (IS_ERR(mt->clk_peri_therm))
- + return PTR_ERR(mt->clk_peri_therm);
- +
- + mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
- + if (IS_ERR(mt->clk_auxadc))
- + return PTR_ERR(mt->clk_auxadc);
- +
- + mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- + if (IS_ERR(mt->thermal_base))
- + return PTR_ERR(mt->thermal_base);
- +
- + ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
- + if (ret)
- + return ret;
- +
- + mutex_init(&mt->lock);
- +
- + mt->dev = &pdev->dev;
- +
- + auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
- + if (!auxadc) {
- + dev_err(&pdev->dev, "missing auxadc node\n");
- + return -ENODEV;
- + }
- +
- + auxadc_base = of_iomap(auxadc, 0);
- + auxadc_phys_base = of_get_phys_base(auxadc);
- +
- + of_node_put(auxadc);
- +
- + if (auxadc_phys_base == OF_BAD_ADDR) {
- + dev_err(&pdev->dev, "Can't get auxadc phys address\n");
- + return -EINVAL;
- + }
- +
- + apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
- + if (!apmixedsys) {
- + dev_err(&pdev->dev, "missing apmixedsys node\n");
- + return -ENODEV;
- + }
- +
- + apmixed_base = of_iomap(apmixedsys, 0);
- + apmixed_phys_base = of_get_phys_base(apmixedsys);
- +
- + of_node_put(apmixedsys);
- +
- + if (apmixed_phys_base == OF_BAD_ADDR) {
- + dev_err(&pdev->dev, "Can't get auxadc phys address\n");
- + return -EINVAL;
- + }
- +
- + ret = device_reset_optional(&pdev->dev);
- + if (ret)
- + return ret;
- +
- + ret = clk_prepare_enable(mt->clk_auxadc);
- + if (ret) {
- + dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
- + return ret;
- + }
- +
- + ret = clk_prepare_enable(mt->clk_peri_therm);
- + if (ret) {
- + dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
- + goto err_disable_clk_auxadc;
- + }
- +
- + if (mt->conf->version != MTK_THERMAL_V1) {
- + mtk_thermal_turn_on_buffer(apmixed_base);
- + mtk_thermal_release_periodic_ts(mt, auxadc_base);
- + }
- +
- + if (mt->conf->version == MTK_THERMAL_V1)
- + mt->raw_to_mcelsius = raw_to_mcelsius_v1;
- + else if (mt->conf->version == MTK_THERMAL_V2)
- + mt->raw_to_mcelsius = raw_to_mcelsius_v2;
- + else
- + mt->raw_to_mcelsius = raw_to_mcelsius_v3;
- +
- + for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
- + for (i = 0; i < mt->conf->num_banks; i++)
- + mtk_thermal_init_bank(mt, i, apmixed_phys_base,
- + auxadc_phys_base, ctrl_id);
- +
- + platform_set_drvdata(pdev, mt);
- +
- + tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- + &mtk_thermal_ops);
- + if (IS_ERR(tzdev)) {
- + ret = PTR_ERR(tzdev);
- + goto err_disable_clk_peri_therm;
- + }
- +
- + ret = devm_thermal_add_hwmon_sysfs(tzdev);
- + if (ret)
- + dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
- +
- + return 0;
- +
- +err_disable_clk_peri_therm:
- + clk_disable_unprepare(mt->clk_peri_therm);
- +err_disable_clk_auxadc:
- + clk_disable_unprepare(mt->clk_auxadc);
- +
- + return ret;
- +}
- +
- +static int mtk_thermal_remove(struct platform_device *pdev)
- +{
- + struct mtk_thermal *mt = platform_get_drvdata(pdev);
- +
- + clk_disable_unprepare(mt->clk_peri_therm);
- + clk_disable_unprepare(mt->clk_auxadc);
- +
- + return 0;
- +}
- +
- +static struct platform_driver mtk_thermal_driver = {
- + .probe = mtk_thermal_probe,
- + .remove = mtk_thermal_remove,
- + .driver = {
- + .name = "mtk-thermal",
- + .of_match_table = mtk_thermal_of_match,
- + },
- +};
- +
- +module_platform_driver(mtk_thermal_driver);
- +
- +MODULE_AUTHOR("Michael Kao <[email protected]>");
- +MODULE_AUTHOR("Louis Yu <[email protected]>");
- +MODULE_AUTHOR("Dawei Chien <[email protected]>");
- +MODULE_AUTHOR("Sascha Hauer <[email protected]>");
- +MODULE_AUTHOR("Hanyi Wu <[email protected]>");
- +MODULE_DESCRIPTION("Mediatek thermal driver");
- +MODULE_LICENSE("GPL v2");
|